牛顿迭代法求解一元高阶方程

       牛顿迭代法(Newton's method),又称为牛顿-拉夫逊(Newton-Raphson)方法,是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。牛顿迭代法作为一种数值计算方法,具有收敛速度快、快速求解复杂方程、简单易用等优点,但也存在初始点选择问题、局限于单根问题、迭代公式的推导等缺点。在实际应用中,需要根据问题的复杂度、求解精度等因素,选择合适的数值计算方法,并进行多组试验和分析,以求得较为精确的结果。

1. 牛顿迭代法简介

1.1 牛顿迭代法背景

       由于多数方程不存在求根公式,求精确根非常困难,甚至不可解,因此寻找方程的近似根就显得特别重要。牛顿迭代法就是为解决这一问题而提出的。

1.2 牛顿迭代法原理

      牛顿迭代法基于函数的导数和函数值的信息,通过不断迭代逼近方程的根。假设要求解方程f(x) = 0的根,首先选取一个初始值x0。通过计算函数f(x)在x0处的导数,得到切线的斜率。然后,找到切线与x轴的交点,将该交点作为新的近似解x1。重复这一过程,不断迭代,直至达到所需精度。

1.3 牛顿迭代法公式

牛顿迭代格式为

                                                                  

牛顿迭代格式的误差为

                                                                  

1.4 牛顿迭代法的优点

  1. 快速求解复杂方程:牛顿迭代法基于泰勒公式展开函数,在一定条件下可以保证收敛性,并且当迭代次数足够多时,可以达到非常高的精度。
  2. 收敛速度快:与其他数值计算方法相比,牛顿迭代法的收敛速度非常快。因为牛顿迭代法的每一次迭代都会朝着方程根的方向进行逼近,而且逼近速度越来越快。
  3. 简单易用:牛顿迭代法的求解过程相对简单,只需要根据泰勒公式展开函数,并进行一定的变量代换,就可以得到逐步逼近方程根的迭代公式。

1.5 牛顿迭代法的缺点

  1. 初始点的选择问题:牛顿迭代法的收敛性与初始点的选取有关。如果初始点选择不当,可能会导致无法收敛或者收敛速度特别慢。
  2. 局限于单根问题:牛顿迭代法只适用于求解单根问题,即方程只有一个解的情况。如果方程有多个解,牛顿迭代法可能会收敛到错误的解或者无法收敛。
  3. 迭代公式的推导:牛顿迭代法的迭代公式需要推导,并且推导过程比较复杂。需要进行泰勒公式展开、变量代换等计算,而且还需要保证公式的收敛性和稳定性。

1.6 牛顿迭代法的应用

       牛顿迭代法在实际应用中广泛存在,如在计算机图形学中精确计算圆的周长、面积等参数,实现快速的路径追踪和光线追踪;在金融领域中计算隐含波动率;在机器学习、神经网络中进行梯度下降等。

2  用C#编写牛顿迭代法求解一元高阶方程

2.1  一元高阶方程

      我们以五次的一元方程为例,设该方程为,注意等式右边必须为0,其中a1~a5为x高阶系数,a0表示常数

                                     

     设置为函数形式可以得到

                                     

方程问题转换为了函数f(x)零点问题,即f(x)=0时,x的值。

2.2  牛顿迭代法代码

        由1.3章节可知,我们需要求解函数f(x)的值和其导数值,代码如下,函数返回值为double数组, double[0]表示f(x)的值,double[1]表示f(x)的导数值。

        /// <summary>
        /// 求解函数的值
        /// </summary>
        /// <param name="a5">x的五次方 的系数</param>
        /// <param name="a4">x的4次方  系数</param>
        /// <param name="a3">x的3次方  系数</param>
        /// <param name="a2">x的2次方  系数</param>
        /// <param name="a1">x的1次方  系数</param>
        /// <param name="a0">常数</param>
        /// <param name="x">x的值</param>
        /// <returns>返回值double[]数组  double[0]表示函数的值 double[1]表示导数的值</returns>
        static double[] fxAnd_diff_fx(double a5,double a4,double a3,double a2,double a1,double a0,double x)
        {
            // 函数fx的值 
            double[] result=  { a5* Math.Pow(x, 5) + a4 * Math.Pow(x, 4) + a3 * Math.Pow(x, 3) + a2 * Math.Pow(x, 2) + a1 * x + a0,
            5*a5* Math.Pow(x, 4) + 4*a4 * Math.Pow(x, 3) + 3*a3 * Math.Pow(x, 2) + 2*a2 * Math.Pow(x, 1) + a1};
            return result; 
        }

整体代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace 牛顿迭代法求解一元高次方程
{
    class Program
    {


        /// <summary>
        /// 求解函数的值
        /// </summary>
        /// <param name="a5">x的五次方 的系数</param>
        /// <param name="a4">x的4次方  系数</param>
        /// <param name="a3">x的3次方  系数</param>
        /// <param name="a2">x的2次方  系数</param>
        /// <param name="a1">x的1次方  系数</param>
        /// <param name="a0">常数</param>
        /// <param name="x">x的值</param>
        /// <returns>返回值double[]数组  double[0]表示函数的值 double[1]表示导数的值</returns>
        static double[] fxAnd_diff_fx(double a5,double a4,double a3,double a2,double a1,double a0,double x)
        {
            // 函数fx的值 
            double[] result=  { a5* Math.Pow(x, 5) + a4 * Math.Pow(x, 4) + a3 * Math.Pow(x, 3) + a2 * Math.Pow(x, 2) + a1 * x + a0,
            5*a5* Math.Pow(x, 4) + 4*a4 * Math.Pow(x, 3) + 3*a3 * Math.Pow(x, 2) + 2*a2 * Math.Pow(x, 1) + a1};
            return result; 
        }

        /// <summary>
        /// 求解的方程根
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // x的五次方 的系数
            double a5 = 5;
            // x的4次方 的系数
            double a4 = -4;
            // x的3次方 的系数
            double a3 = -3;
            // x的2次方 的系数
            double a2 = -2;
            // x的1次方 的系数
            double a1 = -1;
            // 方程的常数
            double a0 = -4;
            // 迭代第k次x的值
            double xk = 0;

            // 迭代第k+1次x的值
            double xk_1 = 0;

            // 设置迭代次数
            int iter = 1000;


            // 求解方程组的值
            for(int i=0;i<iter;i++)
            {
                double[] result = fxAnd_diff_fx(a5, a4, a3, a2, a1, a0, xk);
                xk_1 = xk - result[0] / result[1];
                Console.WriteLine("迭代第{0}次,迭代结果为{1}",i+1,xk_1);
                Thread.Sleep(10);
                xk= xk_1;
            }
            Console.ReadKey();
        }
    }
}

