[转载][转载]曲线拟合的MATLAB实现

函数插值与曲线拟合

1、函数插值

  一维插值:interp1(x,y,cx,’method’)

  一维插值:interp1(x,y,z,cx,cy,’method’)

method:nearest、linear、spline、cubic

例:

clear

echo on

x=-2:0.4:2;

y=[2.8 2.96 2.54 3.44 3.565.4

6.0 8.7 10.1 13.3 14.0];

t=-2:0.01:2;

nst=interp1(x,y,t,'nearest');

plot(x,y,'r*',t,nst)

title('最临近点插值')

lnr=interp1(x,y,t,'linear');

figure(2)

 

plot(x,y,'r*',t,lnr,'b:')

title('线性插值')

spl=interp1(x,y,t,'spline');

figure(3)

plot(x,y,'r*',t,spl)

title('样条插值')

cbc=interp1(x,y,t,'cubic');

figure(4)

plot(x,y,'r*',t,cbc,'k-')

title('三次插值')

2、曲线拟合

多项式拟合:polyfit(x,y,m) 线性:m=1,二次:m=2, …

例:

x=0:0.1:1;

y=[-0.447 1.978 3.28 6.16 7.08 7.347.66 9.56 9.48 9.30 11.2];

A=polyfit(x,y,2)

Z=polyval(A,x);

Plot(x,y,’r*’,x,z,’b’)

matalb 曲线拟合的问题
%多项式拟合函数polyfit示例
x=[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1];
y=[-0.4471 0.978 3.28 6.16 7.08 7.34 7.66 9.56 9.48 9.30 11.2];
n=2;%polynomial order
p=polyfit(x, y, n);
%polyfit 的输出是一个多项式系数的行向量。
%其解是y = -9.8108x2+20.1293x-0.0317。为了将曲线拟合解与数据点比较,
让我们把二者都绘成图。
xi=linspace(0, 1, 100);%x-axis data for plotting
z=polyval(p, xi);%polyval 求多项式值
plot(x, y, ' o ' , x, y, xi, z, ' : ' )
xlabel('x')
ylabel('y=f(x)')

title('Second Order Curve Fitting')

