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

◆ Lmdif_r()

Sub Lmdif_r ( M As  Long,
N As  Long,
X() As  Double,
Fvec() As  Double,
Fjac() As  Double,
FTol As  Double,
XTol As  Double,
GTol As  Double,
Diag() As  Double,
Mode As  Long,
Ipvt() As  Long,
Info As  Long,
XX() As  Double,
YY() As  Double,
IRev As  Long,
Optional Info2 As  Long,
Optional Maxfev As  Long = 0,
Optional Epsfcn As  Double = 0,
Optional Factor As  Double = 100,
Optional Nprint As  Long = 0,
Optional Nfev As  Long 
)

非線形最小二乗法 (レーベンバーグ・マルカート法) (ヤコビ行列不要) (リバースコミュニケーション版)

目的
本ルーチンはM個のN変数非線形関数の二乗和の最小点をレーベンバーグ・マルカート法により求める.
min Σfi(x1, x2, ..., xN)^2 (ただし, Σは i = 1 〜 M)
IRevに従って関数値をユーザーが与える必要がある. ヤコビ行列はルーチン内で前進差分により計算されるため, ユーザーがヤコビ行列を求める必要はない.
引数
[in]M関数の数. (M > 0)
[in]N変数の数. (0 < N <= M)
[in,out]X()配列 X(LX - 1) (LX >= N)
[in] 初期近似解
[out] IRev = 0: 求められた最終近似解.
  IRev = 3: 最新の近似解.
[out]Fvec()配列 Fvec(LFvec - 1) (LFvec >= M)
IRev = 0: 求められた解ベクトルX()における関数値.
IRev = 3: 最新の近似解における関数値.
[out]Fjac()配列 Fjac(LFjac1 - 1, LFjac2 - 1) (LFjac1 >= M, LFjac2 >= N)
上部の N×N 部分に, 対角要素の絶対値が昇順になるように並べ替えを行った上三角行列R が入る.
  P^T * (J^T * J)*P = R^T * R
