roots_hermitenorm#
- scipy.special.roots_hermitenorm(n, mu=False)[source]#
Gauss-Hermite (statistician’s) quadrature.
Compute the sample points and weights for Gauss-Hermite quadrature. The sample points are the roots of the nth degree Hermite polynomial, \(He_n(x)\). These sample points and weights correctly integrate polynomials of degree \(2n - 1\) or less over the interval \([-\infty, \infty]\) with weight function \(w(x) = e^{-x^2/2}\). See 22.2.15 in [AS] for more details.
- Parameters:
- nint
quadrature order.
- mubool, optional
If True, return the sum of the weights, optional.
- Returns:
- xndarray
Sample points.
- wndarray
Weights.
- mufloat
Sum of the weights.
Notes
For small n up to 150 a modified version of the Golub-Welsch algorithm is used. Nodes are computed from the eigenvalue problem and improved by one step of a Newton iteration. The weights are computed from the well-known analytical formula.
For n larger than 150 an optimal asymptotic algorithm is used which computes nodes and weights in a numerical stable manner. The algorithm has linear runtime making computation for very large n (several thousand or more) feasible.
References
[AS]Milton Abramowitz and Irene A. Stegun, eds. Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables. New York: Dover, 1972.
Examples
>>> from scipy.special import roots_hermitenorm >>> roots, weights = roots_hermitenorm(5) >>> roots array([-2.85697001, -1.35562618, 0. , 1.35562618, 2.85697001]) >>> weights array([0.02821815, 0.55666179, 1.33686841, 0.55666179, 0.02821815])
Verify that the values in roots are roots of the Hermite polynomial \(He_5(x)\).
>>> from scipy.special import eval_hermitenorm >>> eval_hermitenorm(5, roots) array([ 1.59872116e-14, -5.32907052e-15, 0.00000000e+00, 5.32907052e-15, -1.59872116e-14])
The values of \(He_5(x)\) evaluated at the roots are indeed either zero or rather close to it. The increasing values for larger roots can be explained by the increasing derivative of the Hermite polynomial at the roots.
Verify that the sum of the weights equals the integral from \(-\infty\) to \(\infty\) of \(\exp(-x^2/2)\) which evaluates to \(\sqrt{2\pi}\). There are two ways to obtain the sum of weights, both yielding the expected result.
>>> sum(weights) np.float64(2.5066282746310002) >>> roots, weights, sum_of_weights = roots_hermitenorm(5, mu=True) >>> sum_of_weights np.float64(2.5066282746310002) >>> from math import exp, pi, sqrt >>> sqrt(2*pi) 2.5066282746310002
Roots and weights obtained from the Hermite polynomial \(He_n(x)\) are used in Gauss-Hermite quadrature where the integral from \(-\infty\) to \(\infty\) of \(f(x)\exp(-x^2/2)\) is evaluated. Roots and weights for order \(n\) are expected to yield the exact result for polynomials \(f(x)\) of a maximal order of \(2n-1\).
>>> f = lambda x: x**4 >>> weights @ f(roots) np.float64(7.519884823892987)
This result is indeed very close to the exact value of \(3\sqrt{2\pi}\).
>>> 3*sqrt(2*pi) 7.519884823893001
In general, Gauss-Hermite quadrature will only yield an approximate value of the integral. Consider the integral from \(-\infty\) to \(\infty\) of \(\cos(x)\exp(-x^2/2)\) which evaluates to \(\sqrt{2\pi}\exp(-1/2)\).
>>> import numpy as np >>> weights @ np.cos(roots) np.float64(1.520412469197972) >>> sqrt(2*pi) * exp(-0.5) 1.5203469010662807
In order to improve the accuracy obtained from Gauss-Hermite quadrature, a large number of nodes can be chosen.
>>> roots, weights = roots_hermitenorm(50) >>> weights @ np.cos(roots) np.float64(1.5203469010662798)