如何使用 CuPy 在 python 上进行三次样条插值?

How to do a cubic spline interpolation on python with CuPy?

我正在编写代码,使用 GPU 多次进行三次样条插值。 我知道如何在 numpy 上使用

scipy.interpolate.splrep

scipy.interpolate.interp1d(kind='cubic')

interp1d 是我现在用于 numpy 数组的。但我需要在 CuPy 上 运行 它们。

但是我应该如何在 CuPy 上做呢?我有一个 x 值和 y 值。我还有一个包含新 x 值的数组。我现在正在编写的代码将为新的 x 值计算新的 y 值。

我将从源代码 scipy.interpolate.CubicSpline 开始,它是纯粹的 python,然后将 np.something 一个一个地替换为 cupy.something

我现在可以自己回答这个问题了。我完成了插值算法。作为ev-br的回答建议,我只是re-write cupy的scipy.interpolate.CubicSpline

scipy.interpolate.CubicSpline包含了很多函数,如果我们只需要一个插值函数就没什么用了。

classCubicSpline有一个父classscipy.interpolate.PPoly,如果你只想要一个插值函数,它也包含了很多不必要的函数。 clear clean后,我只用了classes _PPolyBase, solve_banded(), and prepare_input().

最难的部分是用cython写的函数evaluate()。 Cython不支持cupy,所以我使用了支持cuda的numba来加速循环的速度。

函数的头部evaluate()应该是这样的:

@cuda.jit('void(complex128[:,:,:], float64[:], float64[:], complex128[:,:])')
def evaluate(c, x, xp, out):

有一件重要的事情需要注意,评估函数不是 thread-safe 函数。

只有 evaluate() 中的第一个循环是:

for ip in range(len(xp)):
    xval = xp[IP]
    ......

可以使用cuda.grid(1)cuda.gridsize(1)

此外,我在 evaluate() 中结合了 evaluate_poly1()find_interval_descending() 以更好地适应 numbe 的 cuda 支持。

速度超级快,比原来的scipy功能快3到4倍左右

代码可以在这里找到:https://github.com/GavinJiacheng/Interpolation_CUPY