如何从一维插值得到导数

时间:2015-05-18 17:34:41

标签: python scipy

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

我最终将插值函数添加到多维最小化例程中,因此能够通过分析导数会加快速度,而不是让最小化例程尝试自己计算它们。并且interp1d必须在内部计算它们 - 所以我可以访问它们吗?

3 个答案:

答案 0 :(得分:6)

使用UnivariateSpline代替interp1d,并使用derivative方法生成一阶导数。手册页here中的示例非常明显。

答案 1 :(得分:1)

您可以合并scipy.interpolate.interp1dscipy.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

  1. 在范围限制内,您可以稍微移动[xmin, xmax]
    • x0x0 = xmin + dx
  2. 对于其他点,您可以优化x0 = xmax - dx(将其缩小)。
  3. 插值范围外的均匀函数:

    如果插值函数在插值范围之外变得一致:

    dx

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

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

    线性插值情况:

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

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

    这样您就可以将它们作为数组的组件来访问。

答案 2 :(得分:0)

据我所知,内部 interp1d 使用 BSplineBSpline 有一个 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]