不动点迭代法计算三元一次方程及不同迭代函数对收敛性的影响
题:
用不动点迭代法求方程f(x)=x^3-2*x-1=0的根,按以下两种方案实现,分析迭代函数对收敛性的影响。要求输出每次的迭代结果并统计所用的迭代次数,取精度c=0.5*10^(-5),x0=2.
方案一:化方程为等价方程x=pow(2*x+1,1.0/3)=g(x)
方案二:化方程为等价方程x=(x^3-1)/2
程序流程图:(流程图出自计算方法——江西高校出版社)
方案一:
代码:
#include <iostream>
using namespace std;
#include<math.h>
#include<iomanip>
int main()
{
double x0=0, c = 0.5 * 1e-5,x1=2;
int i = 0;
cout <<setw(3)<< 'i' << setw(12) << "x0" << setw(12) << "x1" << endl;
for(i = 0; abs(x1 - x0) >= c;i++)//如果未满足精度要求
{
x0 = x1;
x1 = pow(2 * x0 + 1, 1.0 / 3);
cout << setw(3) << i << setiosflags(ios::fixed) << setprecision(6) << setw(12) << x0 << setw(12) << x1 << endl;
}
return 0;
}
书本中的方法分析:
对于二分法来说只要设置了精度,无论它是多小的一个数,不断地二分,区间也能很快收敛,程序就能在一定时间内结束;
而对于迭代法,程序可能不收敛,所以需要设置一个大迭代次数MAXREPT防止不停输出。
对于精度c,区间a和b,以及三次方根的函数均可是不变的,固定的,用宏定义,使程序可读性更好。
计算结果:
方案二:
代码:
#include <iostream>
using namespace std;
#include<iomanip>
#define MAXREPT 10//最大迭代次数
#define c 0.5e-5//精度
#define g(x) (x*x*x-1)/2
void main()
{
double x0 = 2,x1=2;
int i = 0;
cout << setw(3) << 'i' << setw(12) << "x0" << setw(12) << "x1" << endl;
for (i = 0; i < MAXREPT; i++)//迭代10次
{
x0 = x1;
x1 = g(x0);
cout << setw(3) << i << cout.precision(5) << setw(12) << x0<<setw(12) << x1 << endl;
if (abs(x1 - x0) <= c)
{
break;
}
}
}
计算结果:
结果不收敛。可见对于不动点迭代法选取不同的g(x),收敛性不同。