This chapter describes routines for performing numerical integration (quadrature) of a function in one dimension. There are routines for adaptive and non-adaptive integration of general functions, with specialised routines for specific cases. These include integration over infinite and semi-infinite ranges, singular integrals, including logarithmic singularities, computation of Cauchy principal values and oscillatory integrals. The library reimplements the algorithms used in QUADPACK, a numerical integration package written by Piessens, Doncker-Kapenga, Uberhuber and Kahaner. Fortran code for QUADPACK is available on Netlib.
Each algorithm computes an approximation to a definite integral of the form,
where w(x) is a weight function (for general integrands w(x)=1). The user provides absolute and relative error bounds (epsabs, epsrel) which specify the following accuracy requirement,
where RESULT is the numerical approximation obtained by the algorithm. The algorithms attempt to estimate the absolute error AbsErr = | Result - I | in such a way that the following inequality holds,
In short, the routines return the first approximation which has an absolute error smaller than epsabs or a relative error smaller than epsrel.
Note that this is an either-or constraint, not simultaneous. To compute to a specified absolute error, set epsrel to zero. To compute to a specified relative error, set epsabs to zero. The routines will fail to converge if the error bounds are too stringent, but always return the best approximation obtained up to that stage.
All the numerical integration methods are available through the function integ.
This function perform a numerical integration.The parameter spec should be a table that defines the following values:
In most case it shoud be a table of two values of the form {a, b} that indicates the extrema of integration. a should be numerical values or the string -inf to indicate that the integral should be extended indefinetely over the negative semi-axis. The integral will be in this case:
The parameter b can be also +inf to perform an integration over the semi-infinite positive interval. You can also set both a and b to infinite values.
If points contains more that two values the intermediate values will be considered as singular points and a special algorithm, QAGP, will be used.
If defined this field enable the calculation of a weighted integral. This parameter should be a table with at least the field type to define the type of the weight. It can be:
Weight with algebraic-logarithmic singularities at the end-points of an integration region. The weight is described by a singular weight function W(x) with the parameters (α, β, μ, ν),
where α > -1, β > -1, and μ = 0, 1, ν = 0, 1. The weight function can take four different forms depending on the values of μ and ν,
The calculated integral is therefore:
This weight enable the computation of the Cauchy principal value of the integral of f over (a,b), with a singularity at ζ,
The adaptive bisection algorithm of QAG is used, with modifications to ensure that subdivisions do not occur at the singular point x = ζ. When a subinterval contains the point x = ζ or is close to it then a special 25-point modified Clenshaw-Curtis rule is used to control the singularity. Further away from the singularity the algorithm uses an ordinary 15-point Gauss-Kronrod integration rule.
Here some example:
-- simple integration of sin(x)/x between 0 and 24*pi
x, err = integ {f= |x| sin(x)/x, points= {0, 24*pi}}
-- integral of exp(-x)/sqrt(x) between 0 and 5, should give
-- sqrt(pi)*erf(sqrt(5)), the demonstration is left as exercise
x, err = integ {f= |x| exp(-x), points= {0, 5},
weight = {type='alglog', alpha = -0.5}}
-- the same of the first but uses a weight to trigger oscillatory method
x, err = integ {f= |x| 1/(x+1), points= {0, 24*pi},
weight = {type='sin', omega = 1}}
-- a fourier integral
x, err = integ {f= |x| exp(-x*x/2)*sin(5*x), points= {'inf', '+inf'},
weight = {type='sin', omega = 4.5}}
-- a famous integral, should gives sqrt(2*pi)
x, err = integ {f= |x| exp(-x*x/2), points= {'inf', '+inf'}}