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:
single scalar to specify a sample distance for all dimensions.
N scalars to specify a constant sample distance for each dimension.i.e.dx,dy,dz, …
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
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:
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.])
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.]]))