20.1 Solvers

Last-modified: 2025-04-05 (土) 14:33:52

20.1 ソルバー

Octaveは次のような非線形方程式を解くことができる。

F (x) = 0

MINPACK サブルーチンfsolveに基づく関数 を使用します。これは反復的な手法であるため、開始点を指定する必要があります。また、解が存在する場合でも収束が保証されないという結果になります。 hybrd

: x = fsolve (fcn, x0)

: x = fsolve (fcn, x0, options)

: [x, fval] = fsolve (…)

: [x, fval, info] = fsolve (…)

: [x, fval, info, output] = fsolve (…)

: [x, fval, info, output, fjac] = fsolve (…)

関数fcnによって定義された非線形方程式系を解きます。

fcn は、関数ハンドル、インライン関数、または評価する関数の名前を含む文字列です。fcn は、未知の変数を定義するベクトル (配列) を受け入れ、方程式の左辺のベクトルを返します。右辺はゼロとして定義されます。言い換えると、この関数は、(近似的に) すべてゼロになる ような ベクトルxを決定しようとします。fcn (x)

x0は解の初期推定値です。x0の形状はfcnのすべての呼び出しで保持されますが、それ以外の場合は列ベクトルとして扱われます。

options は、 アルゴリズムを制御する追加のパラメータを指定する構造体です。現在、 は、次の オプション を認識 しますfsolve: "AutoScaling"、、、、、、、、、、、、、、および。"ComplexEqn""FinDiffType""FunValCheck""Jacobian""MaxFunEvals""MaxIter""OutputFcn""TolFun""TolX""TypicalX""Updating"

"AutoScaling"が の場合"on"、変数は(推定)ヤコビアンの列ノルムに従って自動的にスケールされます。その結果、 は"TolFun"スケーリングに依存しなくなります。デフォルトでは、このオプションは です"off"。これは、予期しない(数学的には正しいが)結果が返される場合があるためです。

"ComplexEqn"が の場合"on"、fsolve方程式が複素導関数を持つ(つまり、正則である)と仮定して、複素変数の複素方程式を解こうとします。これが望ましくない場合は、システムの実数部と虚数部をアンパックして実数システムを取得する必要があります。

"Jacobian"の場合、 fcnが 2 つの出力引数で呼び出されたときに、要求されたポイントの右側のヤコビ行列も返すこと "on"を指定します。

"MaxFunEvals"最適化を停止するまでの関数評価の最大回数を指定します。デフォルト値は 100 * number_of_variables、つまり です。値は正の整数でなければなりません。 100 * length (x0)

"Updating"の場合"on"、関数はヤコビアン計算の回数を減らすために、ブロイデン更新を使用してヤコビアンを更新しようとします。ユーザー関数が常にヤコビアンを計算する場合(出力引数の数に関係なく)、このオプションには利点がないため、無効にする必要があります。

"TolX"は未知の変数の終了許容値を指定しますが、 は"TolFun"方程式の許容値です。と の1e-6 両方でデフォルトは です。 "TolX""TolFun"

その他のオプションの説明については、 を参照してください。を使用する optimsetために、オプション構造体をデフォルト値で初期化するには、 を参照してください。 fsolveoptions = optimset ("fsolve")

最初の出力xは解であり、2 番目の出力fvalにはxで評価された関数fcn の値(理想的には、すべてゼロのベクトル) が含まれます。

3 番目の出力情報は、アルゴリズムが成功したかどうかを報告し、次のいずれかの値を取る可能性があります。

1

解点に収束しました。相対残差誤差は で指定された値より小さくなりますTolFun。

2

最後の相対ステップ サイズは 未満でしたTolX。

3

残差の最終相対減少は 未満でしたTolFun。

0

反復制限 (MaxIterまたはMaxFunEvals) を超えました。

-1

OutputFcnに立ち寄りました。

-2

ヤコビアンが極端に小さくなり、探索が行き詰まりました。

-3

信頼領域の半径が極端に小さくなりました。

出力は、アルゴリズムに関する実行時情報を含む構造体です fsolve。構造体のフィールドは次のとおりです。

iterations

ループの反復回数。

successful

成功した反復回数。

funcCount

関数評価の回数。

最終出力fjac には、 xで評価されたヤコビアンの値が含まれます。

注: 1 つの変数の非線形方程式が 1 つだけの場合は、 を使用する方が fzero通常ははるかに適切です。

ユーザ指定のヤコビアンに関する注意: アルゴリズムの固有の特性として、残差ベクトルが既に分かっている解ベクトルに対しては常にヤコビアンが要求され、これが最後に受け入れられた成功したステップです。多くの場合、これは最後の 2 回の呼び出しの 1 つになりますが、常にそうとは限りません。ヤコビアン計算で残差計算からの中間結果を再利用することによる節約が重要な場合は、 を使用するのが最善の戦略ですOutputFcn。ベクトルの残差が評価された後、 が OutputFcnそのベクトルで呼び出された場合、中間結果は将来のヤコビアン評価のために保存され、ヤコビアン評価が要求されるか、 がOutputFcn異なるベクトルで呼び出されるまで保持されます。後者の場合、中間結果はこの最新のベクトルに置き換えられます。これを実現する方法の簡単な例を以下に示します。