2.3  代码运行演示结果

我们取 a5=5,   a4=-4,  a3=-3  ,a2=-2,   a1=-1,  a0=-4 (大家可以根据需要自行改,若是最高项为x的3次方,设置a5=0,  a4=0  即可)   迭代初值为xk=0;代码运行结果如下,运算结果约为1.5478

牛顿迭代法是一种通过线性逼近来求解方程组的方法。其基本思想是利用函数的一阶导数和二阶导数来更新参数,直到取得收敛解。在每一步迭代中,牛顿法需要求解目标函数的海塞矩阵(Hessian Matrix),这个计算过程相对复杂。而拟牛顿法则通过近似海塞矩阵的逆矩阵或海塞矩阵来简化计算过程。 牛顿迭代法的具体步骤如下: 1. 初始化参数,选择一个初始点作为起点。 2. 计算目标函数的一阶导数和二阶导数,并求出当前点的海塞矩阵。 3. 使用海塞矩阵的逆矩阵(或近似逆矩阵)与一阶导数的乘积来更新参数。 4. 重复步骤2和步骤3,直到达到收敛条件。 需要注意的是,牛顿迭代法对初始点的选择比较敏感,不同的初始点可能会得到不同的解。此外,牛顿迭代法的收敛速度很快,但在计算海塞矩阵的逆矩阵时的计算复杂度较高,因此才有了拟牛顿法的出现。 拟牛顿法是通过构造出可以近似海塞矩阵(或海塞矩阵的逆)的正定对称阵来近似牛顿法。拟牛顿法包含多种方法,如DFP算法、BFGS算法、Broyden类算法等。这些方法都是在不求二阶偏导数的情况下来构造近似矩阵,从而简化计算过程。 综上所述,牛顿迭代法通过利用函数的一阶导数和二阶导数来求解方程组,而拟牛顿法是对牛顿法的一种近似方法,通过构造近似矩阵来简化计算过程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值