numpy.gradient#

numpy.gradient(f,*varargs,axis=None,edge_order=1)[source]#

Return the gradient of an N-dimensional array.

The gradient is computed using second order accurate central differencesin the interior points and either first or second order accurate one-sides(forward or backwards) differences at the boundaries.The returned gradient hence has the same shape as the input array.

Parameters:
farray_like

An N-dimensional array containing samples of a scalar function.

varargslist of scalar or array, optional

Spacing between f values. Default unitary spacing for all dimensions.Spacing can be specified using:

  1. single scalar to specify a sample distance for all dimensions.

  2. N scalars to specify a constant sample distance for each dimension.i.e.dx,dy,dz, …

  3. N arrays to specify the coordinates of the values along eachdimension of F. The length of the array must match the size ofthe corresponding dimension

  4. Any combination of N scalars/arrays with the meaning of 2. and 3.

Ifaxis is given, the number of varargs must equal the number of axesspecified in the axis parameter.Default: 1. (see Examples below).

edge_order{1, 2}, optional

Gradient is calculated using N-th order accurate differencesat the boundaries. Default: 1.

axisNone or int or tuple of ints, optional

Gradient is calculated only along the given axis or axesThe default (axis = None) is to calculate the gradient for all the axesof the input array. axis may be negative, in which case it counts fromthe last to the first axis.

Returns:
gradientndarray or tuple of ndarray

A tuple of ndarrays (or a single ndarray if there is only onedimension) corresponding to the derivatives of f with respectto each dimension. Each derivative has the same shape as f.

Notes

Assuming that\(f\in C^{3}\) (i.e.,\(f\) has at least 3 continuousderivatives) and let\(h_{*}\) be a non-homogeneous stepsize, weminimize the “consistency error”\(\eta_{i}\) between the true gradientand its estimate from a linear combination of the neighboring grid-points:

\[\eta_{i} = f_{i}^{\left(1\right)} - \left[ \alpha f\left(x_{i}\right) + \beta f\left(x_{i} + h_{d}\right) + \gamma f\left(x_{i}-h_{s}\right) \right]\]

By substituting\(f(x_{i} + h_{d})\) and\(f(x_{i} - h_{s})\)with their Taylor series expansion, this translates into solvingthe following the linear system:

\[\begin{split}\left\{ \begin{array}{r} \alpha+\beta+\gamma=0 \\ \beta h_{d}-\gamma h_{s}=1 \\ \beta h_{d}^{2}+\gamma h_{s}^{2}=0 \end{array}\right.\end{split}\]

The resulting approximation of\(f_{i}^{(1)}\) is the following:

\[\hat f_{i}^{(1)} = \frac{ h_{s}^{2}f\left(x_{i} + h_{d}\right) + \left(h_{d}^{2} - h_{s}^{2}\right)f\left(x_{i}\right) - h_{d}^{2}f\left(x_{i}-h_{s}\right)} { h_{s}h_{d}\left(h_{d} + h_{s}\right)} + \mathcal{O}\left(\frac{h_{d}h_{s}^{2} + h_{s}h_{d}^{2}}{h_{d} + h_{s}}\right)\]

It is worth noting that if\(h_{s}=h_{d}\)(i.e., data are evenly spaced)we find the standard second order approximation:

\[\hat f_{i}^{(1)}= \frac{f\left(x_{i+1}\right) - f\left(x_{i-1}\right)}{2h} + \mathcal{O}\left(h^{2}\right)\]

With a similar procedure the forward/backward approximations used forboundaries can be derived.

References

[1]

Quarteroni A., Sacco R., Saleri F. (2007) Numerical Mathematics(Texts in Applied Mathematics). New York: Springer.

[2]

Durran D. R. (1999) Numerical Methods for Wave Equationsin Geophysical Fluid Dynamics. New York: Springer.

[3]

Fornberg B. (1988) Generation of Finite Difference Formulas onArbitrarily Spaced Grids,Mathematics of Computation 51, no. 184 : 699-706.PDF.

Examples

>>>importnumpyasnp>>>f=np.array([1,2,4,7,11,16])>>>np.gradient(f)array([1. , 1.5, 2.5, 3.5, 4.5, 5. ])>>>np.gradient(f,2)array([0.5 ,  0.75,  1.25,  1.75,  2.25,  2.5 ])

Spacing can be also specified with an array that represents the coordinatesof the values F along the dimensions.For instance a uniform spacing:

>>>x=np.arange(f.size)>>>np.gradient(f,x)array([1. ,  1.5,  2.5,  3.5,  4.5,  5. ])

Or a non uniform one:

>>>x=np.array([0.,1.,1.5,3.5,4.,6.])>>>np.gradient(f,x)array([1. ,  3. ,  3.5,  6.7,  6.9,  2.5])

For two dimensional arrays, the return will be two arrays ordered byaxis. In this example the first array stands for the gradient inrows and the second one in columns direction:

>>>np.gradient(np.array([[1,2,6],[3,4,5]]))(array([[ 2.,  2., -1.],        [ 2.,  2., -1.]]), array([[1. , 2.5, 4. ],        [1. , 1. , 1. ]]))

In this example the spacing is also specified:uniform for axis=0 and non uniform for axis=1

>>>dx=2.>>>y=[1.,1.5,3.5]>>>np.gradient(np.array([[1,2,6],[3,4,5]]),dx,y)(array([[ 1. ,  1. , -0.5],        [ 1. ,  1. , -0.5]]), array([[2. , 2. , 2. ],        [2. , 1.7, 0.5]]))

It is possible to specify how boundaries are treated usingedge_order

>>>x=np.array([0,1,2,3,4])>>>f=x**2>>>np.gradient(f,edge_order=1)array([1.,  2.,  4.,  6.,  7.])>>>np.gradient(f,edge_order=2)array([0., 2., 4., 6., 8.])

Theaxis keyword can be used to specify a subset of axes of which thegradient is calculated

>>>np.gradient(np.array([[1,2,6],[3,4,5]]),axis=0)array([[ 2.,  2., -1.],       [ 2.,  2., -1.]])

Thevarargs argument defines the spacing between sample points in theinput array. It can take two forms:

  1. An array, specifying coordinates, which may be unevenly spaced:

>>>x=np.array([0.,2.,3.,6.,8.])>>>y=x**2>>>np.gradient(y,x,edge_order=2)array([ 0.,  4.,  6., 12., 16.])
  1. A scalar, representing the fixed sample distance:

>>>dx=2>>>x=np.array([0.,2.,4.,6.,8.])>>>y=x**2>>>np.gradient(y,dx,edge_order=2)array([ 0.,  4.,  8., 12., 16.])

It’s possible to provide different data for spacing along each dimension.The number of arguments must match the number of dimensions in the inputdata.

>>>dx=2>>>dy=3>>>x=np.arange(0,6,dx)>>>y=np.arange(0,9,dy)>>>xs,ys=np.meshgrid(x,y)>>>zs=xs+2*ys>>>np.gradient(zs,dy,dx)# Passing two scalars(array([[2., 2., 2.],        [2., 2., 2.],        [2., 2., 2.]]), array([[1., 1., 1.],        [1., 1., 1.],        [1., 1., 1.]]))

Mixing scalars and arrays is also allowed:

>>>np.gradient(zs,y,dx)# Passing one array and one scalar(array([[2., 2., 2.],        [2., 2., 2.],        [2., 2., 2.]]), array([[1., 1., 1.],        [1., 1., 1.],        [1., 1., 1.]]))
On this page