自适应 Simpson 积分法学习笔记

自适应 Simpson 积分法,是一种计算一段区间内,形态奇怪的函数和的算法,例如面积并和难以直接用通项公式计算的函数。

Simpson 积分

我们都知道,求解微积分需要求解一个导数的原函数,但这显然更难,比如说 \(f(x)=\dfrac{cx+d}{ax+b}\) 这个函数,就相当难以求解原函数 \(F(x)\) (对应的例题是这个)。

假如我们在求定积分,我们考虑使用一个与 \(f(x)\) 函数图像相近的函数 \(f_n(x)=\sum\limits_{i=0}^na_ix^i\)。显然,\(F_n(x)\) 比较好求,为 \(\alpha+\sum\limits_{i=0}^na'_ix^{i+1}\)。那么我们就得到:

\[\int_a^bf(x)dx\cong\int_a^bf_n(x)dx=F_n(b)-F_n(a) \]

为了方便运算,我们只考虑 \(n=2\) 的情况。相当于此时 \(f_2(x)\) 是一个二次函数。众所周知,要确定一个二次函数,需要确定其上的三个点。我们考虑选择 \(a,b,c=\dfrac{a+b}2\) 三点。我们设 \(f_2(x)=Ax^2+Bx+C\),则 \(F_2=\dfrac A3x^3+\dfrac B2x^2+Cx+\alpha\)。于是有:

\[\int_a^bf(x)dx\cong\int_a^bf_2(x)dx=F_2(b)-F_2(a) \]

\[=\dfrac A3(b^3-a^3)+\dfrac B2(b^2-a^2)+C(b-a) \]

\[=\frac{b-a}6(2A(b^2+ab+a^2)+3B(b+a)+6C) \]

\[=\frac{b-a}6((Aa^2+Ba+C)+(Ab^2+Bb+C)+(A(a+b)^2+2B(a+b)+4C)) \]

\[=\frac{b-a}6(f(a)+f(b)+4(A(c)^2+B(c)+C)) \]

\[=\frac{b-a}6(f(a)+f(b)+4f(c)) \]

于是我们就得到了 Simpson 积分的一个公式:

\[\int_a^bf(x)dx\cong\frac{b-a}6(f(a)+f(b)+4f(c)) \]

自适应 Simpson 积分法

上面这个式子很不错,但是不够好,因为他太粗略了。

比如 \(\int_{-1}^1\frac{3x+4}{x+2}dx\),用 Simpson 积分算出来的值为 \(3.77\cdots\),而实际值已经超过 \(3.8\) 了。这就错的相当离谱。

其根本原因就在于,我们选择的 \(f_2(x)\) 不像 \(f(x)\)。但是我们还有一招:

\[\int_a^bf(x)dx=\int_a^cf(x)dx+\int_c^bf(x)dx \]

为了方便,我们设 \(c=\frac{a+b}2\)。于是想到将原区间分成大量小区间,再用 Simpson 积分求出每个小区间的值,最后再全部合并起来。

比如上述问题,我们将问题转化为:

\[\int_{-1}^0\frac{3x+4}{x+2}dx+\int_0^1\frac{3x+4}{x+2}dx\cong 3.8 \]

假如肯再分解一层,就会得到 \(3.802549\cdots\),已经相当接近正确答案 \(3.802775\cdots\) 了。

但是显然,继续再分解下去一定会造成 \(TLE\),所以当务之急是确定递归的边界条件。

想法也很简单,假如满足:

\[|\int_a^bf_{a,b,2}(x)-(\int_a^cf_{a,c,2}(x)+\int_c^bf_{c,b,2}(x))|\le \alpha\times eps \]

那么就停止递归,否则继续递归,同时 \(eps=\frac{eps}2\)。这里 \(\alpha\) 是一个常量,基本上可以说卡常专用了。

#include<bits/stdc++.h>
#define fsc(x) fixed<<setprecision(x)
using namespace std;
double a,b,c,d,L,R;
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)+f(mid)*4+f(r))*(r-l)/6;
}double dfs(double l,double r,double as,double eps){double mid=(l+r)/2;double a0=simpson(l,mid),a1=simpson(mid,r);if(fabs(a0+a1-as)<=eps*15)return a0+a1+(a0+a1-as)/15;return dfs(l,mid,a0,eps/2)+dfs(mid,r,a1,eps/2);
}int main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>a>>b>>c>>d>>L>>R;cout<<fsc(6)<<dfs(L,R,simpson(L,R),1e-6);return 0;
}

面积并

众所周知,有一道《计算几何水题》,他叫月下柠檬树。这里将以这道题讲解面积并问题如何转化为 Simpson 积分。


计算几何部分,考虑圆的投影还是一个等大的圆,只需要确定圆心就可以了。

