#%config InlineBackend.figure_format = 'svg'
from pylab import *
from scipy.interpolate import barycentric_interpolate
8.4.1Single interval¶
Trapezoidal method used a linear approximation to estimate the integral. To improve the accuracy, let us use a quadratic approximation. For the function , we first construct a quadratic polynomial that interpolates at
and the approximation to the integral is
This is called Simpson rule.

The error in the integral follows from polynomial interpolation error (30)
We cannot apply the integral mean value theorem like we did for trapezoid rule. Define
Then
and
Hence the error can be written as
where we used result from Section 6.7.10 on derivative of divided differences. Now we can apply the integral mean value theorem
The error in Simpson rule is given by
and
8.4.2Composite Simpson rule¶
Let be even, the spacing between points and the points
In the interval , we have the three points using which we can apply Simpson rule. Then
The composite Simpson rule is
The error in this approximation is
If the fourth derivative is continuous and since , we get
We can also derive the asymptotic error formula
The following function implements composite Simpson rule.
def simpson(a,b,n,f,df3):
h = (b-a)/n
x = linspace(a,b,n+1)
y = f(x)
res = 4.0*sum(y[1:n:2]) + 2.0*sum(y[2:n-1:2]) + y[0] + y[n]
est = -(h**4/180.0)*(df3(b) - df3(a))
return (h/3.0)*res, est
8.4.3Compare Trapezoid and Simpson¶
The next function implements both Trapezoid and Simpson methods.
# Performs Trapezoid and Simpson quadrature
def integrate(a,b,n,f):
h = (b-a)/n
x = linspace(a,b,n+1)
y = f(x)
res1 = 0.5*y[0] + sum(y[1:n]) + 0.5*y[n] # Trapezoid
res2 = 4.0*sum(y[1:n:2]) + 2.0*sum(y[2:n-1:2]) + y[0] + y[n] # Simpson
return h*res1, (h/3.0)*res2
The next function performs convergence test.
def test(a,b,f,Ie,n,N):
e1,e2 = zeros(N), zeros(N)
for i in range(N):
I1,I2 = integrate(a,b,n,f)
e1[i],e2[i] = Ie - I1, Ie - I2
if i > 0:
print('%6d %18.8e %14.5g %18.8e %14.5g'%
(n,e1[i],e1[i-1]/e1[i],e2[i],e2[i-1]/e2[i]))
else:
print('%6d %18.8e %14.5g %18.8e %14.5g'%(n,e1[i],0,e2[i],0))
n = 2*n
We will apply this to following examples.
- Atkinson, K. E. (2004). An Introduction to Numerical Analysis (2nd ed.). Wiley.