sqrt函数实现(神奇的算法)写的狠好,但是对于牛顿迭代法的数学解释不是很清晰,我就研究了一下
-
首先要说切线是曲线的线性逼近,怎么理解请看下图
下图是 f(x)=x² 的图像
随便选一点A,做它对于f(x)的切线
可以看出在点A附近,切线与f(x)非常接近
因为切线是一条直线(也就是线性的),所以我们可以说,A点的切线是f(x)的线性逼近。离A点距离越近,这种逼近的效果也就越好,也就是说,切线与曲线之间的误差越小。所以我们可以说在A点附近“ 切线≈f(x) ”。 -
牛顿迭代法:既然切线可以近似于曲线,就研究切线的根,来不断逼近曲线的根
如果想研究任意曲线f(x)的切线的根如何逼近f(x)的根,请看这篇文章牛顿迭代法求平方根(通俗易懂版)
sqrt(a),就是求√a ,就是求 x²=a 的解,也就是 f(x)=x²-a=0 的根。让我们用切线的根来逼近f(x)的根。
- 红色的点是f(x)的根
- 先随便在f(x)上取一点(蓝点),横坐标为Xn,之后作这点关于f(x)的切线,切线交x轴于一点,横坐标为Xn+1
- 在此交点作平行于y轴的直线,交于f(x)于(黄点),横坐标为Xn+1,这就是完成了一次迭代。发现Xn+1较Xn离红点更近
- 按照上述步骤,再作切线,发现这次切线与x轴的交点离红点更更近,这个横坐标就是Xn+2
- 如何求Xn+1与Xn的关系呢?
第一个蓝点的坐标为 (Xn,f(Xn)) ,该点的切线方程为 y-f(Xn)=f '(Xn)(x-Xn) ,
切线与x轴的交点为,令y=0,也就是 f '(Xn)(x-Xn)+f(Xn)=0
- 之后就明白了,求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次就很精确了。就是很神奇,第一个Xn的值,都可以随便猜的,不论是什么值,迭代六七次后就很准
float SqrtByNewton(float a)
{
x=a/2 # Xn取a的一半,随便取的啦
for i in range(10): # 时间复杂度O(n)
x=(x+a/x)/2
return x
}