如何使用 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
我正在编写代码,使用 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