这个例子展示了如何使用csapi
和csape
命令从曲线拟合工具箱™构建三次样条插值。
命令
值= csapi (x, y, xx)
返回xx
的三次样条插值到给定数据(x, y
),使用非结结束条件。这个插值是一个带断点序列的分段三次函数x
,它的三次块结合在一起形成一个具有两个连续导数的函数。“非结”结束条件意味着,在第一次和最后一次内部中断时,即使是三阶导数也是连续的(直到四舍五入错误)。
只指定两个数据点将导致一个直线插值。
X = [0 1];Y = [2 0];xx = linspace (0, 6121);情节(xx csapi (x, y, xx),“k -”, x, y,“罗”)标题("插值到两点")
指定三个数据点可以得到一个抛物线。
X = [2 3 5];Y = [1 0 4];情节(xx csapi (x, y, xx),“k -”, x, y,“罗”)标题(“插值到三个点”)
更一般地,四个或更多的数据点给出三次样条。
X = [1 1.5 2 4.1 5];Y = [1 -1 1 -1 1];情节(xx csapi (x, y, xx),“k -”, x, y,“罗”)标题(“三次样条插值到五个点”)
这些看起来是很好的插值,但是我们怎么检查呢csapi
执行广告吗?
我们已经看到了csapi
插值,因为我们画出了数据点插值函数直接穿过这些点。但为了确保我们得到一个三次样条,最好从期望排序的三次样条数据开始,并检查是否csapi
繁殖这个三次样条,也就是说,返回了数据来自的三次样条。
三次样条函数的一个简单的例子是被截断的三次幂,即函数
在哪里西
是否有一个中断和“+”下标表示截断函数,由命令提供subplus
:
帮助subplus
SUBPLUS积极的部分。x, if x>=0 y = subplus(x):= (x)_{+} =, 0,如果x<=0返回x的正数部分。用于计算截断的幂。
对于特定的选择,截短的三次幂图如下图所示西
=2
.不出所料,它在2的左边是0,在2的右边是(x-2)^3。
情节(xx subplus (xx-2)。^ 3,“y”,“线宽”3)轴([0,-10,70])
现在我们在数据点0:6处插值这个三次样条,并在样条上面用黑色标出插值。
x = 0:6;y = subplus (x - 2) ^ 3;值= csapi (x, y, xx);持有在情节(xx,价值观,“k”, x, y,“罗”)举行从标题(((x - 2) _ +)的Interpolant ^ 3 ')
当比较两个函数时,绘制它们的差异通常会提供更多信息。
Plot (xx, values - subplus(xx-2).^3) title(三次样条插值到((x-2)_+)^3的误差)
要将它们的差异大小放入上下文中,还可以计算最大数据值。这表明这个错误并不比不可避免的舍入错误更糟。
max_y = max (abs (y))
max_y = 64
作为进一步的检验,我们插入一个截断的幂csapi
-produced interpolant at the sites 0:6 cannot coincide with it。例如,插值样条的第一个内部中断并不是一个真正的结csapi
使用“非结”条件,因此插值在该位置有三个连续的导数。这意味着我们不应该复制在该位置截断的三次幂,因为它的三次导数在该位置是不连续的。
值= csapi (x, subplus (x - 1) ^ 3, xx);Plot (xx, values - subplus(xx-1).^3) title((x-1)_+)^3的非结插值错误)
因为1是第一个内结,它对这个内插不活跃。
这个差值有0.18那么大,但是当我们离开1时,这个差值会迅速衰减。这说明三次样条插值基本上是局部的.
可以将插值三次样条保留在适合于后续求值、计算其导数或其他操作的形式中。这是通过调用csapi
在表单中
页= csapi (x, y)
它返回插值的ppform。你可以在一些新的点上计算这个形式xx
由命令
值= fnval (pp、xx)
你可以通过命令来区分插值
民进党=曾经(pp)
或者通过命令对它进行积分
ipp = fnint (pp)
分别返回导数或积分的平形式。
为了显示一个插值函数的微分,我们绘制这个被截断的幂的导数
(还是黄色的)然后在上面,插值函数对截断的三次幂函数的导数(还是黑色的)
情节(xx, 3 * subplus (xx-2)。^ 2,“y”,“线宽”pp = csapi(x,subplus(x-2).^3);民进党=曾经(pp);持有在情节(xx fnval(民进党,xx),“k”)举行从标题(((x-2)_+)^3的导数)
同样,更有用的比较是绘制它们的差异,和之前一样,这并不比舍入误差更大。
Plot (xx, fnval(dpp,xx) - 3*subplus(xx-2).^2) title(插值对((x-2)_+)^3求导的误差)
截短后的幂次的二阶导数是
这个函数和原始函数的插值函数的二阶导数之间的差值图显示现在有跳跃,但它们仍然在舍入误差之内。
ddpp =曾经(民进党);地块(xx, fnval(ddpp,xx) - 6*subplus(xx-2))((x-2)_+)^3插值二阶导数的误差)
截短后的幂的积分为
这个函数与原始函数的插值积分之间的差的图再次表明,误差在舍入误差之内。
ipp = fnint (pp);Plot (xx, fnval(ipp,xx) - subplus(xx-2).^4/4) title(((x-2)_+)^3的插值积分误差)
就像csapi
,csape
命令提供三次样条插值到给定数据。但是,它允许各种附加的结束条件。最简单的版本,
页= csape (x, y)
使用拉格朗日端点条件,这是一种常见的替代非结条件csapi
.csape
不直接返回插值的值,而只返回它的ppform。
例如,再次考虑函数的插值
哪一个csapi
不能很好地复制。我们绘制非结插值的误差csapi
(黑色),以及从得到的插值的错误csape
(红色)。
确切= subplus (xx-1)。^ 3;* * * * * * * * * * * * * * * * *“k”)举行在* * * * * * * * * * * * * * * *“r”)标题(“非结与拉格朗日端点条件下的错误”)({传奇“Not-a-Knot”“拉格朗日”});持有从
在这种情况下,两个插值之间没有太大的区别。
的csape
命令还提供了为插值三次样条指定其他几种结束条件的方法。例如,命令
页= csape (x, y,“变分”)
使用所谓的“自然”结束条件。这意味着二阶导数在两个极值处为零。
这个步骤展示了如何应用“自然的”三次样条插值函数
然后画出误差。下面的代码使用另一种参数语法计算“自然的”样条插值“变分”
论点:使用“第二”
指定csape
应该将极端数据站点的二阶导数设置为默认值0。
页= csape (x, subplus (x - 2) ^ 3,“第二”);Plot (xx, fnval(pp,xx) - subplus(xx-2).^3) title(样条插值((x-2)_+)^3的“自然”误差)
注意右边的大错误。这是由于“自然的”终端条件隐含地坚持二阶导数为零。
我们也可以明确地使用正确的二阶导数来得到一个小的误差。首先,我们计算截断的幂在端点处的正确的二阶导数值。
end = 6*subplus(x([1 end])-2); / /结束
然后我们创建一个插值函数,指定端点处的二阶导数与我们刚刚计算的二阶导数值相匹配。我们通过提供来做到这一点endcond (1)
对于左端点条件,和endcond (2)
右边,还有数据值。
Pp = cape (x,[endcond(1) subplus(x-2))。^ 3 endcond (2)),“第二”);Plot (xx, fnval(pp,xx)) - subplus(xx-2).^3,“r”)标题(样条插值到((x-1)_+)^3的误差;...“当在末端匹配二阶导数时”])
csape
也允许端点的规范山坡上.这是夹紧的(或者,完整的)三次样条插值。该声明
页= csape (x, (sl, y, sr),“夹紧”)
创建三次样条插值数据(x
,y
)也有斜率sl
在最左边的数据点和斜坡老
在最右边的数据站点。
甚至可以混合这些条件。例如,我们经常练习的截断幂函数
斜率为0x
=0,二阶导数为30x
=6(最后一个数据站点)。
因此,通过匹配左端点的斜率和右端点的曲率,我们期望在得到的插值中没有误差。
Pp = cape (x, [0 subplus(x-1))^3 30], [1 2]);Plot (xx, fnval(pp,xx) - subplus(xx-1).^3) title([样条插值到((x-1)_+)^3的误差;...'与混合结束条件。'])
也可以开处方周期结束条件。例如,正弦函数是2*pi周期函数,并且有值[0 -1 0 1 0]
在网站(π/ 2)* (2:2)
.正弦函数和它的周期三次样条插值在这些点之间的差异仅为2%。不坏。
x =(π/ 2)* (2:2);Y = [0 -1 0 1 0];页= csape (x, y,“周期”);xx = linspace(π-π,201);Plot (xx, sin(xx) - fnval(pp,xx),“x”)标题(周期三次样条插值到sin(x)的误差)
未显式覆盖的任何结束条件csapi
或csape
可以通过构造插值来处理csape
默认的边条件,然后添加一个适当的标量乘以一个插值到零值和一些边条件。如果有两个“非标准”的边条件要满足,你可能必须先解一个2 × 2的线性方程组。
例如,假设您想要计算三次样条插值年代
的数据
x = 0: .25:3;Q = @(x) x.*(-1+x.* (-1+x.*x/5));y =问(x);
并强制执行条件
= a * (Ds)(e) + b * (D^ 2s)(e) = c
的一阶和二阶导数年代
在点e
.
数据是由一个四次多项式产生的,恰好满足这个边条件与特定的参数
e = x (1);= 2;b = 3;c = 4;
为了构造满足此特定条件的插值函数,我们首先构造具有默认结束条件的插值函数
pp1 = csape (x, y);
它的第一个多项式部分的一阶导数。
dp1 =曾经(fnbrk (pp1 1));
此外,我们构造三次样条插值到零数据值,指定它的斜率为1e
,
Pp0 = cape (x,[1,zeros(size(y)),0], [1,0]);
以及构造它的第一个多项式的一阶导数。
dp0 =曾经(fnbrk (pp0 1));
然后我们计算λ
对于这两个pp1
和pp0
,
Lam1 = a*fnval(dp1,e) + b*fnval(fnder(dp1),e);a*fnval(dp0,e) + b*fnval(fnder(dp0),e);
并构造正确的线性组合pp1
和pp0
得到三次样条
S:= pp1 + ((c - lambda(pp1))/lambda(pp0)) * pp0
这确实满足了所需的条件,以及右端点的默认结束条件。这个线性组合是通过fncmb
.
s = fncmb (pp0 (c-lam1) / lam0 pp1);
插值误差图表明年代
更接近四次多项式e
比interpolantpp1
在默认条件下可以。
xx = (3): . 05: 7;yy = q (xx);Plot (xx, fnval(pp1,xx) - yy,“x”)举行在Plot (xx, fnval(s,xx) - yy,“o”)举行从传奇({“默认条件”“非标准条件”},“位置”,“本身”)
如果我们想强制执行条件
mu(s):= (D^ 3s)(3) = 14.6
在插值的三阶导数上(四次函数满足这个条件),然后我们构造一个额外的三次样条插值到零值,并且在左端点的一阶导数为零,因此确定是独立的pp0
.
pp2 = csape (x,[0, 0(大小(y)), 1], [0,1]);
然后求出系数d0
和d2
在线性组合中
日升:= ref (0, 1) * ref (0, 1) * ref (0, 1
这就解出了线性方程组
λ= c (s)
μ(s) = 14.6
请注意,这两个pp0
和pp2
在所有插值点消失,因此年代
将匹配给定的数据为任何选择d0
和d2
.
为了好玩,我们使用MATLAB®编码工具编写一个循环来计算λ(pp_j)
和μ(pp_j)
,因为j
= 0:2。
dd = 0(2、3);为j=0:2 j= num2str(j);eval ([“民进党”J' =曾经(pp 'J”),“]);eval ([“ddpp”J=曾经(民进党的J”),“]);eval ([“dd(1,1 +”J“* fnval(民进党)=”J”,e) + b * fnval (ddpp 'J“e);”]);eval ([“dd(2, 1 +”J') = fnval(曾经(ddpp 'J”),3),“]);结束
给定的值λ
和μ
为pp0
,pp1
,pp2
,然后解出定义正确线性组合的系数。
d = dd (: [1,3]) \ ([c; 14.6] dd (:, 2));s = fncmb (fncmb (pp0, d (1) pp2 d (2)), pp1);xxx = 0: .05:3;多= q (xxx);Plot (xxx, yyy - fnval(s,xxx),“x”)标题(样条插值到y = x*(-1+x* (-1+x*x/5))的误差)
为了保证,我们将此误差与此函数的完整三次样条插值得到的误差进行比较:
持有在图(xxx, yyy - fnval(cape (x,[-1,y,-7+(4/5)*27)),“夹紧”), xxx),“o”)举行从传奇({“非标准条件”“Endslope条件”})
误差仅在接近终点时有所不同(而且相差不大),这证明了事实pp0
和pp2
只有在它们各自的端点附近才会相当大。
作为最后的检查,我们验证一下年代
在3处满足三阶导数条件。
fnval(曾经(年代,3),3)
ans = 14.6000