用C语言求下列数值方法估计定积分 ∫_0^π▒〖e^x cos(4x)dx=〗 (e^π-1)/17 (a) 复化梯形公式 (b) 复化 Simpson 公式 (c) (复化)Gauss 公式 比较各种方法的效率和精度。效率可以用计算过程中调用函数值的次数来衡量,精度用误差衡量,这个题目知道精确解,可以直接求误差,但是大部分题目是不知道精确解的。精度也 可以用加密(步长减半)前后误差的比值来衡量,当比值越大,误差下降的速度越快。
时间: 2024-03-10 11:50:09 浏览: 25
下面是使用C语言分别计算复化梯形公式、复化Simpson公式和复化Gauss公式来估计定积分的代码,并比较它们的效率和精度。
```c
#include <stdio.h>
#include <math.h>
// 定义被积函数 f(x)
double f(double x) {
return exp(x) * cos(4 * x);
}
// 复化梯形公式求定积分
double trapezoid(double a, double b, int n) {
double h = (b - a) / n;
double sum = 0.5 * (f(a) + f(b));
for (int i = 1; i < n; i++) {
double x = a + i * h;
sum += f(x);
}
return h * sum;
}
// 复化Simpson公式求定积分
double simpson(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;
if (i % 2 == 0) {
sum += 2 * f(x);
} else {
sum += 4 * f(x);
}
}
return h * sum / 3;
}
// 复化Gauss公式求定积分
double gauss(double a, double b, int n) {
// 节点和系数
double x[] = { -0.9061798459, -0.5384693101, 0, 0.5384693101, 0.9061798459 };
double w[] = { 0.2369268851, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268851 };
// 积分区间转换
double A = (b - a) / 2;
double B = (b + a) / 2;
// 计算积分
double sum = 0;
for (int i = 0; i < n; i++) {
double x_i = A * x[i] + B;
sum += w[i] * f(x_i);
}
return A * sum;
}
int main() {
double a = 0, b = M_PI;
double exact = (exp(M_PI) - 1) / 17.0; // 精确解
printf("精确解为:%f\n", exact);
int n1 = 10, n2 = 20, n3 = 5;
double I1 = trapezoid(a, b, n1);
double I2 = trapezoid(a, b, n2);
double I3 = simpson(a, b, n1);
double I4 = simpson(a, b, n2);
double I5 = gauss(a, b, n3);
printf("复化梯形公式:\n");
printf("n=%d, 近似值=%f, 误差=%f\n", n1, I1, fabs(I1 - exact));
printf("n=%d, 近似值=%f, 误差=%f\n", n2, I2, fabs(I2 - exact));
printf("复化Simpson公式:\n");
printf("n=%d, 近似值=%f, 误差=%f\n", n1, I3, fabs(I3 - exact));
printf("n=%d, 近似值=%f, 误差=%f\n", n2, I4, fabs(I4 - exact));
printf("复化Gauss公式:\n");
printf("n=%d, 近似值=%f, 误差=%f\n", n3, I5, fabs(I5 - exact));
// 计算效率
int count1 = n1 + 1, count2 = n2 + 1, count3 = n3;
printf("复化梯形公式调用函数的次数:%d\n", count1);
printf("复化Simpson公式调用函数的次数:%d\n", count2);
printf("复化Gauss公式调用函数的次数:%d\n", count3);
// 计算精度
double ratio1 = (I1 - I2) / (I2 - exact);
double ratio2 = (I3 - I4) / (I4 - exact);
double ratio3 = (I5 - exact) / (exact);
printf("复化梯形公式步长减半前后误差比值:%f\n", ratio1);
printf("复化Simpson公式步长减半前后误差比值:%f\n", ratio2);
printf("复化Gauss公式步长减半前后误差比值:%f\n", ratio3);
return 0;
}
```
其中,`f(x)`是被积函数;`trapezoid(a, b, n)`是使用复化梯形公式求定积分的函数;`simpson(a, b, n)`是使用复化Simpson公式求定积分的函数;`gauss(a, b, n)`是使用复化Gauss公式求定积分的函数;`main()`函数中的`a`和`b`是积分区间的端点,`n1`、`n2`和`n3`分别是复化梯形公式、复化Simpson公式和复化Gauss公式的节点数;`exact`是精确解;`I1`、`I2`、`I3`、`I4`和`I5`分别是使用不同方法得到的近似解;`count1`、`count2`和`count3`分别是不同方法调用函数的次数;`ratio1`、`ratio2`和`ratio3`分别是不同方法步长减半前后误差的比值。