|
|
◆ Hybrj1_r()
| Sub Hybrj1_r |
( |
N As |
Long, |
|
|
X() As |
Double, |
|
|
Fvec() As |
Double, |
|
|
XTol As |
Double, |
|
|
Info As |
Long, |
|
|
XX() As |
Double, |
|
|
YY() As |
Double, |
|
|
YYpd() As |
Double, |
|
|
IRev As |
Long |
|
) |
| |
非線形連立方程式 (ハイブリッド法) (シンプルドライバ) (リバースコミュニケーション版)
- 目的
- 本ルーチンはn本のn変数非線形方程式よりなる連立方程式
fi(x1, x2, ..., xn) = 0 (i = 1 〜 n)
の解をパウエルのハイブリッド法により求める.
関数値およびヤコビ行列をIRevに従ってユーザーが与える必要がある.
Hybrj1_rは標準的な使用のためのシンプルドライバで, デフォルトパラメータを用いてHybrj_rを呼び出す.
- 引数
-
| [in] | N | 未知数および方程式の数. (N > 0) |
| [in,out] | X() | 配列 X(LX - 1) (LX >= N)
[in] 初期近似解.
[out] IRev = 0: 求められた解ベクトル.
IRev = 2: ヤコビ行列を求める点. |
| [out] | Fvec() | 配列 Fvec(LFvec - 1) (LFvec >= N)
求められた解ベクトルにおける関数値. |
| [in] | XTol | 目標精度. 続く2回の反復間の相対誤差がXTolより小さくなったら終了する. (XTol >= 0) |
| [out] | Info | = 0: 正常終了. (連続した反復間の相対誤差がXTol以下になった)
= -1: パラメータ N の誤り. (N <= 0)
= -2: パラメータ X() の誤り.
= -3: パラメータ Fvec() の誤り.
= -4: パラメータ XTol の誤り. (XTol < 0)
= -6: パラメータ XX() の誤り.
= -7: パラメータ YY() の誤り.
= -8: パラメータ YYpd() の誤り.
= 1: 関数評価回数(IRev = 1で戻る回数)が上限(100*(N + 1))に達した.
= 2: XTolが小さすぎる. 解Xを改善することができなくなった.
= 3: 直近5回のヤコビ行列の評価において解が改善されなかった.
= 4: 直近10回の反復において解が改善されなかった. |
| [out] | XX() | 配列 XX(LXX - 1) (LXX >= N)
IRev = 1の場合, 関数値を求めるべき点を返す. |
| [in] | YY() | 配列 YY(LYY - 1) (LYY >= N)
IRev = 1の場合, 再呼び出し時に関数値 fi(XX()) (i = 1〜N) を与えること. |
| [in,out] | YYpd() | 配列 YYpd(LYYpd1 - 1, LYYpd2 - 1) (LYYpd1 >= N, LYYpd2 >= N)
[in] IRev = 2: 再呼び出し時にX()におけるヤコビ行列(∂fi/∂xj)を与えること.
[out] IRev = 0: 最終近似解におけるヤコビ行列をQR分解して得られる直行行列Q. |
| [in,out] | IRev | リバースコミュニケーションの制御変数.
[in] 最初の呼び出し時に 0 に設定しておくこと. 2回目以降の呼び出し時には値を変更してはならない.
[out] 0 以外の時には下記処理を行ってから再び本ルーチンを呼び出すこと.
= 0: 処理終了. 正常終了かどうかはInfoをチェックすること.
= 1: XX()における関数値を求め YY()に設定すること. YY()以外の変数を変更してはならない.
= 2: X()におけるヤコビ行列を求め YYpd()に設定すること. YYpd()以外の変数を変更してはならない. |
- 出典
- netlib/minpack
- 使用例
- 次の非線形連立方程式を解く.
x1^2 - x2 - 1 = 0
(x1 - 2)^2 + (x2 - 0.5)^2 - 1 = 0
初期値は, (x1, x2) = (0, 0) とする. Sub FHybrj(N As Long, X() As Double, Fvec() As Double, Fjac() As Double, IFlag As Long)
If IFlag = 1 Then
Fvec(0) = X(0) ^ 2 - X(1) - 1
Fvec(1) = (X(0) - 2) ^ 2 + (X(1) - 0.5) ^ 2 - 1
ElseIf IFlag = 2 Then
Fjac(0, 0) = 2 * X(0)
Fjac(1, 0) = 2 * X(0) - 4
Fjac(0, 1) = -1
Fjac(1, 1) = 2 * X(1) - 1
End If
End Sub
Sub Ex_Hybrj1_r()
Const N = 2
Dim X(N - 1) As Double, Fvec(N - 1) As Double, XTol As Double, Info As Long
Dim XX(N - 1) As Double, YY(N - 1) As Double, YYpd(N - 1, N - 1) As Double
Dim IRev As Long
X(0) = 0: X(1) = 0
XTol = 0.0000000001 '1.0e-10
IRev = 0
Do
Call Hybrj1_r(N, X(), Fvec(), XTol, Info, XX(), YY(), YYpd(), IRev)
If IRev = 1 Or IRev = 2 Then
Call FHybrj(N, XX(), YY(), YYpd(), IRev)
End If
Loop While IRev <> 0
Debug.Print "X1, X2 =", X(0), X(1)
Debug.Print "Info =", Info
End Sub
Sub Hybrj1_r(N As Long, X() As Double, Fvec() As Double, XTol As Double, Info As Long, XX() As Double, YY() As Double, YYpd() As Double, IRev As Long) 非線形連立方程式 (ハイブリッド法) (シンプルドライバ) (リバースコミュニケーション版)
- 実行結果
X1, X2 = 1.06734608580669 0.139227666886861
Info = 0
|