from numpy import *
from scipy import linalg
from scipy.linalg import norm
from matplotlib.pyplot import *
from prettytable import PrettyTable
from timeit import default_timer as timer
import sys
sys.path.append('fncbook/')
import fncbook as FNC
# This (optional) block is for improving the display of plots.
# from IPython.display import set_matplotlib_formats
# set_matplotlib_formats("svg","pdf")
# %config InlineBackend.figure_format = 'svg'
rcParams["figure.figsize"] = [7, 4]
rcParams["lines.linewidth"] = 2
rcParams["lines.markersize"] = 4
rcParams['animation.html'] = "jshtml" # or try "html5"
In calculus, you learn that the elegant way to evaluate a definite integral is to apply the Fundamental Theorem of Calculus and find an antiderivative. The connection is so profound and pervasive that it’s easy to overlook that a definite integral is a numerical quantity existing independently of antidifferentiation. However, most conceivable integrands have no antiderivative in terms of familiar functions.
Numerical integration, which also goes by the older name quadrature, is performed by combining values of the integrand sampled at nodes. In this section we will assume equally spaced nodes using the definitions
Numerical integration formulas can be applied to sequences of data values even if no function is explicitly known to generate them. For our presentation and implementations, however, we assume that f is known and can be evaluated anywhere.
A straightforward way to derive integration formulas is to mimic the approach taken for finite differences: find an interpolant and operate exactly on it.
One of the most important integration formulas results from integration of the piecewise linear interpolant (see Piecewise linear interpolation). Using the cardinal basis form of the interpolant in (5.2.3), we have
Geometrically, as illustrated in Figure 5.6.1, the trapezoid formula sums of the areas of trapezoids approximating the region under the curve y=f(x).[1]
The trapezoid formula is the Swiss Army knife of integration formulas. A short implementation is given as Function 5.6.1.
Figure 5.6.1:Trapezoid formula for integration. The piecewise linear interpolant defines trapezoids that approximate the region under the curve.
Like finite-difference formulas, numerical integration formulas have a truncation error.
In Theorem 5.2.2 we stated that the pointwise error in a piecewise linear interpolant with equal node spacing h is bounded by O(h2) as h→0. Using I to stand for the exact integral of f and p to stand for the piecewise linear interpolant, we obtain
where the B2k are constants known as Bernoulli numbers. Unless we happen to be fortunate enough to have a function with f′(b)=f′(a), we should expect truncation error at second order and no better.
If evaluations of f are computationally expensive, we want to get as much accuracy as possible from them by using a higher-order formula. There are many routes for doing so; for example, we could integrate a not-a-knot cubic spline interpolant. However, splines are difficult to compute by hand, and as a result different methods were developed before computers came on the scene.
Knowing the structure of the error allows the use of extrapolation to improve accuracy. Suppose a quantity A0 is approximated by an algorithm A(h) with an
error expansion
as proved by the Euler–Maclaurin formula (5.6.9). The error constants depend on f and can’t be evaluated in general, but we know that this expansion holds. For convenience, we recast the error expansion in terms of n=O(h−1):
The formula (5.6.14) is called Simpson’s formula, or Simpson’s rule. A different presentation and derivation are considered in Exercise 5.6.4.
Equation (5.6.15) is another particular error expansion in the form (5.6.10), so we can extrapolate again! The details change only a little. Considering that
which is sixth-order accurate. Clearly the process can be repeated to get eighth-order accuracy and beyond. Doing so goes by the name of Romberg integration, which we will not present in full generality.
Note in (5.6.17) that Rf(4n) depends on Sf(2n) and Sf(4n), which in turn depend on Tf(n), Tf(2n), and Tf(4n). There is a useful benefit realized by doubling of the nodes in each application of the trapezoid formula. As shown in Figure 5.6.2, when doubling n, only about half of the nodes are new ones, and previously computed function values at the other nodes can be reused.
Figure 5.6.2:Dividing the node spacing by half introduces new nodes only at midpoints, allowing the function values at existing nodes to be reused for extrapolation.
where the nodes referenced in the last line are relative to n=2m. Hence in passing from n=m to n=2m, new integrand evaluations are needed only at the odd-numbered nodes of the finer grid.
Some texts distinguish between a formula for a single subinterval [tk−1,tk] and a composite formula that adds them up over the whole interval to get (5.6.5).
Bailey, D. H., Jeyabalan, K., & Li, X. S. (2005). A Comparison of Three High-Precision Quadrature Schemes. Experimental Mathematics, 14(3), 317–329. 10.1080/10586458.2005.10128931