|
|
◆ Optif9()
| Sub Optif9 |
( |
N As |
Long, |
|
|
X() As |
Double, |
|
|
F As |
LongPtr, |
|
|
Typsiz() As |
Double, |
|
|
Fscale As |
Double, |
|
|
Xpls() As |
Double, |
|
|
Fpls As |
Double, |
|
|
Gpls() As |
Double, |
|
|
Info As |
Long, |
|
|
Optional Info2 As |
Long, |
|
|
Optional Iter As |
Long, |
|
|
Optional D1fcn As |
LongPtr = NullPtr, |
|
|
Optional D2fcn As |
LongPtr = NullPtr, |
|
|
Optional DfcnChk As |
Long = 0, |
|
|
Optional Result As |
LongPtr = NullPtr, |
|
|
Optional Method As |
Long = 1, |
|
|
Optional Iexp As |
Long = 1, |
|
|
Optional Ndigit As |
Long = 0, |
|
|
Optional MaxIter As |
Long = 0, |
|
|
Optional Dlt As |
Double = -1, |
|
|
Optional Gradtl As |
Double = -1, |
|
|
Optional Stepmx As |
Double = 0, |
|
|
Optional Steptl As |
Double = -1 |
|
) |
| |
多変数非線形関数の最小点 (準ニュートン法, 信頼領域法)
- 目的
- 本ルーチンは非線形関数 f(x1, x2, ..., xn) (2階連続的微分可能な実数関数) の局所的最小点 (xs1, xs2, ..., xsn) を求める.
微分係数およびヘッセ行列の計算には, これを解析的に求めるユーザー定義サブルーチンを使うことができる. ユーザー定義サブルーチンが与えられなかった場合, 微分係数は有限差分近似で求められる. また, ヘッセ行列はセカント法(BFGS法)あるいは2次有限差分近似で求められる.
探索アルゴリズムは, 直線探索, Dogleg信頼領域法およびHookstep信頼領域法の3種類を使うことができる.
ヘッセ行列のユーザー定義サブルーチンを与えず, デフォルトパラメータを使用した場合, 準ニュートン法 (BFGS法)のルーチンとして動作する.
- 引数
-
| [in] | N | 問題の次数(パラメータ数). (N > 1) |
| [in] | X() | 配列 X(LX - 1) (LX >= N)
解ベクトルの初期推定値. |
| [in] | F | 目的関数 f(x1, x2, ..., xn) を求めるユーザー定義サブルーチンで, 次のように定義すること. Sub F(N As Long, X() As Double, Fval As Double)
与えられたNおよびX()から関数値を求めFvalに設定する. それ以外の変数を変更してはならない.
End Sub
|
| [in] | Typsiz() | 配列 Typsiz(LTypsiz - 1) (LTypsiz >= N)
X()の各要素のおおよその大きさ. この値はスケーリングに使用される. 例えば, X(0) = -0.001 であれば Typsiz(0) = 0.001 とする.
(ただし, 0であれば1を, 負の値であれば絶対値を使う) |
| [in] | Fscale | 目的関数値の最小点での推定値. 例えば, f(Xpls) = 0.0001 であれば Fscale = 0.0001を与える.
(ただし, 0であれば1を, 負の値であれば絶対値を使う) |
| [out] | Xpls() | 配列 Xpls(LXpls - 1) (LXpls >= N)
求められた解ベクトル(局所的最小点). |
| [out] | Fpls | Xplsにおける関数値. |
| [out] | Gpls() | 配列 Gpls(LGpls - 1) (LGpls >= N)
Xplsにおける微分係数の値. |
| [out] | Info | = 0: 正常終了. (サブコードをInfo2に返す)
= -1: パラメータ N の誤り. (N <= 1)
= -2: パラメータ X() の誤り.
= -4: パラメータ Typsiz() の誤り.
= -6: パラメータ Xpls() の誤り.
= -8: パラメータ Gpls() の誤り.
= 1: 最後の更新において目的関数値が減少しなかった. (局所的最小点にあるか, 非線形性が強すぎるか, Steptlが大きすぎる)
= 2: 最大反復回数を超えた.
= 3: ステップサイズが続けて5回Stepmxを超えた. (関数形が際限なく傾斜しているか, Stepmxが小さすぎる)
= 4: 微分係数計算ルーチン D1fcn の結果が正しくない可能性がある.
= 5: ヘッセ行列計算ルーチン D2fcn の結果が正しくない可能性がある. |
| [out] | Info2 | (省略可)
Info = 0 のときのサブコード.
= 1: 傾きの収束判定条件を満たした.
= 2: ステップサイズの収束判定値を満たした. |
| [out] | Iter | (省略可)
収束までに要した反復回数. |
| [in] | D1fcn | (省略可)
目的関数 f(x1, x2, ..., xn) の微分係数を求めるユーザー定義サブルーチンで, 次のように定義すること. Sub D1fcn(N As Long, X() As Double, G() As Double)
与えられたNおよびX()から微分係数df/dX(i)を求めG(i)に設定する(i = 0 〜 N-1).
他の変数を変更してはならない.
End Sub
このパラメータを省略した場合, あるいは, NullPtrを指定した場合, 微分係数は有限差分により計算される. |
| [in] | D2fcn | (省略可)
目的関数 f(x1, x2, ..., xn) のヘッセ行列を求めるユーザー定義サブルーチンで, 次のように定義すること. Sub D2fcn(N As Long, X() As Double, H() As Double)
与えられたNおよびX()からヘッセ行列d2f/dX(i)dX(j)を求めH(i,j)に設定する(i = 0 〜 N-1, j = 0 〜 N-1).
他の変数を変更してはならない.
End Sub
このパラメータを省略した場合, あるいは, NullPtrを指定した場合, ヘッセ行列はセカント法(BFGS法)あるいは有限差分により計算される. |
| [in] | DfcnChk | (省略可)
ユーザー微分係数ルーチンD1fcnおよびヘッセ行列ルーチンD2fcnを計算開始前にチェックするかどうかを指定する. (省略時 = 0)
= 0: D1fcnとD2fcnをチェックする.
= 1: D1fcnをチェックしない.
= 2: D2fcnをチェックしない.
= 3: D1fcnとD2fcnをチェックしない.
(それ以外の値であれば省略時の既定値とみなす) |
| [in] | Result | (省略可)
反復ごとの中間結果および最終結果を出力するためのユーザー定義サブルーチンで, 次のように定義すること. Sub Result(N As Long, X() As Double, F As Double, G() As Double, H() As Double, P() As Double, Itncnt As Long, Iflag As Long)
与えられた引数より必要な情報を出力する.
N: 変数の数.
X(0〜N-1): 変数の現在値.
F: X()における関数値.
G(0〜N-1): X()における微分値.
H(0〜N-1, 0〜N-1): X()におけるヘッセ行列の値.
P(0〜N-1): 最新のステップ値.
Itncnt: 反復回数.
Iflag: 制御情報.
= 1: 初期値を出力するための初回呼び出し.
= 2: 反復中の呼び出し.
= 3: 最終結果を出力するための最終呼び出し.
すべての引数は入力変数で, 変更してはならない.
End Sub
本ルーチンは反復ごとに呼び出される. これを省略した場合, あるいは, NullPtrを指定した場合, 結果出力のための呼び出しは行わない. |
| [in] | Method | (省略可)
探索アルゴリズムの選択. (省略時 = 1)
= 1: 直線探索.
= 2: Dogleg信頼領域法.
= 3: Hookstep信頼領域法.
(それ以外の値であれば省略時の既定値とみなす) |
| [in] | Iexp | (省略可)
関数の計算時間. (省略時 = 1)
= 0: 普通.
= 1: 時間がかかる.
ヘッセ行列の更新はD2fcnが与えられていればそれを使う. そうでなければ Iexp = 1の場合, セカント法(BFGS法)により行い, Iexp = 0の場合, 2次有限差分により行う.
(0と1以外の値であれば省略時の既定値とみなす) |
| [in] | Ndigit | (省略可)
Fの計算精度(十進桁数). (Ndigit > 0) (省略時 = 最大精度) (Ndigit <= 0 の場合, 省略時の既定値とみなす) |
| [in] | MaxIter | (省略可)
最大反復回数. (MaxIter > 0) (省略時 = 200) (MaxIter <= 0 の場合, 省略時の既定値とみなす) |
| [in] | Dlt | (省略可)
信頼領域法を使う場合の信頼領域半径の初期値. -1が与えられた場合にはスケーリングされた勾配の長さを使う (省略時 = -1) (Dlt <= 0 の場合, -1 とみなす. Dlt > Stepmxの場合, Stepmx とみなす) |
| [in] | Gradtl | (省略可)
勾配の収束判定値. (Gradtl >= 0) (省略時 = 1.0e-5) (Gradtl < 0 の場合, 省略時の既定値とみなす) |
| [in] | Stepmx | (省略可)
ステップサイズの最大値. (省略時 = max(||X||2*1000, 1000)) (Stepmx <= 0 であれば省略時の既定値とみなす) |
| [in] | Steptl | (省略可)
ステップサイズの収束判定値(連続する反復における相対値). 通常, 1.0e-3〜1.0e-7とする (Steptl >= 0) (省略時 = 1.0e-5) (Steptl < 0 の場合, 省略時の既定値とみなす) |
- 出典
- CMLIB
- 使用例
- 次の関数の最小点を求める(ローゼンブロック関数).
f(x1, x2) = 100(x2 - x1^2)^2 + (1 - x1)^2
初期値は, (x1, x2) = (-1.2, 1) とする. Sub FOptif(N As Long, X() As Double, F As Double)
F = 100 * (X(1) - X(0) ^ 2) ^ 2 + (1 - X(0)) ^ 2
End Sub
Sub GOptif(N As Long, X() As Double, G() As Double)
G(0) = -400 * X(0) * (X(1) - X(0) ^ 2) + 2 * X(0) - 2
G(1) = 200 * X(1) - 200 * X(0) ^ 2
End Sub
Sub Ex_Optif9()
Const N = 2
Dim X(N - 1) As Double, Typsiz(N - 1) As Double, Fscale As Double
Dim Xp(N - 1) As Double, Fp As Double, Gp(N - 1) As Double, Info As Long
X(0) = -1.2: X(1) = 1
Typsiz(0) = 1: Typsiz(1) = 1: Fscale = 0.000000000000001 '1.0e-15
Call Optif9(N, X(), AddressOf FOptif, Typsiz(), Fscale, Xp(), Fp, Gp(), Info, , , AddressOf GOptif)
Debug.Print "X1, X2 =", Xp(0), Xp(1)
Debug.Print "Info =", Info
End Sub
Sub Optif9(N As Long, X() As Double, F As LongPtr, Typsiz() As Double, Fscale As Double, Xpls() As Double, Fpls As Double, Gpls() As Double, Info As Long, Optional Info2 As Long, Optional Iter As Long, Optional D1fcn As LongPtr=NullPtr, Optional D2fcn As LongPtr=NullPtr, Optional DfcnChk As Long=0, Optional Result As LongPtr=NullPtr, Optional Method As Long=1, Optional Iexp As Long=1, Optional Ndigit As Long=0, Optional MaxIter As Long=0, Optional Dlt As Double=-1, Optional Gradtl As Double=-1, Optional Stepmx As Double=0, Optional Steptl As Double=-1) 多変数非線形関数の最小点 (準ニュートン法, 信頼領域法)
- 実行結果
X1, X2 = 1.0000000582881 1.00000013384608
Info = 0
|