平方根的计算(二分逼近、牛顿拉普生法)
来源:互联网 发布:淘宝神仿手办 编辑:程序博客网 时间:2024/04/29 15:49
在从二分逼近领略计算科学的魅力一文中,我们介绍了单调函数的求根公式(有零点),如
typedef double (*FuncPtr)(double);double root(double x1, double x2, FuncPtr f){ double x = (x1+x2)/2; while (abs(f(x)) > 1e-9) { // 1e-9:表示epsilon,一个小量 f(x) > 0 ? x2 = x : x1 = x; x = (x1+x2)/2; } return x;}template<int N>double f1(double x){ // 非类型模板参数仅限于常整数(包括 enum 枚举类型) //或者指向外部链接对象的指针 return x*x - N;}double f2(double x){ return 2*x*x+3.2*x-1.8}int main(int, char**){ std::cout << root(0, 5, f1<5>) << std::endl; // 5 的平方根 std::cout << root(-.8, .8, f2) << std::endl; // f(x)=2*x^2+3.2x-1.8 在区间 [-.8,.8] 内的零点 return 0;}
关于 C++ 模板编程的非类型模板参数,请参见 C++基础——非类型模板参数 。
是不是很完美,也不是,二分逼近求解实数的平方根时存在一个隐蔽的 bug,也即是要开平方的实数
double n = .25;double f3(double x){ return x**x-n;}int main(int, char**){ std::cout << root(0, n>1 ? n : 1, f3) << std::endl; return 0;}
牛顿拉普生方法
牛顿法(Newton’s method)又称为牛顿-拉弗森方法(Newton-Raphson method),它是一种在实数域和复数域上近似求解方程的方法。方法使用函数
f(x) 的泰勒级数的前面几项来寻找方程f(x)=0 的根。该法效率极高,应用极广,并不限于求解实数的平方根,相反求解实数的平方根只是其一个具体的应用而已。
接下来我们介绍一个更具效率的平方根的计算方法,即为牛顿拉普生方法(Newton-Raphson method)。
方法说明:
首先,选择一个接近函数
我们将新求得的点的x坐标命名为
已经证明,如果
对于求解实数平方根的函数
double newton(double x, FuncPtr f){ while (abs(f(x))>1e-9) x -= f(x)/(2*x); return x;}double f(doubel x){ return x*x-.25;}int main(int, char**){ std::cout << newton(1., f) << std::endl; return 0;}
牛顿拉普生方法的一个应用
求解如下方程的根:
我们令
double f(double x){ return cos(x)-x*x*x;}double f_prime(double x){ return -sin(x)-3*x*x;}double newton(double x, FuncPtr f){ while (abs(f(x)) > 1e-9) { x -= f(x)/f_prime(x); std::cout << x << std::endl; } return x;}int main(int, char**){ std::cout << newton2(.5, f) << std::endl; return 0;}
References
[1] 牛顿法
- 平方根的计算(二分逼近、牛顿拉普生法)
- 牛顿逼近法求平方根
- 计算平方根(牛顿迭代法)
- 牛顿迭代法计算平方根
- sqart平方根计算的两种方法实现(累加逼近和二分法)
- 牛顿二项式定理计算平方根
- 牛顿法计算平方根-Python
- 二分查找计算平方根
- 牛顿迭代公式计算平方根立方根
- 从二分逼近领略计算科学的魅力
- 用牛顿迭代法求浮点数的平方根(博客)
- 牛顿迭代法求n的平方根
- 牛顿迭代求一个数的平方根
- 牛顿迭代法求数的平方根
- 牛顿迭代法求数的平方根
- 牛顿迭代法输出n的平方根
- 计算平方根的算法
- 计算平方根的算法
- web存储
- 深入浅出学Spring Data JPA
- 递归:汉诺塔
- Android 5.0 Camera (5): take picture
- Android6.0 按键流程(七)无线鼠标右键无效 -- Framework层
- 平方根的计算(二分逼近、牛顿拉普生法)
- Leetcode(2) -Contains Duplicate
- 离线缓存
- 2016年计划
- Android 5.0 Camera (6): record video
- Android开发学习之路--Notification之初体验
- 在SpringMVC中使用Jackson并格式化时间
- ios设置图片的拉伸区域
- (转)JOptionPane类提示框的一些常用的方法