ニュートンラフソン法; ニュートン法; 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);
}
}
}
関連項目
二分法
挟み撃ち法
割線法