rint 0.1.2

A pure Rust library for the numerical integration of real or complex valued functions of real variables in multiple dimensions.
Documentation
use crate::Limits;

/// The geometry of a multi-dimensional integral
///
/// Contains an array of the `centre` points and `half_widths` in each integration axis for a given
/// region, alongside the volume and the longest axis.
pub(crate) struct Geometry<const N: usize> {
    pub(crate) centre: [f64; N],
    pub(crate) half_widths: [f64; N],
    pub(crate) volume: f64,
    pub(crate) largest_axis: usize,
}

impl<const N: usize> Geometry<N> {
    pub(crate) const fn new(limits: &[Limits; N]) -> Self {
        let mut centre = [0.0; N];
        let mut half_widths = [0.0; N];

        let mut volume = 1.0;

        let mut j = 0;
        let mut largest_axis = 0;
        while j < N {
            centre[j] = limits[j].centre();
            half_widths[j] = limits[j].half_width();
            volume *= half_widths[j];
            if half_widths[j] > half_widths[largest_axis] {
                largest_axis = j;
            }
            j += 1;
        }

        Self {
            centre,
            half_widths,
            volume,
            largest_axis,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn geometry_tests() {
        let limits = [
            Limits::new(0.0, 10.0).unwrap(),
            Limits::new(-1.0, 2.0).unwrap(),
            Limits::new(-100.0, 0.0).unwrap(),
        ];

        let centre_should_be = [5.0, 0.5, -50.0];
        let half_widths_should_be = [5.0, 1.5, 50.0];
        let volume_should_be = 375.0;
        let largest_axis_should_be = 2;

        let Geometry {
            centre,
            half_widths,
            volume,
            largest_axis,
        } = Geometry::new(&limits);

        for (a, b) in centre.iter().zip(centre_should_be.iter()) {
            assert!((a - b).abs() < f64::EPSILON);
        }

        for (a, b) in half_widths.iter().zip(half_widths_should_be.iter()) {
            assert!((a - b).abs() < f64::EPSILON);
        }

        assert!((volume - volume_should_be).abs() < f64::EPSILON);
        assert_eq!(largest_axis, largest_axis_should_be);
    }
}