有没有办法让scipy的interp1d(在线性模式下)返回每个插值点的导数?我当然可以编写自己的1D插值例程,但可能scipy的内部是C,因此速度更快,速度已经是一个主要问题。
我最终将插值函数添加到多维最小化例程中,因此能够通过分析导数会加快速度,而不是让最小化例程尝试自己计算它们。并且interp1d必须在内部计算它们 - 所以我可以访问它们吗?
答案 0 :(得分:6)
使用UnivariateSpline
代替interp1d
,并使用derivative
方法生成一阶导数。手册页here中的示例非常明显。
答案 1 :(得分:1)
您可以合并scipy.interpolate.interp1d和scipy.misc.derivative,但必须考虑到这些因素:
调用derivative
方法时,某些dx
被选为间距,x0
处的导数将被计算为{{1}之间的第一阶差异}和x0-dx
:
x0+dx
因此,您不能使derivative(f, x0, dx) = (f(x0+dx) - f(x0-dx)) / (2 * dx)
比derivative
更接近插值函数范围限制,因为dx
会引发 ValueError 告诉你那里没有定义你的插值函数。
那么,你能比f
更接近这些范围限制吗?
如果在dx
(范围)中定义f
:
[xmin, xmax]
:
x0
或x0 = xmin + dx
x0 = xmax - dx
(将其缩小)。如果插值函数在插值范围之外变得一致:
dx
您可以像这样定义插值函数:
f(x0 < xmin) = f(x0 > xmax) = f_out
对于线性情况,只计算一次点之间的差异可能会更便宜:
f = interp1d(x, y, bound_errors=False, fill_value=f_out)
这样您就可以将它们作为数组的组件来访问。
答案 2 :(得分:0)
据我所知,内部 interp1d
使用 BSpline。
BSpline
有一个 derivative
,它给出了 nu
次导数。
因此对于插值 f = interp1d(x, y)
,您可以使用
fd1 = f._spline.derivative(nu=1)
但是,在使用带有前导下划线的函数时,请一如既往地小心。
如果您选择插值区域之外的值,我认为不会检查边界。看来,BSpline
附加了一个拖尾维度,所以你必须写
val = fd1(0).item()
val_arr = fd1(np.array([0, 1]))[..., 0]