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

◆ n2pb()

void n2pb ( int  m,
int  md,
int  n,
double  x[],
double  b[][2],
void(*)(int, int, int, int *, int, double *, int *, double *)  calcr,
void(*)(int, int, int, int, int, double *, int *, double *)  calcj,
void(*)(int, double *, int, int, int, double)  itsum,
double  v[],
int  lv,
int  iv[],
int  liv,
int *  info 
)

非線形最小二乗法 (適応アルゴリズム) (単純制約付き) (省メモリ版)

目的
n2pbは, ガウス・ニュートン法, レーベンバーグ・マルカート法などを組み合わせ拡張した適応アルゴリズムにより, 単純制約条件 bl[i] <= x[i] <= bu[i] (1 <= i <= n) の下で, m個のn変数非線形関数の二乗和の最小点を求める.
min Σfi(x1, x2, ..., xn)^2 (ただし, Σは i = 1 〜 m)
関数値およびヤコビ行列を計算するユーザールーチンが必要である. 関数値およびヤコビ行列の計算は, 1回で行わずに複数回に分けて部分ごとに行うことができる.
引数
[in]mデータ数. (m > 0)
[in]mdcalcrの1回の呼び出しにより計算できる関数値の最大数. (0 < md <= m)
[in]nパラメータ数. (0 < n <= m)
[in,out]x[]配列 x[lx] (lx >= n)
[in] 初期近似解.
[out] 求められた解ベクトル.
[in]b[][]配列 b[lb][2] (lb >= n)
解 x の境界制約条件.
  b[i][0] <= x[i] <= b[i][1] (i = 0 〜 n-1)
[in]calcrfi(x)の関数値を求めるユーザー定義サブルーチンで, 次のように定義すること.
void calcr(int m, int md1, int m1, int *m2, int n, double x[], int *nf, double r[])
{
与えられたx[]から関数値(残差) fiを求め r[i-m1]に設定する (i = m1 〜 m2).
}
md1 (= min(m, md)) は1回の呼び出しでcalcrが返す関数値の最大個数である. calcrが呼び出されたとき, m2の値はmin(m, m1+md1-1)である. calcrはm2の値をより小さい値に変更してもよい (m2 >= m1 >= 1).

nfは呼び出しカウンタである. x[]が同じ場合, calcrに渡されるnfは同じ値を持つ. 与えられたx[]が計算可能範囲外の場合, nf = 0に設定して戻ること. r[]およびnf以外の変数を変更してはならない.
[in]calcjヤコビ行列を求めるユーザー定義サブルーチンで, 次のように定義すること.
void calcj(int m, int md1, int m1, int m2, int n, double x[], int *nf, double j[])
{
与えられたx[]からヤコビ行列(∂fi/∂xj)を求めj[]に設定する(列優先で(i = m1〜m2, j = 1〜n)の順に j[(j-1)*md1+i-m1] に格納).
}
nfは呼び出しカウンタである. x[]が同じ場合, calcjに渡されるnfは同じ値を持つ. 与えられたx[]が計算可能範囲外の場合, nf = 0に設定して戻ること. j[]およびnf以外の変数を変更してはならない.
[in]itsum中間結果を出力するためのユーザー定義サブルーチンで, 次のように定義すること.
iv[18] = 1であれば反復ごとに呼び出される.
void itsum(int n, double x[], int niter, int nf, int ng, double fval)
{
以下の情報を適当な形式で出力する
n: 変数の数
x[]: 解ベクトルの現在の近似値
niter: 反復回数
nf: calcrの呼び出し回数
ng: calcjの呼び出し回数
fval: x[]における関数値
}
引数の値を変更してはならない.
[in,out]v[]配列 v[lv]
浮動小数パラメータおよび作業領域のための配列.
[in]
  v[25] (tuner1): 誤収束の判定パラメータ (0 <= tuner1 <= 0.5) (デフォルト値 = 0.1)
  v[30] (atol): 関数値の目標絶対精度 (0 <= atol) (デフォルト値 = max(1e-20, eps^2). ただし, epsは計算機イプシロン)
  v[31] (rtol): 関数値の目標相対精度 (eps <= rtol <= 0.1) (デフォルト値 = max(1e-10, eps^(2/3)))
  v[32] (xctol): x値の収束判定しきい値 (0 <= xctol <= 1) (デフォルト値 = eps^(1/2))
  v[33] (xftol): 誤収束の判定しきい値 (0 <= xftol <= 1) (デフォルト値 = 100*eps)
  v[34] (lmax0): スケーリングされた一番始めのステップ長の最大幅 (0 < lmax0) (デフォルト値 = 1)
  v[35] (lmaxs), v[36] (sctol): 特異収束の判定パラメータ (0 < lmaxs, 0 <= sctol <= 1) (デフォルト値: lmaxs = 1, sctol = max(1e-10, eps^(2/3))).
    ステップ長lmaxsにおける関数値の減少の推定値がsctol*abs(f)より小さければ info = 7 で戻る (fは現在の反復の出発点における関数値).
  v[37] (dinit): 非負の値を設定しておくとそれによりd[]の全要素を初期化する (-10 <= dinit) (デフォルト値 = 0)
  v[38] (dtol): 自動スケーリングのしきい値 (0 =< dtol) (デフォルト値 = 1.0e-6)
  v[39] (d0): 自動スケーリングの初期値 (0 =< d0) (デフォルト値 = 1)
  v[40] (dfac): 自動スケーリングの係数 (0 <= dfac <= 1) (デフォルト値 = 0.6)
    自動スケーリングではd[i]をスケール係数として, すべてのiについてd[i]*x[i]が同程度の大きさになるように反復ごとにd[i]を調整する.
    まず, d1[i] = max(||Ji||, dfac*d[i])とする(||Ji||はヤコビ行列の第i列の2-ノルム). 次に, 以下のようにd[i]を調整する.
      d1[i] >= dtolの場合: d[i] = d1[i]
      d1[i] < dtolの場合: d[i] = d0
