非線性擬合lsqcurvefit、nlinfit


問題:有些時候我們需要擬合一些非線性的表達式。

比如:我們知道一個表達式的式子是y=A*sin(x).*exp(x)-B./log(x),現在我們手里面有x與y對應的一大把數據。我們如何根據x,y的值找出最佳的A、B值。則我們現在借助Matlab的函數lsqcurvefit、nlinfit,當然你也可以使用lsqnonlin.其具體用法請自己用Matlab的幫助命令進行查看。這里僅簡單介紹一下常用的方式。

 

注意:如果對初值比較敏感,涉及到初值設置的問題;以及擬合表達式包含積分表達式或者微分項等問題;以及一些擬合降維的問題,可以參看我的另一篇博文《數據擬合遇見

 

PS:如果使用Matlab以上函數擬合不出理想的結果的話,可以嘗試使用我自己寫的《數學計算器》里的nlinFitnlinFit2nlinFit4nlinFitDE、nlinFitGA、nlinFitLM、nlinFitPSO、nlinFitPSO2、nlinFitPSO3函數

 

格式:lsqcurvefit(f,a,x,y)、nlinfit(x,y,f,a)

f:符號函數句柄,如果是以m文件的形式調用的時候,別忘記加@.這里需要注意,f函數的返回值是和y匹對的,即擬合參數的標准是(f-y)^2取最小值,具體看下面的例子

a:最開始預估的值(預擬合的未知參數的估計值)。如上面的問題如果我們預估A為1,B為2,則a=[1 2]

x:我們已經獲知的x的值

y:我們已經獲知的x對應的y的值

 

例子1:

問題:對於函數y=a*sin(x)*exp(x)-b/log(x)我們現在已經有多組(x,y)的數據,我們要求最佳的a,b值

%針對上面的問題,我們可以來演示下如何使用這個函數以及看下其效果

>> x=2:10;

>> y=8*sin(x).*exp(x)-12./log(x);

%上面假如是我們事先獲得的值

>> a=[1 2];

>> f=@(a,x)a(1)*sin(x).*exp(x)-a(2)./log(x);

%第一種方法使用lsqcurvefit

>> lsqcurvefit(f,a,x,y)

ans =

   7.999999999999987  11.999999999988997%和我們預期的值8和12結合得非常好

>>

%第二種方法使用nlinfit

>> nlinfit(x,y,f,a)

ans =

   8.000000000000000  11.999999999999998

>>

%**********************************

%另一種方法,假如我們寫了一個如下的m文件

function f=test(a,x)

f=a(1)*sin(x).*exp(x)-a(2)./log(x);

end

%則在上面lsqcurvefit函數調用如下,不要忘記那個@

lsqcurvefit(@test,a,x,y)

 

 

例子2:(多元的情況,注意看格式)

問題:我們已知z=a*(exp(y)+1)-sin(x)*b且有多組(x,y,z)的值,現在求最佳系數a,b

>> x=2:10;

>> y=10*sin(x)./log(x);

>> z=4.5*(exp(y)+1)-sin(x)*13.8;

>> f=@(a,x)a(1)*(exp(x(2,:))+1)-sin(x(1,:))*a(2);

%第一種方法使用lsqcurvefit

>> lsqcurvefit(f,[1 2],[x;y],z)%注意這里面的[x;y],這里的[1 2]表示我們設置f函數里的初始值a(1)=1,,a(2)=2

ans =

   4.499999999999999  13.800000000000024

%第二種方法使用nlinfit

>> nlinfit([x;y],z,f,[1 2])

ans =

   4.500000000000000  13.799999999999956

>>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM