数学建模-插值与拟合模型

插值:求过已知有限个数据点的近似函数。

拟合:已知有限个数据点,求近似函数,不要求过已知数据点,只要求在某种意义下它在这些点上的总偏差最小。

插值和拟合都是要根据一组数据构造一个函数作为近似,由于近似的要求不同,二者的数学方法上是完全不同的。而面对一个实际问题,究竟应该用插值还是拟合,有时容易确定,有时则并不明显。

插值

1、一维插值函数

y = interp1(x0,y0,x,'method')

mothod指定插值的方法,默认为线性插值 
‘nearest’最近项插值 
‘linear’线性插值 
‘spline’立方样条插值 
‘cubic’立方插值

2、三次样条插值

pp = csape(x0,y0,conds,valconds);
y = fnval(pp,x)

‘conds’指定边界条件 
‘complete’边界为一阶导数,一阶导数的值在valconds中给出,若忽略valconds,则使用Lagrange边界条件 
‘not-a-knot’非扭结条件 
‘periodic’周期条件 
‘second’边界为二阶导数,二阶导数值在valconds中给出,若忽略valconds,默认值为【0,0】 
‘variational’设置边界的二阶导数值为【0,0】

3.Lagrange 插值

Matlab 中没有现成的Lagrange 插值函数,必须编写一个M文件实现Lagrange 插值。设n个节点数据以数组x0, y0输入(注意 Matlat 的数组下标从 1 开始),m 个插值点以数组x 输入,输出数组y 为m 个插值。编写一个名为lagrange.m 的M 文件:

function y=lagrange(x0,y0,x);
n=length(x0);m=length(x);
for i=1:m
    z=x(i);
    s=0.0;
    for k=1:n
        p=1.0;
        for j=1:n
            if j~=k
            p=p*(z-x0(j))/(x0(k)-x0(j));
                end
            end
            s=p*y0(k)+s;
        end
        y(i)=s;
    end

4.分段线性插值

简单地说,将每两个相邻的节点用直线连起来,如此形成的一条折线就是分段线性插值函数.

y=interp1(x0,y0,x,'method')
method 指定插值的方法,默认为线性插值。其值可为:
'nearest' 最近项插值
'linear' 线性插值
'spline' 逐段3 次样条插值
'cubic' 保凹凸性3 次插值。

所有的插值方法要求 x0 是单调的。当 x0 为等距时可以用快速插值法,使用快速插值法的格式为'*nearest'、'*linear'、
'*spline'、'*cubic'。

例:机床加工
待加工零件的外形根据工艺要求由一组数据(x, y)给出(在平面情况下),用程控铣床加工时每一刀只能沿x 方向和y 方向走非常小的一步,这就需要从已知数据得到加工所要求的步长很小的(x, y)坐标。


表 1 中给出的x, y数据位于机翼断面的下轮廓线上,假设需要得到x坐标每改变0.1 时的 y坐标。试完成加工所需数据,画出曲线,并求出x = 0处的曲线斜率和13 ≤ x ≤ 15范围内 y的最小值。

clc,clear
x0=[0 3 5 7 9 11 12 13 14 15];
y0=[0 1.2 1.7 2.0 2.1 2.0 1.8 1.2 1.0 1.6];
x=0:0.1:15;
y1=lagrange(x0,y0,x); %调用前面编写的Lagrange插值函数
y2=interp1(x0,y0,x);
y3=interp1(x0,y0,x,'spline');
pp1=csape(x0,y0); y4=ppval(pp1,x);
pp2=csape(x0,y0,'second'); y5=ppval(pp2,x);
fprintf('比较一下不同插值方法和边界条件的结果:\n')
fprintf('x y1 y2 y3 y4 y5\n')
xianshi=[x',y1',y2',y3',y4',y5'];
fprintf('%f\t%f\t%f\t%f\t%f\t%f\n',xianshi')
subplot(2,2,1), plot(x0,y0,'+',x,y1), title('Lagrange')
subplot(2,2,2), plot(x0,y0,'+',x,y2), title('Piecewise linear')
subplot(2,2,3), plot(x0,y0,'+',x,y3), title('Spline1')
subplot(2,2,4), plot(x0,y0,'+',x,y4), title('Spline2')
dyx0=ppval(fnder(pp1),x0(1)) %求x=0处的导数
ytemp=y3(131:151);
index=find(ytemp==min(ytemp));
xymin=[x(130+index),ytemp(index)]

拉格朗日插值的结果根本不能应用,分段线性插值的光滑性较差(特别是在x = 14附近弯曲处),建议选用三次样条插值的结果。

拟合

1.线性最小二乘法

曲线拟合问题的提法是,已知一组(二维)数据,即平面上的n个点( x_{i}, y_{i})  i=1,...,n, x_{i} 互不相同,寻求一个函数(曲线) y = f (x),使 f (x)在某种准则下与所有数据点最为接近,即曲线拟合得最好。

例:用最小二乘法求一个形如 y = a + bx2的经验公式,使它与下表所示的数据拟合。

x=[19 25 31 38 44]';
y=[19.0 32.3 49.0 73.3 97.8]';
r=[ones(5,1),x.^2];
ab=r\y
x0=19:0.1:44;
y0=ab(1)+ab(2)*x0.^2;
plot(x,y,'o',x0,y0,'r')

2.多项式拟合法

如果取{ r_{1}(x),...,r_{m+1}(x)} {1,x,...,x_{m}} 1 1,即用m 次多项式拟合给定数据,Matlab中有现成的函数

a=polyfit(x0,y0,m)

其中输入参数x0,y0 为要拟合的数据,m 为拟合多项式的次数,输出参数a 为拟合多项式y=a_{m}x^{m}+…+a_{1}x+a_{0} 系数a=[ a_{m}, …, a_{1}, a_{0}]。
多项式在x 处的值y 可用下面的函数计算

y=polyval(a,x)。

例:某乡镇企业1990-1996 年的生产利润如下表,试预测1997 年和1998 年的利润。

x0=[1990 1991 1992 1993 1994 1995 1996];
y0=[70 122 144 152 174 196 202];
plot(x0,y0,'*')

发现该乡镇企业的年生产利润几乎直线上升。因此,我们可以用 y =a_{1}x+a_{0}作为拟合函数来预测该乡镇企业未来的年利润。编写程序如下:

x0=[1990 1991 1992 1993 1994 1995 1996];
y0=[70 122 144 152 174 196 202];
a=polyfit(x0,y0,1)
y97=polyval(a,1997)
y98=polyval(a,1998)

求得a_{1}=20a_{0}=−4.0705×10^{4},1997,1997 年的生产利润 y97=233.4286,1998 年的生产利润y98=253.9286。

3.最小二乘优化
 

猜你喜欢

转载自blog.csdn.net/weixin_37079656/article/details/86545654