牛顿迭代法是一种数值算法,能够用于求函数的零点。其思想在于把函数抽象为直线,一步步用估计逼近函数的零点。ios
其逼近速度很是有效,经常在十几步迭代内就能求得很是精确的结果,十分高效。算法
考虑在以下坐标系\(xOy\)中的一条直线:函数
其值在\(x=x_0\)时取值为\(y_0\)。那么这条直线与\(x\)轴的交点的\(x\)坐标\(A\)为多少?spa
设这条直线的解析式为\(y=kx+b\),则有
\[ y_0=kx_0+b \]3d
即
\[ b=y_0-kx_0 \]code
令\(y=0\),得方程
\[ kx+y_0-kx_0=0 \]blog
解得
\[ x=\frac{kx_0-y_0}{k} \]io
即class
\[ x=x_0-\frac{y_0}{k} \]stream
咱们正式开始使用牛顿迭代法求函数\(f(x)\)的零点。
问题:试求\(\sqrt{2}\)的近似值。
原命题等价于求函数\(f(x)=x^2-2\)的零点。
首先咱们随便猜想一个值。不妨设为\(x=4\)吧。
过\((x,f(x))\)点做\(f(x)\)的切线,获得:
根据导数的几何意义,这条直线的斜率为\(f'(x)\),则根据咱们前面获得的结论,这个函数与\(x\)轴的交点的\(x\)坐标为
\[ x'=x-\frac{f(x)}{f'(x)} \]
根据最理想的估计,若是导数不变的话,零点应该就在那个位置。那么咱们令\(x=x'\),这称为一次迭代。
回到例子。\(f(x)=x^2-2\),则\(f'(x)=2x\),则有:
\[ x'=x-\frac{f(x)}{f'(x)}=x-\frac{x^2-2}{2x}=\frac{x}{2}+\frac{1}{x} \]
每次用\(\frac{x}{2}+\frac{1}{x}\)替代\(x\),重复以上过程:
能够看到,仅仅进行了六次迭代,就获得了\(20\)位的精确值。
程序以下:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; const double eps=1e-10; double a,x; double f(double x){return x*x-a;} double df(double x){return 2*x;} int main(){ scanf("%lf",&a); x=1; while(fabs(f(x))>=eps)x-=f(x)/df(x); printf("%.10lf\n",x); }