数值计算方法 Chapter4. 非线性方程求根

Posted Espresso Macchiato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数值计算方法 Chapter4. 非线性方程求根相关的知识,希望对你有一定的参考价值。

0. 问题描述

给定一个复杂方程 f ( x ) = 0 f(x) = 0 f(x)=0,如果直接求解其解析解非常复杂或者难以求解的话,那么可以通过数值求解的方法得到一定精度条件下的数值解。

1. 实根的对分法

对分法使用的条件需要满足:

  1. f ( x ) f(x) f(x)在区间 [ a , b ] [a,b] [a,b]上连续;
  2. f ( a ) ⋅ f ( b ) < 0 f(a) \\cdot f(b) < 0 f(a)f(b)<0

那么, f ( x ) f(x) f(x)在区间 [ a , b ] [a,b] [a,b]中必然存在至少一个零点,我们可以使用二分法不断地迭代求解。

给出python伪代码如下:

def bisect_solve(fn, a, b, epsilon=1e-9):
    assert(fn(a) * fn(b) < 0)
    while b - a >= epsilon:
        m = (a + b)/2
        if fn(m) * fn(a) > 0:
            a = m
        elif fn(m) * fn(b) > 0:
            b = m
        else:
            return m
    return (a+b)/2

2. 迭代法

迭代法的思路是说,将方程 f ( x ) = 0 f(x) = 0 f(x)=0 改写为方程 x = φ ( x ) x = \\varphi(x) x=φ(x)

此时,我们可以构造迭代关系 x k + 1 = φ ( x k ) x_k+1 = \\varphi(x_k) xk+1=φ(xk),如果数列 x k x_k xk收敛,那么数列 x k x_k xk的极限 l i m k → ∞ x k lim_k \\to \\infty x_k limkxk 即为目标方程的解。

而关于数列的收敛条件的判断,我们有定理:

定理 4.1
φ ( x ) \\varphi(x) φ(x)定义在 [ a , b ] [a,b] [a,b]上,且满足:
(1) 当 x ∈ [ a , b ] x \\in [a, b] x[a,b]时,有 a ≤ φ ( x ) ≤ b a \\leq \\varphi(x) \\leq b aφ(x)b
(2) φ ( x ) \\varphi(x) φ(x) [ a , b ] [a,b] [a,b]上可到,且存在正数 L < 1 L < 1 L<1,使得对于任意 x ∈ [ a , b ] x \\in [a, b] x[a,b],有 ∣ φ ′ ( x ) ∣ ≤ L |\\varphi'(x)| \\leq L φ(x)L
则在 [ a , b ] [a, b] [a,b]上有唯一的点 x ∗ x^* x满足 x ∗ = φ ( x ∗ ) x^* = \\varphi(x^*) x=φ(x),称 x ∗ x^* x φ ( x ) \\varphi(x) φ(x)的不动点,且迭代格式 x k + 1 = x k x_k+1 = x_k xk+1=xk对任意的初值 x 0 ∈ [ a , b ] x_0 \\in [a,b] x0[a,b]均收敛于 φ ( x ) \\varphi(x) φ(x)的不动点 x ∗ x^* x,且有误差估计式:
∣ x ∗ − x k ∣ ≤ L k 1 − L ∣ x 1 − x 0 ∣ |x^* - x_k| \\leq \\fracL^k1-L|x_1 - x_0| xxk1LLkx1x0

同样的,我们可以给出python伪代码实现如下:

def iter_solve(fn, x, epsilon=1e-9):
    MAX_ITER_TIME = 10**7
    for _ in range(MAX_ITER_TIME):
        y = fn(x)
        if abs(y-x) <= epsilon:
            return y
        x = y
    return x

3. Newton迭代法

Newton迭代法的思路来源于泰勒展开,给出Talyer展开公式如下:

f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ⋅ ( x − x 0 ) + f ′ ′ ( x 0 ) 2 ! ⋅ ( x − x 0 ) 2 + . . . + f ( n ) ( x 0 ) n ! ⋅ ( x − x 0 ) n + . . . f(x) = f(x_0) + f'(x_0) \\cdot (x-x_0) + \\fracf''(x_0)2! \\cdot (x-x_0)^2 + ... + \\fracf^(n)(x_0)n! \\cdot (x-x_0)^n + ... f(x)=f(x0)+f(x0)(xx0)+2!f(x0)(xx0)2+...+n!f(n)(x0)(xx0)n+...

如果视二阶以上的结果为小量,则有:

x ≃ x 0 + f ( x ) − f ( x 0 ) f ′ ( x 0 ) x \\simeq x_0 + \\fracf(x) - f(x_0)f'(x_0) xx0+f(x0)f(x)f(x0)

x x x为零点时,有 f ( x ) = 0 f(x) = 0 f(x)=0,因此,我们近似即有:

x ≃ x 0 − f ( x 0 ) f ′ ( x

以上是关于数值计算方法 Chapter4. 非线性方程求根的主要内容,如果未能解决你的问题,请参考以下文章

数值分析实验之非线性方程求根(MATLAB实现)

数值分析实验之非线性方程求根(Python 现)

《数值分析》-- 非线性方程的数值解法

《数值分析》-- 非线性方程的数值解法

《数值分析》-- 非线性方程的数值解法

[计算机数值分析]牛顿法求解方程的根