function [fval, fjac] = user_fcn (x, optimvalues, state)
persistent sav = [], sav0 = [];
if (nargin == 1)
 ## evaluation call
 if (nargout == 1)
   sav0.x = x; # mark saved vector
   ## calculate fval, save results to sav0.
 elseif (nargout == 2)
   ## calculate fjac using sav.
 endif
else
 ## outputfcn call.
 if (all (x == sav0.x))
   sav = sav0;
 endif
 ## maybe output iteration status, etc.
endif
endfunction
## ...
fsolve (@user_fcn, x0, optimset ("OutputFcn", @user_fcn, ...))

See also: fzero, optimset.

以下は完全な例です。方程式を解くには

-2x^2 + 3xy   + 4 sin(y) = 6
 3x^2 - 2xy^2 + 3 cos(x) = -4

まず、与えられた関数の値を計算する関数を記述する必要があります。例:

function y = f (x)
 y = zeros (2, 1);
 y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
 y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
endfunction

次に、fsolve指定された初期条件で呼び出して、方程式系の根を求めます。たとえば、 f上で定義した関数を考えると、

[x, fval, info] = fsolve (@f, [1; 2])
results in the solution
x =
 0.57983
 2.54621
fval =
 -5.7184e-10
  5.5460e-10
info = 1

info = 1の値は、解が収束したことを示します。

ヤコビアンが与えられていない場合(上記の例のように)、数値的に近似されます。これはより多くの関数評価を必要とし、したがって効率が悪くなります。上記の例では、ヤコビアンを解析的に計算することができます。

function [y, jac] = f (x)
 y = zeros (2, 1);
 y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
 y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
 if (nargout == 2)
   jac = zeros (2, 2);
   jac(1,1) =  3*x(2) - 4*x(1);
   jac(1,2) =  4*cos(x(2)) + 3*x(1);
   jac(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
   jac(2,2) = -4*x(1)*x(2);
 endif
endfunction

ヤコビアンは次のようにfsolve呼び出して使用できます。

[x, fval, info] = fsolve (@f, [1; 2], optimset ("jacobian", "on"));

これによって、前と同じ解決策が得られます。

: x = fzero (fcn, x0)

: x = fzero (fcn, x0, options)

: [x, fval] = fzero (…)

: [x, fval, info] = fzero (…)

: [x, fval, info, output] = fzero (…)

一変数関数のゼロを見つけます。

fcn は、関数ハンドル、インライン関数、または評価する関数の名前を含む文字列です。

x0はゼロを挟む2つの点を指定する2要素ベクトルでなければならない。言い換えれば、x0 (1)とx0 (2)の間で関数の符号が変わる必要がある。より数学的に言えば、次の式が成り立つ必要がある。

sign (fcn(x0(1))) * sign (fcn(x0(2))) <= 0

x0が単一のスカラーの場合、有効な括弧を取得するために、複数の近い値と遠い値が調べられます。これが成功しない場合、関数は失敗します。

options は、 追加のオプションを指定する構造体です。現在、 は、、、、、、およびのfzeroオプションを認識します 。 "Display""FunValCheck""MaxFunEvals""MaxIter""OutputFcn""TolX"

"MaxFunEvals"検索が停止するまでの関数評価の最大回数を指定します。デフォルト値は ですInf。値は正の整数でなければなりません。

"MaxIter"検索が停止するまでのアルゴリズムの最大反復回数を指定します。デフォルト値は ですInf。値は正の整数でなければなりません。

"TolX"解xの終了許容値を指定します。デフォルト値は ですeps。

その他のオプションの説明については、 を参照してください。を使用する optimsetために、オプション構造体をデフォルト値で初期化するには、 を参照してください。 fzerooptions = optimset ("fzero")

終了時に、関数は近似ゼロ点であるxと、 xで評価された関数であるfvalを返します。

3 番目の出力情報は、アルゴリズムが成功したかどうかを報告し、次のいずれかの値を取る可能性があります。

1 アルゴリズムは解に収束しました。
0 反復または関数評価の最大回数に達しました。
-1 アルゴリズムはユーザーによって終了されましたOutputFcn。
-5 アルゴリズムが特異点に収束した可能性があります。

出力は、アルゴリズムに関する実行時情報を含む構造体です fzero。構造体のフィールドは次のとおりです。

iterations ループの反復回数。
funcCount 関数評価の回数。
アルゴリズム 文字列"bisection, interpolation"。
bracketx x 軸に沿ってゼロを最終的に括弧で囲んだ 2 要素のベクトル。
brackety y 軸に沿ってゼロを最後に括弧で囲んだ 2 要素のベクトル。

See also: optimset, fsolve.