圆台有两种情况。假如一个大圆完全包含另一个小圆,那么圆台的投影就是大圆;否则两圆必有两条公切线,连接后形成的图形即为圆台投影。

转化为公切线两端点,向各自圆心连线,加上公切线和两圆心连线所围成的图形(实为直角梯形)与两圆的面积并。

圆形部分好求,用相似三角形和勾股定理可以简单求出直角梯形的四个交点。

为减少时间复杂度,我们将圆形转为半圆,同时每个圆台只保留一个梯形,最终答案 \(\times 2\) 即可。


注:我求面积并的方法比较非主流,不喜勿喷。

那我们考虑设 \(f(x_0)\) 表示对于每个图形,和 \(x=x_0\) 的两个交点连成的线段的线段并。假如没有两个交点,那么我们就不管它。

有一个基本的思路是,面积并等于大量线段并之和,所以我们这样定义。

将梯形转化为更好求解的三角形,再进行求解即可。

#include<bits/stdc++.h>
#include<bits/extc++.h>
#define fsc(x) fixed<<setprecision(x)
#define SZ 5056577
using namespace std;
const int N=1505;
int n,m,k;double rd[N],o[N];
double al,sc[N][3][2],L,R;
struct hash_map{struct data{double v;int u,nex;};data e[SZ<<1];int h[SZ],cnt;double& operator[](int u){int hu=u%SZ;for(int i=h[hu];i;i=e[i].nex) if(e[i].u==u) return e[i].v;return e[++cnt]=(data){0.0,u,h[hu]},h[hu]=cnt,e[cnt].v;}
}mp;struct line{double l,r;}ans[N];
int cmp(line x,line y){return x.l<y.l;}
double dts(double *a,double *b,double x){return a[1]+(a[1]-b[1])/(a[0]-b[0])*(x-a[0]);
}double f(double x){if(mp[(int)(x*500)]) return mp[(int)(x*500)];for(int i=1;i<=n;i++){if(x<o[i]-rd[i]||x>o[i]+rd[i]) continue;ans[++k].l=0;ans[k].r=sqrt(rd[i]*rd[i]-pow(x-o[i],2));}for(int i=1;i<=m;i++){if(x<sc[i][0][0]||x>sc[i][2][0]) continue;ans[++k].l=dts(sc[i][0],sc[i][2],x);ans[k].r=dts(sc[i][1],sc[i][2*(sc[i][1][0]<x)],x);if(ans[k].l>ans[k].r) swap(ans[k].l,ans[k].r);}sort(ans+1,ans+k+1,cmp);double re=0,lst=-1e9;for(int i=1;i<=k;lst=max(lst,ans[i++].r))re+=max(0.0,ans[i].r-max(lst,ans[i].l));return k=0,mp[(int)(x*500)]=re*2;
}double simpson(double l,double r){return (f(l)+4*f((l+r)/2)+f(r))*(r-l)/6;
}double dfs(double l,double r,double as,double eps){double mid=(l+r)/2;double a0=simpson(l,mid),a1=simpson(mid,r);if(fabs(a0+a1-as)<=eps*15) return a0+a1+(a0+a1-as)/15;return dfs(l,mid,a0,eps/2)+dfs(mid,r,a1,eps/2);
}signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>al,L=1e9,R=-1e9;for(int i=1;i<=n+1;i++) cin>>o[i],o[i]+=o[i-1];for(int i=1;i<=n;i++){o[i]/=tan(al),cin>>rd[i];L=min(o[i]-rd[i],L);R=max(o[i]+rd[i],R);}o[n+1]/=tan(al);L=min(o[n+1],L),R=max(o[n+1],R);for(int i=1;i<=n;i++){if(o[i]+rd[i]>=o[i+1]+rd[i+1]) continue;if(o[i]-rd[i]>=o[i+1]-rd[i+1]) continue;sc[++m][1][0]=o[i+1],sc[m+1][0][0]=sc[m][0][0]=o[i];sc[m+1][2][0]=sc[m][2][0]=o[i+1]+(rd[i]-rd[i+1])*rd[i+1]/(o[i+1]-o[i]);sc[m+1][2][1]=sc[m][2][1]=sqrt(rd[i+1]*rd[i+1]-pow(sc[m][2][0]-o[i+1],2));sc[++m][1][0]=o[i]+(rd[i]-rd[i+1])*rd[i]/(o[i+1]-o[i]);sc[m][1][1]=sqrt(rd[i]*rd[i]-pow(sc[m][1][0]-o[i],2));}for(int i=1;i<=m;i++){if(sc[i][0][0]>sc[i][1][0])swap(sc[i][0],sc[i][1]);if(sc[i][1][0]>sc[i][2][0])swap(sc[i][1],sc[i][2]);if(sc[i][0][0]>sc[i][1][0])swap(sc[i][0],sc[i][1]);}cout<<fsc(2)<<dfs(L,R,simpson(L,R),2e-3);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878218.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

