# Computing derivatives (at a point) efficiently

I need to compute all derivatives for a multi-variable expression upto a certain number of derivatives dmax evaluated at a point. So I need say the n-th x and m-th y derivatives (i.e. D[f[x,y],{x,n},{y,m}]) for all n,m<dmax evaluated at {x0,y0}.

More specifically I usually need only the derivatives such that m is greater or equal than n. What is the most efficient way to calculate this memory and time wise?

My own attempts are:

Based on Series (and undoing the factorial factors):

TimesPositionFactorial[list_List]:=Table[(i-1) ! list[[i]],{i,Length[list]}];

DerivativesAtPointUnpacked[expr_,derivmax_,vars_,points_]:=Block[{L=Length[points],aux=expr},Do[
aux=If[t==1,
TimesPositionFactorial@(Part[#,3]&@(Series[#,{vars[[t]],points[[t]],derivmax}]&@aux)),
Map[TimesPositionFactorial,(Map[Part[#,3]&,(Map[Series[#,{vars[[t]],points[[t]],derivmax}]&,aux,t-1]),t-1]),t-1]];,{t,L}];
aux
]


More narrow (Using the fact that I only need $m\geq n$):

 functionMap[funcs_List, data_] :=
Module[{fn = RotateRight[funcs]},
First[(fn = RotateLeft[fn])][#] & /@ data]

fastDDaux[expr_, derivmax_, var_] := Reap[
Module[{aux = expr},
Sow[aux, fDD];
aux = Do[aux = (D[#, var]) &[aux];
Sow[aux, fDD], {i, derivmax}]], fDD][[2]]

symDD[expr_, derivmax_, vars_List?(Length[#] == 2 &), points_List] :=
derivmax + 1] & /@ (functionMap[
Table[With[{j = j}, fastDDaux[#, j - 1, vars[[2]]] &], {j,
derivmax + 1}],
fastDDaux[expr, derivmax, vars[[1]]] // Flatten] //
Flatten[#, 1] &) /. {vars[[1]] -> points[[1]],
vars[[2]] -> points[[2]]}


This last one seems reasonably good, but still someone here can probably do better. Can we save on memory and time, this would really help since for large value, say dmax=40, the memory and time costs can get really high.

I used functionMap from How to apply or map a list of functions to a list of data?

The points are not machine numbers but high precision numbers. An example function:

exampleFunction[z_,zb_]:=-(1/(4 z zb))(-1+z) (-1+zb) (4 (-1+z) z (-1+zb) zb (-zb^3+z zb^2 (-1+4 zb)-z^2 zb (1-4 zb+6 zb^2)+z^3 (-1+4 zb-6 zb^2+4 zb^3)) Dzf["J"][1][z,zb]-4 (-1+z) z (-1+zb) zb (-zb^3+z zb^2 (-1+4 zb)-z^2 zb (1-4 zb+6 zb^2)+z^3 (-1+4 zb-6 zb^2+4 zb^3)) Dzf["J"][3][z,zb]+(z-zb)^2 (z zb (-1+2 zb+z^2 zb (-1+2 zb)-z (-2+3 zb+zb^2)) Dzf["J"][31][z,zb]-(-1+z) (-1+zb) (zb^2+z (zb-3 zb^2)+z^2 (1-3 zb+2 zb^2)) Dzf["J"][40][z,zb]))


The Dzf derivatives have already been computed and just need to be replaced. They are not important for this part.

• May I ask what an application of 40 derivatives would be? – Henrik Schumacher Mar 23 '18 at 16:23
• Is {x0, y0} a pair of machine numbers, or a pair of exact numbers? Do you have an example function f? – Carl Woll Mar 23 '18 at 17:45
• @HenrikSchumacher: The purpose of the high number of derivatives is to checking the feasibility of an equation by looking at the resulting equalities of a functional consisting of derivatives applied to the equation. Say the RHS is zero, then derivatives applied to it will remain zero, but now it might be possible to show that the LHS is positive, where before it was to complicated an object to say anything useful about. – Kvothe Mar 26 '18 at 9:40
• @Carl, high precision numbers. And I added an example function. – Kvothe Mar 26 '18 at 9:41
• Have you tried to use lower derivatives to calculate higher? – Vsevolod A. Mar 26 '18 at 21:03