how to get derivatives from 1D interpolation
You can combine scipy.interpolate.interp1d and scipy.misc.derivative, but there is something that must be taken into account:
When calling derivative
method with some dx
chosen as spacing, the derivative at x0
will be computed as the first order difference between x0-dx
and x0+dx
:
derivative(f, x0, dx) = (f(x0+dx) - f(x0-dx)) / (2 * dx)
As a result, you can't use derivative
closer than dx
to your interpolated function range limits, because f
will raise a ValueError telling you that your interpolated function is not defined there.
So, what can you do closer than dx
to those range limits?
If f
is defined inside [xmin, xmax]
(range):
- At the range limits you can move
x0
a bit in:x0 = xmin + dx
orx0 = xmax - dx
- For other points you can refine
dx
(make it smaller).
Uniform function outside interpolation range:
If your interpolated function happens to be uniform outside the interpolation range:
f(x0 < xmin) = f(x0 > xmax) = f_out
You may define your interpolated function like this:
f = interp1d(x, y, bound_errors=False, fill_value=f_out)
Linear interpolation case:
For the linear case it might be cheaper to calculate just once the differences between points:
import numpy as np
df = np.diff(y) / np.diff(x)
This way you can access them as the components of an array.
As far as I know, internally interp1d
uses a BSpline.
The BSpline
has a derivative
which gives the nu
th derivative.
So for an interploation f = interp1d(x, y)
you can use
fd1 = f._spline.derivative(nu=1)
However, be carful as always when using functions with leading underscore.
I don't think bounds are checked if you choose values outside the interpolation region. It also seems, that BSpline
appends a tailing dimension, so you have to write
val = fd1(0).item()
val_arr = fd1(np.array([0, 1]))[..., 0]
Use UnivariateSpline
instead of interp1d
, and use the derivative
method to generate the first derivative. The example at the manual page here is pretty self-explanatory.