曲線擬合的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 CArray<double,double>CDoubleArray;
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<M;i++)
  (*A)[i]=0;
 Z=0;
 B[0]=1;
 D1=N;
 P=0;
 C=0;
 for(i=0;i<N;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<N;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<M;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<N;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  t.^2];             
a = X\y                                   

%regress函數
X = [ones(size(t))  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 = X\y


%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 = X\y


%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插值。

從幾何意義上將,擬合是給定了空間中的一些點,找到一個已知形式未知參數的連續曲面來最大限度地逼近這些點;而插值是找到一個(或幾個分片光滑的)連續曲面來穿過這些點。


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章