定积分数值解法:梯形法、矩形法、辛普森法

定积分的数值解法是通过近似方法计算积分值,适用于无法直接求解或解析解复杂的情况。以下是三种常见的数值积分方法:梯形法、矩形法和辛普森法。它们的基本思想是将积分区间划分为若干小区间,并用简单的几何形状(如矩形、梯形或抛物线)近似函数曲线下的面积。

梯形法

  1. 基本思想:
    将积分区间[a,b][a,b][a,b]分成nnn个小区间,每个小区间的长度为Δx=b−an\Delta x = \frac{b - a}{n}Δx=nb−a​。把每个小区间上的曲边梯形近似看成梯形,通过计算这些梯形面积的和来近似定积分的值。

  2. 计算公式:

∫abf(x)dx≈Δx2[f(x0)+2f(x1)+2f(x2)+⋯+2f(xn−1)+f(xn)]\int_{a}^{b}f(x)dx \approx \frac{\Delta x}{2}\left[f(x_0) + 2f(x_1) + 2f(x_2) + \cdots + 2f(x_{n - 1}) + f(x_n)\right]∫ab​f(x)dx≈2Δx​[f(x0​)+2f(x1​)+2f(x2​)+⋯+2f(xn−1​)+f(xn​)]
其中xi=a+iΔxx_i = a + i\Delta xxi​=a+iΔx,i=0,1,⋯ ,ni = 0,1,\cdots,ni=0,1,⋯,n。

矩形法

  1. 基本思想:
    同样将积分区间[a,b][a,b][a,b]分成nnn个小区间,每个小区间长度为Δx=b−an\Delta x = \frac{b - a}{n}Δx=nb−a​。不过这里是用每个小区间上的矩形面积来近似小曲边梯形的面积,进而得到定积分的近似值。矩形的高度可以取小区间的左端点函数值、右端点函数值或中点函数值。

  2. 计算公式:

    • 左矩形公式:∫abf(x)dx≈Δx[f(x0)+f(x1)+f(x2)+⋯+f(xn−1)]\int_{a}^{b}f(x)dx \approx \Delta x\left[f(x_0) + f(x_1) + f(x_2) + \cdots + f(x_{n - 1})\right]∫ab​f(x)dx≈Δx[f(x0​)+f(x1​)+f(x2​)+⋯+f(xn−1​)],其中xi=a+iΔxx_i = a + i\Delta xxi​=a+iΔx,i=0,1,⋯ ,n−1i = 0,1,\cdots,n - 1i=0,1,⋯,n−1。
    • 右矩形公式:∫abf(x)dx≈Δx[f(x1)+f(x2)+f(x3)+⋯+f(xn)]\int_{a}^{b}f(x)dx \approx \Delta x\left[f(x_1) + f(x_2) + f(x_3) + \cdots + f(x_n)\right]∫ab​f(x)dx≈Δx[f(x1​)+f(x2​)+f(x3​)+⋯+f(xn​)],其中xi=a+iΔxx_i = a + i\Delta xxi​=a+iΔx,i=1,2,⋯ ,ni = 1,2,\cdots,ni=1,2,⋯,n。
    • 中矩形公式:∫abf(x)dx≈Δx[f(x0+x12)+f(x1+x22)+⋯+f(xn−1+xn2)]\int_{a}^{b}f(x)dx \approx \Delta x\left[f(\frac{x_0 + x_1}{2}) + f(\frac{x_1 + x_2}{2}) + \cdots + f(\frac{x_{n - 1} + x_n}{2})\right]∫ab​f(x)dx≈Δx[f(2x0​+x1​​)+f(2x1​+x2​​)+⋯+f(2xn−1​+xn​​)],其中xi=a+iΔxx_i = a + i\Delta xxi​=a+iΔx,i=0,1,⋯ ,n−1i = 0,1,\cdots,n - 1i=0,1,⋯,n−1。

辛普森法

  1. 基本思想:
    把积分区间[a,b][a,b][a,b]分成nnn个小区间(nnn为偶数),每个小区间长度为Δx=b−an\Delta x = \frac{b - a}{n}Δx=nb−a​。在每个小区间上,用二次函数来近似代替被积函数,通过计算这些二次函数在小区间上的定积分来近似原函数的定积分。

  2. 计算公式:

∫abf(x)dx≈Δx3[f(x0)+4f(x1)+2f(x2)+4f(x3)+⋯+2f(xn−2)+4f(xn−1)+f(xn)]\int_{a}^{b}f(x)dx \approx \frac{\Delta x}{3}\left[f(x_0) + 4f(x_1) + 2f(x_2) + 4f(x_3) + \cdots + 2f(x_{n - 2}) + 4f(x_{n - 1}) + f(x_n)\right]∫ab​f(x)dx≈3Δx​[f(x0​)+4f(x1​)+2f(x2​)+4f(x3​)+⋯+2f(xn−2​)+4f(xn−1​)+f(xn​)]
其中xi=a+iΔxx_i = a + i\Delta xxi​=a+iΔx,i=0,1,⋯ ,ni = 0,1,\cdots,ni=0,1,⋯,n。

这三种方法各有优缺点。梯形法计算相对简单,但精度一般;矩形法计算简便,适用于一些简单的近似计算,但误差相对较大;辛普森法精度较高,但计算量相对较大,且要求区间划分是偶数个。在实际应用中,可根据具体问题的要求和被积函数的特点选择合适的方法。

