如何构造样条

这个示例展示了如何使用曲线拟合工具箱™中的样条函数以各种方式构造样条。

插值

你可以构建一个三次样条interpolant与下面的余弦函数相匹配x,使用csapi命令。

x = 2*pi*[0 1:.2:.9];y = cos (x);c = csapi (x, y);

你可以用fnplt

fnplt (cs, 2);轴([-1 7 -1.2 1.2])保持情节(x, y,“o”)举行

检查Interpolant

余弦函数是2*pi周期的。我们的三次样条插值在这方面做得怎么样?一种检验方法是计算两个端点的一阶导数之差。

diff(fnval(fnder(cs), [0 2*pi]))
ans = -0.1375

为了加强周期性,使用csape而不是csapi

csp = csape(x, y,“周期”);持有fnplt (csp,‘g’)举行

现在支票兑现了

diff(fnval(fnder(csp), [0 2*pi]))
ans = -2.2806 e-17

甚至二阶导数在端点处也匹配。

diff(fnval(fnder(csp, 2), [0 2*pi]))
ans = -2.2204 e-16

分段线性interpolant到相同的数据是可通过spapi。在这里,我们把它添加到前面的图中,用红色表示。

pl = spapi(2, x, y);持有fnplt (pl,“r”,2)

平滑

如果数据是有噪声的,你通常想要近似而不是插值。例如,使用这些数据

x = linspace(0, 2 *π,51);噪声= cos(x) + .2*(rand(size(x))- 5);情节(x, noisy_y,“x”)轴([-1 7 -1.2 1.2])

插值会得到如下蓝色所示的波形插值。

持有fnplt(csapi(x, noise _y))保持

相反,平滑与适当的公差

托尔=(. 05)^ 2 *(2 *π)
托尔= 0.0157

给出一个平滑的近似值,如下图红色部分所示。

持有fnplt(spaps(x, noisy_y, tol))“r”2) hold住

在区间两端的近似值要差得多,而且远不是周期性的。为了加强周期性,对周期性扩展的数据进行近似,然后将近似限制在原始区间内。

([1 end]) =均值([1 end]);lx =长度(x);lx2 =圆(lx / 2);范围= [lx2: lx2 2:lx2 2:lx2];sps = spaps ([x (lx2: lx) 2 *π(2:lx) x (2: lx2) + 2 *π),noisy_y(范围),2 * tol);

这给出了更接近周期的近似值,用黑色表示。

持有fnplt (sps(0 2 *π)“k”,2)

最小二乘近似

或者,您可以使用带有几个自由度的样条曲线对有噪声的数据进行最小二乘逼近。

例如,您可以尝试一个只有4块的三次样条。

spl2 = spap2(4,4,x, noisy_y);fnplt (spl2“b”2);轴([-1 7 -1.2 1.2])保持情节(x, noisy_y,“x”)举行

选择结

当使用spapispap2,通常需要指定一个特定的样条空间。这是通过指定a来实现的结序列和一个订单,这可能有点问题。但是,当做样条插值的时候x, y使用有序样条的数据k,你可以使用这个函数optknt提供一个良好的结序列,如下例所示。

k = 5;%(5)即。,we are working with quartic splinesx = 2*pi*sort([0 1 rand(1,10)]);y = cos (x);sp = spapi(optknt(x,k), x, y);fnplt (sp 2‘g’);持有情节(x, y,“o”)举行轴([-1 7 -1.1 1.1])

在进行最小二乘逼近时,您可以使用当前的近似值来确定一个可能更好的结的选择newknt。例如,下面的指数函数的近似值不是很好,从它的误差可以看出,用红色标出。

x = linspace (0, 10101);y = exp (x);sp0 = spap2(augknt(0:2:10,4), 4, x, y);情节(x, y-fnval (sp0 x),“r”,“线宽”,2)

不过,您可以使用该初始近似值创建另一个具有相同数量的节,但这是更好的分布。它的误差用黑色标出。

sp1 = spap2(newknt(sp0), 4, x, y);持有情节(x, y-fnval (sp1, x),“k”,“线宽”,2)

网格数据

