模板 - 自适应辛普森法积分

经过模板验证,6位精度取8位或9位还是比较快的。
一道练习题?https://www.luogu.org/problemnew/show/UVA11346

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;


namespace Adaptive_Simpson_Integral {

    /* 备注:
    1.直接往上面模板的F函数中输入本题给定函数,然后调用一次asr(l,r)即可。
    2.可能需要修改精度要求,测试过至少取需求精度的100倍或1000倍就挺好。
     */


    double seps=1e-9;

    double a,b,c,d;

    void init(double _seps,double _a,double _b,double _c,double _d){
        seps=_seps,a=_a,b=_b,c=_c,d=_d;
    }

    double F(double x) {
        //需要积分的函数
        return (c*x+d)/(a*x+b);
    }

    double simpson(double l,double r) {
        double mid=(l+r)/2;
        return (F(l)+4*F(mid)+F(r))*(r-l)/6;
    }

    double asr(double l,double r,double A) {
        double mid=(l+r)/2;
        double L=simpson(l,mid),R=simpson(mid,r);
        if(fabs(L+R-A)<=15*seps)
            return L+R+(L+R-A)/15.0;
        return asr(l,mid,L)+asr(mid,r,R);
    }

    double asr(double l,double r) {
        return asr(l,r,simpson(l,r));
    }

    /* 备注:
    1.直接往上面模板的F函数中输入本题给定函数,然后调用一次asr(l,r)即可。
    2.可能需要修改精度要求,测试过至少取需求精度的100倍或1000倍就挺好。
    */

}


using namespace Adaptive_Simpson_Integral;


int main() {
    double a,b,c,d,L,R;
    scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&L,&R);
    init(1e-8,a,b,c,d);
    printf("%.6f\n",asr(L,R));
}

传入函数指针的自适应辛普森法积分

当有多个要积分的函数时,可以这样写:


double A,B,C,D,E;


namespace Adaptive_Simpson_Integral {

    /* 备注:
    1.直接往上面模板的f函数中输入本题给定函数,然后调用一次asr(l,r)即可。
    2.可能需要修改精度要求,测试过至少取需求精度的100倍或1000倍就挺好。
     */


    double seps=1e-8;

    double f(double x) {
        //需要积分的函数
        return A*x*x+B*x+C;
    }

    double g(double x) {
        //需要积分的函数
        return D*x+E;
    }

    double simpson(double l,double r,double (*F)(double)) {
        double mid=(l+r)/2;
        return (F(l)+4*F(mid)+F(r))*(r-l)/6;
    }

    double asr(double l,double r,double A,double (*F)(double)) {
        double mid=(l+r)/2;
        double L=simpson(l,mid,F),R=simpson(mid,r,F);
        if(fabs(L+R-A)<=15*seps)
            return L+R+(L+R-A)/15.0;
        return asr(l,mid,L,F)+asr(mid,r,R,F);
    }

    double asr(double l,double r,double (*F)(double)) {
        return asr(l,r,simpson(l,r,F),F);
    }


    /* 备注:
    1.直接往上面模板的F函数中输入本题给定函数,然后调用一次asr(l,r)即可。
    2.可能需要修改精度要求,测试过至少取需求精度的100倍或1000倍就挺好。
    */

}


using namespace Adaptive_Simpson_Integral;
posted @ 2019-04-14 19:18  韵意  阅读(190)  评论(0编辑  收藏  举报