Function Repository Resource:

 NDerivative

Source Notebook

Find a numerical approximation to a function derivative near the specified point

Contributed by: Wolfram Research

ResourceFunction["NDerivative"][expr,x,x0]

gives a numerical approximation to the derivative of expr with respect to x at the point x0.

ResourceFunction["NDerivative"][expr,{x,n},x0]

gives a numerical approximation to the nth derivative of expr.

Details and Options

The expression expr must be numeric when its argument x is numeric.
ResourceFunction["NDerivative"][expr,x,x0] is equivalent to ResourceFunction["NDerivative"][expr,{x,1},x0].
ResourceFunction["NDerivative"] is unable to recognize small numbers that should in fact be zero. Chop may be needed to eliminate these spurious residuals.
The following options can be given:
Method"EulerSum"method to use
"Scale"1size at which variations are expected
"Terms"7number of terms to be used
WorkingPrecisionMachinePrecisionprecision to use in internal computations
Possible settings for Method include:
"EulerSum"use Richardson’s extrapolation to the limit
NIntegrateuse Cauchy’s integral formula
With Method→"EulerSum", ResourceFunction["NDerivative"] needs to evaluate expr at x0.
If expr is not analytic in the neighborhood of x0, then the default method "EulerSum" must be used.
The option "Scale"→s is used to capture the scale of variation when using Method→"EulerSum".
When the value of the derivative depends on the direction, the default is to the right. Other directions can be chosen with the option "Scale"→s, where the direction is s.
The option "Terms"→n gives the number of terms to use for extrapolation when using Method→"EulerSum".
With Method→NIntegrate, the expression expr must be analytic in a neighborhood of the point x0.
The option "Scale"→r specifies the radius of the contour of integration to use with Method→NIntegrate.

Examples

Basic Examples (2) 

Take the numerical derivative of an exponential:

In[1]:=
ResourceFunction["NDerivative"][Exp[x], x, 1]
Out[1]=

Take the numerical derivative of a trig power:

In[2]:=
ResourceFunction["NDerivative"][Cos[x]^3, {x, 2}, 0]
Out[2]=

Scope (1) 

The expression and evaluation point may be complex valued:

In[3]:=
ResourceFunction["NDerivative"][Sin[x], x, \[Pi] I]
Out[3]=
In[4]:=
ResourceFunction["NDerivative"][Cos[I x], x, 1 + I]
Out[4]=

Generalizations & Extensions (1) 

NDerivative threads over its first argument:

In[5]:=
ResourceFunction["NDerivative"][{Exp[x], Sin[x]}, x, 1]
Out[5]=

Options (16) 

Method (2) 

Use the default Method→"EulerSum" when expr is not analytic in the neighborhood of x0:

In[6]:=
ResourceFunction["NDerivative"][Re[Cos[I y]], y, 1]
Out[6]=

Check:

In[7]:=
D[ComplexExpand[Re[Cos[I y]]], y] /. y -> 1 // N
Out[7]=

An incorrect answer is obtained with Method→NIntegrate:

In[8]:=
ResourceFunction["NDerivative"][Re[Cos[I y]], y, 1, Method -> NIntegrate]
Out[8]=

Here is a derivative where the default method works poorly:

In[9]:=
ResourceFunction["NDerivative"][Exp[x^2], {x, 3}, 1]
Out[9]=

The correct answer is:

In[10]:=
D[Exp[x^2], {x, 3}] /. x -> 1.
Out[10]=

In this case the expression is analytic, so Method→NIntegrate will work well:

In[11]:=
ResourceFunction["NDerivative"][Exp[x^2], {x, 3}, 1, Method -> NIntegrate]
Out[11]=

Scale (3) 

Use Scale→s to capture the region of variation:

In[12]:=
ResourceFunction["NDerivative"][Sin[100 x], x, 0]
Out[12]=

The scale of variation is around .01:

In[13]:=
ResourceFunction["NDerivative"][Sin[100 x], x, 0, "Scale" -> .01]
Out[13]=

A value of Scale→s that is too large can be compensated by increasing the number of terms:

In[14]:=
ResourceFunction["NDerivative"][Sin[100 x], x, 0, "Terms" -> 11]
Out[14]=

Use Scale to specify directional derivatives. The left and right derivatives of the nonanalytic function |x|:

In[15]:=
ResourceFunction["NDerivative"][Abs[x], {x, 1}, 0]
Out[15]=
In[16]:=
ResourceFunction["NDerivative"][Abs[x], {x, 1}, 0, "Scale" -> -1]
Out[16]=

Check:

In[17]:=
Plot[Abs[x], {x, -1, 1}]
Out[17]=

Complex directions may also be specified:

In[18]:=
ResourceFunction["NDerivative"][Abs[x], {x, 1}, 0, "Scale" -> 1 + I]
Out[18]=

Check:

In[19]:=
Limit[(Abs[(1 + I) h] - Abs[0])/((1 + I) h), h -> 0, Direction -> -1] // N
Out[19]=

Use the option Scale to avoid regions of nonanalyticity when the method used is NIntegrate:

In[20]:=
ResourceFunction["NDerivative"][Exp[1/(1 - x)], x, .5, Method -> NIntegrate]
Out[20]=

Shrinking the radius avoids the essential singularity at x⩵1:

In[21]:=
ResourceFunction["NDerivative"][Exp[1/(1 - x)], x, .5, Method -> NIntegrate, Scale -> .1]
Out[21]=

Check:

In[22]:=
D[Exp[1/(1 - x)], x] /. x -> .5
Out[22]=

Terms (5) 

Increasing the number of terms may improve accuracy. Here is a somewhat inaccurate approximation:

In[23]:=
ResourceFunction["NDerivative"][Sin[x^2], {x, 3}, 1]
Out[23]=

