このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
非線形最小二乗法とヤコビアンの有無
この例では、非線形最小二乗問題を解く 2 つの方法を説明します。この例では、まず、ヤコビ関数を使わずに問題を解きます。次いで、ヤコビアンを含める方法と、それによる効率性の改善について説明します。
この問題には 10 個の項と 2 個の未知数があります。次を最小化する、2 次元ベクトル x を見つけます。
点 x0 = [0.3,0.4]
を開始値とします。
lsqnonlin
は二乗和がユーザー関数で陽的に作成されていないことを想定しているため、lsqnonlin
に渡す関数が以下のベクトル値関数を演算しなければなりません。
ここで、k = 1 ~ 10 です (すなわち、F は 10 個の要素をもたなければなりません)。
ヤコビアンなしで問題を解く
補助関数 myfun
(この例の終わりで定義) は、導関数情報を使用せずにベクトル値目的関数を実装します。点 x0
から開始して、最小化を解きます。
x0 = [0.3,0.4]; % Starting guess [x,resnorm,res,eflag,output] = lsqnonlin(@myfun,x0); % Invoke optimizer
Local minimum possible. lsqnonlin stopped because the size of the current step is less than the value of the step size tolerance. <stopping criteria details>
解と関数評価回数を検証します。
disp(x)
0.2578 0.2578
disp(resnorm)
124.3622
disp(output.funcCount)
72
ヤコビアンを含む問題を解く
目的関数は単純であるため、そのヤコビアンを計算できます。ベクトル関数のヤコビアンでの定義に従って、ヤコビ関数は次の行列を表現します。
ここで、 は目的関数の k 番目の成分です。この例では、次のようになります。
したがって
補助関数 myfun2
(この例の終わりで定義) は、ヤコビアンをもつ目的関数を実装するものです。ソルバーがヤコビアンを使用するようにオプションを設定します。
opts = optimoptions(@lsqnonlin,'SpecifyObjectiveGradient',true);
ソルバーを実行します。
lb = []; % No bounds
ub = [];
[x2,resnorm2,res2,eflag2,output2] = lsqnonlin(@myfun2,x0,lb,ub,opts);
Local minimum possible. lsqnonlin stopped because the size of the current step is less than the value of the step size tolerance. <stopping criteria details>
解は前の解と同じです。
disp(x2)
0.2578 0.2578
disp(resnorm2)
124.3622
ヤコビアンを使用する利点は、ソルバーによる関数評価の回数が大幅に減少することです。
disp(output2.funcCount)
24
補助関数
次のコードは、補助関数 myfun
を作成します。
function F = myfun(x) k = 1:10; F = 2 + 2*k-exp(k*x(1))-exp(k*x(2)); end
次のコードは、補助関数 myfun2
を作成します。
function [F,J] = myfun2(x) k = 1:10; F = 2 + 2*k-exp(k*x(1))-exp(k*x(2)); if nargout > 1 J = zeros(10,2); J(k,1) = -k.*exp(k*x(1)); J(k,2) = -k.*exp(k*x(2)); end end