#%config InlineBackend.figure_format = 'svg'
from pylab import *
The error in some numerical quadrature depends on the number of nodes used which the user has to select. It is desirable to have an automatic algorithm where the user specifies the error ε that is acceptable and the algorithm should select the number of nodes n n n so that
∣ I ( f ) − I n ( f ) ∣ ≤ ϵ |I(f) - I_n(f)| \le \epsilon ∣ I ( f ) − I n ( f ) ∣ ≤ ϵ The error clearly depends on the smoothness of the integrand f f f also. If f f f has a singularity, e.g., f ( x ) = x f(x) = \sqrt{x} f ( x ) = x has singular derivatives at x = 0 x=0 x = 0 , then the error will be large. To have an acceptable error we must use a large n n n (small h h h ). But this will increase the number of nodes. Actually, most of the error will come from the region near the singularity and we can use a small h h h only in those regions, and not everywhere. This requires the ability to use non-uniformly spaced nodes in the numerical integration formula, and all the composite rules allow us to do this.
8.14.1 Adaptive Simpson quadrature ¶ Let n n n be even and we use n + 1 n+1 n + 1 points. The composite Simpson quadrature is
I n ( f ) = ∑ j = 1 n / 2 ( x 2 j − x 2 j − 2 6 ) ( f 2 j − 2 + 4 f 2 j − 1 + f 2 j ) , x 2 j − 1 = 1 2 ( x 2 j − 2 + x 2 j ) I_n(f) = \sum_{j=1}^{n/2} \left( \frac{x_{2j} - x_{2j-2}}{6} \right)( f_{2j-2} + 4 f_{2j-1} + f_{2j}), \qquad x_{2j-1} = \half(x_{2j-2} + x_{2j}) I n ( f ) = j = 1 ∑ n /2 ( 6 x 2 j − x 2 j − 2 ) ( f 2 j − 2 + 4 f 2 j − 1 + f 2 j ) , x 2 j − 1 = 2 1 ( x 2 j − 2 + x 2 j ) with error formula
I ( f ) − I n ( f ) = − 1 2880 ∑ j = 1 n / 2 ( x 2 j − x 2 j − 2 ) 5 f ( 4 ) ( ξ j ) , ξ j ∈ [ x 2 j − 2 , x 2 j ] I(f) - I_n(f) = -\frac{1}{2880} \sum_{j=1}^{n/2}(x_{2j} - x_{2j-2})^5 f^{(4)}(\xi_j), \qquad \xi_j \in [x_{2j-2}, x_{2j}] I ( f ) − I n ( f ) = − 2880 1 j = 1 ∑ n /2 ( x 2 j − x 2 j − 2 ) 5 f ( 4 ) ( ξ j ) , ξ j ∈ [ x 2 j − 2 , x 2 j ] Note that we have a decomposition of the total error into error contributions from each of the sub-intervals. If f ( 4 ) f^{(4)} f ( 4 ) is large in some sub-interval, we should choose the length of that sub-interval x 2 j − x 2 j − 2 x_{2j} - x_{2j-2} x 2 j − x 2 j − 2 to be small, in order to reduce the error.
The best strategy is to equi-distribute the error among all the sub-intervals.
Define
M j = max x ∈ [ x 2 j − 2 , x 2 j ] ∣ f ( 4 ) ( x ) ∣ M_j = \max_{x \in [x_{2j-2},x_{2j}]} |f^{(4)}(x)| M j = x ∈ [ x 2 j − 2 , x 2 j ] max ∣ f ( 4 ) ( x ) ∣ then
∣ I ( f ) − I n ( f ) ∣ ≤ 1 2880 ∑ j = 1 n / 2 ( x 2 j − x 2 j − 2 ) 5 M j |I(f) - I_n(f)| \le \frac{1}{2880} \sum_{j=1}^{n/2}(x_{2j} - x_{2j-2})^5 M_j ∣ I ( f ) − I n ( f ) ∣ ≤ 2880 1 j = 1 ∑ n /2 ( x 2 j − x 2 j − 2 ) 5 M j We want
∣ I ( f ) − I n ( f ) ∣ ≤ ϵ |I(f) - I_n(f)| \le \epsilon ∣ I ( f ) − I n ( f ) ∣ ≤ ϵ This can be achieved if
1 2880 ( x 2 j − x 2 j − 2 ) 5 M j ≤ ϵ n / 2 = 2 ϵ n , j = 1 , 2 , … , n / 2 \frac{1}{2880} (x_{2j} - x_{2j-2})^5 M_j \le \frac{\epsilon}{n/2} = \frac{2 \epsilon}{n}, \qquad j=1,2,\ldots,n/2 2880 1 ( x 2 j − x 2 j − 2 ) 5 M j ≤ n /2 ϵ = n 2 ϵ , j = 1 , 2 , … , n /2 If this condition is not satisfied, then we iteratively refine the sub-intervals until desired error level is reached.
8.14.1.1 Algorithm I ¶ We will assume that we can estimate M j M_j M j and hence we can estimate the error. The algorithm will iteratively increase the number of sub-intervals until the desired error level is reached.
Start with three nodes, i.e., one Simpson rule, and compute I 2 ( f ) I_2(f) I 2 ( f )
and estimate the error. If ∣ I ( f ) − I 2 ( f ) ∣ ≤ ϵ |I(f) - I_2(f)| \le \epsilon ∣ I ( f ) − I 2 ( f ) ∣ ≤ ϵ , then we
stop and the answer is I 2 ( f ) I_2(f) I 2 ( f ) .
Otherwise, insert a point mid-way between the three points and use
two Simpson rules. Estimate the error from each rule. If both errors
are ≤ ϵ / 2 \le \epsilon/2 ≤ ϵ /2 , then stop.
If not, suppose first error > ϵ / 2 > \epsilon/2 > ϵ /2 and second error
≤ ϵ / 2 \le \epsilon/2 ≤ ϵ /2 . Refine the first Simpson rule by inserting two
points.
Now the error from the first two rules must be ≤ ϵ / 4 \le \epsilon/4 ≤ ϵ /4 . If
this is true, then we stop.
Otherwise, continue with sub-division.
8.14.1.2 Algorithm II ¶ We may not be able to estimate the derivatives, and the only information available is the function values. We can approximate the derivatives by first constructing a local approximation and differentiating it. But we have seen other ways to estimate the error in integral, e.g., using Richardson extrapolation.
Set α = a \alpha=a α = a and β = b \beta=b β = b and define
I α , β = ∫ α β f ( x ) d x I_{\alpha,\beta} = \int_\alpha^\beta f(x) \ud x I α , β = ∫ α β f ( x ) d x The Simpson rule is
I α , β ( 1 ) = h 3 [ f ( α ) + f ( α + β 2 ) + f ( β ) ] , h = 1 2 ( β − α ) I_{\alpha,\beta}^{(1)} = \frac{h}{3}\left[f(\alpha) + f\left(\frac{\alpha+\beta}{2}\right) + f(\beta) \right], \qquad h = \half (\beta - \alpha) I α , β ( 1 ) = 3 h [ f ( α ) + f ( 2 α + β ) + f ( β ) ] , h = 2 1 ( β − α ) To estimate the error, we compute a refined estimate as
I α , β ( 2 ) = I α , γ ( 1 ) + I γ , β ( 1 ) , γ = 1 2 ( α + β ) I_{\alpha,\beta}^{(2)} = I_{\alpha,\gamma}^{(1)} + I_{\gamma,\beta}^{(1)}, \qquad \gamma = \half(\alpha + \beta) I α , β ( 2 ) = I α , γ ( 1 ) + I γ , β ( 1 ) , γ = 2 1 ( α + β ) and use error estimate based on Richarson extrapolation, see Section 8.13.2.1
E α , β = 1 15 ∣ I α , β ( 2 ) − I α , β ( 1 ) ∣ ≈ ∣ I α , β − I α , β ( 2 ) ∣ E_{\alpha,\beta} = \frac{1}{15} |I_{\alpha,\beta}^{(2)} - I_{\alpha,\beta}^{(1)}| \approx |I_{\alpha,\beta} - I_{\alpha,\beta}^{(2)}| E α , β = 15 1 ∣ I α , β ( 2 ) − I α , β ( 1 ) ∣ ≈ ∣ I α , β − I α , β ( 2 ) ∣ as the error estimate.
If E α , β ≤ ϵ E_{\alpha,\beta} \le \epsilon E α , β ≤ ϵ
then keep interval [ α , β ] [\alpha,\beta] [ α , β ] and use I α , β ( 2 ) I_{\alpha,\beta}^{(2)} I α , β ( 2 )
as estimate of I α , β I_{\alpha,\beta} I α , β .
Otherwise, divide [ α , β ] [\alpha,\beta] [ α , β ] into [ α , γ ] [\alpha,\gamma] [ α , γ ] and
[ γ , β ] [\gamma,\beta] [ γ , β ] . Now we want to satisfy
E α , γ ≤ ϵ 2 , E γ , β ≤ ϵ 2 E_{\alpha,\gamma} \le \frac{\epsilon}{2}, \qquad E_{\gamma,\beta} \le \frac{\epsilon}{2} E α , γ ≤ 2 ϵ , E γ , β ≤ 2 ϵ If both conditions are satisfied, then the integral is
I α , γ ( 2 ) + I γ , β ( 2 ) I_{\alpha,\gamma}^{(2)} + I_{\gamma,\beta}^{(2)} I α , γ ( 2 ) + I γ , β ( 2 ) .
Otherwise, suppose
E α , γ > ϵ 2 , E γ , β ≤ ϵ 2 E_{\alpha,\gamma} > \frac{\epsilon}{2}, \qquad E_{\gamma,\beta} \le \frac{\epsilon}{2} E α , γ > 2 ϵ , E γ , β ≤ 2 ϵ Then we keep I γ , β ( 2 ) I_{\gamma,\beta}^{(2)} I γ , β ( 2 ) and divide [ α , γ ] [\alpha,\gamma] [ α , γ ]
into [ α , δ ] [\alpha,\delta] [ α , δ ] and [ δ , γ ] [\delta,\gamma] [ δ , γ ] with
δ = 1 2 ( α + γ ) \delta=\half(\alpha + \gamma) δ = 2 1 ( α + γ ) . Now try to satisfy
E α , δ ≤ ϵ 4 , E δ , γ ≤ ϵ 4 E_{\alpha,\delta} \le \frac{\epsilon}{4}, \qquad E_{\delta,\gamma} \le \frac{\epsilon}{4} E α , δ ≤ 4 ϵ , E δ , γ ≤ 4 ϵ If both conditions are satisfied, then integral is
I α , δ ( 2 ) + I δ , γ ( 2 ) + I γ , β ( 2 ) I_{\alpha,\delta}^{(2)} + I_{\delta,\gamma}^{(2)} + I_{\gamma,\beta}^{(2)} I α , δ ( 2 ) + I δ , γ ( 2 ) + I γ , β ( 2 ) .
Continue this process until the errors in all sub-intervals is less
than the tolerance.
This algorithm is implemented in the following code.
simpson1
performs Simpson quadrature in one interval [ a , b ] [a,b] [ a , b ] .asimpson
performs adaptive quadrature in a recursive manner.from scipy.integrate import simpson
# Apply Simpson using points {a, (a+b)/2, c}
def simpson1(f,a,b):
h = 0.5*(b-a)
c = 0.5*(a+b)
return (h/3.0)*(f(a) + 4*f(c) + f(b))
# Performs adaptive Simpson to make error < eps
def asimpson(f,a,b,eps):
c = 0.5*(a+b)
i1 = simpson1(f,a,b)
i2 = simpson1(f,a,c) + simpson1(f,c,b)
err = (1.0/15.0) * abs(i2 - i1)
if err < eps:
print('[%12.6g %12.6g] %12.6g %12.6g %12.6g' % (a,b,err,eps,i2))
return i2
else:
eps1 = 0.5*eps
return asimpson(f,a,c,eps1) + asimpson(f,c,b,eps1)
Let us test it for
I = ∫ 0 1 x d x = 2 3 I = \int_0^1 \sqrt{x} \ud x = \frac{2}{3} I = ∫ 0 1 x d x = 3 2 Here is the result of adaptive quadrature.
f = lambda x: sqrt(x)
a, b = 0.0, 1.0
eps = 0.0001
I = asimpson(f,a,b,eps)
Ie = 2.0/3.0
print('\nIntegral,err,eps = %14.6e %14.6e %14.6e'%(I,abs(I-Ie),eps))
[ 0 0.00390625] 3.00376e-07 3.90625e-07 0.000160285
[ 0.00390625 0.0078125] 1.29637e-09 3.90625e-07 0.000297594
[ 0.0078125 0.015625] 3.66668e-09 7.8125e-07 0.000841723
[ 0.015625 0.03125] 1.03709e-08 1.5625e-06 0.00238075
[ 0.03125 0.0625] 2.93335e-08 3.125e-06 0.00673378
[ 0.0625 0.125] 8.29676e-08 6.25e-06 0.019046
[ 0.125 0.25] 2.34668e-07 1.25e-05 0.0538703
[ 0.25 0.5] 6.63741e-07 2.5e-05 0.152368
[ 0.5 1] 1.87734e-06 5e-05 0.430962
Integral,err,eps = 6.666608e-01 5.898359e-06 1.000000e-04
The interval [ 0 , 0.5 ] [0, 0.5] [ 0 , 0.5 ] is sub-divided into smaller ones which is where the integrand is singular; the other interval [ 0.5 , 1 ] [0.5, 1] [ 0.5 , 1 ] is not divided. The final error is significantly less than the specified error level of eps = 0.0001
.
If we use uniformly spaced points, then
# Simpson rule using uniform sample points
# Choose n to be even only
n, N = 2, 30
for i in range(N):
x = linspace(a, b, n+1)
y = f(x)
I = simpson(y, x=x)
print('%5d %16.6e %16.6e %16.6e' % (int(n/2),(b-a)/n,I,abs(I-Ie)))
if abs(I-Ie) < eps:
break
n = n + 4
1 5.000000e-01 6.380712e-01 2.859548e-02
3 1.666667e-01 6.611443e-01 5.522350e-03
5 1.000000e-01 6.640996e-01 2.567077e-03
7 7.142857e-02 6.651169e-01 1.549768e-03
9 5.555556e-02 6.656036e-01 1.063058e-03
11 4.545455e-02 6.658799e-01 7.867465e-04
13 3.846154e-02 6.660543e-01 6.123652e-04
15 3.333333e-02 6.661726e-01 4.940713e-04
17 2.941176e-02 6.662572e-01 4.094998e-04
19 2.631579e-02 6.663201e-01 3.465749e-04
21 2.380952e-02 6.663684e-01 2.982626e-04
23 2.173913e-02 6.664064e-01 2.602173e-04
25 2.000000e-02 6.664370e-01 2.296245e-04
27 1.851852e-02 6.664621e-01 2.045892e-04
29 1.724138e-02 6.664829e-01 1.837940e-04
31 1.612903e-02 6.665004e-01 1.662976e-04
33 1.515152e-02 6.665153e-01 1.514110e-04
35 1.428571e-02 6.665280e-01 1.386202e-04
37 1.351351e-02 6.665391e-01 1.275340e-04
39 1.282051e-02 6.665488e-01 1.178506e-04
41 1.219512e-02 6.665573e-01 1.093334e-04
43 1.162791e-02 6.665649e-01 1.017949e-04
45 1.111111e-02 6.665716e-01 9.508453e-05
This requires more points (46) to reach the error tolerance, and the final error is still not as small as with adaptive quadrature which uses fewer points.
Error estimates E α , β E_{\alpha,\beta} E α , β like the one used above are reliable only when β − α \beta-\alpha β − α is sufficiently small. Starting with a single Simpson rule as we did above is perhaps not a good idea in general.