gauss-quad 0.3.1

Integrate functions with Gaussian quadrature
Documentation

gauss-quad

Crates.io Version docs.rs Github Repository Link Build Status codecov

This crate lets you integrate functions quickly with Gaussian quadrature.

Gaussian quadrature approximates an integral by only evaluating the integrand at a few carefully chosen points (called nodes), multiplying the results with carefully chosen weights and summing the results.

Through different techniques for choosing the nodes and weights, different types of functions can be integrated while evaluating them a very small number of times.

This enables fast and efficient integration of functions. A quadrature rule with n nodes can perfectly integrate a polynomial of degree 2n-1 or less, and other functions are integrated well if they are well-approximated by a polynomial.

The crate currently supports the following Gaussian quadrature rules:

as well as the following Newton-Cotes formulas:

The crate is no_std compatible (but needs an allocator due to its use of the alloc crate).

Examples

Integrate x^2 from 0 to 1 with Gauss-Legendre quadrature:

use gauss_quad::GaussLegendre;
use approx::assert_abs_diff_eq;

let integrator = GaussLegendre::new(2.try_into()?);

let integral = integrator.integrate(0.0, 1.0, |x| x * x);

assert_abs_diff_eq!(integral, 1.0/3.0);

Integrate x2 * e(-x^2) over the whole real line:

use gauss_quad::GaussHermite;
use approx::assert_abs_diff_eq;

let integrator = GaussHermite::new(10.try_into()?);

let integral = integrator.integrate(|x| x.powi(2));

assert_abs_diff_eq!(integral, core::f64::consts::PI.sqrt() / 2.0, epsilon = 1e-14);

Quadrature rules can be re-used, which means that the weights and nodes only have to be computed once:

use gauss_quad::GaussLegendre;
use approx::assert_abs_diff_eq;

let integrator = GaussLegendre::new(1000.try_into()?);

let integral_1 = integrator.integrate(0, 1, |x| x.sin());
let integral_2 = integrator.integrate(0, core::f64::consts::PI, |x| (x*x).sin());

assert_abs_diff_eq!(integral_1, 0.459697694131860);
assert_abs_diff_eq!(integral_2, 0.772651712690066);

Rules can be nested into double and higher integrals:

let double_integral = integrator.integrate(a, b, |x| integrator.integrate(c(x), d(x), |y| f(x, y)));

If it takes a long time to evaluate the integrand (≫100 µs), the rayon feature can be used to parallelize the computation on multiple cores:

let slow_integral = integrator.par_integrate(a, b, |x| f(x));

This can also be nested with other rules to integrate double and higher integrals in parallel, and the quadrature rules can be different as well:

let slow_double_integral = legendre_integrator.par_integrate(a, b, |x| hermite_integrator.integrate(|y| f(x, y)))

License