|
|
◆ lmdif1()
| function lmdif1 |
( |
f::Function |
, |
|
|
m::Integer |
, |
|
|
n::Integer |
, |
|
|
x::Array{Float64} |
, |
|
|
fvec::Array{Float64} |
, |
|
|
tol::Real |
= 1.0e-10 |
|
) |
| |
非線形最小二乗法 (レーベンバーグ・マルカート法) (ヤコビ行列計算不要) (シンプルドライバ)
- 目的
- lmdif1はm個のn変数非線形関数の二乗和の最小点をレーベンバーグ・マルカート法により求める.
min Σfi(x1, x2, ..., xn)^2 (ただし, Σは i = 1 〜 m)
関数値を計算するユーザールーチンが必要である. ヤコビ行列はルーチン内で有限差分により計算されるため, ユーザーがヤコビ行列を求める必要はない.
lmdif1は, ftol = tol, xtol = tol, gtol = 0, maxfev = 100*(n+1), epsfcn = 0, mode = 1, factor = 100, nprint = 0 としてlmdifを呼び出すのに相当する.
- 戻り値
- info (Int32)
= 0: 正常終了
= -1: 入力パラメータ f の誤り
= -2: 入力パラメータ m の誤り (m < n)
= -3: 入力パラメータ n の誤り (n < 1)
= -4: 入力パラメータ x の誤り
= -5: 入力パラメータ fvec の誤り
= -6: 入力パラメータ tol の誤り (tol < 0)
= 1: 関数呼び出し(iflag = 1または2)回数がmaxfevに達した
= 2: 残差二乗和が減少しなくなった (tolが小さすぎる)
= 3: 解が改善されなくなった (tolが小さすぎる)
= 4: fvecとヤコビ行列の列が計算機イプシロン内で直交した (gtolが小さすぎる)
- 引数
-
| [in] | f | 関数fi(x)の値を求めるユーザーサブルーチンで, 次のように定義すること. _CODE function f(m, n, x, fvec, iflag) if iflag == 1 or iflag == 2 fvec[0] = 関数値 f1(x[0], x[1], ..., x[n-1]) fvec[1] = 関数値 f2(x[0], x[1], ..., x[n-1]) ... fvec[m-1] = 関数値 fn(x[0], x[1], ..., x[n-1]) end end _ENDCODE iflag = 1あるいは2のときに関数値fi(x)を計算してfvecに設定する. |
| [in] | m | 関数の数. (m > 0) |
| [in] | n | 変数の数. (0 < n <= m) |
| [in,out] | x | 1次元配列 (Float64, n)
[in] 初期近似解.
[out] 求められた解ベクトル. |
| [out] | fvec | 1次元配列 (Float64, m)
求められた解ベクトルxにおける関数値. |
| [in] | tol | (省略可)
二乗和および解の相対誤差の許容値. (tol >= 0) (省略時 = 1.0e-10) |
- 出典
- 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 とする. function flmdif1(m, n, x, fvec, iflag)
xdata = [ 77.6, 239.9, 434.8, 760.0 ]
ydata = [ 10.07, 29.61, 50.76, 81.78 ]
for i = 1 : m
fvec[i] = ydata[i] - x[1]*(1 - exp(-xdata[i]*x[2]))
end
end
function TestLmdif1()
m = 4
n = 2
x = [ 500.0, 0.0001 ]
fvec = Vector{Cdouble}(undef, m)
info = lmdif1(flmdif1, m, n, x, fvec)
println(x)
println(fvec)
println(info)
end
function lmdif1(f::Function, m::Integer, n::Integer, x::Array{Float64}, fvec::Array{Float64}, tol::Real=1.0e-10) 非線形最小二乗法 (レーベンバーグ・マルカート法) (ヤコビ行列計算不要) (シンプルドライバ)
- 実行結果
> TestLmdif1()
[241.0848981899996, 0.0005449422284655366]
[0.08766978309846962, 0.06582096155374728, -0.09976824641897508, 0.027576123350030457]
0
|