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

◆ N2g1()

Sub N2g1 ( M As  Long,
N As  Long,
X() As  Double,
F As  LongPtr,
Fj As  LongPtr,
Info As  Long,
Optional NFcall As  Long,
Optional NFjcall As  Long,
Optional Niter As  Long 
)

非線形最小二乗法 (適応アルゴリズム) (シンプルドライバ)

目的
本ルーチンは, ガウス・ニュートン法, レーベンバーグ・マルカート法などを組み合わせ拡張した適応アルゴリズムにより, M個のN変数非線形関数の二乗和の最小点を求める.
min Σfi(x1, x2, ..., xn)^2 (ただし, Σは i = 1 〜 M)
関数値およびヤコビ行列を計算するユーザールーチンが必要である.

N2g1はデフォルトパラメータでN2gを使用するのと等価である. ただし, 分散・共分散行列と回帰診断ベクトルは計算しない.
引数
[in]Mデータ数. (M > 0)
[in]Nパラメータ数. (0 < N <= M)
[in,out]X()配列 X(LX - 1) (LX >= N)
[in] 初期近似解.
[out] 求められた解ベクトル.
[in]F関数 fi(x1, x2, ..., xn) を求めるユーザー定義サブルーチンで, 次のように定義すること.
Sub F(M As Long, N As Long, X() As Double, Nf As Long, Fvec() As Double)
与えられたX()から関数値Fiを求め Fvec(i-1)に設定する(i = 1〜M).
Nfは呼び出しカウンタである. 与えられたX()が計算可能範囲外の場合, Nf = 0 に設 定して戻ること.
それ以外の変数を変更してはならない.
X()が同じ場合, FとFjに渡されるNfは同じ値を持つ.
End Sub
[in]Fj関数 fi(x1, x2, ..., xn) のヤコビ行列を求めるユーザー定義サブルーチンで, 次のように定義すること.
Sub Fj(M As Long, N As Long, X() As Double, Nf As Long, Fjac() As Double)
与えられたX()からヤコビ行列(∂Fi/∂Xj)を求めFjac(i-1,j-1)に設定する(i = 1〜M, j = 1〜N).
Nfは呼び出しカウンタである. 与えられたX()が計算可能範囲外の場合, Nf = 0 に設定して戻ること.
それ以外の変数を変更してはならない.
X()が同じ場合, FとFjに渡されるNfは同じ値を持つ.
End Sub
[out]Info= 0: 正常終了.
= -1: パラメータ M の誤り. (M < N)
= -2: パラメータ N の誤り. (N < 1)
= -3: パラメータ X() の誤り.
= 7: 特異収束. (近傍のヘッセ行列が特異になった)
= 8: 誤収束. (誤った点での収束と思われる. 目標精度が小さすぎる可能性がある)
= 9: 関数評価回数の最大値を超えた.
= 10: 反復回数の最大値を超えた.
= 63: X()の初期点においてF(X)を求めることができない.
= 65: X()において微分係数を求めることができない.
[out]NFcall(省略可)
関数Fの呼び出し回数.
[out]NFjcall(省略可)
関数Fjの呼び出し回数.
[out]Niter(省略可)
反復回数.
出典
netlib/port
使用例
次のデータをモデル関数 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 FN2g(M As Long, N As Long, X() As Double, Nf As Long, Fvec() As Double)
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
For I = 0 To M - 1
Fvec(I) = Ydata(I) - X(0) * (1 - Exp(-Xdata(I) * X(1)))
Next
End Sub
Sub JN2g(M As Long, N As Long, X() As Double, Nf As Long, Fjac() As Double)
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
For I = 0 To M - 1
Fjac(I, 0) = Exp(-Xdata(I) * X(1)) - 1
Fjac(I, 1) = -Xdata(I) * X(0) * Exp(-X(1) * Xdata(I))
Next
End Sub
Sub Ex_N2g1()
Const M = 4, N = 2
Dim X(N - 1) As Double, Info As Long
X(0) = 500: X(1) = 0.0001
Call N2g1(M, N, X(), AddressOf FN2g, AddressOf JN2g, Info)
Debug.Print "C1, C2 =", X(0), X(1)
Debug.Print "Info =", Info
End Sub
Sub N2g1(M As Long, N As Long, X() As Double, F As LongPtr, Fj As LongPtr, Info As Long, Optional NFcall As Long, Optional NFjcall As Long, Optional Niter As Long)
非線形最小二乗法 (適応アルゴリズム) (シンプルドライバ)
実行結果
C1, C2 = 241.084896112856 5.44942234058364E-04
Info = 0