Check:

In[24]:=
D[Sin[x^2], {x, 3}] /. x -> 1`30
Out[24]=

Increasing the number of terms produces a more accurate answer:

In[25]:=
ResourceFunction["NDerivative"][Sin[x^2], {x, 3}, 1, "Terms" -> 10] // FullForm
Out[25]=

Increasing the number of terms further can produce nonsense due to numerical instability:

In[26]:=
ResourceFunction["NDerivative"][Sin[x^2], {x, 3}, 1, "Terms" -> 20]
Out[26]=

Combining an increase in the number of terms with a higher working precision often will reduce the error:

In[27]:=
ResourceFunction["NDerivative"][Sin[x^2], {x, 3}, 1, "Terms" -> 20, WorkingPrecision -> 40]
Out[27]=

WorkingPrecision (6) 

High-order derivatives with Method→"EulerSum" experience significant subtractive cancellation:

In[28]:=
ResourceFunction["NDerivative"][Exp[x], {x, 10}, 0]
Out[28]=

Using a higher working precision and additional terms produces an accurate answer:

In[29]:=
ResourceFunction["NDerivative"][Exp[x], {x, 10}, 0, WorkingPrecision -> 40, "Terms" -> 10]
Out[29]=

For this problem, Method→NIntegrate with default options produces a correct answer:

In[30]:=
ResourceFunction["NDerivative"][Exp[x], {x, 10}, 0, Method -> NIntegrate]
Out[30]=

Higher-order derivatives will again experience numerical instability:

In[31]:=
ResourceFunction["NDerivative"][Exp[x], {x, 20}, 0, Method -> NIntegrate]
Out[31]=

Increasing WorkingPrecision will improve the accuracy:

In[32]:=
ResourceFunction["NDerivative"][Exp[x], {x, 20}, 0, Method -> NIntegrate, WorkingPrecision -> 30]
Out[32]=

An alternative is to increase the radius of the contour of integration:

In[33]:=
ResourceFunction["NDerivative"][Exp[x], {x, 20}, 0, Method -> NIntegrate, "Scale" -> 5]
Out[33]=

Applications (4) 

NDerivative is useful for differentiating functions that are only defined numerically. Here is such a function:

In[34]:=
f[a_?NumericQ, b_?NumericQ] := f[a, b] = Module[{t}, y /. NDSolve[{y'[t] == a - b y[t]^3, y[0] == 1}, y, {t, 0, 1}][[
     1]]]

Here is the derivative of f[a,b][t] with respect to b evaluated at {a,b,t}={1,2,1}:

In[35]:=
ResourceFunction["NDerivative"][f[1, b][1], {b, 1}, 2]
Out[35]=

NDerivative can be used as an aid in developing and testing a more robust function for finding the derivative:

In[36]:=
fb[a_?NumericQ, b_?NumericQ] := fb[a, b] = Module[{t}, yb /. NDSolve[{y'[t] == a - b y[t]^3, yb'[t] == -y[t]^3 - 3 b y[t]^2 yb[t], y[0] == 1, yb[0] == 0}, {y, yb}, {t, 0, 1}][[1]]]

Check:

In[37]:=
fb[1, 2][1]
Out[37]=

Properties & Relations (3) 

The option Method→NIntegrate uses Cauchy's integral formula to compute derivatives:

In[38]:=
ResourceFunction["NDerivative"][Exp[x^2], {x, 4}, 0, Method -> NIntegrate]
Out[38]=

The equivalent computation can be performed using the resource function NResidue:

In[39]:=
4! ResourceFunction["NResidue"][Exp[x^2]/x^(4 + 1), {x, 0}]
Out[39]=

The Wolfram Language has built-in code to compute derivatives of numerical functions:

In[40]:=
f[t_?NumericQ] := 0.001 + 0.002 Sin[50 t]

The built-in numerical derivative code can be used. However, it is unable to capture the rapid oscillations:

In[41]:=
f'[.1]
Out[41]=

The correct answer:

In[42]:=
D[.001 + .002 Sin[50 t], t] /. t -> .1
Out[42]=

Using NDerivative with the appropriate options can compute an accurate derivative:

In[43]:=
ResourceFunction["NDerivative"][f[t], t, .1, Scale -> .1]
Out[43]=
In[44]:=
ResourceFunction["NDerivative"][f[t], t, .1, Method -> NIntegrate, Scale -> 1/2]
Out[44]=

With Method→"EulerSum", NDerivative must be able to evaluate expr at the point x0:

In[45]:=
f[x_?NumericQ] := Tanh[\[Pi] x]/(1 + x^2)
In[46]:=
ResourceFunction["NDerivative"][f[x], x, I]
Out[46]=

Adding an additional definition for f allows NDerivative to compute the derivative:

In[47]:=
f[I // N] = Limit[Tanh[\[Pi] x]/(1 + x^2), x -> I]
Out[47]=
In[48]:=
ResourceFunction["NDerivative"][f[x], x, I]
Out[48]=

Check:

In[49]:=
Limit[D[Tanh[\[Pi] x]/(1 + x^2), x], x -> I] // N
Out[49]=

In this case, Method→NIntegrate produces a more accurate answer:

In[50]:=
ResourceFunction["NDerivative"][f[x], x, I, Method -> NIntegrate, Scale -> 1/10]
Out[50]=

Neat Examples (1) 

Some fractional and complex derivatives can be computed:

In[51]:=
ResourceFunction["NDerivative"][x, {x, -(1/2)}, 1, Method -> NIntegrate]
Out[51]=
In[52]:=
ResourceFunction["NDerivative"][x^4, {x, I}, 1, Method -> NIntegrate]
Out[52]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.0.0 – 14 March 2019

Related Resources

License Information