用C语言实现定积分求解的三种方法,梯形公式,辛普森公式,自适应辛普森公式

1.梯形公式:

梯形公式(trapezoidal rule)是一种求定积分的方法。它假定函数在区间上是一条直线,因此可以通过计算梯形的面积来估计函数的定积分

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

double f(double x)
{
    return sin(x);//所需要求定积分的函数
}

double Trapz(double a, double b, int n)
{
    double h = (b - a) / n;
    double sum = 0;
    for (int i = 1; i < n; i++)
        sum += f(a + i * h);
    return h * (f(a) + f(b)) / 2 + h * sum;
}

int main()
{
    printf("%lf\n", Trapz(0, 3.1415926, 100));//积分下限,积分上限,精度
    return 0;
}

可以用指针来初步优化这个代码:

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

double f(double x)
{
    return sin(x);//所需要求定积分的函数
}

double Trapz(double a, double b, int n)
{
    double h = (b - a) / n;
    double sum = 0;
    double* p;
    p = &a;
    for (int i = 1; i < n; i++)
    {
        *p = *p + h;
        sum += f(*p);
    }
    return h * (f(a) + f(b)) / 2 + h * sum;
}

int main()
{
    printf("%lf\n", Trapz(0, 3.1415926, 100));//积分下限,积分上限,精度
    return 0;
}

2.辛普森公式:

辛普森公式(Simpson's rule)是一种求定积分的方法。它是由英国数学家 Thomas Simpson 在 18世纪末发明的。辛普森公式假定函数在区间上为二次函数,因此能够更精确地计算函数的定积分。

#include <stdio.h>
#include <math.h>
#define PI 3.1415926

double Simpson(double a, double b, int n, double(*f)(double x))
{
    double h = (b - a) / n;
    double sum1 = 0, sum2 = 0;
    int i;
    for (i = 1; i <= n - 1; i += 2)
        sum1 += f(a + i * h);
    for (i = 2; i <= n - 2; i += 2)
        sum2 += f(a + i * h);
    return h / 3 * (f(a) + 4 * sum1 + 2 * sum2 + f(b));
}

double f(double x)
{
    return sin(x);
}

int main()
{
    double s = Simpson(0, PI, 100, f);//积分下限,积分上限,精度,函数
    printf("The result of integral is %lf\n", s);
    return 0;
}

3.adaptive Simpson's rule:

自适应辛普森公式(adaptive Simpson's rule)是一种求定积分的方法,它的基本思想是将定积分的区间分成若干个小区间,然后使用辛普森公式对每个小区间求解,最后将所有小区间的定积分求和得到整个区间的定积分。

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

double f(double x)
{
    return sin(x);
}

double adaptive_simpson(double a, double b, double d)
{
    double c = a + (b - a) / 2;
    double l = (f(a) + 4 * f(c) + f(b)) * (b - a) / 6;
    double r = (f(a) + 4 * f((a + c) / 2) + 2 * f(c) + 4 * f((c + b) / 2) + f(b)) * (b - a) / 12;
    if (fabs(l - r) <= 15 * d)
        return r + (r - l) / 15;
    return adaptive_simpson(a, c, d) + adaptive_simpson(c, b, d);
}

int main()
{
    double a = 0;//积分下限
    double b = 3.14159265;//积分上限
    double d = 0.000001;//精度
    printf("%.6f\n", adaptive_simpson(a, b, d));
    return 0;
}

可以用指针来初步优化这个代码:

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

double f(double x)
{
    return sin(x);
}

double adaptive_simpson(double* a, double* b, double* d)
{
    double c = *a + (*b - *a) / 2;
    double l = (f(*a) + 4 * f(c) + f(*b)) * (*b - *a) / 6;
    double r = (f(*a) + 4 * f((*a + c) / 2) + 2 * f(c) + 4 * f((c + *b) / 2) + f(*b)) * (*b - *a) / 12;
    if (fabs(l - r) <= 15 * *d)
        return r + (r - l) / 15;
    return adaptive_simpson(a, &c, d) + adaptive_simpson(&c, b, d);
}

int main()
{
    double a = 0;//积分下限
    double b = 3.14159265;//积分上限
    double d = 0.000001;//精度
    printf("%.6f\n", adaptive_simpson(&a, &b, &d));
    return 0;
}

  • 14
    点赞
  • 129
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你回答这个问题。下面是用C语言实现复化梯形公式和复化辛普森公式估计定积分的代码: ```c #include <stdio.h> #include <math.h> double f(double x) { // 定义被积函数 return exp(x); // 以e为底的x次方函数 } double trapezoidal(double a, double b, int n) { // 复化梯形公式 double h = (b - a) / n; // 梯形的高度 double sum = (f(a) + f(b)) / 2; // 将首尾两项加入和中 for (int i = 1; i < n; i++) { double x = a + i * h; // 计算每个梯形的左端点x sum += f(x); // 将每个梯形的面积加入和中 } return sum * h; // 最终结果为和乘以梯形的高度 } 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; // 计算每个梯形的左端点x sum += 2 * (i % 2 + 1) * f(x); // 将每个梯形的面积加入和中,注意系数的变化 } return sum * h / 3; // 最终结果为和乘以梯形的高度除以3 } int main() { double a = 0, b = 1; // 积分区间为[0,1] int n = 100; // 梯形梯形数量为100 printf("Trapezoidal rule: %lf\n", trapezoidal(a, b, n)); printf("Simpson's rule: %lf\n", simpson(a, b, n)); return 0; } ``` 在上面的代码中,我们定义了被积函数f(x)为以e为底的x次方函数,然后分别用复化梯形公式和复化辛普森公式估计了在区间[0,1]上的定积分,并输出了结果。你可以根据需要修改被积函数和积分区间,以及调整梯形梯形数量来得到更精确的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值