Python | 牛顿法解一元方程
Posted 算法与编程之美
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python | 牛顿法解一元方程相关的知识,希望对你有一定的参考价值。
本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。
问题描述
在日常生活中面对一元一次方程、一元二次方程甚至是一元三次方程时,我们都可以应用所学的数学知识比如因式分解和求根公式去将其轻易地解开。但并不是所有的方程都能进行因式分解或有求根公式又或者是求根公式复杂,这些问题都导致我们解方程时求解困难,形如x-cos(x)=0、e^x * sin(x)-cos(x)=0、x^4–2x^2+x=0等超越方程和高次方程我们人工计算就无法求得其解。
解决方案
我们可以应用牛顿法解决上述问题。牛顿法又称切线法,简单来说就是不断求函数图像的切线与x轴的交点,来逐渐接近函数解的一个迭代过程,其核心思想就是不断地逼近函数的解。
牛顿法的步骤如下:
.选取一个初始迭代点,如‘1’;
.根据公式求出下一个接近零点的点;
③重复步骤②直到满足:
1). (eps为人设的精度要求)
2).达到最大迭代次数
牛顿法的原理如图:
通过上图我们可以发现,每迭代一次的值都将更接近方程的解。
接下来我们用Python代码来实现牛顿法并求方程的解:
from sympy import * # 定义方程 def function(): x = symbols('x') # 符号变量的定义 fx = -exp(x) * sin(x) + cos(x) - 1 return fx
# 求解方程的一阶导数 def diff_funtion(): fh = function() dth = fh.diff() return dth # 定义牛顿法 def Newton(x0,eps,maxiter): # x1 = x0 - f(x0)/f`(x0) ==> x2 = x1 - f(x1)/f`(x1) x = symbols('x') # 符号变量的定义 fh = function() #方程 dfh = diff_funtion() #方程一阶导 x_n = x0 # x_next代表x(n+1)
print('%5s %14s %23s' %('迭代次数','计算结果','误差')) #利用牛顿法逐渐逼近精确解 for k in range(maxiter): x_b = x_n # x_before代表x(n) fx = fh.evalf(subs = {x:x_b}) # 方程在xn处的数值 dfx = dfh.evalf(subs = {x:x_b}) # 方程的一阶导在xn处的数值 x_n = x_b - fx/dfx errval = abs(fh.evalf(subs = {x:x_n})) #第k次迭代误差大小
# 输出迭代过程 print('%5d %25.15f %25.15f' % (k+1,x_n,errval)) # 如果误差小于给定的精度要求,则退出 if errval < eps: break if k+1 <= maxiter-1: print('方程在满足精度' + str(eps) + '的条件下,近似解为:' + str(x_n) + ',误差是:' + str(errval)) else: print('牛顿迭代法求解数值逼近,已达到最大迭代次数,可能不收敛或精度过高...')
fh = function() plot(fh) #画出函数图像
x0 = float(input('请输入迭代初始值:')) eps = float(input('请输入方程解的精度要求:')) maxiter = int(input('请输入最大迭代次数:')) Newton(x0,eps,maxiter) |
运行结果如下:
用plot()画出函数图像方便选择迭代初始点
结语
这里简单介绍了牛顿法,其本质是函数泰勒展开后,取一阶来近似,即用线性函数近似f(x),毕竟线性函数更好算。应用牛顿法我们几乎可以求解所有方程的近似解,而且精度极高。但通过上诉求方程-e^x*sin(x)+cos(x)-1=0的解我们可以看到牛顿法不能一次性求出所有的解,即当方程有多个解时,选择不同的初始迭代点得到方程的解就不同。
作者:唐雷清
实习编辑:李欣容
稿件来源:深度学习与文旅应用实验室(DLETA)
以上是关于Python | 牛顿法解一元方程的主要内容,如果未能解决你的问题,请参考以下文章