
实验目标
使用编程语言实现以下算法:
1. 使用 复化梯形公式 的 自动控制误差 算法;
2. 使用 龙贝格积分 算法。
实现某个区间 [a, b] 上的积分:$I=\int_a^b{f\left( x \right) dx}$
编程语言与扩展库
编程语言:C++ 语言
IDE 环境:Visual Studio 2017
扩展库:Eigen 库

在项目名称处 右键 >> 属性 >> VC++目录 >> 包含目录 >> 选择 Eigen 模块所在文件夹路径,导入模块;
Eigen 资源文件可以在 Eigen 官网上进行下载。
实现代码
复化梯形积分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
void Trapezoid(double a, double b, double w) { double h = b - a; double T1, T2, S; double x; int k = 0; T1 = 0.5*h*(f(a) + f(b));
while (true) { cout << "T" << pow(2, k) << " = " << T1 << endl;
x = a + 0.5*h; S = 0;
while (x < b) { S += f(x); x += h; }
T2 = 0.5*T1 + 0.5*h*S;
if (abs(T2 - T1) < w) break; else { h = 0.5*h; T1 = T2; k++; } }
cout << endl << "最终计算结果:" << endl << "T = " << T2 << endl; }
|
计算公式:
算法流程图:

龙贝格算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
void Romberg(double a, double b, double w) { double h = b - a; double S, x; int k = 1;
double T1, T2; double S1, S2; double C1, C2; double R1, R2;
T1 = 0.5*h*(f(a) + f(b)); cout << "T1 = " << T1 << endl;
while (true) { x = a + 0.5*h; S = 0;
while (x < b) { S += f(x); x += h; }
T2 = 0.5*T1 + 0.5*h*S; cout << "T" << pow(2, k) << " = " << T2 << endl;
S2 = T2 + (T2 - T1) / 3; cout << "S" << pow(2, k - 1) << " = " << S2 << endl;
if (k == 1) { k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { C2 = S2 + (S2 - S2) / 15; cout << "C" << pow(2, k - 2) << " = " << C2 << endl;
if (k == 2) { C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { R2 = C2 + (C2 - C1) / 63; cout << "R" << pow(2, k - 3) << " = " << R2 << endl;
if (k == 3) { R1 = R2; C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { if (abs(R2 - R1) < w) break; else { R1 = R2; C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } } } } }
cout << endl << "最终计算结果:" << endl << "R = " << R2 << endl; }
|
算法流程图:

源代码整合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| #include <Eigen/Dense> #include <iostream> #include <fstream> #include <vector> #include <cmath>
using namespace Eigen; using namespace std;
double f(double x) { if (x == 0) return 1; else return sin(x) / x; }
void Trapezoid(double a, double b, double w) { double h = b - a; double T1, T2, S; double x; int k = 0; T1 = 0.5*h*(f(a) + f(b));
while (true) { cout << "T" << pow(2, k) << " = " << T1 << endl;
x = a + 0.5*h; S = 0;
while (x < b) { S += f(x); x += h; }
T2 = 0.5*T1 + 0.5*h*S;
if (abs(T2 - T1) < w) break; else { h = 0.5*h; T1 = T2; k++; } }
cout << endl << "最终计算结果:" << endl << "T = " << T2 << endl; }
void Romberg(double a, double b, double w) { double h = b - a; double S, x; int k = 1;
double T1, T2; double S1, S2; double C1, C2; double R1, R2;
T1 = 0.5*h*(f(a) + f(b)); cout << "T1 = " << T1 << endl;
while (true) { x = a + 0.5*h; S = 0;
while (x < b) { S += f(x); x += h; }
T2 = 0.5*T1 + 0.5*h*S; cout << "T" << pow(2, k) << " = " << T2 << endl;
S2 = T2 + (T2 - T1) / 3; cout << "S" << pow(2, k - 1) << " = " << S2 << endl;
if (k == 1) { k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { C2 = S2 + (S2 - S2) / 15; cout << "C" << pow(2, k - 2) << " = " << C2 << endl;
if (k == 2) { C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { R2 = C2 + (C2 - C1) / 63; cout << "R" << pow(2, k - 3) << " = " << R2 << endl;
if (k == 3) { R1 = R2; C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } else { if (abs(R2 - R1) < w) break; else { R1 = R2; C1 = C2; k += 1; h = 0.5*h; T1 = T2; S1 = S2; } } } } }
cout << endl << "最终计算结果:" << endl << "R = " << R2 << endl; }
int main() { cout << endl << "复化梯形算法:" << endl; Trapezoid(0, 1, 1e-6);
cout << endl << "龙贝格算法:" << endl; Romberg(0, 1, 1e-6);
return 0; }
|
运行结果
程序选择 $f\left( x \right) =\sin \left( x \right) /x$ 作为积分函数,计算其 $\left[ 0,\ 1 \right]$ 上的积分值。
写在最后
声明:本专栏内容来源于武汉理工大学 2019-2020 学年数值分析方法课程实验,仅供学习参考。
如有错误或不足地方,还请指出,祝愿读者能够在编程之路上不断进步!