lds-rs 0.1.6

Low Discrepancy Sequence Generation in Rust
Documentation
use crate::lds::VdCorput;

/// The HaltonN struct is a generator for the Halton(n) sequence.
///
/// Properties:
///
/// * `vdcs`: A vector of VdCorput objects.
#[derive(Debug)]
pub struct HaltonN {
    vdcs: Vec<VdCorput>,
}

/// Halton(n) sequence generator
///
/// The [`HaltonN`] class is a sequence generator that generates points in a
/// N-dimensional space using the Halton sequence. The Halton sequence is a
/// low-discrepancy sequence that is commonly used in quasi-Monte Carlo methods.
/// It is generated by iterating over two different bases and calculating the
/// fractional parts of the numbers in those bases. The [`HaltonN`] class keeps
/// track of the current count and bases, and provides a `pop()` method that
/// returns the next point in the sequence as a `std::vector<double>`.
///
/// # Examples
///
/// ```
/// use lds_rs::HaltonN;
/// use approx_eq::assert_approx_eq;
///
/// let mut hgen = HaltonN::new(&[2, 3, 5, 7, 11]);
/// hgen.reseed(10);
/// for _i in 0..10 {
///     println!("{:?}", hgen.pop_vec());
/// }
/// let res = hgen.pop_vec();
///
/// assert_approx_eq!(res[0], 0.65625);
/// ```
impl HaltonN {
    /// Creates a new [`HaltonN`].
    ///
    /// The `new` function creates a new `HaltonN` struct with a specified number of `VdCorput`
    /// instances.
    ///
    /// Arguments:
    ///
    /// * `base`: The `base` parameter is a slice of `usize` values. It represents the base values for
    /// each dimension of the Halton sequence. Each dimension of the Halton sequence uses a different
    /// base value to generate the sequence.
    ///
    /// Returns:
    ///
    /// The `new` function returns a new instance of the `HaltonN` struct.
    pub fn new(base: &[usize]) -> Self {
        HaltonN {
            vdcs: base.iter().map(|b| VdCorput::new(*b)).collect(),
            // vdcs: (0..n).map(|i| VdCorput::new(base[i])).collect(),
        }
    }

    /// Returns the pop vec of this [`HaltonN`].
    ///
    /// The `pop()` function is used to generate the next value in the sequence.
    /// For example, in the [`VdCorput`] class, `pop()` increments the count and
    /// calculates the Van der Corput sequence value for that count and base. In
    /// the [`Halton`] class, `pop()` returns the next point in the Halton sequence
    /// as a `[f64; 2]`. Similarly, in the [`Circle`] class, `pop()`
    /// returns the next point on the unit circle as a `[f64; 2]`. In
    /// the [`Sphere`] class, `pop()` returns the next point on the unit sphere as a
    /// `[f64; 3]`. And in the [`Sphere3Hopf`] class, `pop()` returns
    /// the next point on the 3-sphere using the Hopf fibration as a `[f64; 4]`.
    pub fn pop_vec(&mut self) -> Vec<f64> {
        self.vdcs.iter_mut().map(|vdc| vdc.pop()).collect()
    }

    /// The below code is a Rust function called `reseed` that is used to reset the state of a sequence
    /// generator to a specific seed value. This allows the sequence generator to start generating the
    /// sequence from the beginning or from a specific point in the sequence, depending on the value of the
    /// seed.
    pub fn reseed(&mut self, seed: usize) {
        for vdc in self.vdcs.iter_mut() {
            vdc.reseed(seed);
        }
    }
}