Is there a packaged way to compute higher-order multivariate derivatives (using finite differences, not symbolic calculations) in Python?
For example, if f
computes the function cos(x)*y from R^2 to R, i.e., f
takes numpy arrays of shape 2
and returns floats (or arrays of shape ()
), is there a function partial
such that partial([2,1])(f)
computes the function (d^2/dx^2)(d/dy)f = -cos(x)*1 from R^2 to R, e.g.
np.isclose(partial([2,1])(f)(0),1.0)
There is a host of finite difference tools in the default libraries (so much for ''one way to do it''):
https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.derivative.html https://docs.scipy.org/doc/numpy/reference/generated/numpy.gradient.html https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.approx_fprime.html https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.misc.central_diff_weights.html https://github.com/statsmodels/statsmodels/blob/master/statsmodels/tools/numdiff.py
However, none of them can handle both multivariate functions and higher-order derivatives, i.e., none of them can handle the job above.
(There is also https://pypi.org/project/numdifftools/ but it seems to fall just short of doing what I need. The authors haven't responded to my question.)
It's easy to write the tool myself. However, it seems to be surprisingly difficult to do so well, i.e., in an accurate and stable fashion. For example, a straightforward recursive implementation is unstable for mesh-widths smaller than 1e-3
, even for simple functions like the one above and for mixed derivatives of only second order.
PS: I am not asking for finite differences of an array (https://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html and https://github.com/maroba/findiff do that). I need to evaluate derivatives at arbitrary points without computing the values of the function on a full cartesian grid.