在 C 语言中使用辛普森法则近似计算积分

CBeginner
立即练习

简介

在本实验中,你将学习如何在 C 语言中使用辛普森法则(Simpson's Rule)来近似计算积分。本实验涵盖了定义要积分的函数、积分区间的逐步过程,然后实现辛普森法则算法来计算近似积分。在本实验结束时,你将拥有一个可以使用辛普森法则方法在指定区间上对给定函数进行数值积分的 C 程序。

本实验包括两个主要步骤:定义函数和区间,然后使用具有偶数子区间的辛普森法则来计算近似积分。这个实践练习将帮助你在 C 编程中应用数值积分技术获得实践经验。

定义 f(x) 和区间 [a, b]

在这一步中,我们将为在 C 语言中实现用于数值积分的辛普森法则建立基础组件。我们将定义要积分的函数并指定积分区间。

首先,让我们在 ~/project 目录中创建一个新的 C 文件:

cd ~/project
nano simpson_integration.c

现在,让我们编写初始代码来定义我们的函数和区间:

#include <stdio.h>
#include <math.h>

// 要积分的函数:f(x) = x^2
double f(double x) {
    return x * x;
}

int main() {
    // 定义积分区间 [a, b]
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限

    printf("Integrating f(x) = x^2 from %f to %f\n", a, b);

    return 0;
}

让我们来分析一下这段代码:

  1. 我们包含了必要的头文件:stdio.h 用于输入/输出,math.h 用于数学函数。
  2. f(x) 被定义为一个简单的二次函数 x^2,我们将对其进行积分。
  3. main() 函数中,我们将积分区间设置为从 0 到 1。
  4. 为了清晰起见,我们打印出了积分区间。

编译并运行代码进行验证:

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

示例输出:

Integrating f(x) = x^2 from 0.000000 to 1.000000

使用具有偶数子区间的辛普森法则

在这一步中,我们将实现辛普森法则算法来近似计算我们函数的定积分。我们会将积分函数添加到现有的 C 程序中。

打开之前的文件:

cd ~/project
nano simpson_integration.c

更新代码以包含辛普森法则的实现:

#include <stdio.h>
#include <math.h>

// 要积分的函数:f(x) = x^2
double f(double x) {
    return x * x;
}

// 辛普森法则实现
double simpsons_rule(double a, double b, int n) {
    double h = (b - a) / n;  // 每个子区间的宽度
    double sum = f(a) + f(b);  // 第一个和最后一个点

    // 计算偶数点和奇数点的和
    for (int i = 1; i < n; i++) {
        double x = a + i * h;
        sum += (i % 2 == 0? 2 : 4) * f(x);
    }

    return (h / 3) * sum;
}

int main() {
    // 定义积分区间 [a, b]
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限
    int n = 100;     // 子区间数量(必须为偶数)

    double integral = simpsons_rule(a, b, n);

    printf("Integral of f(x) = x^2 from %f to %f\n", a, b);
    printf("Approximation using Simpson's Rule with %d subintervals: %f\n", n, integral);

    return 0;
}

编译并运行代码:

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

示例输出:

Integral of f(x) = x^2 from 0.000000 to 1.000000
Approximation using Simpson's Rule with 100 subintervals: 0.333333

让我们来分析一下辛普森法则的实现:

  1. simpsons_rule() 接受区间边界和子区间数量。
  2. h 计算每个子区间的宽度。
  3. 我们从区间的第一个和最后一个点开始。
  4. 循环添加中间点的加权贡献。
  5. 偶数点乘以 2,奇数点乘以 4。
  6. 最终结果乘以 h/3 进行缩放。

打印近似积分值

在这最后一步中,我们将通过添加更详细的输出,并将数值近似值与精确积分值进行比较,来增强我们的辛普森法则实现。

打开之前的文件:

cd ~/project
nano simpson_integration.c

更新代码以包含更全面的输出:

#include <stdio.h>
#include <math.h>

// 要积分的函数:f(x) = x^2
double f(double x) {
    return x * x;
}

// 计算 f(x) = x^2 从 a 到 b 的精确积分
double exact_integral(double a, double b) {
    return (pow(b, 3) - pow(a, 3)) / 3.0;
}

// 辛普森法则实现
double simpsons_rule(double a, double b, int n) {
    double h = (b - a) / n;  // 每个子区间的宽度
    double sum = f(a) + f(b);  // 第一个和最后一个点

    // 计算偶数点和奇数点的和
    for (int i = 1; i < n; i++) {
        double x = a + i * h;
        sum += (i % 2 == 0? 2 : 4) * f(x);
    }

    return (h / 3) * sum;
}

int main() {
    // 定义积分区间 [a, b]
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限
    int n = 100;     // 子区间数量(必须为偶数)

    // 计算近似值和精确积分
    double approx_integral = simpsons_rule(a, b, n);
    double exact_value = exact_integral(a, b);
    double error = fabs(exact_value - approx_integral);

    // 打印详细结果
    printf("积分近似结果:\n");
    printf("------------------------------\n");
    printf("函数:f(x) = x^2\n");
    printf("区间:[%.2f, %.2f]\n", a, b);
    printf("子区间数量:%d\n\n", n);

    printf("近似值(辛普森法则):%.6f\n", approx_integral);
    printf("精确值:%.6f\n", exact_value);
    printf("绝对误差:%.6f\n", error);
    printf("相对误差:%.4f%%\n", (error / exact_value) * 100);

    return 0;
}

编译并运行代码:

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

示例输出:

积分近似结果:
------------------------------
函数:f(x) = x^2
区间:[0.00, 1.00]
子区间数量:100

近似值(辛普森法则):0.333333
精确值:0.333333
绝对误差:0.000000
相对误差:0.0000%

此步骤中的主要新增内容:

  1. 添加了 exact_integral() 函数来计算真实积分值
  2. 计算了绝对误差和相对误差
  3. 创建了格式化输出以显示详细的积分结果

总结

在本实验中,我们首先定义了要积分的函数 f(x) = x^2 以及积分区间 [a, b] = [0, 1]。然后我们实现了辛普森法则算法来近似计算该函数的定积分。辛普森法则包括将区间划分为偶数个子区间,并计算这些子区间端点和中点处函数值的加权和。最后,我们将打印使用辛普森法则获得的近似积分值。