所有样条插值和逼近命令在曲线拟合工具箱也可以处理网格数据,在任何数量的变量。

例如,这是一个双三次样条插值到墨西哥帽函数。

x =。+ (4: .2:4);y = 3: .2:3;(yy, xx) = meshgrid (y、x);r =π* sqrt (xx。^ 2 + yy。^ 2);z =罪(r)。/ r;bcs = csapi({x,y}, z);fnplt(bcs)轴([-5 5 -5 5 -。5 (1)

这是最小二乘逼近同一网格上同一函数的噪声值。

knotsx = augknt(linspace(x(1), x(end), 21), 4);knotsy = augknt(linspace(y(1), y(end), 15), 4);bsp2 = spap2 ({knotsx, knotsy}, (4 - 4), {x, y}, z + .02 *(兰德(大小(z))));fnplt(bsp2)轴([-5 5 -5 5 -。5 (1)

曲线

由于曲线拟合工具箱能够很好地处理网格化数据向量值样条函数。这也使得处理参数曲线很容易。

例如,这里是一个无穷大的近似值,通过将三次样条曲线通过下图中标记的点得到。

t = 0:8;xy = [0 0;1; 2]1.7 0;1 -1;0 0;1 1;-1.7 0;1 1;0 0]。”;infty = csape(t, xy,“周期”);fnplt(infty, 2)轴([-2 2 -1.1 1.1])保持情节(xy (1:), xy (2:)“o”)举行

这是同一条曲线,但在三维空间中运动。

滚轮= csape(t, [xy;0 1/2 1 1/2 0 1/2 1 1/2 0],“周期”);fnplt(滚轮,2,[0 4],“b”)举行fnplt(滚轮,2,[4 8])“r”)plot3 (0, 0, 0,“o”)举行

曲线的两部分用不同的颜色绘制,原点被标记出来,以帮助可视化这个双翼空间曲线。

表面

带有R^3值的二元张量积样条给出了曲面。例如,这是一个很好的环面近似。

x = 0:4;y = 2:2;R = 4;r = 2;v = 0 (3、5、5);v(3,:,:) = [0 (R-r)/2 0 (R-r)/2 0]。'*[1,1,1,1];v(2,:,:) = [R (R +R)/2 R (R +R)/2 R]。'*[0 1 0 -1 0];v(1,:,:) = [R (R +R)/2 R (R +R)/2 R]。'*[1 0 -1 0 1];dough0 = csape ({x, y}, v,“周期”);fnplt (dough0)轴平等的,轴

这是那个表面的法线冠。

nx = 43;nx的xy = [(1);linspace (2, 2, nx)];点= fnval (dough0 xy) ';各级= fnval (fndir (dough0、眼睛(2)),xy);法线=交叉(接单(4:6 -:),各级(1:3,:));法线= (normals. / repmat (√sum(法线。*法线)),3,1))';pn =[点,点+法线];持有j = 1: nx plot3 (pn ([j, j + nx], 1), pn ([j, j + nx], 2), pn ([j, j + nx], 3))结束持有

最后,这是它在(x,y)平面上的投影。

fnplt(fncmb(dough0, [1 0 0;轴([-5.25 5.25 -4.14 4.14]),轴

分散的数据

也可以对平面上未网格化数据点的值进行内插。例如,考虑将单元正方形平滑映射到单元磁盘的任务。我们将数据值标记为圆形,并将相应的数据站点标记为x。每个数据站点通过一个箭头连接到它的相关值。

n = 64;t = linspace(0, 2 *π,n + 1);t(结束)= [];值= (cost;罪(t)];:情节(值(1)、价值观(2:)”或“)轴平等的,轴网站= values. / repmat (max (abs(值))、2、1);持有情节(网站(1:),网站(2:)“xk”)箭袋(网站(1:),网站(2:)...值(1:)网站(1:),值(2:)网站(2:))

然后使用tpaps构造二元插值向量值薄板样条。

st = tpaps(位点,值,1);

样条曲线确实平滑地(近似地)将单位正方形映射到单位磁盘,就像它的图形通过fnplt表示。图中显示了样条映射下的等间距正方形网格的图像

持有fnplt (st)