数值积分的python实现——NewtonCotes、复化求积、Romberg、richardson递推
数值积分的python实现——NewtonCotes,复化求积,Romberg,richardson递推
- 1. 机械求积
- 2. Newton-Cotes公式
- 3. 复化求积方法
- 3.1 复化梯形公式
- 3.2 复化辛普森公式
- 实现代码
- 4. 求积公式的递推化
- 4.1 复化梯形公式的递推化
- 实现代码
- 4.2 龙贝格(Romberg)算法
- 4.3 理查森(Richardson)外推算法
- 实现代码
\qquad 使用牛顿-莱布尼兹公式直接去求一个函数 f ( x ) f(x) f(x) 在区间 [ a , b ] [a,b] [a,b] 上的定积分值 I I I,在数值方法上比较困难,因为需要先求出被积函数的原函数 F ( x ) F(x) F(x)。
I = ∫ a b f ( x ) d x = F ( b ) − F ( a ) \qquad\qquad I=\displaystyle\int_a^bf(x)dx=F(b)-F(a) I=∫abf(x)dx=F(b)−F(a)
\qquad 通过积分中值定理,在积分区间 [ a , b ] [a,b] [a,b] 上存在某个点 ξ \xi ξ,使得
I = ∫ a b f ( x ) d x = ( b − a ) f ( ξ ) , ξ ∈ ( a , b ) \qquad\qquad I=\displaystyle\int_a^bf(x)dx=(b-a)f(\xi),\quad\xi\in(a,b) I=∫abf(x)dx=(b−a)f(ξ),ξ∈(a,b)
\qquad
1. 机械求积
\qquad 根据积分中值定理,只需要合理选择 ξ ∈ ( a , b ) \xi\in(a,b) ξ∈(a,b) 的值,就可以求出定积分,例如最基本的梯形公式和中矩形公式。
\qquad
用红色虚线矩形的面积,代替 f ( x ) f(x) f(x) 与 x x x 轴所围的面积。
梯形公式
: 取 f ( ξ ) ≈ f ( a ) + f ( b ) 2 f(\xi)\approx\dfrac{f(a)+f(b)}{2} f(ξ)≈2f(a)+f(b)
∫ a b f ( x ) d x = b − a 2 [ f ( a ) + f ( b ) ] \qquad\qquad\displaystyle\int_a^bf(x)dx=\dfrac{b-a}{2}[f(a)+f(b)] ∫abf(x)dx=2b−a[f(a)+f(b)]
中矩形公式
: 取 f ( ξ ) ≈ f ( a + b 2 ) f(\xi)\approx f\left(\dfrac{a+b}{2}\right) f(ξ)≈f(2a+b)
∫ a b f ( x ) d x = ( b − a ) f ( a + b 2 ) \qquad\qquad\displaystyle\int_a^bf(x)dx=(b-a)f\left(\dfrac{a+b}{2}\right) ∫abf(x)dx=(b−a)f(2a+b)
\qquad 更一般地,可以在积分区间 [ a , b ] [a,b] [a,b] 上选取一些求积节点 x k x_k xk,用 f ( x k ) f(x_k) f(xk) 的加权平均(权值为 A k A_k Ak)来近似 f ( ξ ) f(\xi) f(ξ) 的值,也就是采用“机械求积”方法:
f ( ξ ) ≈ ∑ k = 0 n A k f ( x k ) \qquad\qquad f(\xi)\approx\displaystyle\sum_{k=0}^nA_kf(x_k) f(ξ)≈k=0∑nAkf(xk) ⟹ ∫ a b f ( x ) d x = ( b − a ) ∑ k = 0 n A k f ( x k ) \ \ \ \Longrightarrow\displaystyle\int_a^bf(x)dx=(b-a)\displaystyle\sum_{k=0}^nA_kf(x_k) ⟹∫abf(x)dx=(b−a)k=0∑nAkf(xk)
梯形公式: n = 2 , A 0 = 1 , x 0 = a , A 1 = 1 , x 1 = b n=2,A_0=1,x_0=a,A_1=1,x_1=b n=2,A0=1,x0=a,A1=1,x1=b
中矩形公式: n = 1 , A 0 = 1 , x 0 = a + b 2 n=1,A_0=1,x_0=\dfrac{a+b}{2} n=1,A0=1,x0=2a+b
2. Newton-Cotes公式
\qquad 将积分区间 [ a , b ] [a,b] [a,b] 划分为 n n n 等分,步长为 h = b − a n h=\dfrac{b-a}{n} h=nb−a,选取等距求积节点 x k = a + k h x_k=a+kh xk=a+kh 构造出牛顿-科特斯 (Newton-Cotes) \text{(Newton-Cotes)} (Newton-Cotes) 公式:
I n = ( b − a ) ∑ k = 0 n C k ( n ) f ( x k ) \qquad\qquad I_n=(b-a)\displaystyle\sum_{k=0}^nC_k^{(n)}f(x_k) In=(b−a)k=0∑nCk(n)f(xk)
\qquad 其中, C k ( n ) C_k^{(n)} Ck(n) 为科特斯系数,若 x = a + t h x=a+th x=a+th,则
C k ( n ) = h b − a ∫ 0 n ∏ j = 0 j ≠ k n t − j k − j d t = ( − 1 ) n − k n k ! ( n − k ) ! ∫ 0 n ∏ j = 0 j ≠ k n ( t − j ) d t \qquad\qquad C_k^{(n)}=\dfrac{h}{b-a}\displaystyle\int_0^n\displaystyle\prod^n_{j=0\atop j\ne k}\dfrac{t-j}{k-j}dt=\dfrac{(-1)^{n-k}}{nk!(n-k)!}\displaystyle\int_0^n\displaystyle\prod_{j=0\atop j\ne k}^n(t-j)dt Ck(n)=b−ah∫0nj=kj=0∏nk−jt−jdt=nk!(n−k)!(−1)n−k∫0nj=kj=0∏n(t−j)dt
\qquad
当 n = 1 n=1 n=1 时, C 0 ( 1 ) = C 1 ( 1 ) = 1 2 C_0^{(1)}=C_1^{(1)}=\dfrac{1}{2} C0(1)=C1(1)=21,也就是梯形公式(单区间, x 0 = a , x 1 = b x_0=a,x_1=b x0=a,x1=b)
T = I 1 = b − a 2 [ f ( a ) + f ( b ) ] \qquad\qquad T=I_1=\dfrac{b-a}{2}[f(a)+f(b)] T=I1=2b−a[f(a)+f(b)]
当 n = 2 n=2 n=2 时, C 0 ( 2 ) = 1 6 , C 1 ( 2 ) = 4 6 , C 2 ( 2 ) = 1 6 C_0^{(2)}=\dfrac{1}{6},C_1^{(2)}=\dfrac{4}{6},C_2^{(2)}=\dfrac{1}{6} C0(2)=61,C1(2)=64,C2(2)=61,也就是辛普森 (Simpson) \text{(Simpson)} (Simpson)公式( 2 2 2 等分区间)
S = I 2 = b − a 6 [ f ( a ) + 4 f ( a + b 2 ) + f ( b ) ] \qquad\qquad S=I_2=\dfrac{b-a}{6}\left[f(a)+4f\left(\dfrac{a+b}{2}\right)+f(b)\right] S=I2=6b−a[f(a)+4f(2a+b)+f(b)]
当 n = 4 n=4 n=4 时,也就是科特斯公式( 4 4 4 等分区间)
C = I 4 = b − a 90 [ 7 f ( a ) + 32 f ( x 1 ) + 12 f ( x 2 ) + 32 f ( x 3 ) + 7 f ( b ) ] \qquad\qquad C=I_4=\dfrac{b-a}{90}\left[7f(a)+32f(x_1)+12f(x_2)+32f(x_3)+7f(b)\right] C=I4=90b−a[7f(a)+32f(x1)+12f(x2)+32f(x3)+7f(b)]
\qquad 其中, x 0 = a , x 4 = b , x k = a + k h , h = b − a 4 x_0=a,x_4=b,x_k=a+kh,h=\dfrac{b-a}{4} x0=a,x4=b,xk=a+kh,h=4b−a
【注意】当 n ≥ 8 n\ge8 n≥8 时,科特斯系数 C k ( n ) C_k^{(n)} Ck(n) 出现负值,求积计算变得不稳定。
\qquad
3. 复化求积方法
\qquad 由于高阶的牛顿-科特斯公式不稳定,无法通过提高阶数 n n n 来提高求积精度。
\qquad 为了提高精度,可以采用复化求积方法:将积分区间 [ a , b ] [a,b] [a,b] 分成若干个子区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1],在每个子区间上采用低阶 ( n < 8 ) (n<8) (n<8) 的牛顿-科特斯公式。
\qquad
3.1 复化梯形公式
\qquad 将积分区间 [ a , b ] [a,b] [a,b] 进行 n n n 等分,步长为 h = b − a n h=\dfrac{b-a}{n} h=nb−a,等距求积节点 x k = a + k h , k = 0 , 1 , ⋯ , n x_k=a+kh,k=0,1,\cdots,n xk=a+kh,k=0,1,⋯,n,在每个子区间 [ x k , x k + 1 ] , k = 0 , 1 , ⋯ , n − 1 [x_k,x_{k+1}],k=0,1,\cdots,n-1 [xk,xk+1],k=0,1,⋯,n−1 上采用梯形公式:
T ( k ) = x k + 1 − x k 2 [ f ( x k ) + f ( x k + 1 ) ] = h 2 [ f ( x k ) + f ( x k + 1 ) ] \qquad\qquad T^{(k)}=\dfrac{x_{k+1}-x_k}{2}[f(x_k)+f(x_{k+1})]=\dfrac{h}{2}[f(x_k)+f(x_{k+1})] T(k)=2xk+1−xk[f(xk)+f(xk+1)]=2h[f(xk)+f(xk+1)]
\qquad 记 n n n 等分时求得积分的结果为 T n T_n Tn,那么
∫ a b f ( x ) d x ≈ T n = ∑ k = 0 n − 1 T ( k ) = h 2 ∑ k = 0 n − 1 [ f ( x k ) + f ( x k + 1 ) ] \qquad\qquad\displaystyle\int_a^bf(x)dx\approx T_n=\displaystyle\sum_{k=0}^{n-1}T^{(k)}=\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+f(x_{k+1})] ∫abf(x)dx≈Tn=k=0∑n−1T(k)=2hk=0∑n−1[f(xk)+f(xk+1)]
误差为 R n ( f ) = − b − a 12 h 2 f ′ ′ ( η ) , η ∈ ( a , b ) R_n(f)=-\dfrac{b-a}{12}h^2f^{''}(\eta),\quad\eta\in(a,b) Rn(f)=−12b−ah2f′′(η),η∈(a,b) 为 h 2 h^2 h2 阶
\qquad
3.2 复化辛普森公式
\qquad 将积分区间 [ a , b ] [a,b] [a,b] 进行 n n n 等分,步长为 h = b − a n h=\dfrac{b-a}{n} h=nb−a,等距求积节点 x k = a + k h , k = 0 , 1 , ⋯ , n x_k=a+kh,k=0,1,\cdots,n xk=a+kh,k=0,1,⋯,n,在每个子区间 [ x k , x k + 1 ] , k = 0 , 1 , ⋯ , n − 1 [x_k,x_{k+1}],k=0,1,\cdots,n-1 [xk,xk+1],k=0,1,⋯,n−1 上采用辛普森公式:
S ( k ) = x k + 1 − x k 6 [ f ( x k ) + 4 f ( x k + 1 2 ) + f ( x k + 1 ) ] = h 6 [ f ( x k ) + 4 f ( x k + 1 2 ) + f ( x k + 1 ) ] \qquad\qquad\begin{aligned}S^{(k)}&=\dfrac{x_{k+1}-x_k}{6}\left[f(x_k)+4f\left(x_{k+\frac{1}{2}}\right)+f(x_{k+1})\right]\\ &=\dfrac{h}{6}\left[f(x_k)+4f\left(x_{k+\frac{1}{2}}\right)+f(x_{k+1})\right]\end{aligned} S(k)=6xk+1−xk[f(xk)+4f(xk+21)+f(xk+1)]=6h[f(xk)+4f(xk+21)+f(xk+1)]
\qquad 记 n n n 等分时求得积分的结果为 S n S_n Sn,那么
∫ a b f ( x ) d x ≈ S n = ∑ k = 0 n − 1 S ( k ) = h 6 ∑ k = 0 n − 1 [ f ( x k ) + 4 f ( x k + 1 2 ) + f ( x k + 1 ) ] \qquad\qquad\displaystyle\int_a^bf(x)dx\approx S_n=\displaystyle\sum_{k=0}^{n-1}S^{(k)}=\dfrac{h}{6}\displaystyle\sum_{k=0}^{n-1}\left[f(x_k)+4f\left(x_{k+\frac{1}{2}}\right)+f(x_{k+1})\right] ∫abf(x)dx≈Sn=k=0∑n−1S(k)=6hk=0∑n−1[f(xk)+4f(xk+21)+f(xk+1)]
误差 R n ( f ) = − b − a 180 ( h 2 ) 4 f ( 4 ) ( η ) , η ∈ ( a , b ) R_n(f)=-\dfrac{b-a}{180}\left(\dfrac{h}{2}\right)^4f^{(4)}(\eta),\quad\eta\in(a,b) Rn(f)=−180b−a(2h)4f(4)(η),η∈(a,b) 为 h 4 h^4 h4 阶
实现代码
例:求积分 I = ∫ 0 1 sin ( x ) x d x I=\displaystyle\int_0^1\dfrac{\sin(x)}{x}dx I=∫01xsin(x)dx, 7 7 7 位有效数字准确值为 0.9460831 0.9460831 0.9460831
import numpy as npdef trapezoid(f,a,b): # trapezoid(n=1)return (b-a)*(f(b)+f(a))/2def simpson(f,a,b): # simpson(n=2)t = (a+b)/2val = (b-a)*(f(a)+4*f(t)+f(b))/6return valdef compositeInt(f,a,b,n,mode='trapezoid'):h = (b-a)/nval = 0eps = 1e-10if mode=='trapezoid':for k in range(n):xk = a+k*h+epsxk1 = xk+hval += trapezoid(f,xk,xk1) if mode=='simpson':for k in range(n):xk = a+k*h+epsxk1 = xk+hval += simpson(f,xk,xk1) return valif __name__ == '__main__':a = 0b = 1f = lambda x: np.sin(x)/x print('====== trapezoid: newton-cotes(1st-order) ======')val = compositeInt(f, a, b, 8)print('trapezoid: %.7f' % (val)) print('====== simpson: newton-cotes(2nd-order) ======')val = compositeInt(f, a, b, 4,'simpson')print('simpson: %.7f' % (val))
运行结果:
====== trapezoid: newton-cotes(1st-order) ======
trapezoid: 0.9456909 (2位有效数字)
====== simpson: newton-cotes(2nd-order) ======
simpson: 0.9460833 (6位有效数字)
( 1 ) \qquad(1) (1) 由于 4 4 4 等分的复化辛普森方法在每个子区间上还需要再计算一个二分点,因此区间的等分数实际上是 8 8 8 等分。
( 2 ) \qquad(2) (2) 然而, 4 4 4 等分的复化辛普森方法的精度高于 8 8 8 等分的复化梯形方法。由误差公式也可计算出 ∣ R 8 ( f ) ∣ ≤ 0.000434 \vert R_8(f)\vert\le0.000434 ∣R8(f)∣≤0.000434 以及 ∣ R 4 ( f ) ∣ ≤ 0.271 × 1 0 − 6 \vert R_4(f)\vert\le0.271\times10^{-6} ∣R4(f)∣≤0.271×10−6。
\qquad
4. 求积公式的递推化
\qquad 复化求积方法如果要提高精度,就必然增加求积子区间的数量。例如,将 [ a , b ] [a,b] [a,b] 进行 n n n 等分时,求积节点的数量为 n + 1 n+1 n+1;若将每个求积区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1] 再一分为二,求积节点的数量变为 2 n + 1 2n+1 2n+1,每次等分之后,求积区间的数量就要翻倍。如果仍然在每个子区间上使用复化公式,无疑会极大地增加计算量。
\qquad 为了提高计算效率,可以将等分前后的积分值与进行比较,从而形成“递推关系”。
\qquad
4.1 复化梯形公式的递推化
\qquad 为了提高复化求积公式的精度,可以选择将每个求积子区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1] 一分为二的方式,也就在区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1] 增加一个等距的中间点 x k + 1 2 = 1 2 ( x k + x k + 1 ) x_{k+\frac{1}{2}}=\dfrac{1}{2}(x_k+x_{k+1}) xk+21=21(xk+xk+1)。
\qquad
- 假设将 [ a , b ] [a,b] [a,b] 等分 n n n 个点 a , x 1 , ⋯ , x n − 2 , b a,x_1,\cdots,x_{n-2},b a,x1,⋯,xn−2,b,步长 h = b − a n h=\dfrac{b-a}{n} h=nb−a,考虑复化梯形公式:
1 ) \qquad1) 1) 以求积子区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1] 为例, n n n 等分时的梯形公式为
T 1 = h 2 [ f ( x k ) + f ( x k + 1 ) ] \qquad\qquad T_1=\dfrac{h}{2}[f(x_k)+f(x_{k+1})] T1=2h[f(xk)+f(xk+1)]
2 ) \qquad2) 2) 进行 2 n 2n 2n 等分时,需要将每个求积子区间 [ x k , x k + 1 ] [x_k,x_{k+1}] [xk,xk+1] 一分为二,变成了两个等距的子区间 [ x k , x k + 1 2 ] [x_k,x_{k+\frac{1}{2}}] [xk,xk+21] 和 [ x k + 1 2 , x k + 1 ] [x_{k+\frac{1}{2}},x_{k+1}] [xk+21,xk+1],在两个子区间上分别采用梯形公式。此时, 2 n 2n 2n 等分时的复化梯形公式为是:
T 2 = h 4 [ f ( x k ) + f ( x k + 1 2 ) ] + h 4 [ f ( x k + 1 2 ) + f ( x k + 1 ) ] = h 4 [ f ( x k ) + 2 f ( x k + 1 2 ) + f ( x k + 1 ) ] = h 4 [ f ( x k ) + f ( x k + 1 ) ] + h 2 f ( x k + 1 2 ) = 1 2 T 2 + h 2 f ( x k + 1 2 ) \qquad\qquad\begin{aligned}T_2&=\dfrac{h}{4}[f(x_k)+f(x_{k+\frac{1}{2}})]+\dfrac{h}{4}[f(x_{k+\frac{1}{2}})+f(x_{k+1})]\\ &=\dfrac{h}{4}[f(x_k)+2f(x_{k+\frac{1}{2}})+f(x_{k+1})]\\ &=\dfrac{h}{4}[f(x_k)+f(x_{k+1})]+\dfrac{h}{2}f(x_{k+\frac{1}{2}})\\ &=\dfrac{1}{2}T_2+\dfrac{h}{2}f(x_{k+\frac{1}{2}})\end{aligned} T2=4h[f(xk)+f(xk+21)]+4h[f(xk+21)+f(xk+1)]=4h[f(xk)+2f(xk+21)+f(xk+1)]=4h[f(xk)+f(xk+1)]+2hf(xk+21)=21T2+2hf(xk+21)
- 考虑整个求积区间 [ a , b ] [a,b] [a,b], n n n 等分时的复化梯形求积为:
T n = h 2 ∑ k = 0 n − 1 [ f ( x k ) + f ( x k + 1 ) ] \qquad\qquad T_n=\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+f(x_{k+1})] Tn=2hk=0∑n−1[f(xk)+f(xk+1)]
\qquad 按照上述规则, 2 n 2n 2n 等分时的复化梯形求积为:
T 2 n = h 4 ∑ k = 0 n − 1 [ f ( x k ) + f ( x k + 1 ) ] + h 2 ∑ k = 0 n − 1 f ( x k + 1 2 ) \qquad\qquad T_{2n}=\dfrac{h}{4}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+f(x_{k+1})]+\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}f(x_{k+\frac{1}{2}}) T2n=4hk=0∑n−1[f(xk)+f(xk+1)]+2hk=0∑n−1f(xk+21)
\qquad
\qquad
\qquad 对比这两个式子,可得到 n n n 等分与 2 n 2n 2n 等分时采用复化梯形公式求积结果的关系:
T 2 n = 1 2 T n + h 2 ∑ k = 0 n − 1 f ( x k + 1 2 ) \qquad\qquad T_{2n}=\dfrac{1}{2}T_n+\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}f(x_{k+\frac{1}{2}}) T2n=21Tn+2hk=0∑n−1f(xk+21)
\qquad 也就是说,从 n n n 等分到 2 n 2n 2n 等分,不需要再在 2 n 2n 2n 个新的求积区间上使用复化梯形公式重新计算,只需要在 n n n 等分求积结果 T n T_n Tn 的基础上,加上 n n n 个新的求积节点的值 f ( x k + 1 2 ) f(x_{k+\frac{1}{2}}) f(xk+21) 即可。
实现代码
仍以求积分 I = ∫ 0 1 sin ( x ) x d x I=\displaystyle\int_0^1\dfrac{\sin(x)}{x}dx I=∫01xsin(x)dx为例:
import numpy as np
def trapezoid(f,a,b): # trapezoid(n=1)return (b-a)*(f(b)+f(a))/2def compositeInt_trape(f,a,b,n): # recursive composite integrationeps = 1e-10val = trapezoid(f,a+eps,b)print('T1: %.7f' % (val))i = 1while i<=np.log2(n):h = (b-a)/(2**i)t = 0for k in range(1,2**(i-1)+1):xkc = a + (2*k-1)*ht += f(xkc)*h val = val/2 + tprint('T%d: %.7f' % (2**i,val))i += 1return val if __name__ == '__main__':a = 0b = 1f = lambda x: np.sin(x)/x n = 3 # 区间等分次数(3次等分后分为8个等距区间)val = compositeInt_trape(f, a, b, 2**n)print('recursive trapezoid: %.7f' % (val))
运行结果:
T1: 0.9207355
T2: 0.9397933
T4: 0.9445135
T8: 0.9456909
recursive trapezoid: 0.9456909
\qquad 本例中等分了 3 3 3 次之后的子区间数为 2 3 = 8 2^3=8 23=8,和第 3 3 3 节例子中复化梯形公式的结果相同,但是计算量减少了。
\qquad
4.2 龙贝格(Romberg)算法
Romberg \qquad\text{Romberg} Romberg算法,是另一种减少计算量的算法,也是基于递推的方式。
- 分析梯形公式的误差
\qquad
R n ( f ) = − b − a 12 h 2 f ′ ′ ( η ) , η ∈ ( a , b ) \qquad R_n(f)=-\dfrac{b-a}{12}h^2f^{''}(\eta),\quad\eta\in(a,b) Rn(f)=−12b−ah2f′′(η),η∈(a,b)
\qquad
\qquad 可以得到: { I − T n = − b − a 12 h 2 f ′ ′ ( η ) , η ∈ ( a , b ) I − T 2 n = − b − a 12 ( h 2 ) 2 f ′ ′ ( η ˉ ) , η ˉ ∈ ( a , b ) \left\{\begin{aligned} I-T_n&=-\dfrac{b-a}{12}h^2f^{''}(\eta),\qquad\eta\in(a,b) \\ \\ I-T_{2n}&=-\dfrac{b-a}{12}\left(\dfrac{h}{2}\right)^2f^{''}(\bar\eta),\qquad\bar\eta\in(a,b) \end{aligned} \right. ⎩ ⎨ ⎧I−TnI−T2n=−12b−ah2f′′(η),η∈(a,b)=−12b−a(2h)2f′′(ηˉ),ηˉ∈(a,b)
\qquad
\qquad 若假设 f ′ ′ ( η ) ≈ f ′ ′ ( η ˉ ) f^{''}(\eta)\approx f^{''}(\bar\eta) f′′(η)≈f′′(ηˉ),那么
\qquad
I − T 2 n I − T n ≈ 1 4 ⟹ I − T 2 n ≈ 1 3 ( T 2 n − T n ) \qquad\qquad\dfrac{I-T_{2n}}{I-T_n}\approx\dfrac{1}{4}\Longrightarrow I-T_{2n}\approx\dfrac{1}{3}(T_{2n}-T_n) I−TnI−T2n≈41⟹I−T2n≈31(T2n−Tn)
\qquad
\qquad 从而可以通过递推关系得到积分值估计: T ‾ = T 2 n + 1 3 ( T 2 n − T n ) = 4 3 T 2 n − 1 3 T n \overline T=T_{2n}+\dfrac{1}{3}(T_{2n}-T_n)=\dfrac{4}{3}T_{2n}-\dfrac{1}{3}T_n T=T2n+31(T2n−Tn)=34T2n−31Tn
\qquad 又由 T n = h 2 ∑ k = 0 n − 1 [ f ( x k ) + f ( x k + 1 ) ] T_n=\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+f(x_{k+1})] Tn=2hk=0∑n−1[f(xk)+f(xk+1)]
\qquad 和 T 2 n = h 4 ∑ k = 0 n − 1 [ f ( x k ) + f ( x k + 1 ) ] + h 2 ∑ k = 0 n − 1 f ( x k + 1 2 ) T_{2n}=\dfrac{h}{4}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+f(x_{k+1})]+\dfrac{h}{2}\displaystyle\sum_{k=0}^{n-1}f(x_{k+\frac{1}{2}}) T2n=4hk=0∑n−1[f(xk)+f(xk+1)]+2hk=0∑n−1f(xk+21)
\qquad 可得到积分值估计值 T ‾ \overline T T 实际上就是辛普森公式的积分值 S n S_n Sn:
T ‾ = 4 3 T 2 n − 1 3 T n = h 6 ∑ k = 0 n − 1 [ f ( x k + f ( x k + 1 ) ] + 2 h 3 ∑ k = 0 n − 1 f ( x k + 1 2 ) = h 6 ∑ k = 0 n − 1 [ f ( x k ) + 4 f ( x k + 1 2 ) + f ( x k + 1 ) ] = S n \qquad\qquad\begin{aligned}\overline T&=\dfrac{4}{3}T_{2n}-\dfrac{1}{3}T_n\\ &=\dfrac{h}{6}\displaystyle\sum_{k=0}^{n-1}[f(x_k+f(x_{k+1})]+\dfrac{2h}{3}\displaystyle\sum_{k=0}^{n-1}f(x_{k+\frac{1}{2}})\\ &=\dfrac{h}{6}\displaystyle\sum_{k=0}^{n-1}[f(x_k)+4f(x_{k+\frac{1}{2}})+f(x_{k+1})]=S_n\end{aligned} T=34T2n−31Tn=6hk=0∑n−1[f(xk+f(xk+1)]+32hk=0∑n−1f(xk+21)=6hk=0∑n−1[f(xk)+4f(xk+21)+f(xk+1)]=Sn
\qquad
- 依次类推,考虑(2等分)辛普森公式的误差
I − S 2 n I − S n ≈ 1 16 ⟹ I − S 2 n ≈ 1 16 ( S 2 n − S n ) \qquad\qquad\dfrac{I-S_{2n}}{I-S_n}\approx\dfrac{1}{16}\Longrightarrow I-S_{2n}\approx\dfrac{1}{16}(S_{2n}-S_n) I−SnI−S2n≈161⟹I−S2n≈161(S2n−Sn)
\qquad
\qquad 从而可以通过递推关系得到积分值估计: S ‾ = 16 15 S 2 n − 1 15 S n \overline S= \dfrac{16}{15}S_{2n}-\dfrac{1}{15}S_n S=1516S2n−151Sn
\qquad 验证可知积分值估计值 S ‾ \overline S S 就是科特斯公式的积分值: C n = 16 15 S 2 n − 1 15 S n C_n= \dfrac{16}{15}S_{2n}-\dfrac{1}{15}S_n Cn=1516S2n−151Sn
\qquad
- 依次类推,考虑(4等分)科特斯公式的误差
I − C 2 n I − C n ≈ 1 64 ⟹ I − C 2 n ≈ 1 64 ( C 2 n − C n ) \qquad\qquad\dfrac{I-C_{2n}}{I-C_n}\approx\dfrac{1}{64}\Longrightarrow I-C_{2n}\approx\dfrac{1}{64}(C_{2n}-C_n) I−CnI−C2n≈641⟹I−C2n≈641(C2n−Cn)
\qquad
\qquad 从而可以通过递推关系得到积分值估计: C ‾ = 64 63 C 2 n − 1 63 C n \overline C=\dfrac{64}{63}C_{2n}-\dfrac{1}{63}C_n C=6364C2n−631Cn
\qquad 也就得到了龙贝格 ( Romberg ) (\text{Romberg}) (Romberg)公式:
R n = 64 63 C 2 n − 1 63 C n \qquad\qquad R_n=\dfrac{64}{63}C_{2n}-\dfrac{1}{63}C_n Rn=6364C2n−631Cn
\qquad 使用龙贝格公式时,需要首先将求积区间 [ a , b ] [a,b] [a,b] 等分 2 3 = 8 2^3=8 23=8 次。在这些子区间上,采用复化梯形公式进行求积运算。其具体过程可以表示成:
k k k | h h h | T 2 k T_{2^k} T2k | S 2 k − 1 S_{2^{k-1}} S2k−1 | C 2 k − 2 C_{2^{k-2}} C2k−2 | R 2 k − 3 R_{2^{k-3}} R2k−3 |
---|---|---|---|---|---|
0 0 0 | b − a b-a b−a | T 1 = 0.92073549 T_1=0.92073549 T1=0.92073549 | |||
1 1 1 | b − a 2 \frac{b-a}{2} 2b−a | T 2 = 0.93979328 T_2=0.93979328 T2=0.93979328 | S 1 S_1 S1 | ||
2 2 2 | b − a 4 \frac{b-a}{4} 4b−a | T 4 = 0.94451352 T_4=0.94451352 T4=0.94451352 | S 2 S_2 S2 | C 1 C_1 C1 | |
3 3 3 | b − a 8 \frac{b-a}{8} 8b−a | T 8 = 0.94569086 T_8=0.94569086 T8=0.94569086 | S 4 S_4 S4 | C 2 C_2 C2 | R 1 R_1 R1 |
表中, k k k 表示等分次数, h h h 表示子区间长度,等分后的子区间数为 2 k 2^k 2k
T 2 k T_{2^k} T2k 表示 k k k 次等分时,采用复化梯形公式求积分的值(详见4.1节代码运行结果)
从第 4 4 4 列开始,就是采用龙贝格递推算法的加速过程,不需要再进行复化求积。
4.3 理查森(Richardson)外推算法
\qquad 龙贝格算法实际上是理查森 (Richardson) \text{(Richardson)} (Richardson)外推算法的一种特殊情况。
梯形公式的余项,可以展开成级数形式( α l \alpha_l αl 与 h h h 无关):
T ( h ) = I + α 1 h 2 + α 2 h 4 + ⋯ + α l h 2 l + ⋯ T(h)=I+\alpha_1h^2+\alpha_2h^4+\cdots+\alpha_lh^{2l}+\cdots T(h)=I+α1h2+α2h4+⋯+αlh2l+⋯
T ( h 2 ) = I + α 1 h 2 4 + α 2 h 4 16 + ⋯ + α l ( h 2 ) 2 l + ⋯ T(\frac{h}{2})=I+\alpha_1\frac{h^2}{4}+\alpha_2\frac{h^4}{16}+\cdots+\alpha_l(\frac{h}{2})^{2l}+\cdots T(2h)=I+α14h2+α216h4+⋯+αl(2h)2l+⋯
⟹ T 1 ( h ) = 4 T ( h 2 ) − T ( h ) 3 = I + β 1 h 4 + β 2 h 6 + ⋯ \Longrightarrow T_1(h)=\dfrac{4T(\frac{h}{2})-T(h)}{3}=I+\beta_1h^4+\beta_2h^6+\cdots ⟹T1(h)=34T(2h)−T(h)=I+β1h4+β2h6+⋯ (辛普森公式序列)
T 1 ( h 2 ) = I + β 1 h 4 16 + β 2 h 6 64 + ⋯ \qquad T_1(\frac{h}{2})=I+\beta_1\frac{h^4}{16}+\beta_2\frac{h^6}{64}+\cdots T1(2h)=I+β116h4+β264h6+⋯
⟹ T 2 ( h ) = 16 T 1 ( h 2 ) − T 1 ( h ) 15 = I + γ 1 h 6 + γ 2 h 8 + ⋯ \qquad\Longrightarrow T_2(h)=\dfrac{16T_1(\frac{h}{2})-T_1(h)}{15}=I+\gamma_1h^6+\gamma_2h^8+\cdots ⟹T2(h)=1516T1(2h)−T1(h)=I+γ1h6+γ2h8+⋯ (科特斯公式序列)
⋯ ⋯ \qquad\qquad\cdots\cdots ⋯⋯
\qquad 将龙贝格算法进行扩展,并进行公式化,可得到理查森 (Richardson) \text{(Richardson)} (Richardson)递推关系:
T m ( k ) = 4 m 4 m − 1 T m − 1 ( k + 1 ) − 1 4 m − 1 T m − 1 ( k ) , k = 1 , 2 , ⋯ \qquad\qquad T_m^{(k)}=\dfrac{4^m}{4^m-1}T_{m-1}^{(k+1)}-\dfrac{1}{4^m-1}T_{m-1}^{(k)}\ ,\quad k=1,2,\cdots Tm(k)=4m−14mTm−1(k+1)−4m−11Tm−1(k) ,k=1,2,⋯
\qquad 特别地,当选择 m = 3 m=3 m=3 时,即为龙贝格算法:
( 1 ) \qquad(1) (1) m = 1 m=1 m=1 时, T 1 ( k ) = 4 3 T 0 ( k + 1 ) − 1 3 T 0 ( k ) T_1^{(k)}=\dfrac{4}{3}T_0^{(k+1)}-\dfrac{1}{3}T_0^{(k)} T1(k)=34T0(k+1)−31T0(k)
( 2 ) \qquad(2) (2) m = 2 m=2 m=2 时, T 2 ( k ) = 16 15 T 1 ( k + 1 ) − 1 15 T 1 ( k ) T_2^{(k)}=\dfrac{16}{15}T_1^{(k+1)}-\dfrac{1}{15}T_1^{(k)} T2(k)=1516T1(k+1)−151T1(k)
( 3 ) \qquad(3) (3) m = 3 m=3 m=3 时, T 3 ( k ) = 64 63 T 2 ( k + 1 ) − 1 63 T 2 ( k ) T_3^{(k)}=\dfrac{64}{63}T_2^{(k+1)}-\dfrac{1}{63}T_2^{(k)} T3(k)=6364T2(k+1)−631T2(k)
\qquad 当 m > 3 m>3 m>3 时,即为理查森 (Richardson) \text{(Richardson)} (Richardson)外推算法,如下表所示:
k k k | h h h | T 0 ( k ) ( T 2 k ) T_0^{(k)}\ (T_{2^k}) T0(k) (T2k) | T 1 ( k ) ( S 2 k − 1 ) T_1^{(k)}\ (S_{2^{k-1}}) T1(k) (S2k−1) | T 2 ( k ) ( C 2 k − 2 ) T_2^{(k)}\ (C_{2^{k-2}}) T2(k) (C2k−2) | T 3 ( k ) ( R 2 k − 3 ) T_3^{(k)}\ (R_{2^{k-3}}) T3(k) (R2k−3) | T 4 ( k ) T_4^{(k)} T4(k) |
---|---|---|---|---|---|---|
0 0 0 | b − a b-a b−a | T 0 ( 1 ) : T 1 = 0.92073549 T_0^{(1)}:T_1=0.92073549 T0(1):T1=0.92073549 | ||||
1 1 1 | b − a 2 \frac{b-a}{2} 2b−a | T 0 ( 2 ) : T 2 = 0.93979328 T_0^{(2)}:T_2=0.93979328 T0(2):T2=0.93979328 | T 1 ( 1 ) : S 1 T_1^{(1)}:S_1 T1(1):S1 | |||
2 2 2 | b − a 4 \frac{b-a}{4} 4b−a | T 0 ( 3 ) : T 4 = 0.94451352 T_0^{(3)}:T_4=0.94451352 T0(3):T4=0.94451352 | T 1 ( 2 ) : S 2 T_1^{(2)}:S_2 T1(2):S2 | T 2 ( 1 ) : C 1 T_2^{(1)}:C_1 T2(1):C1 | ||
3 3 3 | b − a 8 \frac{b-a}{8} 8b−a | T 0 ( 4 ) : T 8 = 0.94569086 T_0^{(4)}:T_8=0.94569086 T0(4):T8=0.94569086 | T 1 ( 3 ) : S 4 T_1^{(3)}:S_4 T1(3):S4 | T 2 ( 2 ) : C 2 T_2^{(2)}:C_2 T2(2):C2 | T 3 ( 1 ) : R 1 T_3^{(1)}:R_1 T3(1):R1 | |
4 4 4 | b − a 16 \frac{b-a}{16} 16b−a | T 0 ( 5 ) : T 16 = 0.94598503 T_0^{(5)}:T_{16}=0.94598503 T0(5):T16=0.94598503 | T 1 ( 4 ) : S 8 T_1^{(4)}:S_8 T1(4):S8 | T 2 ( 3 ) : C 4 T_2^{(3)}:C_4 T2(3):C4 | T 3 ( 2 ) : R 2 T_3^{(2)}:R_2 T3(2):R2 | T 4 ( 4 ) T_4^{(4)} T4(4) |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
从第 4 4 4 列开始,每个表项的值满足其左侧、左上侧的递推关系。
实现代码
仍以求积分 I = ∫ 0 1 sin ( x ) x d x I=\displaystyle\int_0^1\dfrac{\sin(x)}{x}dx I=∫01xsin(x)dx为例:
import numpy as npdef trapezoid(f,a,b): # trapezoid(n=1)return (b-a)*(f(b)+f(a))/2def compositeInt_trape(f,a,b,n): #recursiveeps = 1e-10num = np.log2(n).astype(int)val = np.zeros(num+1)val[0] = trapezoid(f,a+eps,b)i = 1while i<=np.log2(n):h = (b-a)/(2**i)t = 0for k in range(1,2**(i-1)+1):xkc = a + (2*k-1)*ht += f(xkc)*h val[i] = val[i-1]/2 + ti += 1return valdef romberg(f,a,b):# 只需要等分3次val_t = compositeInt_trape(f, a, b, 2**3) t1 = np.concatenate((np.ones(1),val_t[0:-1]))t2 = (4*val_t - t1)/3val_s = t2[1:] t1 = np.concatenate((np.ones(1),val_s[0:-1]))t2 = (16*val_s - t1)/15val_c = t2[1:] t1 = np.concatenate((np.ones(1),val_c[0:-1]))t2 = (64*val_c - t1)/63val_r = t2[1] print(val_t[-1::-1].flatten())print(val_s[-1::-1].flatten())print(val_c[-1::-1].flatten())print('[%.8f]' % (val_r)) return val_rdef richardson(f,a,b,k):n = k+2val_t = compositeInt_trape(f, a, b, 2**n)print(val_t[-1::-1].flatten()) for i in range(1,n):t0 = 4**it1 = np.concatenate((np.ones(1),val_t[0:-1]))t2 = (t0*val_t - t1)/(t0-1)val_t = t2[1:]print(val_t[-1::-1].flatten())print('[%.8f]' % (val_t[1])) return val_t[1]if __name__ == '__main__':a = 0b = 1f = lambda x: np.sin(x)/x val = romberg(f, a, b)print('romberg: %.7f' % (val)) val = richardson(f, a, b, 2) # 比Romberg多等分一次print('richardson: %.7f' % (val))
运行结果:
[0.94569086 0.94451352 0.93979328 0.92073549]
[0.94608331 0.94608693 0.94614588]
[0.94608307 0.946083 ]
[0.94608307]
romberg: 0.9460831
只需要进行 2 3 = 8 2^3=8 23=8 等分,并分别计算复合梯形公式的结果 T 1 , T 2 , T 4 , T 8 T_1,T_2,T_4,T_8 T1,T2,T4,T8 ( T 8 T_8 T8 只具有2位有效数字),就可以递推出具有更高精度的结果 T 3 ( 1 ) T_3^{(1)} T3(1) (具有7位有效数字)。
[0.94598503 0.94569086 0.94451352 0.93979328 0.92073549]
[0.94608309 0.94608331 0.94608693 0.94614588]
[0.94608307 0.94608307 0.946083 ]
[0.94608307 0.94608307]
[0.94608307]
richardson: 0.9460831
参考:
数值微分的python实现
数值积分的python实现——NewtonCotes、复化求积、Romberg、richardson递推相关推荐
- 数值分析——数值积分(Newton-Cotes、复化求积、Gauss求积、正交多项式Gauss)
数值分析-数值积分 前言 敲黑板 牛顿-莱布尼兹公式的局限性 常见的近似求法 代数精度 插值型求积公式 Newton-Cotes公式 复化求积 Gauss 求积公式 基于正交多项式的Gauss求积公式 ...
- 数值分析复化求积matlab,MATLAB数值分析实验二(复合梯形、辛普森和龙贝格求积,以及二重积分计算等)...
1.理解如何在计算机上使用数值方法计算定积近似值; 2.学会复合梯形.复合Simpson和龙贝格求积分公式的编程与应用. 3.探索二重积分在矩形区域的数值积分方法. 佛山科学技术学院 实 验 报 告 ...
- 变步长梯形公式数值积分的Python程序
基本代码: from sympy import *def f(t):f = 2000*log(140000/(140000-2100*t))-9.8*treturn fx = symbols('x') ...
- 梯形公式的数值积分的Python程序
代码 例子 下面的代码的意图是改变积分区域的梯形块数,得到不同精度的积分值. 以对函数f(t) = 2000×ln(140000/(140000-2100×t))-9.8×t 进行积分为例,积分区域为 ...
- python ftp文件夹文件递归上传推送
python ftp文件夹文件递归上传推送 posted on 2018-10-16 17:05 秦瑞It行程实录 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnbl ...
- 2.3 基本算法之递归变递推 1188 菲波那契数列(2) python
http://noi.openjudge.cn/ch0203/1760/ """2.3 基本算法之递归变递推 1188 菲波那契数列(2)--3分 http://ybt. ...
- 2.3 基本算法之递归变递推 放苹果 python
http://noi.openjudge.cn/ch0203/666/ """ 2.3 基本算法之递归变递推 666 放苹果 http://noi.openjudge.c ...
- 钉钉一行代码_利用Python快速搭建钉钉和邮件数据推送系统
前面的文章我们写到了利用Python实现钉钉和邮件的数据推送,在数据处理这一块实现了对mysql和odps的数据获取和处理,可以满足常规业务大部分数据场景需求,在一家初创公司数据基础建设还不完善的时候 ...
- 蓝桥杯python省赛冲刺篇2——常用算法的详细解析及对应蓝桥杯真题:打表模拟法、递推递归法、枚举法、贪心算法、差分与前缀和
注意:加了题目链接 目录 注意:加了题目链接 一.打表模拟法 介绍 1. 算式问题 题目描述 解析与代码演示 2. 求值 题目描述 解析与代码演示 3. 既约分数 题目描述 解析与代码演示 4. 天干 ...
最新文章
- Intellij IDEA使用教程(超详细)
- js中深拷贝和浅拷贝问题
- Java 异常处理的误区和经验总结--转载
- 转]Window, Linux动态链接库的分析对比
- docker+jenkins+maven+svn
- Markdown编译器插入公式的数学符号及字体颜色、背景
- (转) Spring 3 报org.aopalliance.intercept.MethodInterceptor问题解决方法
- java处理请求的流程_Java Spring mvc请求处理流程详解
- Navicat打开保存的查询
- 是什么意思网络语_网络语“随薪锁欲”是什么意思?
- 无线路由器挖洞方法大比拼:白盒 or 黑盒?
- 自我总结(五)---(学习j2ee)
- Docker下安装Anaconda
- WCF入门(七)——异常处理1
- layui动态设置checkbox选中状态
- 开源的shell工具finalShell
- itunes安装后不能用,双击后等很长时间,提示:ITUNES 驱动程序缺少用于导入和刻录的CD与DVD注册的设置...
- 六、量子纠错码的构成法
- python高级函数_python高级之函数
- kali之beef的使用
热门文章
- 〖Python自动化办公篇⑳〗 - python实现邮件自动化 - 发送html邮件和带附件的邮件
- 看伟大的领袖如何激励行动有感
- 天气预报接口,在自己的网页上加入天气预报吧
- “你家娃为什么这么爱看书?”只用3招,孩子秒变小书迷
- 2020起重机械指挥考试题库及起重机械指挥考试试题
- 使用springboot+netty处理tcp/ip服务端编程
- html 人物介绍 轮播,jQuery卡通人物介绍卡牌轮播切换代码
- 【MMU篇】初见MMU和TLB
- Mac 之 Command Line Tools
- 经纬恒润受邀出席首届中国汽车芯片应用创新拉力赛新闻发布会