龙哥量化:通达信技术指标编写技巧分享篇1-成交量和换手率

龙哥微信:Long622889代写通达信技术指标、选股公式(通达信,同花顺,东方财富,大智慧,文华,博易,飞狐)代写期货量化策略(TB交易开拓者,文华8,金字塔) 春节假期, 和朋友闲聊,发现在选股思路上很杂乱, 完全没有体系,但是大致可以分为两种,趋势策略和震荡策略,其…

昆明理工大学材料科学与工程学院 2025年硕士研究生招生预测调剂名额 (供考生提前规划)

亲爱的考生: 为助力各位考生提前规划考研调剂方向,昆明理工大学材料科学与工程学院结合近年招生趋势及学科发展需求,预测2025年材料工程相关专业将有部分调剂名额,具体信息如下。欢迎符合条件的考生持续关注! 一、预测调剂专业及名额注: 最终调剂名额以2025年研招网官方发…

hive-pig--pig安装

1.下载 curl https://dlcdn.apache.org/pig/pig-0.17.0/pig-0.17.0.tar.gz -o /opt/software/pig-0.17.0.tar.gz2.解压 tar -zxvf /opt/software/pig-0.17.0.tar.gz -C /usr/local/src/ mv /usr/local/src/pig-0.17.0/ /usr/local/src/pig 3.把二进制路径添加到命令行路径 echo…

PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络

神经常微分方程(Neural ODEs)是深度学习领域的创新性模型架构,它将神经网络的离散变换扩展为连续时间动力系统。与传统神经网络将层表示为离散变换不同,Neural ODEs将变换过程视为深度(或时间)的连续函数。这种方法为机器学习开创了新的研究方向,尤其在生成模型、时间序…

[ArkUI] 记录一次 ArkUI 学习心得 (1) -- 基础概念

1.一个原生鸿蒙应用的源码目录其中:ets是项目的源码目录.ets/pages是页面目录, 用于渲染页面.resources是资源目录,下面会讲. 2.第一个原生鸿蒙应用 话不多说,直接上代码. @Entry @Component struct Index {@State message: string = My First Program!;@State num: number = 0…

互联网已经没法用了

图片:作者制作我们已经到了这样的地步——曾经能让我们随时随地获取全世界信息的互联网,现在已经完全没法用了。 罪魁祸首是广告,情况糟糕到一种极端的程度,以至于它被称为“广告末日”(adpocalypse)。 现在我打开的几乎每个网站都塞满了广告,整个页面都快撑爆了。在电脑…

uniCloud(dcloud.net.cn)https证书配制

前端网页托管-->参数配置-->域名信息-->更新证书 阿里云 https--SSL证书获取

Cisco Catalyst 9800-CL Wireless Controller for Cloud, IOS XE Release 17.16.1 ED - 思科虚拟无线控制器系统软件

Cisco Catalyst 9800-CL Wireless Controller for Cloud, IOS XE Release 17.16.1 ED - 思科虚拟无线控制器系统软件Cisco Catalyst 9800-CL Wireless Controller for Cloud, IOS XE Release 17.16.1 ED 面向云的思科 Catalyst 9800-CL 无线控制器,专为基于意图的网络全新打造…

Cisco Catalyst 9800 Wireless Controller, IOS XE Release 17.16.1 ED - 思科无线控制器系统软件

Cisco Catalyst 9800 Wireless Controller, IOS XE Release 17.16.1 ED - 思科无线控制器系统软件Cisco Catalyst 9800 Wireless Controller, IOS XE Release 17.16.1 ED 思科 Catalyst 9800 系列无线控制器 IOS XE 系统软件 请访问原文链接:https://sysin.org/blog/cisco-cat…

图解收银台

收银核心和支付引擎是支付系统最核心的两个子系统之一。本篇主要讲清楚收银核心的设计与实现,包括收银核心如何渲染可用支付方式,如何做可支付检查,收银台核心的系统架构、领域模型,常见支付方式等。如果说电子商务是现代经济的繁华都市,那么在线支付系统无疑就是最繁忙的…

Easysearch 集群重置 admin 用户密码

admin 用户是 Easysearch 通过配置文件 user.yml 默认添加的,配置如下: ## Demo users admin:hash: "$2y$12$mA9DDk7iOBQA3u.Ebc0QSOVKsgwlkm6OJcrEcpyrTrT5M5It86usq" # 465f7466f79a67b9039dreserved: trueexternal_roles:- "admin"description: "…

Linux 中awk命令自定义函数

001、[root@PC1 test]# echo a | awk function my_length(str) {return length(str)}; {text = "Hello"; print "Length of text:", my_length(text)} Length of text: 5 。