旅行好きなソフトエンジニアの備忘録

プログラミングや技術関連のメモを始めました

【C#】 ニュートン法を使って非線形方程式の解を求める

ニュートン法を使ってf(x)=0を満たすxを計算します。まずはニュートン法を実装しますが、ここ(【C#】 微分を計算するクラス - 旅行好きなソフトエンジニアの備忘録)で作成したDerivativeというクラスを利用します。

public class NewtonMethod1D
{
    /// <summary>
    /// ニュートン法により非線形方程式の解を求めるメソッド
    /// </summary>
    /// <param name="f">非線形方程式</param>
    /// <param name="initialX">解の初期値</param>
    /// <param name="iteration">計算回数</param>
    /// <param name="acceptableError">許容誤差</param>
    /// <param name="xn">計算終了後の解</param>
    /// <returns>許容誤差以内で解が求まった場合にtrue</returns>
    public static bool Compute(Func<double, double> f, double initialX, int iteration, double acceptableError, out double xn)
    {
        ValidateArguments(iteration, acceptableError);

        bool found = false;
        xn = initialX;
        for (int i = 0; i < iteration; ++i)
        {
            double fx = f(xn);
            if (Math.Abs(fx) <= acceptableError)
            {
                found = true;
                break;
            }
            double fdx = Derivative.Compute(f, xn);
            xn -= f(xn)/fdx;
        }

        return found;
    }

    private static void ValidateArguments(int iteration, double acceptableError)
    {
        if (iteration <= 0)
        {
            throw new ArgumentOutOfRangeException("iteration", "iteration must be positive");
        }
        if (acceptableError <= 0.0)
        {
            throw new ArgumentOutOfRangeException("acceptableError", "acceptableError must be positive");
        }
    }
}

次にNewtonMethod1Dクラスを利用して、f(x)=0.5-x+0.2sinx=0を満たすxを計算します。

// 非線形方程式
Func<double, double> f = x => 0.5 - x + 0.2*Math.Sin(x);
// 解の初期値を0.2とする
double initialX = 0.2;
// 計算回数
int iteration = 30;
// 許容誤差
double acceptableError = 0.001;
double xn;
bool found = NewtonMethod1D.Compute(f, initialX, iteration, acceptableError, out xn);

数回の計算で解が見つかり、求める解は約0.6155であることが分かります。

Javaで学ぶシミュレーションの基礎

Javaで学ぶシミュレーションの基礎


関連記事
【C#】 ニュートン法を使って連立非線形方程式の解を求める - 旅行好きなソフトエンジニアの備忘録