r2rs-nmath 0.1.1

Statistics programming for Rust based on R's nmath package
Documentation
// "Whatever you do, work at it with all your heart, as working for the Lord,
// not for human masters, since you know that you will receive an inheritance
// from the Lord as a reward. It is the Lord Christ you are serving."
// (Col 3:23-24)

use std::str::FromStr;

use strafe_testing::r::{RString, RTester};

use crate::{
    rng::{LEcuyerCMRG, MarsagliaMulticarry, MersenneTwister, SuperDuper, WichmannHill},
    traits::RNG,
};

pub fn mersenne_twister_rng_inner(seed: u16) {
    let seed = seed as u32;
    let num = 50;

    let r_seed = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Mersenne-Twister")
        .set_display(&RString::from_str(".Random.seed").unwrap())
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap()
        .into_iter()
        .skip(1)
        .map(|i| i as i32)
        .collect::<Vec<_>>();

    let mut rust_rng = MersenneTwister::new();
    rust_rng.set_seed(seed);

    let rust_seed = rust_rng.get_state();

    for (r, rust) in r_seed.iter().zip(rust_seed.iter()) {
        assert_eq!(r, rust, "Seeds not equal!");
    }

    let r_ret = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Mersenne-Twister")
        .set_display(&RString::from_string(format!("runif({})", num,)))
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap();

    let rust_ret = (0..num).map(|_| rust_rng.unif_rand()).collect::<Vec<_>>();

    for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
        assert_relative_eq!(r, rust, max_relative = 0.0001);
    }
}

pub fn lecuyer_cmrg_rng_inner(seed: u16) {
    let seed = seed as u32;
    let num = 50;

    let r_seed = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("L\\'Ecuyer-CMRG")
        .set_display(&RString::from_str(".Random.seed").unwrap())
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap()
        .into_iter()
        .skip(1)
        .map(|i| i as i32)
        .collect::<Vec<_>>();

    let mut rust_rng = LEcuyerCMRG::new();
    rust_rng.set_seed(seed);

    let rust_seed = rust_rng.get_state();

    for (r, rust) in r_seed.iter().zip(rust_seed.iter()) {
        assert_eq!(r, rust, "Seeds not equal!");
    }

    let r_ret = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("L\\'Ecuyer-CMRG")
        .set_display(&RString::from_string(format!("runif({})", num,)))
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap();

    let rust_ret = (0..num).map(|_| rust_rng.unif_rand()).collect::<Vec<_>>();

    for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
        assert_relative_eq!(r, rust, max_relative = 0.0001);
    }
}

pub fn marsagllia_multicarry_rng_inner(seed: u16) {
    let seed = seed as u32;
    let num = 50;

    let r_seed = RTester::new()
        .set_seed(seed as u16)
        .set_display(&RString::from_str(".Random.seed").unwrap())
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap()
        .into_iter()
        .skip(1)
        .map(|i| i as i32)
        .collect::<Vec<_>>();

    let mut rust_rng = MarsagliaMulticarry::new();
    rust_rng.set_seed(seed);

    let rust_seed = rust_rng.get_state();

    for (r, rust) in r_seed.iter().zip(rust_seed.iter()) {
        assert_eq!(r, rust, "Seeds not equal!");
    }

    let r_ret = RTester::new()
        .set_seed(seed as u16)
        .set_display(&RString::from_string(format!("runif({})", num,)))
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap();

    let rust_ret = (0..num).map(|_| rust_rng.unif_rand()).collect::<Vec<_>>();

    for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
        assert_relative_eq!(r, rust, max_relative = 0.0001);
    }
}

pub fn super_duper_rng_inner(seed: u16) {
    let seed = seed as u32;
    let num = 50;

    let r_seed = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Super-Duper")
        .set_display(&RString::from_str(".Random.seed").unwrap())
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap()
        .into_iter()
        .skip(1)
        .map(|i| i as i32)
        .collect::<Vec<_>>();

    let mut rust_rng = SuperDuper::new();
    rust_rng.set_seed(seed);

    let rust_seed = rust_rng.get_state();

    for (r, rust) in r_seed.iter().zip(rust_seed.iter()) {
        assert_eq!(r, rust, "Seeds not equal!");
    }

    let r_ret = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Super-Duper")
        .set_display(&RString::from_string(format!("runif({})", num,)))
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap();

    let rust_ret = (0..num).map(|_| rust_rng.unif_rand()).collect::<Vec<_>>();

    for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
        assert_relative_eq!(r, rust, max_relative = 0.0001);
    }
}

pub fn wichmann_hill_rng_inner(seed: u16) {
    let seed = seed as u32;
    let num = 50;

    let r_seed = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Wichmann-Hill")
        .set_display(&RString::from_str(".Random.seed").unwrap())
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap()
        .into_iter()
        .skip(1)
        .map(|i| i as i32)
        .collect::<Vec<_>>();

    let mut rust_rng = WichmannHill::new();
    rust_rng.set_seed(seed);

    let rust_seed = rust_rng.get_state();

    for (r, rust) in r_seed.iter().zip(rust_seed.iter()) {
        assert_eq!(r, rust, "Seeds not equal!");
    }

    let r_ret = RTester::new()
        .set_seed(seed as u16)
        .set_rand_type("Wichmann-Hill")
        .set_display(&RString::from_string(format!("runif({})", num,)))
        .run()
        .unwrap()
        .as_f64_vec()
        .unwrap();

    let rust_ret = (0..num).map(|_| rust_rng.unif_rand()).collect::<Vec<_>>();

    for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
        assert_relative_eq!(r, rust, max_relative = 0.0001);
    }
}