对于收敛的迭代过程,只要迭代足够多次,就可以使得结果达到任意精度,但有时迭代过程收敛缓慢,从而使计算量变得很大,因此对迭代过程加速的研究显得尤为重要。
设 x k x_{k} xk 是根 x ∗ x^{*} x∗ 的某个近似值,用迭代公式校正一次得
x ‾ k + 1 = φ ( x k ) \overline{x}_{k+1}=\varphi(x_{k}) xk+1=φ(xk)
假设 φ ′ ( x ) \varphi'(x) φ′(x) 在所考察得范围内改变不大,其估计值为 L,则有
x ∗ − x ‾ k + 1 ≈ L ( x ∗ − x k ) x^{*} - \overline{x}_{k+1} \approx L(x^{*}-x_{k}) x∗−xk+1≈L(x∗−xk)
由此解出 x ∗ x^{*} x∗ 得
x ∗ ≈ 1 1 − L x ‾ k + 1 − L 1 − L x k x^{*}\approx\frac{1}{1-L}\overline{x}_{k+1}-\frac{L}{1-L}x_{k} x∗≈1−L1xk+1−1−LLxk
也就是说,如果将迭代值 x ‾ k + 1 \overline{x}_{k+1} xk+1 与迭代初值 x k x_{k} xk 进行加权平均,可以期望所得到得解是比 x ‾ k + 1 \overline{x}_{k+1} xk+1 更好的近似根。
总的来说,通过给定估计值 L 的控制,对一次迭代值跟迭代初值进行加权平均,我们有理由相信加权后的解相比加权前的解可以是更好的近似根。
运行示例:
- 此为 未对迭代过程加速,找到符合精度要求的近似根,需要迭代 9 次。
- 此为加速迭代过程,估计值 L 取 0.2,迭代 4 次后找到符合精度要求的根。显然,加速的效果是显著的。
程序源码:
#include <iostream>
#include <cmath>
using namespace std;
/**
* 原函数 f(x) = (x+1)^(1/3)
*/
double f(double x)
{
return pow(x + 1, 1.0 / 3);
}
int main(void)
{
double x0;
cout << "请输入迭代初值:";
cin >> x0;
double accrucy;
cout << "请输入精度:";
cin >> accrucy;
int n;
cout << "请输入您想要的最大迭代次数:";
cin >> n;
double L;
cout << "请输入估计值 L:";
cin >> L;
double x2;
int count = 0;
do
{
double x1 = f(x0);
// 对迭代值 x1 与 x0 进行加权平均得到 x2
x2 = 1.0 / (1 - L) * x1 - L / (1 - L) * x0;
if (abs(x0 - x2) < accrucy)
{
cout << "近似解为:" << x2 << endl;
break;
}
// 继续下一次迭代,直至找到符合精度要求的根或最大迭代次数用完
cout << "第" << ++count << "次迭代!\t迭代函数的值为:" << x2 << "\t此次迭代精度为:" << abs(x2 - x0) << endl;
double item = x0;
x0 = x2;
x2 = item;
if (count > n)
{
cout << "迭代次数耗尽,迭代结束!未找到符合精度要求的根!!!" << endl;
break;
}
} while (abs(x0 - x2) >= accrucy);
return 0;
}