基于Python实现Aitken迭代法和牛顿迭代法


对于非线性方程,我们可以使用迭代的方式求出近似解。下面介绍两种比较经典的算法:简单迭代法、牛顿法


简单迭代法

对于待求解方程,先把方程写成 f ( x ) = 0 f(x)=0 f(x)=0 的形式,然后改成如下同解形式:
x = φ ( x ) x = \varphi(x) x=φ(x)选一个初始值 x 0 x_0 x0,然后做迭代:
x k + 1 = φ ( x k ) ,          k = 1 , 2 , 3 , … x_{k+1}=\varphi(x_{k}), \;\;\;\;k=1,2,3,\dots xk+1=φ(xk),k=1,2,3,如果迭代序列 { x k } \{x_k\} {xk} 收敛于真解,则称简单迭代法使收敛的。

简单迭代法的收敛条件

根据压缩映射原理,如果 φ ( x ) \varphi(x) φ(x) 为定义域上的压缩映射,则 φ ( x ) \varphi(x) φ(x) 在定义域上有唯一的不动点,且对于任何初值,由迭代格式 x k + 1 = φ ( x k ) x_{k+1}=\varphi(x_{k}) xk+1=φ(xk) 产生的迭代序列 { x k } \{x_k\} {xk} 收敛于该不动点。

另外我们还常常讨论简单迭代法的局部收敛性,感兴趣的同学查阅相关书籍,此处不再赘述。


简单迭代法的Aitken加速算法

假设 φ ( x ) \varphi(x) φ(x) α \alpha α 处可导,有
x k + 1 − α = φ ′ ( ξ 1 ) ( x k − α ) x k + 2 − α = φ ′ ( ξ 2 ) ( x k + 1 − α ) x_{k+1} - \alpha=\varphi'(\xi_1)(x_k-\alpha)\\ x_{k+2} - \alpha=\varphi'(\xi_2)(x_{k+1}-\alpha) xk+1α=φ(ξ1)(xkα)xk+2α=φ(ξ2)(xk+1α)假设 φ ′ ( ξ 1 ) ≈ φ ′ ( ξ 2 ) \varphi'(\xi_1)\approx \varphi'(\xi_2) φ(ξ1)φ(ξ2),有
x k + 1 − α x k + 2 − α = x k − α x k + 1 − α \frac{x_{k+1}-\alpha}{x_{k+2} - \alpha}=\frac{x_k-\alpha}{x_{k+1} - \alpha} xk+2αxk+1α=xk+1αxkα得到
α = x k − ( x k + 1 − x k ) 2 x k + 2 − 2 x k + 1 + x k \alpha=x_k-\frac{(x_{k+1}-x_k)^2}{x_{k+2}-2x_{k+1} +x_k} α=xkxk+22xk+1+xk(xk+1xk)2
x ^ k = x k − ( x k + 1 − x k ) 2 x k + 2 − 2 x k + 1 + x k          k = 1 , 2 , 3 , … \widehat x_k=x_k-\frac{(x_{k+1}-x_k)^2}{x_{k+2}-2x_{k+1} +x_k} \;\;\;\;k=1,2,3,\dots x k=xkxk+22xk+1+xk(xk+1xk)2k=1,2,3,以上即为Aitken加速算法的迭代格式,序列 { x ^ k } \{\widehat x_k\} {x k} 要比序列 { x k } \{x_k\} {xk} 更快地收敛于 α \alpha α

