rint
Numerical integration routines written in Rust.
Overview
This library contains numerical integration routines for both functions of one dimension (see quadrature) and functions with multiple dimensions up to $N = 15$ (see multi). The basic principle of the library is to expose all of the routines through the trait system. Each of the one- and multi-dimensional integrators take as a parameter a type implementing the trait Integrand.
The integration routines attempt to make approximations to integrals such as the one-dimensional integral,
I = \int_{b}^{a} f(x) dx
or the $N$-dimensional
I = \int_{\Sigma_{N}} f(\mathbf{x}) d\mathbf{x}
where $\mathbf{x} = (x_{1}, x_{2}, \dots, x_{N})$ and $\Sigma_{N}$ is an $N$-dimensional hypercube. The functions $f(x)$ and $f(\mathbf{x})$ can be real valued, with return type f64 or complex valued with return type Complex<f64>. The numerical integration routines approximate the integral of a function by performing a weighted sum of the function evaluated at defined points/abscissae. For example, in the one-dimensional case,
I = \int_{b}^{a} f(x) dx \approx \sum_{i = 1}^{n} W_{i} f(X_{i}) = I_{n}
where the $X_{i}$ and $W_{i}$ are the rescaled abscissae and weights,
X_{i} = \frac{b + a + (a - b) x_{i}}{2} \\ W_{i} = \frac{(a - b) w_{i}}{2}
Integration rules have a polynomial order. Rules of higher polynomial order use more points/abscissae and weights for evaluating the sum.
The library contains both non-adaptive and adaptive integration routines. In the case of an adaptive routine, the user supplies an error Tolerance which acts as a goal for the numerical error estimate. The numerical integration is considered successful when the numerical error is less than the user supplied tolerance. On success, the output of the numerical integration is an IntegralEstimate.
Traits
The primary entry point for the library is the Integrand trait. A type implementing the Integrand trait represents a real or complex valued function which is to be integrated. The trait requires the definition of two associated types, Integrand::Point and Integrand::Scalar, and an implementation of the method Integrand::evaluate.
-
Integrand::Point: This associated type defines the point at which the function is to be evaluated, and determines the types of numerical integrators which are available to the user to integrate the function. Integrators are provided for univariate functions $f(x)$ through the associated typePoint=f64, while integrators for multivariate functions $f(\mathbf{x})$ are provided through the associated typePoint=[f64;N]where $N$ is the dimensionality of the point $\mathbf{x}=(x_{1},\dots,x_{N})$ which is limited to $2 \le N \le 15$. -
Integrand::Scalar: This is the output type of the function to be integrated. A real valued function should have the output typeScalar=f64, while a complex valued function should have output typeScalar=Complex<f64>. -
Integrand::evaluate: The trait requires an implementation of anevaluatemethod, which defines how the function takes the inputIntegrand::Pointand turns this into the output typeIntegrand::Scalar. In other words, this method tells the integrators how to evaluate the function at a point, allowing the integration to be done.
As an example, consider probability density function of a normal distribution,
f(x) = \frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{- \frac{(x - \mu)^{2}}{2 \sigma^{2}}}
which has mean $\mu$ and standard deviation $\sigma$. To integrate this function, one first implements the Integrand trait,
use Integrand;
The type NormalDist can then be passed as a parameter to a one-dimensional integration routine in the module quadrature and integrated over a given (possibly infinite) region.
Modules
quadrature
The quadrature module provides a number of numerical quadrature integration routines of a function in one dimension. The routines are based primarily on the algorithms presented in the Fortran library QUADPACK (Piessens, de Doncker-Kapenga, Ueberhuber and Kahaner) and reimplemented in the GNU scientific library (GSL) (Gough, Alken, Gonnet, Holoborodko, Griessinger). The integrators use Gauss-Kronrod integration rules, combining two rules of different order for efficient estimation of the numerical error. The rules for an $n$-point Gauss-Kronrod rule contain $m = (n - 1) / 2$ abscissae shared by the Gaussian and Kronrod rules and an extended set of $n - m$ Kronrod abscissae. Thus, only $n$ total function evaluations are required for both the integral and error estimates.
The rint library departs from the naming conventions of the QUADPACK and GSL, but provides a selection of comparable implementations:
-
quadrature::Basic: A non-adaptive routine which applies a provided Gauss-Kronrod integrationquadrature::Ruleto a function exactly once. -
quadrature::Adaptive: A one-dimensional adaptive routine based on theqag.fQUADPACK andqag.cGSL implementations. The integration is region is bisected into subregions and an initial estimate is performed. Upon each further iteration of the routine the subregion with the highest numerical error estimate is bisected again and new estimates are calculated for these newly bisected regions. This concentrates the integration refinement to the regions with highest error, rapidly reducing the numerical error of the routine. Gauss-Kronrod integrationquadrature::Rules are provided of various order to use with the adaptive algorithm. -
quadrature::AdaptiveSingularity: A one-dimensional adaptive routine based on theqags.fQUADPACK andqags.cGSL implementations. Adaptive routines concentrate new subintervals around the region of highest error. If this region contains an integrable singularity, then the adaptive routine ofquadrature::Adaptivemay fail to obtain a suitable estimate. However, this can be combined with an extrapolation proceedure such as the Wynn epsilon-algorithm to extrapolate the value at these integrable singularities and provide a suitable estimate. As well as handling integrable singularities,quadrature::AdaptiveSingularitycan be used to calculate integrals with infinite or semi-infinite bounds by using the appropriate constructors.
multi
The multi module provides numerical integration routines for integrating functions with dimensionality between $2 \le N \le 15$. The functions can be either real-valued or complex, and are integrated over an $N$-dimensional hypercube. The routines are based primarily on the DCUHRE FORTRAN library (Bernsten, Espelid, Genz), which use sets of fully-symmetric integration rules to obtain integral and error estimates. Unlike the original algorithm the routines presented in multi currently only operate on a single function not a vector of functions. The module provides two classes of routine:
-
multi::Basic: A non-adaptive routine which applies a fully-symmetric integration rulemulti::Ruleto a multi-dimensional function exactly once. -
multi::Adaptive: A $2 \le N \le 15$ dimensional adaptive routine with a similar approach to the one-dimensional adaptive routines found inquadrature. On each iteration of the algorithm the axis along which the largest contribution to the error estimate was obtained is used as the bisection axis to bisect the integration region and then calculate new estimates for these newly bisected volumes. This concentrates the integration refinement to the regions with highest error, rapidly reducing the numerical error of the routine. The algorithm uses fully-symmetric integration rules,multi::Rule, of varying order and generality. These are generated through theRule*::generateconstructors.
One-dimensional example
The following example integrates the function
f(x) = \frac{\log(x)}{(1 + 100 x^{2})}
over the semi-infinite interval $0 < x < \infty$ using an adaptive integration routine with singularity detection (see quadrature::AdaptiveSingularity). Adapted from the QUADPACK & GSL numerical integration test suites.
use ;
use AdaptiveSingularity;
use Error;
;
Multi-dimensional example
The following example integtates a 4-dimensional function $f(\mathbf{x})$,
f(\mathbf{x}) = \frac{x_{3}^{2} x_{4} e^{x_{3} x_{4}}}{(1 + x_{1} + x_{2})^{2}}
where $\mathbf{x} = (x_{1}, x_{2}, x_{3}, x_{4})$ over an $N=4$ dimensional hypercube $((0,1),(0,1),(0,2),(0,1))$ using a fully-symmetric 7-point adaptive algorithm. Adapted from P. van Dooren & L. de Ridder, "An adaptive algorithm for numerical integration over an n-dimensional cube", J. Comp. App. Math., Vol. 2, (1976) 207-217
use ;
use ;
use Error;
const N: usize = 4;
;