I'm wondering if an automatic differentiation package exists for Mathematica. This is what I mean by automatic differentiation.
2 Answers
For anyone still interested in this: I'm working on an implementation of dual numbers for Mathematica which should allow you to calculate automatic derivatives of (hopefully) many programs.
Check it out on GitHub.
Here's a quick example of how to obtain the derivative of a programmatic function with a While loop (adapted from the documentation). It's a fixed point algorithm to solve an equation:
f[a_?NumericQ, x0 : _?NumericQ : 1.0] :=
Module[{ x = x0, y, i = 0},
While[(y = Cos[a x]) != x,
x = y;
i++
];
x
];
It doesn't have a symbolic derivative:
Derivative[1] @ f
(* Derivative[1][f] *)
You can find the derivative of its first argument simply by passing a Dual with non-standard part equal to 1:
<<DualNumbers`
f[1.]
f[Dual[1., 1.]]
(* 0.739085 *)
(* Dual[0.739085, -0.297474] *)
The first argument of Dual is the function value and the second argument is the derivative at that point. Let's convince ourselves that this derivative is correct:
With[{h = 0.001, a = 1.0},
(f[a + h] - f[a - h])/(2 h)
]
(* -0.297474 *)
Let's also check the derivative of the second argument:
f[1., Dual[1., 1.]]
(* Dual[0.739085, 1.86543*10^-14] *)
The derivative of the second argument is pretty much zero. This makes sense, of course, since small variations in the initial value in the fixed point search shouldn't influence the result.
- 23,370
- 46
- 75
-
I'm intrigued! Could you add an example or two here of using it for automatic differentiation? – Chris K Sep 14 '20 at 17:38
-
1@ChrisK I'm still working on documentation and examples, but this should give you an idea. If you have any ideas to try it out on, please let me know :). – Sjoerd Smit Sep 14 '20 at 18:20
-
1For neural networks, I always wanted something that could derive backward AD in matrix or einsum notation. For instance results in https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf . When I was on tensorflow team, we derived them by hand, basically through "guess-and-check" – Yaroslav Bulatov Sep 14 '20 at 19:00
-
BTW, if you make it work for einsum notation, @Carl Woll's
TensorReduceautomatically translates it into matrix notation -- https://mathematica.stackexchange.com/questions/207336/generating-an-efficient-way-to-compute-einsum – Yaroslav Bulatov Sep 14 '20 at 19:08 -
2@YaroslavBulatov That's a good idea, but I've not used that package before so it might be a while for me to look into this. Feel free to make a pull request to my repo if you have any ideas about this. – Sjoerd Smit Sep 14 '20 at 19:15
-
Thanks for the examples. Now I need to come up with some application for myself ;) – Chris K Sep 15 '20 at 00:38
-
2For anyone interested in the question by @YaroslavBulatov : see the discussion on GitHub: https://github.com/ssmit1986/DualNumbers/issues/1 – Sjoerd Smit Sep 16 '20 at 06:30
-
@SjoerdSmit This is very cool. Thanks! This is Forward mode AD, right? are you planning to implement reverse mode AD too? – sra Jan 29 '21 at 00:24
-
@psimeson Correct, this is for forwards AD. Reverse AD will be a lot more work to implement and I don't plan on starting that any time soon (if at all), given how much time I can spend on these sorts of hobby projects right now (i.e., not a lot). I also think that reverse mode AD should probably be implemented at a deeper level in the kernel code and that's not really my expertise. I'm kinda hoping that the idea might be picked up in Champaign for a future release of WL. – Sjoerd Smit Jan 29 '21 at 07:38
-
@SjoerdSmit I hope Wolfram picks up the AD idea and implements it at the core level. Julia language seems to be doing so. – sra Jan 29 '21 at 16:13
-
@SjoerdSmit can we find an example for Derivatives of tensor valued functions of second-order tensors using this package? – ABCDEMMM Jun 18 '21 at 23:13
-
@ABCDEMMM If you post an issue in my GH repository with some examples of what you want to do (i.e, desired input and output), I'll take a look when I have time. – Sjoerd Smit Jun 21 '21 at 08:54
-
Dual numbers can be implemented by adding just one line to a notebook:
$Pre=MatrixFunction[Function[ε,#],{{0,0},{1,0}}]/.{{a_,b_},{0,a_}}->a+ε b /.{{a_,0},{b_,a_}}->a+ε b&;https://mathematica.stackexchange.com/a/241593/651 – Anixx Dec 17 '21 at 15:52
Try this. It may not be exactly what your looking for, but it also may give you a good starting point.
- 124,525
- 11
- 401
- 574
- 4,518
- 2
- 30
- 58
D/Derivative. It will be interesting to see some rudimentary implementations. See also http://forums.wolfram.com/mathgroup/archive/2008/Feb/msg00381.html – Szabolcs Feb 16 '12 at 15:19D. – David Z Feb 16 '12 at 18:12