[out]
  v[0] (dgnorm): diag(d)^(-1)*g の2ノルム (g は勾配の最新値)
  v[1] (dstnrm): diag(d)^(-1)*s の2ノルム (s は現在のステップ長)
  v[9] (f): 現在の関数値 (二乗和の1/2)
  v[12] (f0): 現在の反復の出発点における関数値
[in]lv配列 v[]のサイズ (lv >= 105 + n*(2*n + 21) + (n + 1)*min(nd, m) + m)
[in,out]iv[]配列 iv[liv]
整数パラメータおよび作業領域のための配列.
[in]
  iv[0]: 0に設定して呼び出すと, 実行開始前にiv[]およびv[]の全てのパラメータをデフォルト値に初期化する.
    12に設定して呼び出すと, iv[]およびv[]はユーザーにより設定済であると見なし初期化を行わない. サブルーチンivsetはiv[0]=12に設定するため, 最初にivsetを呼び出してiv[]およびv[]をデフォルト値に設定し, 次に必要なパラメータを非デフォルト値に変更し, それを使用して実行を開始することができる.
  iv[15] (dtype): 自動スケーリングの設定 (Dtype = 0, 1 または 2) (デフォルト値 = 1)
    = 0: 自動スケーリングを行わない (スケール係数 = 1)
    = 1: 反復ごとに自動スケーリングを行う
    = 2: 1回目の反復のみ自動スケーリングを行い, その後スケール係数を変更しない
  iv[16] (mxfcal): 関数評価回数の最大値 (デフォルト値 = 200)
  iv[17] (mxiter): 反復回数の最大値 (デフォルト値 = 150)
  iv[18] (outlev): 中間情報の出力を指定する (デフォルト値 = 0)
    != 1: itsumを参照しない
    = 1: 反復ごとにitsumを呼び出す
  iv[24] (inits): 非線形最小二乗ルーチンはヘッセ行列の一部の近似Sをセカント更新により求める. 通常, S行列の初期値は0としてよいが, 時に他の値に設定すると有効なことがある. (デフォルト値 = 0)
    = 0: S行列を0に初期化する
    = 3: sの初期値を関数値の差分により推定する
    = 4: sの初期値を微分値の差分により推定する
[out]
  iv[0]: リターンコード
    = 3: x値収束条件を満たした
    = 4: 関数値相対収束条件を満たした
    = 5: x値および関数値相対収束条件の両方を満たした
    = 6: 関数値絶対収束条件を満たした
    = 7: 近傍のHessian行列が特異になった
    = 8: 誤った点での収束と思われる(目標精度が小さすぎる可能性がある)
    = 9: 関数評価回数の最大値を超えた
    = 10: 反復回数の最大値を超えた
    = 11: stopxがtrueを返した(外部割込み)
    = 12: iv[]とv[]の割り当てと初期化を行った
    = 13: xの初期値において関数値を計算できなかった
    = 14: 不正なパラメータ
    = 15: livが小さすぎる
    = 16: lvが小さすぎる
    = 17: mまたはnを変更してリスタートが試みられた
    = 18: iv[24]の値が範囲が
    = 19...45: v[iv[0]]の値が範囲外
    = 50: iv[0]の値が範囲外
    = 87...(86+m): jtol[iv[0]-86]が正でない
  iv[5] (nfcall): calcrの呼び出し回数
  iv[29] (ngcall): calcjの呼び出し回数
  iv[30] (niter): 反復回数
  iv[43] (lastiv): livの最小値
  iv[44] (lastv): lvの最小値
  iv[60] (r): v[iv[60]-1]から始まる領域に残差ベクトルrを格納した
[in]liv配列 iv[]のサイズ (liv >= 82 + 4*n)
[out]info= 0: 正常終了 (iv[0] = 3〜6)
= -1: 入力パラメータ m の誤り (m < 1) (iv[0] = 66)
= -2: 入力パラメータ nd の誤り (nd < 1) (iv[0] = 66)
= -3: 入力パラメータ n の誤り (n < 1) (iv[0] = 66)
= -8: 入力パラメータ v[18]〜v[49] の誤り (範囲外の値) (iv[0] = 19〜50)
= -9: 入力パラメータ lv の誤り (lvが小さすぎる) (iv[0] = 16)
= -10: 入力パラメータ iv[0] の誤り (範囲外の値) (iv[0] = 80)
= -11: 入力パラメータ liv の誤り (livが小さすぎる) (iv[0] = 15)
= 7: 特異収束 (近傍のHessian行列が特異になった)
= 8: 誤収束 (誤った点での収束と思われる。目標精度が小さすぎる可能性がある)
= 9: 関数評価回数の最大値を超えた
= 10: 反復回数の最大値を超えた
= 14: iv[]およびv[]の領域の割り付けを行った (iv[0]=13の呼び出し後に正常終了した)
= 17: mまたはnを変更して再スタートを行った
= 63: x[]の初期点において関数値を求めることができない
= 65: x[]において微分係数を求めることができない
出典
netlib/port