Wolfram Research

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" 1 size at which variations are expected
"Terms" 7 number of terms to be used
WorkingPrecision MachinePrecision precision to use in internal computations
Possible settings for Method include:
"EulerSum" use Richardson’s extrapolation to the limit
NIntegrate use 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 MethodNIntegrate, 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 MethodNIntegrate.

Examples

Basic Examples

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

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

NDerivative threads over its first argument:

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

Options

Method

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 MethodNIntegrate:

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 MethodNIntegrate will work well:

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

Scale

Use Scales 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 Scales 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

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

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, MethodNIntegrate 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

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

The option MethodNIntegrate 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 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, MethodNIntegrate produces a more accurate answer:

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

Neat Examples

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

Resource History

See Also

License Information