以前困惑于求各种根式求值,现在学了牛顿迭代法,下次再求根式我就直接手撕根号了。
铺垫
现在让你求 是多少?硬算的话肯定不行,估算大概是在附近,现在画出的函数图像,再标记的位置:
在点(9,3)做切线,明显看出和在点(9,3)重合,两条线十分接近点 ,两条线之间的间隔就是估算的误差,算出切线在x=11时的函数值,就是的近似解。
因为求该点切线需要用到该点的斜率,我们先求导算出斜率:
将斜率带入切线方程:
将x=11带入切线方程
所以近似的等于,事实上,你可以使用计算器去校验一下, 由计算器求得的结果是3.317(精确到小数点后第3位),所以我们的计算结果是非常不错的。
牛顿迭代法
在求一个复杂的方程的时候,想简单的估算一下,就可以按照下面的方法做:
在上任意选一个x=a,作其切线。函数在a点的函数值并不等于零,可以说是x=a个近似解,但误差太大了,我们要让函数值等于0。往左可以看到x=b时,f(b)的函数值更接近0了,这时b这个近似解比a误差更小,我们先把b这个点算出来,怎么求b的值呢?
b点是切线方程L在x轴上的截距,令切线方程中的,即可求出x轴的截距。
所以下一个点的点b计算公式:
算出点b的点之后继续将b带入f(x)中试试点b的函数值有没有更趋近于0,继续作点b的切线重复第一步,循环往复,最终求出来的值b是个比之前更好的近似解。
代码实现
import math
# 求导
def numerical_diff(f, x):
h = 1e-10
return (f(x + h) - f(x)) / h
# 牛顿迭代法实现
def solution(a, f):
b = 0
Delta = 1
while Delta > 0.000001:
b = a - f(a) / numerical_diff(f, a)
Delta = f(b)
a = b
return b
def fun1(x):
return x ** 5 + 2 * x - 1
def fun2(x):
return x - math.cos(x)
fun1_ret = solution(0, fun1)
print("x**5+2*x-1 的近似解为:", fun1_ret)
fun2_ret = solution(math.pi / 2, fun2)
print("x-cos(x) 的近似解为:", fun2_ret)
# output:
# x**5+2*x-1 的近似解为: 0.48638904079265016
# x-cos(x) 的近似解为: 0.7390851781433039
- 参考资料:《普林斯顿微积分读本》