Python 使用指定节点插值插值。splrep—;意外结果
我不明白Python 使用指定节点插值插值。splrep—;意外结果,python,scipy,interpolation,Python,Scipy,Interpolation,我不明白interpolate.splrep函数是如何工作的。简单代码不会抛出任何错误,但interpolate.splev返回意外结果 degree = 4; arg = np.linspace(0, 2.0 * np.pi, 1000); val = np.sin(arg); m = arg.size - degree - 1; step = (arg[-1] - arg[0]) / (m + 1); knots = np.linspace(step, m * step, m); f =
interpolate.splrep
函数是如何工作的。简单代码不会抛出任何错误,但interpolate.splev
返回意外结果
degree = 4;
arg = np.linspace(0, 2.0 * np.pi, 1000);
val = np.sin(arg);
m = arg.size - degree - 1;
step = (arg[-1] - arg[0]) / (m + 1);
knots = np.linspace(step, m * step, m);
f = interpolate.splrep(arg, val, k=degree, s=0, t=knots, per=0);
x = 0.123456;
print interpolate.splev(x, f) - np.sin(x);
此代码打印2.81341438303e+118
,但如果我更改参数per
,则代码运行良好:
...
f = interpolate.splrep(arg, val, k=degree, s=0, t=knots, per=1);
...
结果是-1.80411241502e-16
。
你能解释一下结果吗?这不是一个bug吗?参数
per
切换周期边界条件(pbc)。如果没有pbc,拟合似乎不会收敛,但是有了pbc,拟合就起作用了。在打印数据和样条曲线拟合结果时,您也可以看到:它仅在边界处发散,数据集的其余部分拟合得很好
这项研究告诉我们,拥有一个均衡的学位组合不是一个好主意。您有degree=4
(偶数)和s=0
看起来你定义了很多结!B样条曲线是分段拟合的。如果有很多节点,则每个样条函数仅对极少量的点有效。你有1000个横坐标点和995节。样条曲线的有效点越少,函数的自由度就越大,因此如果只有很少的点,样条曲线实际上可以是任何东西
更改行m=arg.size-degree-1代码>到m=arg.size-度-20代码>已生成
>>> print interpolate.splev(x, f) - np.sin(x);
3.08053624276e-10
没有pbc
所以,问问你自己,为什么你要这样计算结数!要么坚持使用pbc,即per=1
,要么稍微减少节点数。两者都能稳定贴合感,实现收敛 我完全理解我写的内容以及每个参数的含义。这不是一个随机代码,这只是我程序的简化部分。我唯一不明白的是,如果例程不能处理输入数据,为什么它不会抛出任何错误。这是一种非常奇怪的行为,在大型项目中可能会导致严重的问题。如果例程不能正确地处理输入数据,它必须通知您。它在找到解决方案方面没有问题,而是您希望拟合收敛,但情况并非如此。大多数numpy/scipy拟合函数在不收敛时不会抛出错误或警告,您将始终必须检查一些诊断数据,例如协方差。。。如果结数是固定的,pbc有严重问题吗?你认为这不是问题吗?这很可悲。MATLAB在这种情况下工作得更好。如果你要解一个接近奇异的线性方程组,MATLAB(至少)会给出一个警告。它确实有助于调试大型项目。其中一些函数会给出“排名警告”,但有些配置却没有。现在我们正在讨论一个倾向于偏离主题的话题。对我来说,还不清楚你是想要一个合适的工作,还是你抱怨错过了警告。我对前者有一个答案,后者应该在scipy邮件列表中讨论。