r2rs-nmath 0.1.1

Statistics programming for Rust based on R's nmath package
Documentation
use crate::{
    rng::{fixup, i2_32m1},
    traits::RNG,
};

#[derive(Clone, Debug)]
pub struct SuperDuper {
    state: [u32; 2],
}

impl Default for SuperDuper {
    fn default() -> Self {
        Self::new()
    }
}

impl SuperDuper {
    pub fn new() -> Self {
        let mut ret = Self { state: [0; 2] };
        ret.randomize();
        ret
    }

    pub fn fixup_seeds(&mut self) {
        if self.state[0] == 0 {
            self.state[0] = 1
        }
        self.state[1] |= 1;
    }
}

impl RNG for SuperDuper {
    fn set_seed(&mut self, mut seed: u32) {
        for _ in 0..50 {
            seed = seed.wrapping_mul(69069).wrapping_add(1);
        }

        (0..2).for_each(|j| {
            seed = seed.wrapping_mul(69069).wrapping_add(1);
            self.state[j] = seed;
        });

        self.fixup_seeds()
    }

    fn get_state(&self) -> Vec<i32> {
        self.state.clone().iter().map(|&i| i as i32).collect()
    }

    fn unif_rand(&mut self) -> f64 {
        let i1 = self.state[0];
        self.state[0] ^= (i1 >> 15) & 0o377777;

        let i1 = self.state[0];
        self.state[0] ^= i1 << 17;

        let i2 = self.state[1];
        self.state[1] = i2.wrapping_mul(69069);

        let (i1, i2) = (self.state[0], self.state[1]);

        fixup((i1 ^ i2) as f64 * i2_32m1)
    }
}