//最小二乘法曲线拟合
typedef CArrayCDoubleArray;
BOOL CalculateCurveParameter(CDoubleArray *X,CDoubleArray *Y,long M,long N,CDoubleArray *A)
{
 //X,Y --  X,Y两轴的坐标
 //M   --  结果变量组数
 //N   --  采样数目
 //A   --  结果参数

 register long i,j,k;
 double Z,D1,D2,C,P,G,Q;
 CDoubleArray B,T,S;
 B.SetSize(N);
 T.SetSize(N);
 S.SetSize(N);
 if(M>N)M=N;
 for(i=0;i
  (*A)[i]=0;
 Z=0;
 B[0]=1;
 D1=N;
 P=0;
 C=0;
 for(i=0;i
 {
  P=P+(*X)[i]-Z;
  C=C+(*Y)[i];
 }
 C=C/D1;
 P=P/D1;
 (*A)[0]=C*B[0];
 if(M>1)
 {
  T[1]=1;
  T[0]=-P;
  D2=0;
  C=0;
  G=0;
  for(i=0;i
  {
   Q=(*X)[i]-Z-P;
   D2=D2+Q*Q;
   C=(*Y)[i]*Q+C;
   G=((*X)[i]-Z)*Q*Q+G;
  }
  C=C/D2;
  P=G/D2;
  Q=D2/D1;
  D1=D2;
  (*A)[1]=C*T[1];
  (*A)[0]=C*T[0]+(*A)[0];
 }
 for(j=2;j
 {
  S[j]=T[j-1];
  S[j-1]=-P*T[j-1]+T[j-2];
  if(j>=3)
  {
   for(k=j-2;k>=1;k--)
    S[k]=-P*T[k]+T[k-1]-Q*B[k];
  }
  S[0]=-P*T[0]-Q*B[0];
  D2=0;
  C=0;
  G=0;
  for(i=0;i
  {
   Q=S[j];
   for(k=j-1;k>=0;k--)
    Q=Q*((*X)[i]-Z)+S[k];
   D2=D2+Q*Q;
   C=(*Y)[i]*Q+C;
   G=((*X)[i]-Z)*Q*Q+G;
  }
  C=C/D2;
  P=G/D2;
  Q=D2/D1;
  D1=D2;
  (*A)[j]=C*S[j];
  T[j]=S[j];
  for(k=j-1;k>=0;k--)
  {
   (*A)[k]=C*S[k]+(*A)[k];
   B[k]=T[k];
   T[k]=S[k];
  }
 }
 return TRUE;
}

 

*%只考虑线性拟合*                           
                                          
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
*%原始数据 *                                
t = [0 .3 .8 1.1 1.6 2.3]';               
y = [0.5 0.82 1.14 1.25 1.35 1.40]';      
                                          
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
*%多项式拟合 *                              
                                          
                                          
p=polyfit(t,y,2)                          
                                          
%利用左除                                 
X = [ones(size(t))  t.^2];             
a = Xy                                   
                                          
%regress函数
X = [ones(size(t))  t.^2];
b=regress(y,X)

%lsqcurvefit函数
fun=inline('x(1)*t.^2+x(2)*t+x(3)','x','t');
x=lsqcurvefit(fun,[0,0,0],t,y)

%Curve Fitting Toolbox
fit1= fit(t,y,'poly2')

%Curve Fitting Toolbox(自定义多项式)
mymodel = fittype('a*t^2+b*t+c','independent','t');
%mymodel = fittype('a*x^2+b*x+c');
fit1= fit(t,y,mymodel,'start',[0,0,0])

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%指数形式的拟合


X = [ones(size(t))  exp(-t)  t.*exp(-t)];
a = Xy


%lsqcurvefit函数
fun=inline('x(1)+x(2)*exp(-t)+x(3).*t.*exp(-t)','x','t');
x=lsqcurvefit(fun,[0,0,0],t,y)


%Curve Fitting Toolbox
mymodel = fittype('a+b*exp(-t)+c*t*exp(-t)','independent','t');
%mymodel = fittype('a+b*exp(-x)+c*x*exp(-x)');
fit1= fit(t,y,mymodel,'start',[0,0,0])

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%不含常数项的多项式拟合
%利用左除
X = [t  t.^2];
a = Xy


%regress函数
X = [t  t.^2];
b=regress(y,X)


%lsqcurvefit函数
fun=inline('x(1)*t.^2+x(2)*t','x','t');
x=lsqcurvefit(fun,[0,0],t,y)


%Curve Fitting Toolbox
mymodel = fittype('a*t^2+b*t','independent','t');
%mymodel = fittype('a*x^2+b*x');
fit1= fit(t,y,mymodel,'start',[0,0])

MATLAB软件提供了基本的曲线拟合函数的命令.

多项式函数拟合a=polyfit(xdata,ydata,n)

其中n表示多项式的最高阶数,xdataydata为将要拟合的数据,它是用数组的方式输入.输出参数a为拟合多项式y=a1xn+...+anx+an+1的系数

   多项式在x处的值y可用下面程序计算.

                               y=polyval(a,x,m)        

线性:m=1,二次:m=2,…        

polyfit的输出是一个多项式系数的行向量。为了计算在xi数据点的多项式值,调用MATLAB的函数polyval

例:

x=0:0.1:1;

y=[-0.447 1.978 3.28 6.16 7.087.34 7.66 9.56 9.48 9.30 11.2];

A=polyfit(x,y,2)

Z=polyval(A,x);

Plot(x,y,’r*’,x,z,’b’)

   一般的曲线拟合p=curvefit(‘Fun’,p0,xdata,ydata)

其中Fun表示函数Fun(p,data)M函数文件,p0表示函数的初值.curvefit()命令的求解问题形式是最小二乘解

若要求解点x处的函数值可用程序f=Fun(p,x)计算.

2、函数插值

 一维插值:interp1(x,y,cx,’method’)

 一维插值:interp1(x,y,z,cx,cy,’method’)

method:nearestlinearsplinecubic

例:

clear

echo on

x=-2:0.4:2;

y=[2.8 2.96 2.54 3.44 3.565.4

6.0 8.7 10.1 13.314.0];

t=-2:0.01:2;

nst=interp1(x,y,t,'nearest');

plot(x,y,'r*',t,nst)

title('最临近点插值')

lnr=interp1(x,y,t,'linear');

figure(2)

 

plot(x,y,'r*',t,lnr,'b:')

title('线性插值')

spl=interp1(x,y,t,'spline');

figure(3)

plot(x,y,'r*',t,spl)

title('样条插值')

cbc=interp1(x,y,t,'cubic');

figure(4)

plot(x,y,'r*',t,cbc,'k-')

title('三次插值')

3 二维插值

二维插值是基于与一维插值同样的基本思想。然而,正如名字所隐含的,二维插值是对两变量的函数z=f(x,y)进行插值。interp2的基本形式是interp2(x,y, z, xi, yi,method)。这里xy是两个独立变量,z是一个应变量矩阵。xyz的关系是

z(i, :) = f(x, y(i))z(:, j) =f(x(j), y).

也就是,当x变化时,z的第i行与y的第i个元素y(i)相关,当y变化时,z的第j列与x的第j个元素x(j)相关,。xi是沿x-轴插值的一个数值数组;yi是沿y-轴插值的一个数值数组。

可选的参数method可以是'linear''cubic''nearest'。在这种情况下,cubic不意味着3次样条,而是使用3次多项式的另一种算法。linear方法是线性插值,仅用作连接图上数据点。nearest方法只选择最接近各估计点的粗略数据点。在所有的情况下,假定独立变量xy是线性间隔和单调的。

已知观察数据如下表所示,按下属方案求最小二乘拟合函数,并求出偏差平方和,比较拟合曲线的优劣。
  x:0 0.2 0.6 1.0 1.3 1.6 1.7 1.8 1.9 2.2 2.3 2.5 2.6
  y:0 -2.5 -4.0 -5.7 -3.5 -2.0 -1.0 2.0 3.5 4.0 7.0 7.5 9.9
  x:2.9 3.1 3.4 3.8 4.1 4.4 4.7 4.8 4.9 5.0 5.1 5.3
  y:10.9 11.9 13.5 13.0 11.9 9.0 6.5 4.0 1.5 0.0 -2.5 -5.0

 

 

%用离散正交多项式求三次拟合多项式
% x,y--表示原始数据的节点坐标
% w--表示权重系数
% N--表示要拟合的离散正交多项式的最高次数
% polyapproximate()--是自定义函数,可以求解多项式的系数
% 其返回值c为多项式系数,error为偏差平方和
x=[0 0.2 0.6 1.0 1.3 1.6 1.7 1.8 1.9 2.2 2.3 2.5 2.6 2.9 3.1 3.4 3.8 4.1 4.4 4.7 4.8 4.9 5.0 5.1 5.3];
nn=length(x);
for i=1:nn
    w(i)=1;
end
y=[0 -2.5 -4.0 -5.7 -3.5 -2.0 -1.0 2.0 3.5 4.0 7.0 7.5 9.9 10.9 11.9 13.5 13.0 11.9 9.0 6.5 4.0 1.5 0.0 -2.5 -5.0];
N=3;%此处可取3 or 4.
[c,error]=polyapproximate(x,y,w,N)
t=0:0.1:5.3;
u=polyval(c,t);
plot(t,u,x,y,'+')


 

%自定义函数polyapproximate(),用来做离散正交多项式拟合
% 此函数的作用是做不同次数的离散正交多项式的拟合
% X,Y 为原始数据的坐标值矩阵
% w 为权重系数
% N 为离散正交多项式的最高次数
function [C,E]=polyapproximate(X,Y,w,N)
M=length(X);
for i=1:N+1
    for j=1:i
        if j~=i
            P(i,j)=0;
        else
            P(i,j)=1;
        end
    end
end
S=0;
d(1)=0;
for i=1:M
    d(1)=d(1)+w(i);
    S=S+w(i)*X(i);
end
AF(1)=S/d(1);
P(2,1)=-AF(1);
for i=1:M
    PX(i,1)=1;
    PX(i,2)=X(i)-AF(1);
end
BA(1)=0;
for k=2:N+1
    S=0;
    dd=0;
    for i=1:M
        S=S+w(i)*X(i)*PX(i,k)*PX(i,k);
        dd=dd+w(i)*PX(i,k)*PX(i,k);
    end
    d(k)=dd;
    AF(k)=S/d(k);
    BA(k-1)=d(k)/d(k-1);
    P(k+1,1)=-AF(k-1)*P(k,1)-BA(k-1)*P(k-1,1);
    for i=1:k-1
        j=k-i+1;
        if j>=k
            t=0;
        else
            t=P(k-1,j);
        end
        P(k+1,j)=P(k,j-1)-AF(k-1)*P(k,j)-BA(k-1)*t;
    end
    for i=1:M
        PX(i,k+1)=PX(i,k)*(X(i)-AF(k-1))-BA(k-1)*PX(i,k-1);
    end
end
d(N+1)=0;
for i=1:M
    d(N+1)=d(N+1)+w(i)*PX(i,N+1)*PX(i,N+1);
end
for i=1:N+1
    FM=0;
    for k=1:M
        FM=FM+w(k)*Y(k)*PX(k,i);
    end
    gp(i)=FM/d(i);
end
for i=1:N+1
    C(i)=0;
    for j=i:N+1
        C(i)=C(i)+gp(j)*P(j,i);
    end
end
C=flipud(C');
%C=C'
U=0;
for i=1:M
    U=U+w(i)*Y(i)*Y(i);
end
V=0;
for k=1:N+1
    V=V+gp(k)*gp(k)*d(k);
end
E=U-V;

拟合预测
    拟合预测是建立一个模型去逼近实际数据序列的过程,适用于发展性的体系。建立模型时,通常都要指定一个有明确意义的时间原点和时间单位。而且,当t趋向于无穷大时,模型应当仍然有意义。将拟合预测单独作为一类体系研究,其意义在于强调其唯“象”性。一个预测模型的建立,要尽可能符合实际体系,这是拟合的原则。拟合的程度可以用最小二乘方、最大拟然性、最小绝对偏差来衡量。主要方法有:
  
  a、回归预测:主要含自回归、线形回归、同态线形回归和多元回归。
  b、“s”模型。主要用来拟合生命总量不受直接限制的体系从发生发展直到饱和点这一阶段的形象。
  c、生命旋回:对一事物从零开始,经过成长、兴盛,达到全盛期后再逐渐衰落,最后又回到零的过程的预测。它适合于总量有限的体系。
  d、周期拟合模型。当系统的条件未知,而仅对实际发生的周期因素建立的拟合模型。其准确性取决与模型的合理性,并经常为预测结果所验证,属于动态预测模型。


插值和拟合都是函数逼近或者数值逼近的重要组成部分.他们的共同点都是通过已知一些离散点集M上的约束,求取一个定义
在连续集合S(M包含于S)的未知连续函数,从而达到获取整体规律的目的,即通过"窥几斑"来达到"知全豹"。

简单的讲,所谓拟合是指已知某函数的若干离散函数值{f1,f2,…,fn},通过调整该函数中若干待定系数f(λ1, λ2,…,λ3), 使得该函数与已知点集的差别(最小二乘意义)最小。如果待定函数是线性,就叫线性拟合或者线性回归(主要在统计中),否则叫作非线性拟合或者非线性回归。表达式也可以是分段函数,这种情况下叫作样条拟合。

而插值是指已知某函数的在若干离散点上的函数值或者导数信息,通过求解该函数中待定形式的插值函数以及待定系数,使得该函数在给定离散点上满足约束。插值函数又叫作基函数,如果该基函数定义在整个定义域上,叫作全域基,否则叫作分域基。如果约束条件中只有函数值的约束,叫作Lagrange插值,否则叫作Hermite插值。

从几何意义上将,拟合是给定了空间中的一些点,找到一个已知形式未知参数的连续曲面来最大限度地逼近这些点;而插值是找到一个(或几个分片光滑的)连续曲面来穿过这些点。


posted @ 2015-10-16 09:55  alameda  阅读(250)  评论(0编辑  收藏  举报