【C#】 迴圈小練習_非線性方程式求解 I

非線性方程式求解(牛頓反覆運算法)

非線性方程式是指方程式中包含一個變數的幕次不是1次,例如 y = 4x2- 3 等等……..
這類型的方程式要尋求精確的解有時比較困難,因此找出近似根就顯得很重要,
牛頓反覆運算法就是牛頓在17世紀提出的一種解方程式 f(x) = 0 2的方法

假設r 是 f(x)=0的根,選取x0 作為 r 的初始近似值,過點(x0 ,  f(x0)) 作曲線 y=f(x) 的切線L,
L的方程式為  y=f(x0)+ f(x0)(x-x0) ,求出L與x軸交點的水平座標 x1= x0 -f(x0) / f(x0),稱x1為 r的一次近似值。
重複以上過程,得r的近似值序列,其中 xn1= xn -f(xn) / f(xn),稱為r的n1次近似值。

也就是說,這需要用到非線性方程式的曲線切線來求出近似解。請參閱:函數求根:牛頓法(含廣義牛頓法)

 class Program
    {
        static double func(double x)  //待求解方程式
        {
            return x * x * x * x - 3 * x * x * x + 1.5 * x * x - 4.0;
        }
        static double dfunc(double x)
        {
            return 4 * x * x * x - 9 * x * x + 3 * x;
        }

        /// <summary>
        /// 牛頓反覆運算法
        /// </summary>
        /// <param name="x"> 初始值</param>
        /// <param name="maxcyc"> 反覆運算次數</param>
        /// <param name="precision">代表精確度</param>
        /// <returns>傳為值為1,否則傳回0</returns>
        static int NewtonMethod(double[] x, int maxcyc, double precision)
        {
            double x0, x1;
            int i;
            x0 = x[0];
            i = 0;
            while (i < maxcyc)
            {
                if (dfunc(x0) == 0.0)
                {
                    Console.WriteLine("反覆運算中導數為0!\n");
                    return 0;
                }
                x1 = x0 - func(x0) / dfunc(x0);
                if (Math.Abs(x1 - x0) < precision || Math.Abs(func(x1)) < precision)
                {
                    x[0] = x1;
                    return 1;
                }
                else
                {
                    x0 = x1;
                }
                i++;
            }
            Console.WriteLine("反覆運算超過預設值!仍沒有達到精度!\n");
            return 0;
        }



        static void Main(string[] args)
        {
            //建構非線性方程式
            //建構非線性方程式的導數方程式
            //透過反覆運算公式求解
            double precision;
            int maxcyc, result;
            double[] x = { 2.0 };//初值
            maxcyc = 1000; //反覆運算次數
            precision = 0.00001; //精度

            result = NewtonMethod(x, maxcyc, precision);
            if (result == 1)
            {
                Console.WriteLine(string.Format("方程式 x * x * x * x - 3 * x * x * x + 1.5 * x * x - 4.0;\n在2.0 附近的根為:{0}", x[0]));
            }
            else
            {
                Console.WriteLine("反覆運算失敗!\n");
            }
            Console.ReadLine();
        }
    }


心中小劇場:我還是無法理解公式阿>"<~~~

水滴可成涓流,涓流可成湖泊大海。
汲取累積知識,將知識堆積成常識;將常識探究成學識;將學識簡化為知識;授人自省。