一、积分的概念
积分(integral)的几何意义是函数的曲线上 x x 的一段区间与 x x 轴围成的曲边梯形的面积:
x x 的区间为 [a,b] [ a , b ] ,那么上图阴影面积为:
∫baf(x)dx ∫ a b f ( x ) d x
计算方法一:分割成无穷多个小区间。
∫baf(x)dx=limn→∞∑i=1nb−anf(a+b−ani) ∫ a b f ( x ) d x = lim n → ∞ ∑ i = 1 n b − a n f ( a + b − a n i )
计算方法二:牛顿-莱布尼茨公式。
若
F′(x)=f(x) F ′ ( x ) = f ( x ) ,那么
∫baf(x)dx=F(b)−F(a) ∫ a b f ( x ) d x = F ( b ) − F ( a )
如果容易求出
n n 趋近于无穷大时
f f 的和,可以使用方法一,如
f(x)=x2 f ( x ) = x 2 。
而这时
f(x)=1x f ( x ) = 1 x 就不适用。
如果容易求得
F F ,可以使用方法二,如
f(x)=1x f ( x ) = 1 x 。
但如果两个特点都不满足,那么两种方法都无法使用。
于是,我们引入了
数值积分。
最常用的就是自适应辛普森积分。
二、辛普森公式
基本思想就是把复杂的函数 f f 近似成二次函数。
∫baf(x)dx≈∫ba(Ax2+Bx+C)dx ∫ a b f ( x ) d x ≈ ∫ a b ( A x 2 + B x + C ) d x
=A3(b3−a3)+B2(b2−a2)+C(b−a) = A 3 ( b 3 − a 3 ) + B 2 ( b 2 − a 2 ) + C ( b − a )
=2A(b3−a3)+3B(b2−a2)+6C(b−a)6 = 2 A ( b 3 − a 3 ) + 3 B ( b 2 − a 2 ) + 6 C ( b − a ) 6
=2A(b−a)(b2+ab+a2)+3B(b+a)(b−a)+6C(b−a)6 = 2 A ( b − a ) ( b 2 + a b + a 2 ) + 3 B ( b + a ) ( b − a ) + 6 C ( b − a ) 6
=(b−a)(2Ab2+2Aab+2Aa2+3Bb+3Ba+6C)6 = ( b − a ) ( 2 A b 2 + 2 A a b + 2 A a 2 + 3 B b + 3 B a + 6 C ) 6
=(b−a)(Aa2+Ba+C+Ab2+Bb+C+Aa2+2Aab+Ab2+2Bb+2Ba+4C)6 = ( b − a ) ( A a 2 + B a + C + A b 2 + B b + C + A a 2 + 2 A a b + A b 2 + 2 B b + 2 B a + 4 C ) 6
=(b−a)(f(a)+f(b)+A(a+b)2+2B(a+b)+4C)6 = ( b − a ) ( f ( a ) + f ( b ) + A ( a + b ) 2 + 2 B ( a + b ) + 4 C ) 6
=(b−a)(f(a)+f(b)+4(A(a+b2)2+B(a+b2)+C))6 = ( b − a ) ( f ( a ) + f ( b ) + 4 ( A ( a + b 2 ) 2 + B ( a + b 2 ) + C ) ) 6
=(b−a)(f(a)+f(b)+4f(a+b2))6 = ( b − a ) ( f ( a ) + f ( b ) + 4 f ( a + b 2 ) ) 6
我们得到辛普森公式:
∫baf(x)dx≈(b−a)(f(a)+f(b)+4f(a+b2))6 ∫ a b f ( x ) d x ≈ ( b − a ) ( f ( a ) + f ( b ) + 4 f ( a + b 2 ) ) 6
b−a b − a 的值越小,上式两边越接近。
三、处理精度问题
有了 Simpson 公式,一个自然的想法是把积分区间拆成多个小区间后求和。
但是分成区间的个数和长度因积分区间和精度要求甚至被积函数而异。
换句话说,分的区间数太少不满足精度要求,太多了会 TLE 。
「自适应」就是求积分时能够自动控制切割的区间大小和长度,使精度能满足要求。
具体地: solve(l,r,f) s o l v e ( l , r , f ) 表示求 ∫rlf(x)dx ∫ l r f ( x ) d x 。
(1)取 mid=l+r2 m i d = l + r 2 。
(2)用 Simpson 公式近似计算 f(x) f ( x ) 在区间 [l,mid] [ l , m i d ] 和区间 [mid,r] [ m i d , r ] 内的积分,分别为 ls l s 和 rs r s ,及 [l,r] [ l , r ] 的近似积分 sum s u m 。
(3)如果 ls+rs l s + r s 与 sum s u m 的误差允许,则返回 sum s u m 。
(4)否则递归 solve(l,mid) s o l v e ( l , m i d ) 和 solve(mid,r) s o l v e ( m i d , r ) ,返回这两个递归计算结果的和。
四、代码
很短。
double solve(double L, double R, double ans) {
double mid = (L + R) / 2, l = simpson(L, mid), r = simpson(mid, R);
if (fabs(l + r - ans) <= eps) return ans;
return solve(L, mid, l) + solve(mid, R, r);
}
五、应用