XLPack 6.1
C/C++ API リファレンスマニュアル
読み取り中…
検索中…
一致する文字列を見つけられません

◆ _n2g()

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

非線形最小二乗法 (適応アルゴリズム)

目的
n2gは, ガウス・ニュートン法, レーベンバーグ・マルカート法などを組み合わせ拡張した適応アルゴリズムにより, m個のn変数非線形関数の二乗和の最小点を求める.
min Σfi(x1, x2, ..., xn)^2 (ただし, Σは i = 1 〜 m)
関数値およびヤコビ行列を計算するユーザールーチンが必要である.
引数
[in]mデータ数. (m > 0)
[in]nパラメータ数. (0 < n <= m)
[in,out]x[]配列 x[lx] (lx >= n)
[in] 初期近似解.
[out] 求められた解ベクトル.
[in]calcrfi(x)の関数値を求めるユーザー定義サブルーチンで, 次のように定義すること.
void calcr(int m, int n, double x[], int *nf, double r[])
{
与えられたx[]から関数値(残差)fiを求めr[i-1]に設定する(i = 1〜m).
}
nfは呼び出しカウンタである. x[]が同じ場合, calcrに渡されるnfは同じ値を持つ. 与えられたx[]が計算可能範囲外の場合, nf = 0に設定して戻ること. r[]およびnf以外の変数を変更してはならない.
[in]calcjヤコビ行列を求めるユーザー定義サブルーチンで, 次のように定義すること.
void calcj(int m, int n, double x[], int *nf, double j[])
{
与えられたx[]からヤコビ行列(∂fi/∂xj)を求め j[]に設定する(列優先で(i = 1〜m, j = 1〜n)の順に格納).
}
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
  v[41] (dltfdc): 共分散行列を計算する際の有限差分ステップサイズを次のようにする (covreq = -1, -2 の場合)
    dltfdc*max(|x[i]|, 1/d[i]) (eps <= dltfdc <= 1) (デフォルト値 = eps^(1/3))
  v[43] (delta0): 共分散行列を計算する際の有限差分ステップサイズを次のようにする (covreq = 1, 2 の場合)
    delta0*max(|x[i]|, 1/d[i])*sign(x[i]) (eps <= delta0 <= 1) (デフォルト値 = eps^(1/2))
[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*(m + 2*n + 17) + 2*m)
[in,out]iv[]配列 iv[liv]
整数パラメータおよび作業領域のための配列.
[in]
  iv[0]: 0に設定して呼び出すと, 実行開始前にiv[]およびv[]の全てのパラメータをデフォルト値に初期化する.
    12に設定して呼び出すと, iv[]およびv[]はユーザーにより設定済であると見なし初期化を行わない. サブルーチンivsetはiv[0]=12に設定するため, 最初にivsetを呼び出してiv[]およびv[]をデフォルト値に設定し, 次に必要なパラメータを非デフォル値に変更し, それを使用して実行を開始することができる.
  iv[14] (covreq): 共分散行列の計算方法 (デフォルト値 = 1)
     = 1, -1: sigma * H^(-1) * (J^T * J) * H^(-1)
     = 2, -2: sigma * H^(-1)
     = 3, -3: sigma * (J^T * J)
    ただし, sigma = rssq / max(1, m-n) (rssqは残差二乗和), Hはヘッセ行列, Jはヤコビ行列である.
    共分散行列の下三角部分が v[iv[25]-1] から行ごとに格納される.
    符号は計算に使用するユーザー定義サブルーチンを示す.
       < 0: calcrのみを使って計算する
       > 0: calcrおよびcalcjを使って計算する(calcjが使えなければcalcrのみを使う)
  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の初期値を微分値の差分により推定する
  iv[56] (rdreq): 共分散行列と回帰診断ベクトルの計算の指定 (デフォルト値 = 0)
    = 0: 計算しない
    = 1: 共分散行列のみ計算
    = 2: 回帰診断ベクトルのみ計算
    = 3: 共分散行列と回帰診断ベクトルを計算
[out]
  iv[0]: リターンコード
    = 3: x値収束条件を満たした
    = 4: 関数値相対収束条件を満たした
    = 5: x値および関数値相対収束条件の両方を満たした
    = 6: 関数値絶対収束条件を満たした
    = 7: 近傍のヘッセ行列が特異になった
    = 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[25] (covmat): 共分散行列の計算結果を示す
    = -2, -1: 共分散行列を求めるのに失敗した
    = 0: 共分散行列の計算を行わなかった
    > 0: 共分散行列の下三角部分を v[iv[25]-1]から始まる領域に行ごとに格納した
  iv[29] (ngcall): calcjの呼び出し回数 (共分散行列計算のための呼び出しを含む)
  iv[30] (niter): 反復回数
  iv[43] (lastiv): livの最小値
  iv[44] (lastv): lvの最小値
  iv[51] (nfcov): 共分散行列計算のためのcalcrの呼び出し回数
  iv[52] (ngcov): 共分散行列計算のためのcalcjの呼び出し回数
  iv[60] (r): v[iv[60]-1]から始まる領域に残差ベクトルrを格納した
  iv[66] (regd): 回帰診断ベクトルの計算結果を示す
    = -2, -1: 回帰診断ベクトルを求めるのに失敗した
    = 0: 回帰診断ベクトルの計算を行わなかった
    > 0: 回帰診断ベクトルを v[iv[66]-1]から始まる領域に格納した
[in]liv配列 iv[]のサイズ. (liv >= 82 + n)
[out]info= 0: 正常終了 (iv[0] = 3〜6)
= -1: 入力パラメータ m の誤り (m < 1) (iv[0] = 66)
= -2: 入力パラメータ n の誤り (n < 1) (iv[0] = 66)
= -7: 入力パラメータ v[18]〜v[49] の誤り (範囲外の値) (iv[0] = 19〜50)
= -8: 入力パラメータ lv の誤り (lvが小さすぎる) (iv[0] = 16)
= -9: 入力パラメータ iv[0] の誤り (範囲外の値) (iv[0] = 80)
= -10: 入力パラメータ liv の誤り (livが小さすぎる) (iv[0] = 15)
= 7: 特異収束 (近傍のヘッセ行列が特異になった)
= 8: 誤収束 (誤った点での収束と思われる. 目標精度が小さすぎる可能性がある)
= 9: 関数評価回数の最大値を超えた
= 10: 反復回数の最大値を超えた
= 14: iv[]およびv[]の領域の割り付けを行った (iv[0]=13の呼び出し後に正常終了した)
= 17: mまたはnを変更して再スタートを行った
= 63: x[]の初期点において関数値を求めることができない
= 65: x[]において微分係数を求めることができない
出典
netlib/port