不动点迭代法(Fixed Point Iteration)迭代求根的python程序

迭代法的作用

许多复杂的求解问题,都可以转换成方程f(x)=0的求解问题。这一系列的解叫做方程的根。对于非线性方程的求解,在自变量范围内往往有多个解,我们将此变化区域分为多个小的子区间,对每个区间进行分别求解。我们在求解过程中,选取一个近似值或者近似区间,然后运用迭代方法逐步逼近真实解。
方程求根的常用迭代法有:二分法不动点迭代牛顿法弦截法

不动点迭代法

简单迭代法或基本迭代法又称不动点迭代法
1、不动点(FixedPoint)
首先来看一下什么是不动点:
在这里插入图片描述
换句话说,函数φ的不动点是y=φ(x)与y=x的交点,下图画出了函数y=cos(x)与y=x在区间[0,π/2]的交点,即cos(x)的不动点:
在这里插入图片描述
2、不动点迭代(Fixed Point Iteration)
不动点迭代的基本思想:
在这里插入图片描述
也就是说,为了求解方程f(x)=0,首先将方程转换为x=g(x),然后初始化x0,循环迭代xi+1=g(xi),直到满足收敛收件。
这里将方程f(x)=0转换为x=g(x)是很容易的,比如对于f(x)=x-cos(x),求解f(x)=0即为求解x-cos(x)=0,即x=cos(x),因此g(x)=cos(x)。
再例如对于方程:
在这里插入图片描述
可以等价为
在这里插入图片描述
还可以等价为
在这里插入图片描述
也就是说,将方程f(x)=0转换为x=g(x)有不同的方式,因此对方程f(x)=0来说,g(x)也不是唯一的。
3、不动点迭代的收敛性
这个迭代过程是很简单的,但这里有个关键性的问题:迭代收敛么?即经过N次迭代后是否会收敛于不动点?
在这里插入图片描述
通俗点讲,若要使不动点迭代收敛,则要求φ(x)在区间[a,b]上的函数值也在此区间内,另外还要求φ(x)的斜率绝对值不大于1。其证明过程比较复杂,有兴趣的可以查阅一些相关文献。

例题

求方程式:x3 - 0.165 × x2 + 3.993 × 10-4 = 0在(0,0.11)上的根

先看看不用迭代法计算的结果

from sympy import *
from sympy.abc import x

def func(x):
    return x**3 - 0.165*x**2 + 3.993*10**(-4)
result = solveset(func(x), x, Interval(0, 0.11))
print(result)

结果:

FiniteSet(0.0623775815137495)

约定一个误差,当误差小于某个数值的时候,迭代停止

代码:

xl = 0  #区间下限
xu = 0.11  #区间上限
x = (xl+xu)/2  #迭代初始值
x_list = [x]
i = 0

while True:
    x = x ** 3 - 0.165 * x ** 2 + 3.993 * 10 ** (-4) + x
    x_list.append(x)
    if len(x_list) > 1:
        i += 1
        error = abs((x_list[-1] - x_list[-2]) / x_list[-1])
        if error < 10**(-6):
            print(f'迭代第{i}次后,误差小于10^-6')
            break
    else:
        pass

结果:

迭代第777次后,误差小于10^-6
所求方程式的根为0.062370654088088

迭代至电脑默认误差为0

xl = 0  #区间下限
xu = 0.11  #区间上限
x = (xl+xu)/2  #迭代初始值
x_list = [x]
i = 0

while True:
    x = x ** 3 - 0.165 * x ** 2 + 3.993 * 10 ** (-4) + x
    x_list.append(x)
    if len(x_list) > 1:
        i += 1
        error = abs((x_list[-1] - x_list[-2]) / x_list[-1])
        if error == 0:
            print(f'迭代第{i}次后,误差为0')
            break
    else:
        pass

print(f'所求方程式的根为{x_list[-1]}')

结果:

迭代第3402次后,误差为0
所求方程式的根为0.062377581513749114

画迭代法

import matplotlib.pyplot as plt
xl = 0  #区间下限
xu = 0.11  #区间上限
x = (xl+xu)/2  #迭代初始值
x_list = [x]
i = 0

x_values = []
y_values = []
while True:
    x = x ** 3 - 0.165 * x ** 2 + 3.993 * 10 ** (-4) + x
    x_list.append(x)
    if len(x_list) > 1:
        i += 1
        error = abs((x_list[-1] - x_list[-2]) / x_list[-1])
        x_values.append(i)
        y_values.append(error)
        if error == 0:
            print(f'迭代第{i}次后,误差为0')
            break
    else:
        pass

print(f'所求方程式的根为{x_list[-1]}')

#设置绘图风格
plt.style.use('ggplot')
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
#坐标轴负号的处理
plt.rcParams['axes.unicode_minus']=False
#横坐标是迭代次数
#纵坐标是误差值
plt.plot(x_values,
         y_values,
         color = 'steelblue', # 折线颜色
         marker = 'o', # 折线图中添加圆点
         markersize = 1, # 点的大小
         )
# 修改x轴和y轴标签
plt.xlabel('迭代次数')
plt.ylabel('误差值')
# 显示图形
plt.show()

结果:

迭代第3402次后,误差为0
所求方程式的根为0.062377581513749114

在这里插入图片描述

对比牛顿迭代法,牛顿迭代法要快很多,而且准确率也高
牛顿迭代法(Newton’s Method)迭代求根的Python程序

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值