|
◆ sos_r()
void sos_r |
( |
int |
n, |
|
|
double |
x[], |
|
|
double |
rtolx, |
|
|
double |
atolx, |
|
|
double |
tolf, |
|
|
int |
nprint, |
|
|
int |
maxiter, |
|
|
int * |
iter, |
|
|
double |
work[], |
|
|
int |
lwork, |
|
|
int |
iwork[], |
|
|
int |
liwork, |
|
|
int * |
info, |
|
|
int * |
k, |
|
|
double |
xx[], |
|
|
double * |
yy, |
|
|
int * |
irev |
|
) |
| |
連立非線形方程式 (ブラウンの方法) (リバースコミュニケーション版)
- 目的
- sos_rはn本のn変数非線形方程式よりなる連立方程式
fi(x1, x2, ..., xn) = 0 (i = 1 〜 n)
の解をブラウンの方法により求める.
アルゴリズムはニュートン法を変形した反復法に基づいており, ガウス−ザイデル法の手順に似たガウス消去法を用いる. 収束はおおむね二次収束である. 本ルーチンの収束特性は方程式の順番に影響を受ける. 線形および弱い非線形の方程式を先に並べるとよい.
irevに従って関数値をユーザーが与える必要がある. アルゴリズムで必要なすべての偏微分係数は差分商で近似される.
- 引数
-
[in] | n | 未知数および方程式の数. (n > 0) |
[in,out] | x[] | 配列 x[lx] (lx >= n)
[in] 初期近似解.
[out] 求められた解ベクトル. |
[in] | rtolx | 収束判定に用いられる相対誤差許容値(rtolx >= 0). 次式により解の精度をチェックする.
abs(x[i] - xold[i]) <= rtolx*abs(x[i]) + atolx
ここで, xold[i]は前回の反復時の値を表す. |
[in] | atolx | 収束判定に用いられる絶対誤差許容値(atolx >= 0). 解ベクトルの要素のいくつかが0の可能性があるならば, 計算効率をよくするためにatolxを適切な値(残りの要素のスケールに依存)に設定しなければならない. |
[in] | tolf | 残差の収束判定基準(tolf >= 0). 全ての式の残差(関数値)がこれより小さくなれば収束と見なす. この収束判定は方程式のスケーリングに依存するため, tolfに適切な値を与えるように細心の注意が必要である. 値が適切でない場合, 不十分な反復で終了してしまうことがある. |
[in] | nprint | = 0: 中間結果出力のために戻らない.
= 1: 中間結果出力のために反復ごとにirev = 50で戻る.
(他の値であれば nprint = 0 とみなす.) |
[in] | maxiter | 最大反復回数. (maxiter >= 1) |
[out] | iter | 収束に要した反復回数. |
[out] | work[] | 配列 work[lwork]
作業領域.
終了時, 求められた最終近似解における残差ノルムがwork[0]に入る. |
[in] | lwork | 配列 work[]のサイズ. (lwork >= 1 + 5*n + n*(n + 1)/2) |
[out] | iwork[] | 配列 iwork[liwork]
作業領域.
info = 0で戻った場合, iwork[0]にサブコードが入る.
= 1: 解ベクトルの各要素x[i]が誤差許容値判定条件を満たした: abs(x[i] - xold[i]) <= rtolx*abs(x[i]) + atolx.
= 2: すべての残差がtolf以下になった: abs(f(x,i)) <= tolf.
= 3: 上の2つ共満たした.
= 4: 収束の可能性あり (誤差許容値が小さすぎる、あるいは、収束の遅い関数である). (残差ノルムは数回の連続した反復においてほぼ一定であった) |
[in] | liwork | 配列 iwork[]のサイズ. (liwork >= n) |
[out] | info | = 0: 正常終了 (iwork[0]にサブコードが入る)
= -1: 入力パラメータ n の誤り (n < 1)
= -3: 入力パラメータ rtolx の誤り (rtolx < 0)
= -4: 入力パラメータ atolx の誤り (atolx < 0)
= -5: 入力パラメータ tolf の誤り (tolf < 0)
= -6: 入力パラメータ maxiter の誤り (maxiter <= 0)
= -10: 入力パラメータ lwork の誤り (lwork < 1+5*n+n*(n+1)/2)
= -12: 入力パラメータ liwork の誤り (liwork < n)
= 1: 反復回数の上限に達した (収束が非常に遅い可能性がある。誤差許容値が適切であるか確認せよ)
= 2: 反復回数の上限に達した (局所的な最小点にあるか計算精度不足の可能性がある)
= 3: 反復が発散した (残差ノルムが数回の連続した反復において増加した)
= 4: Jacobianに関連する行列が特異になった |
[out] | k | irev = 1, 2: k番目の関数値を求めることを示す.
irev = 50: ここまでの反復回数. |
[out] | xx[] | 配列 xx[lxx] (lxx >= n)
irev = 1, 2: 関数値を求めるべき点を返す.
irev = 50: 最新の近似解. |
[in,out] | yy | [in] irev = 1, 2: 再呼び出し時に関数値fi(xx[]) (i = k)を与えること.
[out] irev = 50: 最新の近似解における残差ノルム. |
[in,out] | irev | リバースコミュニケーションの制御変数.
[in] 最初の呼び出し時に 0 に設定しておくこと. 2回目以降の呼び出し時には値を変更してはならない.
[out] 0 以外の時には下記処理を行ってから再び本ルーチンを呼び出すこと.
= 0: 処理終了. 正常終了かどうかはinfoをチェックすること.
= 1, 2: xx[]におけるk番目の関数値を求め yyに設定すること. yy以外の変数を変更してはならない.
= 50: 途中結果(k: 反復回数, yy: xx[]における残差ノルム, など)を出力する(nprint = 1 の場合のみ). どの変数も変更してはならない. |
- 出典
- SLATEC
|