|
|
◆ Optif9_r()
| Sub Optif9_r |
( |
N As |
Long, |
|
|
X() As |
Double, |
|
|
Typsiz() As |
Double, |
|
|
Fscale As |
Double, |
|
|
Xpls() As |
Double, |
|
|
Fpls As |
Double, |
|
|
Gpls() As |
Double, |
|
|
Info As |
Long, |
|
|
XX() As |
Double, |
|
|
YY As |
Double, |
|
|
YYp() As |
Double, |
|
|
YYp2() As |
Double, |
|
|
IRev As |
Long, |
|
|
Optional Info2 As |
Long, |
|
|
Optional Iter As |
Long, |
|
|
Optional Iagflg As |
Long = 0, |
|
|
Optional Iahflg As |
Long = 0, |
|
|
Optional Iresult As |
Long = 0, |
|
|
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) を求める.
ユーザーは微分係数および/またはヘッセ行列を解析的に求め与えることができる. 微分係数が与えられない場合, 1次有限差分近似を使用して求められる. また, ヘッセ行列が与えられない場合, セカント法(BFGS法)あるいは2次有限差分近似を使用して求められる.
探索アルゴリズムは, 直線探索, Dogleg信頼領域法およびHookstep信頼領域法の3種類を使うことができる.
ヘッセ行列のユーザー定義サブルーチンを与えず, デフォルトパラメータを使用した場合, 準ニュートン法 (BFGS法)のルーチンとして動作する.
Optif9_rはOptif9のリバースコミュニケーション版である.
- 引数
-
| [in] | N | 問題の次数(パラメータ数). (N > 1) |
| [in] | X() | 配列 X(LX - 1) (LX >= N)
解ベクトルの初期推定値. |
| [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() の誤り.
= -3: パラメータ Typsiz() の誤り.
= -5: パラメータ Xpls() の誤り.
= -7: パラメータ Gpls() の誤り.
= -9: パラメータ XX() の誤り.
= -11: パラメータ YYp() の誤り.
= -12: パラメータ YYp2() の誤り.
= 1: 最後の更新において目的関数値が減少しなかった. (局所的最小点にあるか, 非線形性が強すぎるか, Steptlが大きすぎる)
= 2: 最大反復回数を超えた.
= 3: ステップサイズが続けて5回Stepmxを超えた. (関数形が際限なく傾斜しているか, Stepmxが小さすぎる)
= 4: 微分係数計算ルーチン D1fcn の結果が正しくない可能性がある.
= 5: ヘッセ行列計算ルーチン D2fcn の結果が正しくない可能性がある. |
| [out] | XX() | 配列 XX(LXX - 1) (LXX >= N)
IRev = 1, 2, 3: 再呼び出し時に関数値, 微分係数値またはヘッセ行列を求めるべき点を返す.
IRev = 4〜6: 途中結果出力のために, 現在の解ベクトルXを返す. |
| [in,out] | YY | [in] IRev = 1: 再呼び出し時に関数値f(XX)を与えること.
[out] IRev = 4〜6: 途中結果出力のために, 現在のXにおける関数値を返す. |
| [in,out] | YYp() | 配列 YYp(LYYp - 1) (LYYp >= N)
[in] IRev = 2: 再呼び出し時にXX()における微分係数値を与えること.
[out] IRev = 4〜6: 途中結果出力のために, 現在のXにおける微分係数値を返す. |
| [in,out] | YYp2() | 配列 YYp2(LYYp21 - 1, LYYp22 - 1) (LYYp21 >= N, LYYp22 >= N)
[in] IRev = 3: 再呼び出し時にXX()におけるヘッセ行列を与えること.
[out] IRev = 4〜6: 途中結果出力のために, 現在のXにおけるヘッセ行列を返す. YYp2()はまたヘッセ行列の計算のための作業領域として使用される. |
| [in,out] | IRev | リバースコミュニケーションの制御変数.
[in] 最初の呼び出し時に 0 に設定しておくこと. 2回目以降の呼び出し時には値を変更してはならない.
[out] 0 以外の時には下記処理を行ってから再び本ルーチンを呼び出すこと.
= 0: 処理終了. 正常終了かどうかはInfoをチェックすること.
= 1: XX()における関数値を求め YYに設定すること. YY以外の変数を変更してはならない.
= 2: XX()における微分係数値を求め YYp()に設定すること. YYp()以外の変数を変更してはならない. (Iagflg = 1 の場合)
= 3: XX()におけるヘッセ行列を求め YYp2()に設定すること. YYp2()以外の変数を変更してはならない. (Iahflg = 1 の場合)
= 4, 5, 6: 途中結果 (XX(), YY, YYp(), YYp2(), Iter)を出力する. どの変数も変更してはならない. (Iresult = 1 の場合)
IRev = 4: 探索開始前の初期値を返す.
IRev = 5: 反復中の途中結果を返す.
IRev = 6: 最終結果を返す. |
| [out] | Info2 | (省略可)
Info = 0 のときのサブコード.
= 1: 傾きの収束判定条件を満たした.
= 2: ステップサイズの収束判定値を満たした. |
| [out] | Iter | (省略可)
収束までに要した反復回数. |
| [in] | Iagflg | (省略可)
微分係数の計算方法の指定. (省略時 = 0)
= 0: 有限差分により近似する.
= 1: 解析的に求めるため IRev = 2 として戻る (計算開始前に, 有限差分値と比較してユーザーが与えた値の正当性のチェックを行う).
= 2: 解析的に求めるため IRev = 2 として戻る (チェックを行わない). |
| [in] | Iahflg | (省略可)
ヘッセ行列の計算方法の指定. (省略時 = 0)
= 0: セカント法あるいは有限差分により近似する. (Iexpを参照)
= 1: 解析的に求めるため IRev = 3 として戻る (計算開始前に, 有限差分値と比較してユーザーが与えた値の正当性のチェックを行う).
= 2: 解析的に求めるため IRev = 3 として戻る (チェックを行わない). |
| [in] | Iresult | (省略可)
反復ごとの中間結果および最終結果の出力の指定. (省略時 = 0)
= 0: 出力を行わない (Irev = 4〜6 として戻ることはない).
= 1: 出力を行う (反復ごとに Irev = 4〜6 として戻る).
(0と1以外の値であれば省略時の既定値とみなす) |
| [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 Ex_Optif9_r()
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
Dim Info As Long, Iagflg As Long
Dim XX(N - 1) As Double, YY As Double, YYp(N - 1) As Double
Dim YYp2(N - 1, N - 1) As Double, IRev As Long
Iagflg = 1
X(0) = -1.2: X(1) = 1
Typsiz(0) = 1: Typsiz(1) = 1: Fscale = 0.000000000000001 '1.0e-15
IRev = 0
Do
Call Optif9_r(N, X(), Typsiz(), Fscale, Xp(), Fp, Gp(), Info, XX(), YY, YYp(), YYp2(), IRev, , , Iagflg)
If IRev = 1 Then
YY = 100 * (XX(1) - XX(0) ^ 2) ^ 2 + (1 - XX(0)) ^ 2
ElseIf IRev = 2 Then
YYp(0) = -400 * XX(0) * (XX(1) - XX(0) ^ 2) + 2 * XX(0) - 2
YYp(1) = 200 * XX(1) - 200 * XX(0) ^ 2
End If
Loop While IRev <> 0
Debug.Print "X1, X2 =", Xp(0), Xp(1)
Debug.Print "Info =", Info
End Sub
- 実行結果
X1, X2 = 1.0000000582881 1.00000013384608
Info = 0
|