什么是牛顿 - 拉夫逊方法?
牛顿其人:Isaac Newton(1642 年 12 月 25 日– 1727 年 3 月 20 日)是一位英国数学家,物理学家,天文学家,神学家和作家,被公认为有史以来最有影响力的科学家之一,并且是科学革命的关键人物。他的书《自然哲学的数学原理》于 1687 年首次出版,奠定了古典力学的基础。牛顿还为光学做出了开创性的贡献,并与戈特弗里德·威廉·莱布尼兹(Gottfried Wilhelm Leibniz)发展了无穷微积分的学科。
牛顿
拉弗森 Joseph Raphson 生卒不详,其最著名的著作是 1690 年出版的《通用分析方程》。它包含一种方法,现在称其为牛顿 - 拉夫森方法,用于近似方程式的求根。艾萨克·牛顿(Isaac Newton)在 1671 年写的《通量法》中开发了一个非常相似的公式,但是这项工作要到 1736 年才出版,这是拉夫森分析之后近 50 年。但是,该方法的 Raphson 版本比 Newton 方法更简单,因此通常被认为是更好的方法。
所以,牛顿迭代法(简写)就是一种近似求解实数域与复数域求解方程的数学方法。那么这个方法是具体是什么原理呢?
牛顿迭代如何迭代?
直接看数学公式描述如何迭代不直观,先来看动图就很容易理解牛顿迭代法为什么叫迭代法以及怎样迭代的:
啥时候停止迭代呢?
如何编码呢?
从图上大致可以知道有两个根,如果直接解方程,则很难求出其根,可以编个代码试试:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/*假定待求根函数如下*/
#define F(x) (2*(x)*(x)-10*cos(x)+(x)-80)
/*其一阶导数为*/
#define DF(x) (4*(x)+10*sin(x)+1)
float newton_rooting(float x0,float precision,float min_deltax,int max_iterations)
{
float xn,xn1,fn,fn1,dfn;
float deltax;
int step = 0;
xn = x0;
xn1 = x0;
do{
xn = xn1;
fn = F(xn);
dfn = DF(xn);
/*判 0*/
if( fabs(dfn) <1e-6 )
{
if( fabs(fn)>precision )
return NAN;
else
return fn;
}
xn1 = xn - fn/dfn;
fn1 = F(xn1);
deltax = fabs(xn1-xn);
step++;
if( step>max_iterations )
{
if( fabs(fn1)<precision )
return xn;
else
return NAN;
}
}
while( fabs(fn1)>precision || deltax>min_deltax );
return xn1;
}
void main()
{
float root_guess = 23.0f;
float precision = 0.00001f;
float min_deltax = 0.001f;
float root;
int step = 7;
root = newton_rooting( root_guess,precision,min_deltax,step );
printf("根为: %f,函数值为:%f\n", root,F(root));
root_guess = -23;
root = newton_rooting( root_guess,precision,min_deltax,step );
printf("根为: %f,函数值为:%f\n", root,F(root));
}
结果:
根为: 6.457232, 函数值为:0.000004
根为: -6.894969,函数值为:-0.000008
函数值已经很接近于 0 了,如果还需要更为精确的值,则可以选择在此基础上进一步求解,比如利用二分法逼近。
需要注意些啥?
有哪些应用?
总结一下
牛顿迭代法在解决实际问题时,利用迭代求方程近似根的数学原理,在工程中有着很好的实用价值。比如求一个趋势的极值,传递函数参数辨识等都有广泛的实际应用。本文抛砖引玉,有可能文章也有很多错误疏漏的地方,如有不同看法或者发现错误,欢迎留言交流指正。