作者:faaronzheng 转载请注明出处!
今天遇到一个题,不用库函数求立方根。网上有很多介绍了,就是使用牛顿迭代法进行近似计算。下面自己总结一下。
下面首先介绍一下牛顿迭代法:牛顿迭代法的核心思想是使用泰勒级数的线性项近似计算函数f(x)=0的根。把f(x)在点
x0
x
0
的某邻域内展开成泰勒级数,取其线性部分(即泰勒展开的前两项),并令其等于0,
即
f(x)+f′(x0)(x−x0)=0
f
(
x
)
+
f
′
(
x
0
)
(
x
−
x
0
)
=
0
,以此作为非线性方程 f(x)=0的近似方程,即切线方程(p.s. 其实就是两点式直线方程y-
y0
y
0
=k(x-
x0
x
0
)),若
f′(x)≠0
f
′
(
x
)
≠
0
,则其解为
x=x0−f(x)f′(x)
x
=
x
0
−
f
(
x
)
f
′
(
x
)
, j将其推广,得到牛顿迭代法的一个迭代关系式
xn+1=xn−f(xn)f′(xn)
x
n
+
1
=
x
n
−
f
(
x
n
)
f
′
(
x
n
)
。
通俗的讲,这个迭代过程先随机先一个初始点
x0
x
0
,过(
x0
x
0
,f(
x0
x
0
))做函数的切线,将切线和横坐标的切点做下一个点继续做切线,知道切线和函数的切点落在横坐标上。下面的动画可以形象的展示这一过程。
接下来我们的目标就是构造出f(x)=0,以求立方根为例,我们只要令
f(x)=
x3−n
x
3
−
n
就可以。剩下的就是将上面的想法编码实现:
public double f(double x, double num) // 函数
{
return x*x*x-num;
}
public double _f(double x) // 导函数
{
return 3*x*x;
}
public double getCubeRoot(double input)
{
double x=1;
do
{
x = x - f(x,input)/_f(x);
} while(f(x,input) > 0.00001 || f(x,input) < -0.00001);
return x;
}