tensors-rs 0.1.2

Compact NumPy-like dense tensor primitives for safe numerical Rust.
Documentation
//! Small deterministic random number generator for optional initialization.

use crate::numeric::Float;

/// Deterministic 64-bit linear congruential generator.
#[derive(Clone, Debug)]
pub(crate) struct SmallRng {
    state: u64,
    spare: Option<f64>,
}

impl SmallRng {
    pub(crate) fn new(seed: u64) -> Self {
        Self {
            state: seed ^ 0x9e37_79b9_7f4a_7c15,
            spare: None,
        }
    }

    fn next_u64(&mut self) -> u64 {
        self.state = self
            .state
            .wrapping_mul(6364136223846793005)
            .wrapping_add(1442695040888963407);
        self.state
    }

    pub(crate) fn uniform<T: Float>(&mut self) -> T {
        let value = (self.next_u64() >> 11) as f64 * (1.0 / ((1u64 << 53) as f64));
        T::from_f64(value)
    }

    pub(crate) fn normal<T: Float>(&mut self) -> T {
        if let Some(spare) = self.spare.take() {
            return T::from_f64(spare);
        }
        let u1 = (self.uniform::<f64>()).max(f64::MIN_POSITIVE);
        let u2 = self.uniform::<f64>();
        let radius = (-2.0 * u1.ln()).sqrt();
        let theta = core::f64::consts::TAU * u2;
        self.spare = Some(radius * theta.sin());
        T::from_f64(radius * theta.cos())
    }
}