利用牛顿迭代法求平方根

数理介绍,不喜欢数学的言下之意也就是绝大部分人能够略过了。算法

简单推导

假设f(x)是关于X的函数:app

An illustration of one iteration of Newton's method

求出f(x)的一阶导,即斜率:函数

f'(x_{n}) = \frac{ \mathrm{rise} }{ \mathrm{run} } = \frac{ \mathrm{\Delta y} }{ \mathrm{\Delta x} } = \frac{ f( x_{n} ) - 0 }{ x_{n} - x_{n+1} } = \frac{0 - f(x_{n})}{(x_{n+1} - x_{n})}\,\!

简化等式获得:spa

 x_(n+1)=x_n-(f(x_n))/(f^'(x_n))

而后利用获得的最终式进行迭代运算直至求到一个比较精确的满意值,为何能够用迭代法呢?理由是中值定理(Intermediate Value Theorem):3d

若是f函数在闭区间[a,b]内连续,必存在一点x使得f(x) = cc是函数f在闭区间[a,b]内的一点code

咱们先猜想一X初始值,例如1,固然地球人都知道除了1自己以外任何数的平方根都不会是1。而后代入初始值,经过迭代运算不断推动,逐步靠近精确值,直到获得咱们主观认为比较满意的值为止。例如要求768的平方根,由于252 = 625,而302 = 900,咱们可先代入一猜想值26,而后迭代运算,获得较精确值:27.7128。blog

回到咱们最开始的那个”莫名其妙”的公式,咱们要求的是N的平方根,令x2 = n,假设一关于X的函数f(x)为:ci

f(X) = X2 - nrem

f(X)的一阶导为:get

f'(X) = 2X

代入前面求到的最终式中:

Xk+1 = Xk - (Xk2 - n)/2Xk

化简即获得咱们最初提到的那个求平方根的神奇公式了:

 x_(k+1)=1/2(x_k+n/(x_k))

用泰勒公式推导

我以前介绍过在The Art and Science of C一书中有用到泰勒公式求平方根的算法,其实牛顿迭代法也能够看做是泰勒公式(Taylor Series)的简化,先回顾下泰勒公式:

f(x_0+epsilon)=f(x_0)+f^'(x_0)epsilon+1/2f^('')(x_0)epsilon^2+....

仅保留等式右边前两项:

f(x_0+epsilon) approx f(x_0)+f^'(x_0)epsilon.

f(X0+ε) = 0,获得:

epsilon_0=-(f(x_0))/(f^'(x_0))

再令X1 = X0 + ε0,获得ε1…依此类推可知:

epsilon_n=-(f(x_n))/(f^'(x_n))

转化为:

 x_(n+1)=x_n-(f(x_n))/(f^'(x_n))

引伸

从推导来看,其实牛顿迭代法不只能够用来求平方根,还能够求立方根,甚至更复杂的运算。

一样,咱们还能够利用C语言来实现下那个最简单的求平方根的公式(尽管咱们能够直接用sqrt()完成)

#include <stdio.h>
#include <math.h>
#define N 768
main() {
float x=1;
int i;
for (i=1;i<=1000;i++) {  // recursion times : 1000
x = (x + N/x)/2;
}
printf("The square root of %d is %f\n",N,x);
}
相关文章
相关标签/搜索