为方便计算可构造如下Aitken加速算法
{ y k = φ ( x k ) z k = φ ( x k ) x k + 1 = x k − ( y k − x k ) 2 z k − 2 y k + x k ,      k = 0 , 1 , 2 , ⋯ \left\{\begin{array}{l}y_k=\varphi(x_k)\\z_k=\varphi(x_k)\\x_{k+1}=x_k-\frac{{(y_k-x_k)}^2}{z_k-2y_k+x_k},\;\;k=0,1,2,\cdots\end{array}\right. yk=φ(xk)zk=φ(xk)xk+1=xkzk2yk+xk(ykxk)2,k=0,1,2,


基于Pyhton实现的Aitken加速算法

算法代码

import numpy as np
import math

def Aitken(x0,epsilon,iternum,phi):#初值,精度要求,最大迭代次数,迭代函数
    xk_1 = x0
    for i in range(iternum):
        y = phi(xk_1)
        z = phi(y)
        if (z - 2*y +xk_1)!= 0:
            xk = xk_1 - (y - xk_1)**2 / (z - 2*y +xk_1)
            print("第",i+1,"次迭代 ","xk=",xk,"  xk-1=",xk_1,"  |xk - xk-1|=",abs(xk-xk_1));
            if abs(xk-xk_1)<epsilon:
                return xk
            else:
                xk_1 = xk
        else:
            return x
    print("方法失败")
    return 0

实验

计算 x k + 1 = 1.6 + 0.99 c o s ( x ) x_{k+1}=1.6+0.99cos(x) xk+1=1.6+0.99cos(x) 在初值取 x 0 = π 2 x_0=\frac\pi2 x0=2π 时的根。

def phi(x): 
    return 1.6+0.99*math.cos(x)
    
Aitken(1.57080,1/(10)**7,10,phi)#初值1.57080,精度10^-7,最大迭代次数为10

实验结果
在这里插入图片描述
最终结果为 1.585471801521943


牛顿迭代法

设函数 f ( x ) = 0 f(x)=0 f(x)=0 在有根区间 [ a , b ] [a,b] [a,b] 上二阶连续可微, x 0 x_0 x0 α \alpha α 的近似值,将 f ( x ) f(x) f(x) x 0 x_0 x0 处作Taylor展开,有
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + f ′ ′ ( ξ 0 ) ( x − x 0 ) 2 2 f(x) = f(x_0) + f'(x_0)(x - x_0)+f''(\xi_0)\frac{(x-x_0)^2}{2} f(x)=f(x0)+f(x0)(xx0)+f(ξ0)2(xx0)2用其线性主部近似 f ( x ) f(x) f(x)
f ( x ) ≈ f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) f(x) \approx f(x_0) + f'(x_0)(x - x_0) f(x)f(x0)+f(x0)(xx0)将非线性方程 f ( x ) = 0 f(x)=0 f(x)=0 近似化为线性方程
f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) = 0 f(x_0) + f'(x_0)(x - x_0)=0 f(x0)+f(x0)(xx0)=0 f ′ ( x 0 ) f'(x_0) f(x0) 不为0,则有
x 1 = x 0 − f ( x 0 ) f ′ ( x 0 ) x_1 = x_0-\frac{f(x_0)}{f'(x_0)} x1=x0f(x0)f(x0)一般地,有
x k + 1 = x k − f ( x k ) f ′ ( x k ) x_{k+1} = x_k-\frac{f(x_k)}{f'(x_k)} xk+1=xkf(xk)f(xk)以上迭代格式称为牛顿迭代格式。

基于Pyhton实现的牛顿迭代法

算法代码

import numpy as np
import math
from scipy.misc import derivative

def Newton(x0,epsilon,iternum,f):#初值,精度要求,最大迭代次数,迭代函数
    xk_1 = x0
    for i in range(iternum):
        fx = f(xk_1)
        fdx = derivative(f,xk_1,dx=1e-6)
        if fdx!= 0:
            xk = xk_1 - fx / fdx
            print("第",i+1,"次迭代 ","xk=",xk,"  xk-1=",xk_1,"  |xk - xk-1|=",abs(xk-xk_1));
            if abs(xk-xk_1)<epsilon:
                return xk
            else:
                xk_1 = xk
        else:
            break
    print("方法失败")
    return 0

实验
求方程 x e x − 1 = 0 xe^x-1=0 xex1=0 0.5 0.5 0.5 处的根,要求精度为 ε = 1 0 − 5 \varepsilon=10^{-5} ε=105

def func(x): #f
    return x*math.exp( x )-1
    
Newton(0.5,1/(10**5),10,func)

实验结果
在这里插入图片描述
最终结果为 0.5671432904097838

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值