如何直接获得scipy插值的梯度?

时间:2011-08-01 21:32:44

标签: scipy gradient interpolation volume spline

我有一个较大的3D numpy标量值数组(如果必须,可以称之为“音量”)。我想在一系列不规则的情况下插入一个平滑的标量场,而不是全部 已知的前期非整数xyz坐标。

现在Scipy对此的支持非常好:我用

过滤音量
filtered_volume = scipy.ndimage.interpolation.spline_filter(volume)

并调用

scipy.ndimage.interpolation.map_coordinates(
    filtered_volume,
    [[z],[y],[x]],
    prefilter=False)

对于(x,y,z)感兴趣,以获得表面上很好的(平滑等)插值。

到目前为止一切顺利。但是,我的应用程序还需要插值字段的局部导数。目前我通过中心差分获得这些:我还在6个额外点处对体积进行采样(这至少可以通过仅调用map_coordinates来完成)并且例如从(i(x+h,y,z)-i(x-h,y,z))/(2*h)计算x导数。 (是的,我知道我可以将额外的水龙头数量减少到3并做出“单方面”的差异,但不对称会让我烦恼。)

我的直觉是应该有更直接的方法来获得渐变 但我不知道足够的样条数学(还)要弄清楚,或者理解是什么 继续Scipy实施的内容:scipy/scipy/ndimage/src/ni_interpolation.c

有没有比中央差异“更直接”获得渐变的更好方法?优选地,允许使用现有功能获得它们而不是攻击Scipy的内部。

1 个答案:

答案 0 :(得分:1)

啊哈:根据numpy代码中引用的classic paper on splines,n阶样条和它们的导数是相关的

   n          n-1           n-1
 dB (x)/dx = B   (x+1/2) - B   (x-1/2)

因此,使用SciPy的样条插值,我可以通过维持低阶预滤波量并且每个导数查询几次来获得我的导数。这意味着添加相当数量的内存(可能与缓存的“主”卷竞争),但可能对低阶样条的评估更快,因此我不清楚它是否比中心差分更快或更不整体使用我目前正在做的小补偿。尚未尝试过。