用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;
}

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年12月27日
下一篇 2023年12月27日

相关推荐