我大胆宣称,interp1(..., "spline")
中实现的三次样条的Octave实现与例如Wolfram's Mathworld中概述的“自然三次样条”算法不同。我编写了自己的后者实现,并将其与interp1(..., "spline")
函数的输出进行了比较,结果如下:
我发现当我尝试与4个点进行相同的比较时,解决方案也有所不同,而且,Octave解决方案与将单个三次多项式拟合到所有四个点相同(并且实际上不会产生分段样条。三个间隔)。
我也试图在Octave的splines实现中深入了解,发现在5分钟内阅读和理解它太过于迟钝。
我知道在实现三次样条时,可以选择边界条件的几个选项(“自然”与“钳制”)。我的实现使用“自然”边界条件(其中两个外部点的二阶导数设置为零)。
如果 Octave的三次样条曲线确实与标准三次样条曲线不同,那么究竟是什么呢?
编辑:
上面比较图中显示的两种解决方案的二阶差异在此绘制:
首先,在Octave的情况下似乎只有两个三次多项式:一个适合前两个区间,一个适合最后两个区间。其次,它们显然不使用“自然”样条,因为极端的二阶导数不会趋于零。
另外,我认为这个事实是我在中间(即第3个)点的实现的二阶差异只是一个巧合,而不是算法所要求的。对不同的点集重复此测试将确认/反驳这一点。
答案 0 :(得分:1)
不同的结束条件解释了您的实现与Octave之间的区别。 Octave使用 not-a-knot 条件(取决于输入)
请参阅help spline
为了解释你的观察结果:由于非结点条件,第三个导数在第2和第(n-1)个断点处是连续的,所以这就是为什么Octave的二阶导数看起来更少“断裂”,因为它是前两个和后两个段的连续直线。如果你看三阶导数,你可以更清楚地看到效果 - 第三阶导数只在第3个阶段(中间)不连续
x = 1:5;
y = rand(1,5);
xx = linspace(1,5);
pp = interp1(x, y, 'spline', 'pp');
yy = ppval(pp, xx);
dyy = ppval(ppder(pp, 3), xx);
plot(xx, yy, xx, dyy);
pp
数据结构也是这样的
pp =
scalar structure containing the fields:
form = pp
breaks =
1 2 3 4 5
coefs =
0.427823 -1.767499 1.994444 0.240388
0.427823 -0.484030 -0.257085 0.895156
-0.442232 0.799439 0.058324 0.581864
-0.442232 -0.527258 0.330506 0.997395
pieces = 4
order = 4
dim = 1
orient = first