自适应辛普森积分

辛普森积分法

在求一段不规则图形的面积的时候,使用抛物线来近似曲线。

我们在学习积分的时候常常使用长方形来近似无限分割后的曲线的积分面积。但是如果在数值计算的时候,这样会造成不小的精度误差。因此辛普森积分使用抛物线上的曲线来近似 ( a , f ( a ) ) , ( b , f ( b ) ) (a,f(a)),(b,f(b)) (a,f(a)),(b,f(b))这一段曲线。

因此对于已知的函数方程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kero5nTh-1662090310637)(C:\Users\Henry\AppData\Roaming\Typora\typora-user-images\image-20220902000549955.png)]

我们用抛物线来近似a,b之间的面积。即通过确定的 ( a , f ( a ) ) (a,f(a)) (a,f(a)) ( a + b 2 , f ( a + b 2 ) ) (\frac{a+b}{2},f(\frac{a+b}{2})) (2a+b,f(2a+b)) ( b , f ( b ) ) (b,f(b)) (b,f(b))三个点确定的抛物线积分而得的面积 S = b − a 6 ( f ( a ) + 4 f ( a + b 2 ) + f ( b ) ) S=\frac{b-a}{6}(f(a)+4f(\frac{a+b}{2})+f(b)) S=6ba(f(a)+4f(2a+b)+f(b))

自适应辛普森积分:

对于一段面积,先用辛普森积分法求出整段的面积S。然后找到中点mid,分别求出左边的面积L和右边的面积R。

while(fabs(S-L-R)>eps){
	S=L+R;
	递归对于每个区间接着做。
}

模板:(只需要改动定义的f函数即可。)

double f(double x){
    
    

}

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

double dfs(double l,double r,double S){
    
    
    double mid=(l+r)/2;
    double L=simpson(l,mid),R=simpson(mid,r);
    if(fabs(L+R-S)<eps) return L+R;
    return dfs(l,mid,L)+dfs(mid,r,R);
}

void solve(){
    
    
	double L=2000,R=-2000;
	scanf("%d",&n);
	for(int i=0;i<n;++i){
    
    
		scanf("%lf%lf%lf",&c[i].p.x,&c[i].p.y,&c[i].r);
		L=min(L,c[i].p.x-c[i].r);
		R=max(R,c[i].p.x+c[i].r);
	}
	double S=simpson(L,R);
	printf("%.3lf",dfs(L-100,R+100,S));
}

猜你喜欢

转载自blog.csdn.net/m0_51780913/article/details/126659656