あなたは十分に得ることができますfsolve
。ただし、いくつかの作業を行う必要があります。オプションを読み、Matlab の最適化メソッドの出力関数'OutputFcn'
を記述します。これは、Matlab の ODE ソルバーで使用される同じ名前のオプションに似ています。オプション値を複製する例を次に示します(具体的にはデフォルトアルゴリズムの場合)。'Display','iter'
fsolve
'trust-region-dogleg'
function stop = outfun(x,optimValues,state)
% See private/trustnleqn
stop = false;
switch state
case 'init'
header = sprintf(['\n Norm of First-order Trust-region\n',...
' Iteration Func-count f(x) step optimality radius']);
disp(header);
case 'iter'
iter = optimValues.iteration; % Iteration
numFevals = optimValues.funccount; % Func-count
F = optimValues.fval; % f(x)
normd = optimValues.stepsize; % Norm of step
normgradinf = optimValues.firstorderopt; % First-order optimality
Delta = optimValues.trustregionradius; % Trust-region radius
if iter > 0
formatstr = ' %5.0f %5.0f %13.6g %13.6g %12.3g %12.3g';
iterOutput = sprintf(formatstr,iter,numFevals,F'*F,normd,normgradinf,Delta);
else
formatstr0 = ' %5.0f %5.0f %13.6g %12.3g %12.3g';
iterOutput = sprintf(formatstr0,iter,numFevals,F'*F,normgradinf,Delta);
end
disp(iterOutput);
case 'done'
otherwise
end
その後、次の方法でこれを呼び出すことができます。
function example
P1a=@(x)[x(1)+x(2)*(x(2)*(5-x(2))-2)- 13; x(1)+x(2)*(x(2)*(1+x(2))-14)-29];
x0 = [15; -2];
opts = optimoptions('fsolve','Display','off','OutputFcn',@outfun,'TolFun',eps,'TolX',eps);
[x,fval,exitflag,output] = fsolve(P1a,x0,opts);
これはまだコマンド ウィンドウに出力されるだけです。ここからは、配列、ファイル、またはその他のデータ構造にデータを書き込むことができる出力関数を作成することです。グローバル変数を使用してこれを行う方法は次のとおりです(一般的には、良い考えではありません)。
function stop = outfun2(x,optimValues,state)
stop = false;
global out; % Global variable, define in main function too
switch state
case 'init'
out = [];
case 'iter'
iter = optimValues.iteration; % Iteration
numFevals = optimValues.funccount; % Func-count
F = optimValues.fval; % f(x)
normd = optimValues.stepsize; % Norm of step
normgradinf = optimValues.firstorderopt; % First-order optimality
Delta = optimValues.trustregionradius; % Trust-region radius
out = [out;iter numFevals F'*F normd normgradinf Delta];
case 'done'
otherwise
end
global out;
次に、を呼び出す前にメイン関数で宣言するだけfsolve
です。出力関数をネストされた関数にすることでこれを達成することもできます。この場合、out
配列は外側のメイン関数と共有されます。
out
2 番目の出力関数の例では、配列全体を再割り当てする代わりに、動的メモリ割り当てを実行します。これを回避する方法はありません。なぜなら、私たちもアルゴリズムも、収束するまでに何回の反復が必要かを知らないからです。ただし、数百回の反復では、動的メモリ割り当てはかなり高速になります。
ツールが手元にあるので、「収束率の決定」はあなたに任せます...