第十九篇 牛顿拉普森求根
插值方法的一个缺点是需要在计算确实函数值的符号是变化的。外推法则没有这个问题,但这并不是说就可以避免收敛的问题。最广泛使用的外推方法通常被称为牛顿-拉夫森法。它的外推法的原理是基于函数在猜测值处的斜率
牛顿拉普森法
假设展开一个泰勒级数,关于一个单根xi猜想。关于x方向上的“小”步长,泰勒展开式为
在展开式中去掉高于f’(xi)的项,并假设xi+1是求解的根,即f(xi + h) = 0,上市可以写成
经过变换得到递推方程
在下图中有一个简单的图形解释。外推只是在选择在估计值xi处与函数相切。这种方法的新特点是需要计算函数的导数,有时候求导数是很困难的。然而,对于简单的代数表达式,如方程上面方程,微分很容易求得。
这种方法往往具有良好的收敛性,根据之前的经验,牛顿-拉夫森方法的收敛条件为在根附近
即
可以看出,如果f(x)变大或者f’(x()变得非常小,可能又会遇到相应的困难。如果最初的猜测恰好能得出f‘(x)≈0,切线将平行于x轴。在这种情况下,x的下一个估计值将远离根,并且收敛缓慢。
计算实例:
使用牛顿拉普森找下面函数在x=2附近的根
牛顿拉普森公式为
因此在这个例子中
可以把迭代过程的结果显示在下面的表中
这种情况下收敛速度是很快得。f(x)的列并不是完全需要得,因为递归公式仅根据xi来导出。
程序如下
分为一个主程序和一个检查收敛得子程序check,还有两个函数程序,分别求f(x)和f’(x)
#对于一个单根得牛顿拉普森法
import B
x0=1.2;tol=1e-5;limit=100
print('开始的猜测值',x0)
print('前几次迭代值')
iters=0
def f34(x):f34=x**3-x-1.0return f34
def f34dash(x):f34dash=3.0*x**2-1.0return f34dash
while(True):iters=iters+1x1=x0-f34(x0)/f34dash(x0)if B.check(x1,x0,tol)==True or iters==limit:breakx0=x1if iters<5:print(x1)
print('迭代到收敛的次数',iters)
print('解',x1)
check
def check(x1,x0,tol):check=not abs(x1-x0)/abs(x0)>tolreturn check
终端输出结果
程序结果与计算结果一致。