Gaussian quadrature is a technique to evaluate integrals by summing a weighted integrand at a finite number of points. It can correctly evaluate some forms of integral to machine precision, rather than the approximations produced by techniques like the trapezium rule. When I first looked into using it, I found a huge number of explanations but it still took a while for me to put all the pieces together. In this post I will explain the background of the method in the way I found most helpful, and give a few demonstrative examples. I’ll show how to integrate polynomial functions between any finite limits, and give an example with an infinite upper limit. Before that though, I will introduce the more general quadrature method.
Integration by Quadrature
Suppose we try to evaluate an integral numerically by expanding it as a summation
For this to work the coefficients (“weights”) and sample points have to be found. Weights can be found for any set of sample points; to illustrate this suppose there is an integral to evaluate between limits [-1, 1] and we are happy to approximate as an -term polynomial series, with so that . I might chose the sample points then we can write
where the last line was just finding the integral of the polynomial. This would certainly be satisfied if the coefficients of were equated, so , and , so we can cancel the ‘s and write the matrix equation
After substituting for the sample points , this linear set of equations can be solved using linear algebra techniques to get , and .
Using these weights let’s take a specific example of . It is easy to calculate , and , and so the result of the integral is . Evaluating the integral directly gives , so we had *exactly* the right answer with only three sample points. For comparison using the trapezium rule with 1000 sample points gives which is only accurate to four decimal places.
With this technique polynomials up to degree can be integrated exactly between given limits from sample points. If a smaller number of sample points are used, then the result will be an approximation from the series expansion between the limits; this could be a good approximation but there is no guarantee. Functions which do not have finite polynomial expansions such as cannot be integrated exactly, but a high-degree polynomial can be an excellent approximation in a range.
Gaussian Quadrature – Choosing Sample Points
I said earlier that any sample points could be used if appropriate weights were calculated. In the previous example, if we had chosen then the weights would have been but the answer would have been identical. One could ask the question: “is there an optimum set of sample locations?” It turns out that for certain classes of functions there is, and in these cases sample points can produce exact answers of integrands with degree . This relies on some of the fundamental properties of orthogonal polynomials, and is what distinguishes “quadrature rules” from Gaussian-quadrature.
Suppose the function to be integrated can be written as
where is referred to as a weight function. Rather than expanding as a polynomial series with terms, expand it up to terms then use polynomial division to write it with the form
where is a quotient function, is a remainder function and is an as-yet unspecified orthogonal polynomial of degree [1]. Whilst and are unspecified their degrees must both be [1] since has a degree of .
Writing the integral out again
it is apparent that if were itself expanded in orthogonal polynomials it would only need to be expanded up to degree , so and
This is a very interesting form. From here, the properties of orthogonal polynomials imply that if the limits and were the limits of orthogonality for a class of orthogonal polynomials and happened to be their weight function, then the first integral would be zero. In that case the integral of a function of degree could be evaluated exactly by performing the integral of which is only of degree .
Now, when we evaluate this integral numerically we don’t have the form of or and we certainly don’t want to have to work them out! What we have is a summation over sample points
Although the integral , there is nothing to guarantee that this is also true for the summations . To ensure that they are zero, use the trick of making the sample positions where ; these points are available for a large number of polynomials in software packages and tables. The first term on every line then disappears, making the integral
which is samples of a function with degree , and we know from before that this situation produces an exact answer. To summarise, the function was expanded up to degree . By carefully selecting sample locations, we have found an integral of an -degree function which will give the same answer, and we only need samples to evaluate that integral exactly. So we can evaluate a polynomial of degree with only samples of it. Since the zeros and weights only have to be calculated once (and that’s already been done for a lot of polynomials), this method allows fast and accurate evaluation of integrals with very few samples.
Example 1
The Legendre polynomials have the weight function and are orthogonal in the range . The zeros of the third degree Legendre polynomial are . These can be substituted into the matrix above giving
which can be solved to give the weights . The code to achieve this in Python is below; note that the SciPy function roots_legendre automatically returns the weights, so the code calculates them and prints them both out.
import numpy as np
import scipy.special as sp
roots, weights = sp.roots_legendre(3)
a = np.ones((len(roots), len(roots)))
for i in range(1, len(roots)):
a[i] = roots**i
b = np.array([2, 0, 2/3])
my_weights = np.linalg.solve(a, b)
print(f"Calculated weights: {my_weights}")
print(f"Weights from Scipy: {weights}")
Using these sample points and weights, the function evaluates to the exact answer of 6. This is expected because with sample points, results will be exact up to degree . In contrast, if the sample points were (0, 0.5, 1) again then exact results would only be expected up to degree ; using them gives the answer 9.833 which is clearly wrong.
Making samples of the function at the zeros of the Legendre polynomials and using the corresponding weights has increased the degree of the function which can be integrated exactly to .
Example 2 – Change of Interval
Requiring limits may seem restrictive, but the technique can be used for any finite interval by making a change of variables. Define
which maps the limits to and makes the integral
Then by writing and repeating the process above, it becomes clear that the sample points can be the ith zero of in the range [-1, +1] and that the weights are the same as before. Specifically the function would be sampled as with and .
As a specific example the function can be integrated between the limits with the code below. It gives 100032.0 which is exactly the right answer.
import numpy as np
import scipy.special as sp
def f(x):
return 5*x**4
roots, weights = sp.roots_legendre(3)
lim_0 = -2
lim_1 = 10
quad_result = (lim_1-lim_0)/2*np.sum(weights * f((lim_1-lim_0)/2*roots + (lim_0+lim_1)/2))
print(f"Quadrature = {quad_result:.8f}")
print(f"Analytical = {100032:.8f}")
In making this step, a method has been demonstrated to evaluate polynomial functions up to degree using only sample points with any finite limits.
Other limits and Weight Functions
If an integral contains an infinite limit then the formulas above will be difficult to use. Whilst other methods to evaluate these improper integrals do exist [2], there can be complications when using them in practice; for example in [2] the midpoint Riemann sum is used to avoid evaluating and . Furthermore, functions such as do not have finite polynomial expansions and so can’t be integrated exactly with the outlined method. In these cases it might be possible to use the Gaussian quadrature technique using the zeros of other orthogonal polynomials.
Integrals of the form
can be evaluated exactly using this method, if the weights and limits are as given in [3, pp.774; 4]. Once a set of suitable polynomials have been identified, their zeros and the weight coefficients can be found. One example will be given for Gauss-Laguerre quadrature, but other weight functions and limits exist.
Gauss-Laguerre Quadrature
Gauss-Laguerre quadrature can be used for weight functions and limits . In this case the sample locations are the zeros of the order Laguerre polynomial; for these are .
To calculate the weights the integrals have to be computed for . This gives for the first three, which are then plugged into a matrix similar to the one above
Solving this for the weights gives . The code to achieve this is given below.
import numpy as np
import scipy.special as sp
roots, weights = sp.roots_laguerre(3)
a = np.ones((len(roots), len(roots)))
for i in range(1, len(roots)):
a[i] = roots**i
b = np.array([1, 1, 2])
my_weights = np.linalg.solve(a, b)
print(f"Calculated weights: {my_weights}")
print(f"Weights from Scipy: {weights}")
As an example the integral
will be evaluated, where is a generalised Laguerre polynomial. Since is of degree 10, exact evaluation of this function requires at least 6 samples since . Computing with five samples gives 65.99603, whilst >=6 samples give 66.0, which is also the analytical answer from [3, 22.13.12]. The code to demonstrate this is given below.
import numpy as np
import scipy.special as sp
L10 = sp.genlaguerre(10, 3)
def f(x):
return L10(x)
def integrand(x):
return np.exp(-x)*f(x)
roots, weights = sp.roots_laguerre(6)
print(f"Quadrature = {np.sum(weights * f(roots)):.5f}")
L9 = sp.genlaguerre(9, 3)
print(f"Analytical = {L10(0) - L9(0):.5f}")
Conclusion
In this post I introduced the general idea of quadrature rules, where samples of a function can be used to exactly integrate a polynomial of degree . I then explained how this was expanded with Gaussian quadrature, by using the properties of orthogonal polynomials so that samples can give some exact integrals of polynomials with degree , provided the sample locations are chosen as the zeros of certain orthogonal polynomials. I have shown how that is extended to very general integrals with finite limits and how some variations of the technique, such as Gauss-Laguerre quadrature, can evaluate some integrals with infinite limits.
References
[1] – BCcampus Open Publishing, Dividing Polynomials, Accessed 07/2022.
[2] – W. H. Press, “Numerical Recipes: The Art of Scientific Computing”, https://numerical.recipes
[3] – M. Abbramowitz & I. Stegun, “Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables”, https://archive.org/details/AandS-mono600
[4] – Digital Library of Mathematical Functions, https://dlmf.nist.gov/18.3 accessed 07/2022.