梯型法
为逼近, 用
.
各y是f在分点
的函数值,其中.
例1. 使用n = 4时的梯型法估计, 比较估计值和精确值.
x和y值如下:
序号 | x | y |
---|---|---|
0 | 1 | 1 |
1 | 1.25 | 1.5625 |
2 | 1.5 | 2.25 |
3 | 1.75 | 3.0625 |
4 | 2 | 4 |
我们有
积分精确值是:
两者相对误差为0.446%
梯形法用程序实现比较方便, C++实现如下:
#include <iostream>
using namespace std;
double integrate(std::function<double(double)> f, double a, double b, int n) {
double h = (b - a) / n, sum = 0, x = a;
for (int i = 0; i <= n; ++i) {
x = a + i * h;
if (i == 0 || i == n) sum += f(x);
else sum += 2 * f(x);
}
return sum * h / 2;
}
int main(int argc, const char * argv[]) {
auto f = [](double x) { return x * x; };
cout << integrate(f, 1, 2, 4) << endl;
return 0;
}
梯形法的误差估计
如果连续且M是的值在上的一个上界,则
, 其中.
例2. 用n=10步长时的体形法估计时带来的误差的上界。
对于和
.
则
.
Simpson法
为逼近, 用
.
各y是f在分点
.
Simpson法的误差估计
若连续,而M是在[a, b] 上的一个上界, 则
.
其中h = (b - a) / n.
例4 用n = 4时的Simpson逼近, 并计算误差。
序号 | x | y |
---|---|---|
0 | 0 | 0 |
1 | 0.5 | 0.3125 |
2 | 1 | 5 |
3 | 1.5 | 25.3125 |
4 | 2 | 80 |
则
则
用C++实现Simpson法的代码如下:
#include <iostream>
#include <math.h>
using namespace std;
double integrate(std::function<double(double)> f, double a, double b, int n) {
double h = (b - a) / n, sum = 0, x = a;
for (int i = 0; i <= n; ++i) {
x = a + i * h;
if (i == 0 || i == n) sum += f(x);
else sum += (i % 2 ? 4 : 2) * f(x);
}
return sum * h / 3;
}
int main(int argc, const char * argv[]) {
auto f = [](double x) { return 5 * pow(x, 4); };
cout << integrate(f, 0, 2, 4) << endl;
return 0;
}
例5 比较梯形法和Simpton法逼近
ln2可以由公式 计算,分别用梯形法和Simpton法计算。
用C++代码计算方法如下:
#include <iostream>
#include <math.h>
using namespace std;
enum IntegrateMethod {
Trapezoid,
Simpton
};
double integrate(std::function<double(double)> f, double a, double b, int n, IntegrateMethod method) {
double h = (b - a) / n, sum = 0, x = a;
for (int i = 0; i <= n; ++i) {
x = a + i * h;
if (i == 0 || i == n) sum += f(x);
else {
if (method == Simpton) {
sum += (i % 2 ? 4 : 2) * f(x);
} else {
sum += 2 * f(x);
}
}
}
return sum * h / (method == Simpton ? 3 : 2);
}
int main(int argc, const char * argv[]) {
auto f = [](double x) { return 1 / x; };
cout << integrate(f, 1, 2, 100, Trapezoid) << endl;
cout << integrate(f, 1, 2, 100, Simpton) << endl;
return 0;
}