插值数据并找到峰值的最准确方法是什么?

3
我手头的数据始终在一个二次多项式(二次函数)上。我想尽可能精确地找到插值函数的峰值。
到目前为止,我一直使用 `interp1d`,然后使用 `linspace` 和简单的 `for` 循环提取峰值。虽然你可以使用大量新生成的样本在 `linspace` 中,但使用拟合多项式的导数仍然可以更精确。
现在,我唯一找到的返回拟合多项式系数的函数是 `polyfit`,但这个拟合函数相当不准确(大多数情况下,函数甚至没有通过数据点)。
我已经尝试使用 `UnivariateSpline`,拟合函数似乎非常准确,并且很容易获得导数样条和其根。
其他多项式拟合函数(`BarycentricInterpolator`、`KroghInterpolator` 等)表示由于数值稳定性问题,它们不计算多项式系数。
`UnivariateSpline` 及其导数有多准确,或者是否有更好的选择?
2个回答

1
如果你只需要找到一个二次多项式的最小值/最大值,为什么不这样做:
import matplotlib.pyplot as plt
from scipy.interpolate import KroghInterpolator
import numpy as np

x=range(-20,20)
y=[]
for i in x:
    y.append((i**2)+25)

x=x[1::5]
y=y[1::5]

f=KroghInterpolator(x,y)
xfine=np.arange(min(x),max(x),.5)
yfine=f(xfine)

val_interp=min(yfine)
print val_interp

plt.scatter(x,y)
plt.plot(xfine, yfine)
plt.show()

1
但是这种方法仍然依赖于np.arange的步长,而在这种情况下为0.5。我想将二次函数的最大值降至浮点/双精度。 - Tjaz Brelih
@TjazBrelih 它确实提供了浮点/双精度精度。将 y.append((i**2)+25) 更改为 y.append((i**2)+25.086)。然后运行程序。0.5间距的插值即使在您传递的原始数据中不存在该值,也会找到最小值。 - Will.Evo
只有在函数沿着x轴不发生偏移时才有效。当您将y.append((i**2)+25)更改为y.append(((i+0.2)**2)+25)时,您将无法找到真正的峰值,而只能在间隔为_0.5_的采样插值函数的最大/最小值。 - Tjaz Brelih
@TjazBrelih 我不知道你在说什么。即使x轴有偏移,脚本也能正常工作...你只需要将xfine的间距调小一点(对于你的示例,0.1的间距效果非常好)。你最初的问题是要找到峰值y值的准确方法...我的解决方案就是这样。用你的数据替换生成数据的代码部分,你就有了一个解决方案。 - Will.Evo
问题在于x轴的偏移基本上是随机的。另一件事是,我不只有一个数据集要插值,而是有很多,每个数据集都有自己的偏移量。如果您使用最小可能间距进行np.arange,则此方法将起作用。最终,我选择了polyfit方法,因为它返回二次函数的实际系数,因此您可以通过“手动”导出峰值的x和y坐标。 - Tjaz Brelih

0
最终我选择了polyfit。虽然拟合函数并没有完全经过数据点,但最终结果仍然不错。通过返回的系数,我得到了峰值所需的x和y坐标。

对于这些点,取导数,然后使用线性拟合并寻找零交叉点怎么样?这样做会更准确且计算回归更简单。只是好奇,因为我也需要找到插值最大值。 - Hephaestus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接