牛顿迭代
牛頓迭代法(Newton's method)
又叫“牛頓-拉弗森方法”(Newton-Raphson method),它是一種在實(shí)數(shù)域和復(fù)數(shù)域上近似求解方程的方法,方法是使用f(x)泰勒級(jí)數(shù)前幾項(xiàng)來(lái)尋找f(y) = 0的根。
原理
對(duì)于非線性方程同樣適用
總之,牛頓迭代公式:
應(yīng)用
求某些方程的根
1 double a, b, c, d;
2 const double esp = 1e-6;
3
4 double f(double x){
5 return a * x * x * x + b * x * x + c * x + d;
6 }
7
8 double fd(double x){
9 return 3 * a * x *x + 2 * b * x + c;
10 }
11
12 //求解ax^3 + bx^2 + cx + d = 0的一個(gè)根
13 double newton(double x)
14 {
15 while (fabs(f(x)) > esp){x = x - f(x) / fd(x);}
16 return x;
17 }
如果想求出一個(gè)范圍內(nèi)的所有的跟,則可以在該范圍內(nèi)枚舉初始值x,來(lái)逼近根的值。
1 #include<stdio.h>
2 #include<iostream>
3 #include<vector>
4 using namespace std;
5
6 double a, b, c,d;
7 const int INF = 0x3f3f3f3f;
8 const int maxn = 2;
9 const double esp = 1e-6;
10 double Abs(double x)
11 {
12 return x >= 0 ? x : -x;
13 }
14 double f(double x)
15 {
16 return a * x * x * x + b * x * x + c * x + d;
17 }
18
19 //需要f的導(dǎo)數(shù)在適當(dāng)?shù)膮^(qū)間內(nèi)絕對(duì)值不大于于某個(gè)小于1的正數(shù)
20 double fd(double x)
21 {
22 return 3 * a * x *x + 2 * b * x + c;
23 }
24
25 //求解ax^3 + bx^2 + cx + d = 0的所有根
26 void newton()
27 {
28 vector<double>ans;
29 //在一個(gè)大區(qū)域中逐個(gè)點(diǎn)用牛頓法,可找出大多數(shù)3次方程所有根
30 for (int x0 = -maxn; x0 < maxn; x0++)
31 {
32 double x1 = x0;
33 int cnt = 0; //迭代次數(shù)
34 while (Abs(f(x1)) > esp)
35 {
36 if ((++cnt) > 10000) break; //迭代次數(shù)超過(guò)1000,認(rèn)為方程無(wú)解
37 double x = x1;
38 x1 = x - f(x) / fd(x);
39 }
40 if (cnt > 10000) continue;
41 int flag = 0;
42 for(int i = 0;i < ans.size();i++)
43 if (Abs(ans[i] - x1) < 0.01)
44 {
45 flag = 1;
46 break;
47 }
48 if (!flag && x1 < INF && x1 > -INF) ans.push_back(x1); //x1==inf || -inf是在極值點(diǎn),并不一定是方程的根
49 }
50 if (ans.size() == 0) printf("無(wú)解
");
51 else
52 {
53 for (int i = 0; i < ans.size(); i++)
54 printf("%lf ", ans[i]);
55 printf("
");
56 }
57 }
58
59 int main()
60 {
61 while (scanf("%lf%lf%lf%lf",&a,&b,&c,&d) == 4)
62 newton();
63
64 return 0;
65 }
View Code
(這個(gè)代碼測(cè)試起來(lái)有很多錯(cuò)誤,有好的意見(jiàn)歡迎留言)
高精度開(kāi)根號(hào)
對(duì)于一個(gè)已知的數(shù) a,開(kāi)根號(hào)本質(zhì)上是求一個(gè)X,使得 X2=a,即X2 - a = 0的根。
由前面易知迭代公式Xn+1 = Xn - (Xn2 - a) / 2Xn = (Xn + a / Xn) / 2。
實(shí)際操作還需要套一個(gè)高精度除法。
缺點(diǎn)
并不能求解所有方程的根,而且得到的只是近似值,不是準(zhǔn)確值。
收斂的充分條件:
若 f 二階可導(dǎo),那么在待求的零點(diǎn) x 周圍存在一個(gè)區(qū)域,只要起始點(diǎn) x0 位于這個(gè)臨近區(qū)域內(nèi),那么牛頓-拉弗森方法必定收斂。
駐點(diǎn)
從代數(shù)上看,導(dǎo)數(shù)為0,無(wú)法迭代出下一個(gè)值。
越來(lái)越遠(yuǎn)的不收斂
循環(huán)震蕩的不收斂
參考鏈接:
https://blog.csdn.net/wubaizhe/article/details/75574798
https://baike.baidu.com/item/牛頓迭代法/10887580?fr=aladdin
https://zh.wikipedia.org/wiki/牛頓法
https://www.zhihu.com/question/20690553
總結(jié)
- 上一篇: Google Mesa概览
- 下一篇: 史诗级升级!iPhone支持Siri操作