在 C 语言中评估有限差分近似值

CCBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何在 C 语言中评估导数的有限差分近似值。本实验涵盖以下步骤:

  1. 定义一个数学函数 f(x) 并设置有限差分近似的步长 h
  2. 在给定的评估点 x 处计算 f(x) 导数的前向和后向有限差分近似值。
  3. 打印计算出的近似值,并将它们与真实导数进行比较。

完成本实验后,你将对如何在 C 语言中实现有限差分方法以及评估近似值的准确性有扎实的理解。

定义 f(x) 和步长 h

在这一步中,你将学习如何在 C 语言中定义一个数学函数并设置有限差分近似的步长。

首先,为你的有限差分近似程序创建一个新的 C 文件:

cd ~/project
nano finite_difference.c

现在,添加以下代码来定义函数和步长:

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

// 定义函数 f(x)
double f(double x) {
    return x * x;  // 示例函数:f(x) = x^2
}

int main() {
    // 定义步长 h
    double h = 0.0001;  // 用于精确近似的小步长

    // 计算导数的点
    double x = 2.0;

    printf("函数:f(x) = x^2\n");
    printf("步长 h:%f\n", h);
    printf("计算点 x:%f\n", x);

    return 0;
}

示例输出:

函数:f(x) = x^2
步长 h:0.000100
计算点 x:2.000000

让我们来剖析一下关键部分:

  1. f(x) 函数:我们定义了一个简单的二次函数 f(x) = x^2。你可以修改这个函数来表示任何你想要近似的数学函数。

  2. 步长 h:这是在有限差分近似中使用的一个小值。较小的 h 通常会提供更精确的结果,但极小的值可能会导致数值精度问题。

  3. 计算点 x:这是我们将计算导数近似值的点。

编译程序以确保它能正常运行:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

示例输出:

函数:f(x) = x^2
步长 h:0.000100
计算点 x:2.000000

计算前向/后向差分

在这一步中,你将学习如何计算导数的前向和后向有限差分近似值。

打开上一个文件并修改代码以包含导数近似方法:

cd ~/project
nano finite_difference.c

用前向和后向差分计算更新代码:

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

// 定义函数 f(x)
double f(double x) {
    return x * x;  // 示例函数:f(x) = x^2
}

int main() {
    // 定义步长 h
    double h = 0.0001;  // 用于精确近似的小步长

    // 计算导数的点
    double x = 2.0;

    // 前向差分近似
    double forward_diff = (f(x + h) - f(x)) / h;

    // 后向差分近似
    double backward_diff = (f(x) - f(x - h)) / h;

    printf("前向差分近似:%f\n", forward_diff);
    printf("后向差分近似:%f\n", backward_diff);

    return 0;
}

编译并运行程序:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

示例输出:

前向差分近似:4.000100
后向差分近似:3.999900

让我们来剖析一下有限差分近似:

  1. 前向差分:使用 x 之后的点计算导数

    • 公式:(f(x + h) - f(x)) / h
    • 近似向前的变化率
  2. 后向差分:使用 x 之前的点计算导数

    • 公式:(f(x) - f(x - h)) / h
    • 近似向后的变化率

请注意,对于函数 f(x) = x^2,其真实导数为 2x(在 x = 2 时为 4)。这些近似值非常接近实际导数的值。

打印近似值

在这一步中,你将改进程序以打印详细的近似结果,并将它们与实际导数进行比较。

打开上一个文件并修改代码以包含全面的输出:

cd ~/project
nano finite_difference.c

用详细的近似值打印更新代码:

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

// 定义函数 f(x)
double f(double x) {
    return x * x;  // 示例函数:f(x) = x^2
}

// 实际导数函数
double actual_derivative(double x) {
    return 2 * x;  // x^2 的导数是 2x
}

int main() {
    // 定义多个步长用于比较
    double step_sizes[] = {0.1, 0.01, 0.001, 0.0001};
    int num_steps = sizeof(step_sizes) / sizeof(step_sizes[0]);

    // 计算导数的点
    double x = 2.0;

    // 实际导数的值
    double true_derivative = actual_derivative(x);

    printf("导数近似分析\n");
    printf("--------------------------------\n");
    printf("函数:f(x) = x^2\n");
    printf("计算点:x = %f\n", x);
    printf("实际导数:%f\n\n", true_derivative);

    printf("步长 | 前向差分 | 后向差分 | 前向误差 | 后向误差\n");
    printf("-----------------------------------------------------------------------\n");

    // 计算并打印不同步长的近似值
    for (int i = 0; i < num_steps; i++) {
        double h = step_sizes[i];

        // 前向差分近似
        double forward_diff = (f(x + h) - f(x)) / h;

        // 后向差分近似
        double backward_diff = (f(x) - f(x - h)) / h;

        // 计算绝对误差
        double forward_error = fabs(forward_diff - true_derivative);
        double backward_error = fabs(backward_diff - true_derivative);

        printf("%9f | %11f | %12f | %11f | %12f\n",
               h, forward_diff, backward_diff, forward_error, backward_error);
    }

    return 0;
}

编译并运行程序:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

示例输出:

导数近似分析
--------------------------------
函数:f(x) = x^2
计算点:x = 2.000000
实际导数:4.000000

步长 | 前向差分 | 后向差分 | 前向误差 | 后向误差
-----------------------------------------------------------------------
    0.100000 |     4.100000 |      3.900000 |      0.100000 |       0.100000
    0.010000 |     4.010000 |      3.990000 |      0.010000 |       0.010000
    0.001000 |     4.001000 |      3.999000 |      0.001000 |       0.001000
    0.000100 |     4.000100 |      3.999900 |      0.000100 |       0.000100

关键观察结果:

  1. 随着步长 h 减小,近似值变得更准确
  2. 前向和后向差分收敛到实际导数
  3. 误差随着步长变小而减小

总结

在本实验中,你学习了如何在 C 语言中定义一个数学函数并设置有限差分近似的步长。你还学习了如何计算导数的前向和后向有限差分近似值。涵盖的关键步骤包括定义函数 f(x) 和步长 h,以及实现前向和后向差分方法来在给定的评估点 x 处近似导数。这为理解和在数值分析与科学计算中实现有限差分技术奠定了基础。