数值方法求积分 详解+模板代码
来源:互联网 发布:j罗 皇马 数据 编辑:程序博客网 时间:2024/04/30 12:33
什么是数值积分
数值积分可以用来求定积分的近似值。对于很多函数来说,我们是可以使用初等函数来表示出其积分的,对于这种函数,只需要求出不定积分然后代入值就能得到定积分了。
可是除此之外还有许多难求的函数和没法使用初等函数表示的函数。当我们想要求出它们的定积分的时候,需要使用数值积分来求解。
在ACM中一些题目需要使用数值积分来求解,以下列出一些求数值积分的方法,由简单到难,而对ACMer来说最重要的是复合Simpson,其精度较高,且可调精度,是乱搞积分几何的利器。
我从这学的:网易公开课 MIT 数值积分
学习的契机是想要A掉这题:ZOJ 3898
我的题解
法一·黎曼和
黎曼和是用将区间等长分为
n 段,然后用矩形去逼近函数,每段的长为Δx 。可以选择每段左侧的函数值作为矩形的高,也可以选择每段右侧的函数值作为矩形的高。
若设
n+1 个函数值从左至右为x0,x1⋯xn ,可得如下公式:这种逼近比较粗糙,不过能比较好地传达数值积分的概念。Left Hand Riemann=Right Hand Riemann=Δxf(x0)+Δxf(x1)+⋯+Δxf(xn−1)=Δx∑i=0n−1f(xi)Δxf(x1)+Δxf(x2)+⋯+Δxf(xn)=Δx∑i=1nf(xi)
法二·梯形法
黎曼和虽然简单,但是精度堪忧,没法很好地模拟逼近函数,接下来介绍第二种方法。
可以看出用矩形逼近的时候有很多空缺,使用梯形去逼近,就能大大提高精度了,看上去很像了。
沿用之前的xi ,由梯形公式我们可以得到如下公式:Trapezoid=Δx(f(x0)+f(x1))2+Δx(f(x1)+f(x2))2+⋯+Δx(f(xn−1)+f(xn))2=Δx(f(x0)2+f(x1)+⋯+f(xn−1)+f(xn)2)=Left Hand Riemann+Right Hand Riemann2
可以看出梯形法求出的就是左右黎曼和的平均值。公式中第一个和最后一个需要除以
2 其他都能合出来1 个。
法三·Simpson公式
前两种都比较简单,但是精度比较差,第三种方法是用抛物线去逼近。
其实我并不知道是怎么计算的,是从公开课上学来的。
使用
Simpson 公式首先需要n 为偶数。将整个区间分为
n2 段,每段的底为2Δx ,高比较难搞,但是是有公式的:Simpson height=f(xl)+4f(xm)+f(xr)6 于是有公式:
Simpson=Δx3(f(x0)+4f(x1)+2f(x2)+⋯+2f(xn−2)+4f(xn−1)+f(xn))
法四·复合Simpson
Simpson 公式的精度其实已经相当不错了,可是相对于ACM中所需的精度仍然有差距。为了提高精度,我们需要多次重复利用
Simpson 公式。我们先定义被积函数为
f(x) ,定义Simpson(l,r)=(r−l)f(l)+4f(l+r2)+f(r)6 这也就是常规的
Simpson 公式,再定义函数RSimpson 为复合Simpson 。当我们要求
RSimpson(l,r) ,先令m=l+r2 当
Simpson(l,r)≈Simpson(l,m)+Simpson(m,r) 时我们就认为精度够了返回其中一个。当不满足的时候我们就再分段去求
RSimpson(l,m)+RSimpson(m,r) 这样得到的精度就比较高了,而且通过定义
≈ 的范围可以调整精度。总结公式如下:
RSimpson(l,r)={Simpson(l,r) approximateRSimpson(l,m)+RSimpson(m,r) else
复合Simpson的实现
inline double getAppr(double fl, double fm, double fr, double l, double r) { return (fl+4*fm+fr)*(r-l)/6.0;}double Simpson(double l, double r, double fl, double fr) { double m = (l+r)/2, lm = (l+m)/2, rm = (r+m)/2; double fm = f(m), flm = f(lm), frm = f(rm); double vlr = getAppr(fl, fm, fr, l, r); double vlm = getAppr(fl, flm, fm, l, m); double vrm = getAppr(fm, frm, fr, m, r); return fabs(vlr-vlm-vrm) < EPS ? vlr : Simpson(l, m, fl, fm)+Simpson(m, r, fm, fr);}
复合Simpson的实现2(Natureal的代码)
inline double getAppr(double l,double r){ return (f(l) + 4.0*f((l+r)/2) + f(r)) * (r - l) / 6.0;}double Simpson(double l,double r){ double sum = getAppr(l,r); double mid = (l+r)/2; double suml = getAppr(l,mid); double sumr = getAppr(mid,r); return (fabs(sum - suml - sumr) < EPS) ? sum : Simpson(l, mid) + Simpson(mid, r);}
- 数值方法求积分 详解+模板代码
- matlab数值积分方法求pi的近似值及其比较
- 数值积分方法
- C++求积分代码
- 变步长梯形求数值积分
- java 多线程并行求数值积分(πPI) 之 join() 方法应用
- 数值计算方法 数值积分(伪代码 c/c++ python)
- matlab数值积分中函数积分的4种方法
- 利用蒙特卡罗方法求积分
- 数值积分
- 数值积分
- 数值积分
- 数值积分
- 数值积分
- 数值积分
- 数值积分
- 求定积分的算法模板
- 自适应辛普森公式求积分模板
- Maven随笔之一:Maven环境搭建与第一个maven项目
- C++ HDU 2081 手机短号
- 在win2008R2上使用(NLB)网络负载均衡
- EventBus3.0的使用
- C++预学习
- 数值方法求积分 详解+模板代码
- Oracle数据库使用DMP文件恢复数据
- laravel框架实现phpExcel导入导出
- Eclipse的自动补全功能开启方法
- FreeRTOS操作系统教程,支持F103,F407和F429,配套145个例子,1200页教程
- javaweb中mysql数据库连接方法
- 安装NetWeaver Java 7.5(Windows 2012 R2上)
- HDU 1325 Is It A Tree? 并查集判断是否成树
- Random rand =new Random(47);