XLPack 7.0
XLPack 数値計算ライブラリ (Excel VBA) リファレンスマニュアル
読み取り中…
検索中…
一致する文字列を見つけられません

◆ 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]FplsXplsにおける関数値.
[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