2分法は指定した区間内の解は必ず求めるものの,解の収束は遅い.
関数&ref(rf_newton.eq1.gif,nolink,70%);が連続で微分可能関数であるならば,関数の勾配値を用いることで収束を早めることができる.

解の初期値を&ref(rf_newton.eq2.gif,nolink,70%);とする.
&ref(rf_newton.eq3.gif,nolink,70%);での関数&ref(rf_newton.eq1.gif,nolink,70%);の接線は,
#ref(rf_newton.eq4.gif,nolink,70%)

となる.この接線が&ref(rf_newton.eq5.gif,nolink,70%);軸と交差する(&ref(rf_newton.eq6.gif,nolink,70%);)点は,
#ref(rf_newton.eq7.gif,nolink,70%)

&ref(rf_newton.eq8.gif,nolink,70%);を次の近似値として同様の処理を繰り返すことで解に近づいていく.図2はこの手順を示したものである.
この方法をニュートン・ラフソン法(Newton-Raphson method),もしくは単にニュートン法(Newton method)と呼ぶ.
ニュートン法の式は以下となる.
#ref(rf_newton.eq9.gif,nolink,70%)

反復回数を多くすると限りなく&ref(rf_newton.eq10.gif,nolink,70%);の解に近づく.
反復を終了するための収束条件は,
#ref(rf_newton.eq11.gif,nolink,70%)

となる.

ニュートン法は2分法と異なり解のある区間でなく初期近似値1つだけを指定するだけでよく,収束も速い.
しかし,&ref(rf_newton.eq1.gif,nolink,70%);だけでなくその微分値&ref(rf_newton.eq12.gif,nolink,70%);も必要で,初期値によっては解へ収束しない場合もある.


|&ref(newton.jpg,,100%);|
|CENTER:図2 ニュートン法|


ニュートン法のコード例を以下に示す.
#code(C){{
/*!
 * ニュートン・ラフソン法(Newton-Raphson method)
 * @param[in] func 関数値を与える関数ポインタ
 * @param[inout] x 探索開始位置を受け取り,解を返す
 * @param[inout] max_iter 最大反復数(反復終了後,実際の反復数を返す)
 * @param[inout] eps 許容誤差(反復終了後,実際の誤差を返す) 
 * @return 1:成功,0:失敗
 */
int newton(double func(const double), double dfunc(const double), 
           double &x, int &max_iter, double &eps)
{
    double f, df, dx;
    int k;
    for(k = 0; k < max_iter; ++k){
        f = func(x);
        df = dfunc(x);
        x = xn-f/df;

        // 収束判定
        dx = fabs(f/df);
        if(dx < eps || fabs(f) < eps){
            max_iter = k; eps = dx;
            return 1;
        }
    }

    max_iter = k; eps = dx;
    return 0;
}
}}



トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS