起源
前两天为解三次方程时套了盛金公式,然而公式内部存在立方根的求解。
抛开大常数的 STL,我们还有什么方法来求开根的精确值呢?(当然三次以上的开根就没有 STL 了。)
牛顿迭代法横空出世。
前置数学知识
求偏导法求曲线在某点处的切线。
首先我们要了解导数的定义。
导数,又称“瞬时变化率”,是描述某个变量在极短时间内变化率的名词。
所以我们可以用导数描述曲线上一点在横坐标变化极小,可忽略不计时纵坐标的变化率,也即这一点的切线斜率。
根据定义,函数
f(x) 在点
(x0,f(x0)) 处的导数为
f′(x0)=Δx→0limΔxf(Δx+x0)−f(x0)。
再套用直线的点斜式即可得出切线方程
y=f′(x0)(x−x0)+f(x0)。
这里我们要用到的是多项式函数的导数。
前置算法知识
牛顿迭代法:通过对函数进行不断求导,从而不断逼近一个方程的精确解的算法。
具体操作如下:
然后我们计算函数在点
(x0,f(x0)) 处的切线。
套用上面的公式即得切线方程为
y=f′(x0)(x−x0)+f(x0)。
计算切线与 x 轴交点的横坐标。
将
y 赋值为
0 有
f′(x0)(x−x0)+f(x0)=0,解得
x=f′(x0)x0f′(x0)−f(x0)=x0−f′(x0)f(x0),我们记为
x1。
接下来不断重复
xi+1=xi−f′(xi)f(xi) 这一步骤,即可得到
f(x)=0 的精确解。
实现
我们构造函数
f(x)=xm−n,其中
n 为待开方数,
m 为开根的次数,则此方程的解即为
mn。
那么我们就需要对
f(x) 求导。
套定义有:
f′(x)=Δx→0limΔx(x+Δx)m−n−(xm−n)
=Δx→0limΔx(x+Δx)m−xm
=Δx→0limΔxxm+mxm−1Δx+⋯−xm
=Δx→0limΔxmxm−1Δx+⋯+(Δx)m
=Δ→0lim(mxm−1+⋯+(Δx)m−1)=mxm−1
代入牛顿迭代法公式得
xi+1=xi−mxim−1xim−n,多次迭代即可。
此外,牛顿迭代法还有着精度高的优点。
牛顿迭代法的收敛率是平方级别的,这意味着每次迭代后近似解的精确数位会翻倍。 ——OI WiKi
因而我们在求解高精度开根时也可以用到它。