Skip to article frontmatterSkip to article content

Simpson rule

from pylab import *

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 f:[a,b]Rf : [a,b] \to \re, we first construct a quadratic polynomial p2(x)p_2(x) that interpolates at a,b,c=12(a+b)a, b, c = \half(a+b)

p2(a)=f(a),p2(b)=f(b),p2(c)=f(c)p_2(a) = f(a), \qquad p_2(b) = f(b), \qquad p_2(c) = f(c)

and the approximation to the integral is

I2(f)=abp2(x)dx=h3[f(a)+4f(c)+f(b)],h=12(ba)I_2(f) = \int_a^b p_2(x) \ud x = \frac{h}{3}[f(a) + 4 f(c) + f(b)], \qquad h = \half(b-a)

This is called Simpson rule. The error is

E2(f)=I(f)I2(f)=ab(xa)(xc)(xb)changes sign at x=cf[a,b,c,x]dxE_2(f) = I(f) - I_2(f) = \int_a^b \underbrace{(x-a)(x-c)(x-b)}_{\textrm{changes sign at $x=c$}} f[a,b,c,x] \ud x

Define

w(x)=ax(ta)(tc)(tb)dxw(x) = \int_a^x (t-a)(t-c)(t-b)\ud x

Then

w(a)=w(b)=0,w(x)>0x(a,b)w(a) = w(b) = 0, \qquad w(x) > 0 \quad \forall x \in (a,b)

and

w(x)=(xa)(xc)(xb)w'(x) = (x-a)(x-c)(x-b)

Hence the error can be written as

E2(f)=abw(x)f[a,b,c,x]dx=[w(x)f[a,b,c,x]]ababw(x)ddxf[a,b,c,x]dx=abw(x)f[a,b,c,x,x]dx\begin{aligned} E_2(f) &= \int_a^b w'(x) f[a,b,c,x] \ud x \\ &= [w(x) f[a,b,c,x]]_a^b - \int_a^b w(x) \dd{}{x} f[a,b,c,x] \ud x \\ &= - \int_a^b w(x) f[a,b,c,x,x] \ud x \end{aligned}

Now we can apply the integral mean value theorem

E2(f)=f[a,b,c,ξ,ξ]abw(x)dx,for some ξ[a,b]=124f(4)(η)[415h5],for some η[a,b]\begin{aligned} E_2(f) &= -f[a,b,c,\xi,\xi] \int_a^b w(x) \ud x, \quad \textrm{for some $\xi \in [a,b]$} \\ &= -\frac{1}{24} f^{(4)}(\eta) \left[ \frac{4}{15} h^5 \right], \quad \textrm{for some $\eta \in [a,b]$} \end{aligned}

The error in Simpson rule is given by

E3(f)=190h5f(4)(η),for some η[a,b]E_3(f) = -\frac{1}{90} h^5 f^{(4)}(\eta), \quad \textrm{for some $\eta \in [a,b]$}

By construction, Simpson rule is exact for quadratic polynomials. The error formula tells us that even for cubic polynomials, the error is zero.

2Composite Simpson rule

Let n2n \ge 2 be even, the spacing between points h=(ba)/nh = (b-a)/n and the n+1n+1 points

xj=a+jh,j=0,1,2,,nx_j = a + j h, \quad j=0,1,2,\ldots,n

Then

I(f)=abf(x)dx=j=1n/2x2j2x2jf(x)dx=j=1n/2{h3[f2j2+4f2j1+f2j]h590f(4)(ηj)},ηj[x2j2,x2j]\begin{aligned} I(f) &= \int_a^b f(x) \ud x \\ &= \sum_{j=1}^{n/2} \int_{x_{2j-2}}^{x_{2j}} f(x) \ud x \\ &= \sum_{j=1}^{n/2}\left\{ \frac{h}{3}[f_{2j-2} + 4 f_{2j-1} + f_{2j}] - \frac{h^5}{90} f^{(4)}(\eta_j) \right\}, \quad \eta_j \in [x_{2j-2},x_{2j}] \end{aligned}

The composite Simpson rule is

In(f)=h3[f0+4f1+2f2++2fn2+4fn1+fn]I_n(f) = \frac{h}{3}[ f_0 + 4 f_1 + 2 f_2 + \ldots + 2 f_{n-2} + 4 f_{n-1} + f_n]

The error in this approximation is

En(f)=I(f)In(f)=h590(n2)[2nj=1n/2f(4)(ηj)]E_n(f) = I(f) - I_n(f) = -\frac{h^5}{90} \left(\frac{n}{2}\right) \left[ \frac{2}{n} \sum_{j=1}^{n/2} f^{(4)}(\eta_j) \right]

If the fourth derivative is continuous, then

En(f)=1180(ba)h4f(4)(η),for some η[a,b]E_n(f) = -\frac{1}{180} (b-a)h^4 f^{(4)}(\eta), \quad \textrm{for some $\eta \in [a,b]$}

We can also derive the asymptotic error formula

En(f)E~n(f)=h4180[f(3)(b)f(3)(a)]E_n(f) \approx \tilde E_n(f) = -\frac{h^4}{180}[ f^{(3)}(b) - f^{(3)}(a)]
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

3Compare Trapezoid and Simpson

The next function implements 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]
    res2 = 4.0*sum(y[1:n:2]) + 2.0*sum(y[2:n-1:2]) + y[0] + y[n]
    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