使用指定节点插值interpolate.splrep - 意外结果

时间:2014-12-23 00:23:29

标签: 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(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。 你能解释一下结果吗?不是一个错误吗?

1 个答案:

答案 0 :(得分:0)

参数per切换周期性边界条件(pbc)。似乎没有pbc,拟合不会收敛,但是对于pbc,它可以工作。你可以看到,当绘制数据和样条拟合结果时:它只会在边界发散,其余的数据集非常合适!

documentation of the function interpolate.splrep表示组合均匀度不是一个好主意。您有degree = 4(偶数)和s = 0

看来你定义了很多结! B样条是分段拟合的。如果你有很多结,每个样条函数只对很小一部分有效。你有1000个横坐标和995节。样条曲线必须有效的点越少,函数剩余的自由度就越大,因此如果你有几个点,样条曲线几乎可以是任何东西......

将行m = arg.size - degree - 1;更改为m = arg.size - degree - 20;已经产生了

>>> print interpolate.splev(x, f) - np.sin(x);
3.08053624276e-10

没有pbc!

所以,问问自己为什么要按照你的方式计算结数!要么坚持它并引入pbc,即per=1,要么减少结点数。两者都能稳定合身并实现融合!