c++代码实现

#include <iostream>
#include <cmath>
#define pi 3.1415926535  // 定义圆周率π的值
using namespace std;

// 基类,定义积分函数和积分区间
class fx {
protected:
    double a, b;  // 积分下限和上限
    static double y;  // 用于存储函数值的静态变量

public:
    // 构造函数,初始化积分区间
    fx(double A = 0, double B = 0) {
        a = A;
        b = B;
    }

    // 设置积分区间的函数
    void setfxa_b(double A = 0, double B = 0) {
        a = A;
        b = B;
    }

    // 定义被积函数 f(x) = sin(x)
    double f(double x) {
        y = sin(x);  // 计算 sin(x) 的值并存储到 y 中
        return y;    // 返回函数值
    }
};

// 初始化静态变量 y
double fx::y = 0;

// 矩形法类,继承自基类 fx
class rectencle : public fx {
public:
    double step, ans;  // 定义步长和积分结果
    int p;             // 定义区间划分的份数

    // 构造函数,初始化积分区间、份数,并调用积分函数
    rectencle(double a, double b, int P) : fx(a, b) {
        ans = 0;       // 初始化积分结果为 0
        p = P;         // 设置区间划分份数
        getstep();     // 计算步长
        integrate();   // 调用积分函数计算结果
    }

    // 计算步长
    void getstep() {
        step = (b - a) / p * 1.0;  // 计算每个小区间的宽度
    }

    // 实现矩形法积分
    void integrate() {
        for (int i = 1; i <= p; i++) {
            ans += f(a + step * i) * step;  // 在每个小区间上取右端点的函数值计算矩形面积
        }
    }

    // 输出积分结果
    void showans() {
        cout << ans << endl;  // 输出积分结果
    }
};

// 梯形法类,继承自基类 fx
class ladder : public fx {
public:
    double step, ans;  // 定义步长和积分结果
    int p;             // 定义区间划分的份数

    // 构造函数,初始化积分区间、份数,并调用积分函数
    ladder(double a, double b, int P) : fx(a, b) {
        ans = 0;       // 初始化积分结果为 0
        p = P;         // 设置区间划分份数
        getstep();     // 计算步长
        integrate();   // 调用积分函数计算结果
    }

    // 计算步长
    void getstep() {
        step = (b - a) / p * 1.0;  // 计算每个小区间的宽度
    }

    // 实现梯形法积分
    void integrate() {
        for (int i = 1; i <= p; i++) {
            ans += (f(a + step * i) + f(a + step * (i - 1))) * step * 0.5;  // 使用梯形公式计算每个小区间的面积
        }
    }

    // 输出积分结果
    void showans() {
        cout << ans << endl;  // 输出积分结果
    }
};

// 辛普森法类,继承自基类 fx
class simpson : public fx {
public:
    double step, ans;  // 定义步长和积分结果
    int p;             // 定义区间划分的份数

    // 构造函数,初始化积分区间、份数,并调用积分函数
    simpson(double a, double b, int P) : fx(a, b) {
        ans = 0;       // 初始化积分结果为 0
        p = P;         // 设置区间划分份数
        getstep();     // 计算步长
        integrate();   // 调用积分函数计算结果
    }

    // 计算步长
    void getstep() {
        step = (b - a) / p * 1.0;  // 计算每个小区间的宽度
    }

    // 实现辛普森法积分
    void integrate() {
        double h = (b - a) / p;  // 计算步长
        ans = f(a) + f(b);       // 初始化结果为区间两端点的函数值之和

        // 遍历每个小区间,计算中间点的函数值并加权
        for (int i = 1; i <= p - 1; ++i) {
            double x = a + h * i;  // 计算当前点的 x 值
            ans += f(x) * ((i & 1) ? 4 : 2);  // 奇数点乘以 4,偶数点乘以 2
        }
        ans *= h / 3;  // 最后乘以步长的三分之一
    }

    // 输出积分结果
    void showans() {
        cout << ans << endl;  // 输出积分结果
    }
};

// 主函数,测试三种积分方法
int main() {
    rectencle test1(0, pi / 2, 10000);  // 创建矩形法对象,积分区间为 [0, π/2],划分为 10000 份
    ladder test2(0, pi / 2, 10000);     // 创建梯形法对象,积分区间为 [0, π/2],划分为 10000 份
    simpson test3(0, pi / 2, 10000);    // 创建辛普森法对象,积分区间为 [0, π/2],划分为 10000 份

    test1.showans();  // 输出矩形法的积分结果
    test2.showans();  // 输出梯形法的积分结果
    test3.showans();  // 输出辛普森法的积分结果
}

运行结果

在这里插入图片描述

显示精度的差异

将主函数改为

int main() {
	int i=1;
	cout<<"rectencle:"<<endl;// 测试矩形法(rectencle)
	for(; i<1000000; i*=10) {
		rectencle test1(0,pi/2,i);
		test1.showans();
	}
	cout<<"ladder:"<<endl;// 测试梯形法(ladder)
	for(i=1; i<1000000; i*=10) {
		ladder test2(0,pi/2,i);
		test2.showans();
	}
	cout<<"simpson:"<<endl;// 测试辛普森法(simpson)
	for(i=1; i<1000000; i*=10) {
		simpson test3(0,pi/2,10000);
		test3.showans();
	}
	return 0;
}

运行结果

在这里插入图片描述


笔者于学习完高数后有感,如有纰漏,请见谅。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