代码中使用牛顿法和弦截法求解非线性方程

最开始关注这类与数值分析有关的编程问题,是因为在为中石化编写一个计算天然气流量的项目中需要迭代计算一些数值。

牛顿法求解非线性方程

本节主要分为三个部分。

牛顿迭代法的理论依据

具体的理论依据请参照高等数学中的基础部分:泰勒展开式。在网上可以所搜到更多的细节内容,但是这不是这篇文章的重点,不赘述了。这个公式在高等数学中是比较基础的内容,不管知道还是不知道都不用深究,因为不影响实际的使用。

泰勒展开式中最关键的内容就是求导,如果你的非线性方程求导比较方便的话就可以好办了,继续往下看;如果你的非线性方程不方便求导的话,直接跳到下一节。

牛顿迭代法的计算步骤

  1. 给出一个初始的近似根 $x_0$ 及精度 $\varepsilon$。
    • $x_0$ 需要充分接近 x 以保证局部收敛。
    • $\varepsilon$ 是误差范围,一般设定为 $10^{-6}$ 就可以了。
  2. 计算 $x_1=x_0 - \frac{f(x_0)}{f’(x_0)}$ 。
  3. 若 $|x_1 - x_0| < \varepsilon$ 转到 4;否则回到 2。
  4. 输出 $x_1$ 为满足精度的根,结束。

牛顿迭代法的实际运用

求方程 $xe^x -1=0$ 的根。编写代码完成下面的迭代公式:

$$x_{k+1} = x_k - \frac{x_k - e^{-x_k}}{1 + x_k}$$

取初始为 $x_0=0.5$,迭代结果见下表:

K0123
$x_k$0.50.571020.567160.56714

弦截法求解非线性方程

弦截法是牛顿法的变种和优化,相比较牛顿法来说,计算量更少。它的思想是用切线斜率近似割线斜率。最重要是的该方法不用求导

弦截法的核心内容

在牛顿法的基础是改进,使用函数值代替导数值,省去计算导数的计算量,不过需要引入两组值作为迭代点。

下面是弦截法的核心迭代方程:

$$
x_{k+1} = x_k - \frac{f(x_k)(x_k-x_{k-1})}{f(x_k)-f(x_{k-1})}
$$

基本上可以在任意非线性方程的求解问题上套用。

弦截法的计算步骤

  1. 给出两个初始的近似根 $x_0$、$x_1$ 及精度 $\varepsilon$。
  2. 计算 $x_{k+1} = x_k - \frac{f(x_k)(x_k-x_{k-1})}{f(x_k)-f(x_{k-1})}$
  3. 若 $|x_{k+1} - x_k| < \varepsilon$ 转到 4;否则回到 2。
  4. 输出 $x_{k+1}$ 为满足精度的根,结束。

弦截法与牛顿法的比较

  • 相同:
    • 都是线性化方法
  • 不同:
    • 牛顿法是单点迭代,计算量大,需要求导
    • 弦截法是多点迭代,计算量更少,不用求导

具体的代码编码就不在这里给出来了,都是基本的线性公式,没有一点难度。