ここで, P は並べ替えを表す置換行列, J は最終的に求められたヤコビ行列である.
[in]FTol二乗和の相対誤差の許容値. 二乗和の減少の予測値と実際の値の両方がFTolより小さくなったら終了する. (FTol >= 0)
[in]XTol解の相対誤差の許容値. 続く2回の反復間の相対誤差がXTolより小さくなったら終了する. (XTol >= 0)
[in]GTol関数ベクトルとヤコビ行列の列の直交性の許容値. Fvec()とヤコビ行列のすべての列の角度のcosの絶対値がGTolより小さくなったら終了する. (GTol >= 0)
[in,out]Diag()配列 Diag(LD - 1) (LD >= N)
[in] Mode = 2の場合にスケーリング因子を入力する. (Diag(i) > 0)
[out] Mode = 1の場合に自動的に設定される.
[in]Mode= 1: 変数のスケーリングを自動的に行う.
= 2: ユーザーがDiag()に設定した値を使って変数のスケーリングを行う.
(他の値であれば Mode = 1 とみなす.)
[out]Ipvt()配列 Ipvt(LIpvt - 1) (LIpvt >= N)
置換行列を定義するピボット情報.
[out]Info= 0: 正常終了. (サブコードをInfo2に返す)
= -1: パラメータ M の誤り. (M < N)
= -2: パラメータ N の誤り. (N <= 0)
= -3: パラメータ X() の誤り. (配列X()の大きさが不足)
= -4: パラメータ Fvec() の誤り. (配列Fvec()の大きさが不足)
= -5: パラメータ Fjac() の誤り. (配列Fjac()の大きさが不足)
= -6: パラメータ FTol の誤り. (FTol < 0)
= -7: パラメータ XTol の誤り. (XTol < 0)
= -8: パラメータ GTol の誤り. (GTol < 0)
= -9: パラメータ Diag() の誤り. (配列Diag()の大きさが不足, または, Mode = 2 のときにDiag(i) < 0)
= -11: パラメータ Ipiv() の誤り. (配列Ipiv()の大きさが不足)
= -13: パラメータ XX() の誤り. (配列XX()の大きさが不足)
= -14: パラメータ YY() の誤り. (配列YY()の大きさが不足)
= 1: 関数評価回数(IRev = 1)がMaxfevに達した.
= 2: 残差二乗和が減少しなくなった. (FTolが小さすぎる)
= 3: 解が改善されなくなった. (XTolが小さすぎる)
= 4: Fvecとヤコビ行列の列が計算機イプシロン内で直交した. (GTolが小さすぎる)
[out]XX()配列 XX(LXX - 1) (LXX >= N)
IRev = 1の場合, 関数値を求めるべき点を返す.
[in]YY()配列 YY(LYY - 1) (LYY >= M)
IRev = 1の場合, 再呼び出し時に関数値fi(XX()) (i = 1〜M)を与えること.
[in,out]IRevリバースコミュニケーションの制御変数.
[in] 最初の呼び出し時に 0 に設定しておくこと. 2回目以降の呼び出し時には値を変更してはならない.
[out] 0 以外の時には下記処理を行ってから再び本ルーチンを呼び出すこと.
= 0: 処理終了. 正常終了かどうかはInfoをチェックすること.
= 1 または 2: XX()における関数値を求めYY()に設定すること. YY()以外の変数を変更してはならない.
= 3: 途中結果(X(), Fvec()など)を出力する (Nprint > 0 の場合). どの変数も変更してはならない.
[out]Info2(省略可)
Info = 0 で戻ったときのサブコード.
= 1: 二乗和の相対減少値およびその予測値の両方がFTol以下になった
= 2: 連続する2回の反復の相対誤差がXTol以下になった
= 3: 上の2つ共満たした
= 4: Fvecとヤコビ行列のすべての列との角度のコサインの絶対値がGTol以下になった
[in]Maxfev(省略可)
関数評価回数(IRev = 1)の上限値. (省略時 = 200*(N + 1))
(Maxfev <= 0 であれば省略時の既定値とみなす.)
[in]Epsfcn(省略可)
前進差分近似のステップ幅を決めるパラメータで, 目的関数計算の相対誤差程度に設定する. マシンイプシロンより小さい値が設定された場合, マシンイプシロン値とみなされる. (省略時 = 0)
[in]Factor(省略可)
初期ステップの最大値を決める定数. ||Diag×X||2×Factorが0でない場合これを最大値とする. 0の場合Factor自身の値を最大値とする. 通常, 0.1〜100の範囲で, 一般的には100とすればよい. (省略時 = 100)
(Factor <= 0 であれば省略時の既定値とみなす.)
[in]Nprint(省略可)
> 0: 最初の反復, Nprint回の反復ごと, 最終反復後に途中結果の出力のために IRev = 3 として戻る.
<= 0: 途中結果の出力のために戻らない.
(省略時 = 0)
[out]Nfev(省略可)
関数評価回数 (IRev = 1).
出典
netlib/minpack
使用例
次のデータをモデル関数 f(x) = c1*(1 - exp(-c2*x)) で近似する. 2つのパラメータc1, c2は非線形最小二乗法により定める.
f(x) x
10.07 77.6
29.61 239.9
50.76 434.8
81.78 760.0
初期値は, c1 = 500, c2 = 0.0001 とする.
Sub FLmdif(M As Long, N As Long, X() As Double, Fvec() As Double, IFlag As Long)
Dim Xdata(3) As Double, Ydata(3) As Double, I As Long
Ydata(0) = 10.07: Xdata(0) = 77.6
Ydata(1) = 29.61: Xdata(1) = 239.9
Ydata(2) = 50.76: Xdata(2) = 434.8
Ydata(3) = 81.78: Xdata(3) = 760
If IFlag = 1 Or IFlag = 2 Then
For I = 0 To M - 1
Fvec(I) = Ydata(I) - X(0) * (1 - Exp(-Xdata(I) * X(1)))
Next
End If
End Sub
Sub Ex_Lmdif_r()
Const M = 4, N = 2
Dim X(N - 1) As Double, Fvec(M - 1) As Double, Fjac(M - 1, N - 1) As Double
Dim FTol As Double, XTol As Double, GTol As Double, Diag(N - 1) As Double
Dim Mode As Long, Ipvt(N - 1) As Long, Info As Long
Dim XX(N - 1) As Double, YY(M - 1) As Double, IRev As Long, IFlag As Long
FTol = 0.00000001: XTol = 0.00000001: GTol = 0.00000001 '1.0e-8
X(0) = 500: X(1) = 0.0001
IRev = 0
Do
Call Lmdif_r(M, N, X(), Fvec(), Fjac(), FTol, XTol, GTol, Diag(), Mode, Ipvt(), Info, XX(), YY(), IRev)
If IRev = 1 Or IRev = 2 Then
IFlag = IRev
Call FLmdif(M, N, XX(), YY(), IFlag)
End If
Loop While IRev <> 0
Debug.Print "C1, C2 =", X(0), X(1)
Debug.Print "Info =", Info
End Sub
Sub Lmdif_r(M As Long, N As Long, X() As Double, Fvec() As Double, Fjac() As Double, FTol As Double, XTol As Double, GTol As Double, Diag() As Double, Mode As Long, Ipvt() As Long, Info As Long, XX() As Double, YY() As Double, IRev As Long, Optional Info2 As Long, Optional Maxfev As Long=0, Optional Epsfcn As Double=0, Optional Factor As Double=100, Optional Nprint As Long=0, Optional Nfev As Long)
非線形最小二乗法 (レーベンバーグ・マルカート法) (ヤコビ行列不要) (リバースコミュニケーション版)
実行結果
C1, C2 = 241.084897132837 5.44942231312974E-04
Info = 0