如何从一维插值中获得导数

how to get derivatives from 1D interpolation

有没有办法让scipy的interp1d(在线性模式下)到return每个插值点的导数?我当然可以编写自己的 1D 插值例程,但大概 scipy 在 C 内部,因此速度更快,速度已经是一个主要问题。

我最终将插值函数的修改输入到多维最小化例程中,因此能够通过解析导数会大大加快速度,而不是让最小化例程尝试自行计算它们。 interp1d 必须在内部计算它们 --- 我可以访问它们吗?

使用 UnivariateSpline instead of interp1d, and use the derivative method to generate the first derivative. The example at the manual page here 是不言自明的。

可以组合scipy.interpolate.interp1d and scipy.misc.derivative,但有一点必须要注意:

当调用 derivative 方法并选择一些 dx 作为 间距 时,x0 处的导数将被计算为一阶差分在 x0-dxx0+dx 之间:

derivative(f, x0, dx) = (f(x0+dx) - f(x0-dx)) / (2 * dx)

因此,您不能使用比 dx 更接近内插函数范围限制的 derivative,因为 f 会引发 ValueError 告诉你你的插值函数没有在那里定义。

那么,除了 dx 这些范围限制之外,您还能做些什么?

如果f定义在[xmin, xmax]内(范围):

  1. 在范围限制下,您可以 x0 移动一点:
    • x0 = xmin + dxx0 = xmax - dx
  2. 对于其他点,您可以优化 dx(使其变小)。

插值范围外的均匀函数:

如果你的插值函数恰好在插值范围之外是均匀的:

f(x0 < xmin) = f(x0 > xmax) = f_out

您可以这样定义插值函数:

f = interp1d(x, y, bound_errors=False, fill_value=f_out)

线性插值情况:

对于线性情况,只计算一次点之间的差异可能更便宜:

import numpy as np
df = np.diff(y) / np.diff(x)

这样您就可以将它们作为数组的组成部分进行访问。

据我所知,内部 interp1d 使用 BSplineBSpline 有一个 derivative 给出 nuth 导数。

所以对于插值 f = interp1d(x, y) 你可以使用

fd1 = f._spline.derivative(nu=1)

但是,在使用带有前导下划线的函数时要一如既往地小心。 如果您选择插值区域之外的值,我认为不会检查边界。似乎 BSpline 附加了一个尾部维度,所以你必须写

val = fd1(0).item()
val_arr = fd1(np.array([0, 1]))[..., 0]