由梯形算法可以推得:
,这里h为2n个区间的步长,即h = (b - a) / 2n;
如果有2^n个相同的子区间,则上式变为:
,这里hn为2^n个区间的步长,即hn = (b - a) / 2^n;
所以,对于Romberg算法,可以采用如下公式计算:
,
伪代码:
input a, b, M
h ← b - a
for n = 1 to M do
h ← h / 2
for m = 1 to n do
end do
end do
output R(n,m) (0 ≤ n ≤ M, 0 ≤ m ≤ n)
(算法详细说明可参考《数值分析(原书第3版)》,(美)David Kincaid, Ward Cheney著,王国荣、俞耀明、徐兆亮译,机械工业出版社,2005年9月第1版,第400到402页。)
编程环境为VS 2005。源代码文件为“上交用_7.cpp”。
依据2.1中的伪代码编程,并添加了误差判断条件,当|R[n][m]-R[n-1][m]| <= e(e为指定误差)时,程序结束。
//ROMBERG求定积分
#include "stdafx.h"
#include <iostream>
#include <complex>
//exp(const complex& _ComplexNum)函数
#include //使用三角函数及log函数
const int M = 10;//用于指定ROMBERG函数中二维数组的长度
double ROMBERG(double a, double b, double e);
double f(double x);
int main()
{
using namespace std;
cout << "Romberg积分结果为: " << ROMBERG(0, 1, 0.00001) << endl;
return 0;
}
double f(double x)
{
return (4.0 / (1 + x * x));
}
double ROMBERG(double a, double b, double e)
{
double R[M][M] = {0};
double h = b - a;//步长
double temp;//
R[0][0] = h * (f(a) + f(b)) / 2;
for(int n = 1; n < M; n++)
{
h /= 2;
temp = 0;
for(int i = 1; i <= pow(2.0,n-1); i++)
temp += f( a + ( 2 * i - 1 ) * h );
R[n][0] = R[n-1][0] / 2 + h * temp;
for(int m = 1; m < 4; m++)//只求到第四列
{
R[n][m] = R[n][m-1] + ( R[n][m-1] - R[n-1][m-1] ) / ( pow(4.0,m) - 1 );
//判断误差
if( n>=4 && m==3 )
if(fabs(R[n][m]-R[n-1][m]) <= e)
{
//输出结果
for(int i = 0; i <= 3; i++)
{
for(int j = i; j <= n; j++)
std::cout << "R[" << j << "][" << i << "] = " << R[j][i] << std::endl;
std::cout << std ::endl;
}
return R[n][3];
}
}
}
return R[M][3];
}
R[0][0] = 0.920735
R[1][0] = 0.939793
R[2][0] = 0.944514
R[3][0] = 0.945691
R[4][0] = 0.945985
R[1][1] = 0.946146
R[2][1] = 0.946087
R[3][1] = 0.946083
R[4][1] = 0.946083
R[2][2] = 0.946083
R[3][2] = 0.946083
R[4][2] = 0.946083
R[3][3] = 0.946083
R[4][3] = 0.946083
Romberg积分结果为: 0.946083
请按任意键继续. . .