Navigation : Top/MATLAB/カーブフィッテング

  • 追加された行はこの色です。
  • 削除された行はこの色です。
*カーブフィッテング [#l4bb7932]

**多項式 [#n4e71567]

関数 polyfit は、最小二乗的にデータ群に適合する多項式の係数を出力します。 
 p = polyfit(x,y,n) 
x と y は、適合されるデータ群のxデータ、yデータで、n は、出力される多項式の次数です。 

細かい刻みで、polyfit 推定値を計算し、実データ値と比較するために重ねて、プロットします。 
 x2 = 1:.1:5; 
 y2 = polyval(p,x2); 
 plot(x,y,'o',x2,y2) 
 grid on 


** 一般形 (R14以降) [#a130cf75]
*** Help通り [#d77fc3b7]
最初に以下のような M-ファイルを作成します。
データの x座標 と y座標に対応するベクトルを受け取る。
データを最も良く近似する指数関数のパラメータを返す。
そのためには、つぎのコードを M-ファイルにコピー、貼り付け、 MATLAB パス上のディレクトリにfitcurvedemoとして保存してください。
 function [estimates, model] = fitcurvedemo(xdata, ydata)
 % ランダムな出発点を用いて fminsearch を呼び出します
 start_point = rand(1, 2);
 model = @expfun;
 estimates = fminsearch(model, start_point);
 % expfun は入力として曲線のパラメータを受け取り、
 % A * exp(-B * xdata) - ydataの二乗誤差の和sseと
 % FittedCurveを出力します。 FMINSEARCH は、sseのみを必要としますが、 
 % 最後にFittedCurve のプロットも行います。
     function [sse, FittedCurve] = expfun(params)
         A = params(1);
         B = params(2);
         FittedCurve = A .* exp(-B * xdata);
         ErrorVector = FittedCurve - ydata;
         sse = sum(ErrorVector .^ 2);
     end
 end
この M-ファイルは、 fminsearch 関数を呼び出します。この関数は、データと指数関数A*exp(-B*t)との差の二乗和を最小にするパラメータ A と Bをみつけます。 入れ子関数 expfun は 二乗和を計算します。
- 例題の実行
-- この例題を実行するために、最初に近似するためのランダムなデータを作成します。 
-- つぎのコマンドは、パラメータ A = 40 と B=0.5をもつ指数近似できるランダムなデータを作成します。
 xdata = (0:.1:10)'; 
 ydata = 40 * exp(-.5 * xdata) + randn(size(xdata));
- データを指数関数で近似するためには、つぎのように入力します。
 [estimates, model] = fitcurvedemo(xdata,ydata)
これは、パラメータ A と Bに対する推定値を出力します。
 estimates =  40.1334    0.5025
-結果のプロット
-- 近似曲線とデータをプロットするためには、つぎのコマンドを入力します。
 plot(xdata, ydata, '*')
 hold on
 [sse, FittedCurve] = model(estimates);
 plot(xdata, FittedCurve, 'r')
  
 xlabel('xdata')
 ylabel('f(estimates,xdata)')
 title(['Fitting to function ', func2str(model)]);
 legend('data', ['fit using ', func2str(model)])
 hold off


*** ちょっと変えてみた. [#e5741f55]
fminsearchを使う.
以下の関数を用意.ここではy=exp(-x^a)という関数の最適なaを探す.

 function [estimates, model] = fitcurve(xdata, ydata, start_point)
 model = @expfun;
 estimates = fminsearch(model, start_point);
   function [sse, FittedCurve] = expfun(params)
        lambda = params(1);
        FittedCurve = exp(-xdata.^lambda/8);
        A = params(1);
        FittedCurve = exp(-xdata.^A);
        ErrorVector = FittedCurve - ydata;
        sse = sum(ErrorVector .^ 2);
    end
 end

これを使い,以下のように実行すると最適値fが出力される.
 [f] = fitcurve(x,y,start_point)
 実際
 [f] = fitcurve(x,y,[1])

---------------------------------------------------------------

** 一般形 (R13まで) [#j9932ee5]

If you know the form of the required function you can use fmins to find the best coefficients. Suppose that you think that some data should conform to a relation of the form a*x+b*sin(x)+c. You need to write a matlab function that for given values of a, b and c, calculates the square of the disparity. Its first argument is a vector of coefficients, its last argument is a vector of the given data values. The other arguments (in this case, just one) are vectors of free variables. You need to write the function this way so that fmins can use it. 

 function out=fun(coeff,X,Y) 
 % fun.m 
 a = coeff(1); 
 b = coeff(2); 
 c = coeff(3); 
 Y_fun = a .* X + b .* sin(X)+c; 
 DIFF = Y_fun - Y; 
 SQ_DIFF = DIFF.^2; 
 
 out = sum(SQ_DIFF); 

If you call this file fun.m, then 
 x=1:10; 
 y=sin(x); 
 bestcoeffs=fmins('fun',[1 1 1],[],[],x,y); 
 yfit=bestcoeffs(1)*x +bestcoeffs(2)*sin(x) + bestcoeffs(3); 
 %Now compare y with yfit 
 plot(x,y,x,yfit); 

will display the results. The [1 1 1] argument to fmins provides the starting values for a, b and c. 

fmins becomes fminsearch since R13. 

*** fmins から fminsearchへの変換   バージョン4では、次の呼び出し方法でfminsを使用していました。 [#u8266f94]

 [X,OPTIONS] = fmins('FUN',x0,OPTIONS,[],P1,P2,...);
 
 バージョン5では、つぎのように fminsearch を呼び出します。
 
 [X,FVAL,EXITFLAG,OUTPUT] = fminsearch(@FUN,xs0,...
                                       OPTIONS,P1,P2,...);

*** Referenece [#i3ca5a5e]
http://www-h.eng.cam.ac.uk/help/tpl/programs/Matlab/curve_fitting.html