我正在寻找一种算法,该算法可以平滑地插入点,这些点进入 live 。
例如,假设我从10(x,y)对数组开始。我目前正在使用scipy和高斯窗口来生成平滑曲线。但是,我不知道是如何响应某个将来点生成的第11个点(而不完全重做所有11个点的平滑)来更新平滑曲线。
我要寻找的是一种算法,可以遵循先前的平滑曲线直到第10个(x,y)对,并且 也可以在第10个和第10个之间平滑插值第11对(在某种程度上类似于重做整个算法-因此没有锋利的边缘)。是否有可以满足我需求的东西?
答案 0 :(得分:2)
我认为您可以使用Cubic Spline。给定n
点(x_1, y_1)..(x_n, y_n)
的列表,该算法在p_k
和(x_k, y_k)
之间找到具有以下约束的三次多项式(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})
处具有相同的一阶导数; p_k
和p_{k+1}
在(x_{k+1}, y_{k+1})
处具有相同的二阶导数。此外,还有一些边界条件,为第一个和最后一个多项式定义。我使用了natural
,它在曲线的末端将二阶导数强制为零。
您可以应用的步骤是:
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])