未分類未分類
ニュートンラフソン法; ニュートン法; Newton Raphson Method

概要
ニュートンラフソン法は関数値が0を通る点を求める求根アルゴリズムの一つ。関数値と関数の微分値をもとに収束計算を行う。
なめらかな関数でありx軸に平行な領域がなく根を持つ限り収束する。他の求根アルゴリズムに比べ収束速度が早いが安定性に欠ける。
ニューロンラフソン法

アルゴリズム
\(f(x)=0\)となる\(x\)を求める。
・初期値
収束計算を行う初期値\(x_0\)を設定する。

・収束計算
\(\quad x_{n+1} = x_{n}-\frac{f(x_n)}{f'(x_n)} \)

留意点
初期値次第では異なる\(x\)に収束する。
\(f'(x) \approx 0\)となるような点があると収束速度が落ちる。
また微分不連続な関数には適応できない。


ソースコード

namespace RootFindingMethod {

    /// <summary>NewtonRaphson法</summary>
    /// <remarks>f(x)=0となるxを求める</remarks>
    public static class NewtonRaphsonMethod {

        /// <summary>求根</summary>
        /// <param name="func">f(x)=0となる関数f(x)</param>
        /// <param name="diff_func">f(x)=0となる関数の微分f'(x)</param>
        /// <param name="init">初期値</param>
        /// <param name="precision_level">精度レベル</param>
        public static double Execute(Func<double, double> func, Func<double, double> diff_func, double init, int precision_level) {
            double x = init;

            while(precision_level > 0) {

                x -= func(x) / diff_func(x);
                precision_level--;
            }

            return x;
        }

        /// <summary>求根</summary>
        /// <param name="func">f(x)=0となる関数f(x)</param>
        /// <param name="diff_func">f(x)=0となる関数の微分f'(x)</param>
        /// <param name="init">初期値</param>
        /// <param name="precision_epsilon">収束しきい値</param>
        /// <remarks>収束しきい値は小さすぎると実質無限ループに陥る</remarks>
        public static double Execute(Func<double, double> func, Func<double, double> diff_func, double init, double precision_epsilon) {
            double x = init, dx;

            do {
                dx = func(x) / diff_func(x);
                x -= dx;

            } while(Math.Abs(dx) > precision_epsilon);

            return x;
        }
    }
}

単体テスト

namespace RootFindingMethod.Tests {
    [TestClass()]
    public class NewtonRaphsonMethodTests {
        [TestMethod()]
        public void ExecuteTest1() {
            Func<double, double> func = (x) => x * x - 2;
            Func<double, double> diff_func = (x) => 2 * x;
            
            double v = NewtonRaphsonMethod.Execute(func, diff_func, 0.1, 12);

            Assert.AreEqual(v, Math.Sqrt(2), 1e-14);
        }

        [TestMethod()]
        public void ExecuteTest2() {
            Func<double, double> func = (x) => x * x - 2;
            Func<double, double> diff_func = (x) => 2 * x;
            
            double v = NewtonRaphsonMethod.Execute(func, diff_func, 0.1, 5e-15);

            Assert.AreEqual(v, Math.Sqrt(2), 1e-14);
        }
    }
}


関連項目
二分法
挟み撃ち法
割線法

ライブラリライブラリ
確率統計確率統計
線形代数線形代数
幾何学幾何学
最適化最適化
微分方程式微分方程式
画像処理画像処理
補間補間
機械学習機械学習
クラスタリングクラスタリング
パズルゲーム・パズル
未分類未分類