我认为您可以使用Cubic Spline。给定n 点(x_1, y_1)..(x_n, y_n) 的列表,算法在(x_k, y_k) 和(x_{k+1}, y_{k+1}) 之间找到一个三次多项式p_k,并具有以下约束:
- 多项式
p_k和p_{k+1}经过点(x_{k+1}, y_{k+1});
- 多项式
p_k 和p_{k+1} 在(x_{k+1}, y_{k+1}) 处具有相同的一阶导数;
- 多项式
p_k 和p_{k+1} 在(x_{k+1}, y_{k+1}) 处具有相同的二阶导数。
此外,还为第一个和最后一个多项式定义了一些边界条件。我使用了natural,它在曲线末端强制二阶导数为零。
您可以应用的步骤是:
- 使用三次样条插值前 10 个点。
- 将
p_10 处的一阶导数值赋给变量d。
- 对
p_10 和p_11 运行三次样条,强制p_10 处的一阶导数为d,p_11 处的二阶导数为零。
从那里,您可以对剩余的点重复相同的步骤。
此代码将为所有点生成插值:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import CubicSpline
height=4
n = 20
x = np.arange(n)
xs = np.arange(-0.1,n+0.1,0.1)
y = np.random.uniform(low=0, high=height, size=n)
plt.plot(x, y, 'o', label='data')
cs = CubicSpline(x, y)
plt.plot(xs, cs(xs), color='orange')
plt.ylim([0, height+1])
现在,此代码将插入前 10 个点,然后在点 10 和 11 之间进行另一个插值:
k = 10
delta = 0.001
plt.plot(x, y, 'o', label='data')
xs = np.arange(x[0], x[k-1]+delta, delta)
cs = CubicSpline(x[0:k], y[0:k])
plt.plot(xs, cs(xs), color='red')
d = cs(x[k-1], 1)
xs2 = np.arange(x[k-1], x[k]+delta, delta)
cs2 = CubicSpline(x[k-1:k+1], y[k-1:k+1], bc_type=((1, d), 'natural'))
plt.plot(xs2, cs2(xs2), color='blue')
plt.ylim([0, height+1])