matrix_oxide/
random.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3/// Simple Pseudo Random Number Generator
4fn linear_congruential_generator(seed: &mut u64) -> u64 {
5    const A: u64 = 1664525;
6    const C: u64 = 1013904223;
7    const M: u64 = 1 << 32;
8
9    *seed = (*seed).wrapping_mul(A).wrapping_add(C) % M;
10    *seed
11}
12
13/// Generate a (pseudo)random `Vec<T>`
14pub fn gen_rand_vec<T: Random>(n: usize) -> Vec<T> {
15    // Seed is current time (secs) since the unix epoch
16    let start = SystemTime::now();
17    let duration = start
18        .duration_since(UNIX_EPOCH)
19        .expect("Oh shit broo, time went backwards!");
20    let mut seed = duration.as_secs();
21
22    (0..n).map(|_| T::random(&mut seed)).collect()
23}
24
25/// Trait for generating random values
26pub trait Random {
27    fn random(seed: &mut u64) -> Self;
28}
29/// Implements Random trait for `f64`
30impl Random for f64 {
31    fn random(seed: &mut u64) -> Self {
32        linear_congruential_generator(seed) as f64 / (u64::MAX as f64)
33    }
34}
35/// Implements Random trait for `i64`
36impl Random for i64 {
37    fn random(seed: &mut u64) -> Self {
38        // Constrain the max random number for i64 to 50,000
39        const MAX: i64 = 50_000;
40        (linear_congruential_generator(seed) % (MAX as u64)) as i64
41    }
42}
43/// Implements Random trait for `i32`
44impl Random for i32 {
45    fn random(seed: &mut u64) -> Self {
46        // Constrain the max random number for i32 to 5,000
47        const MAX: i64 = 5_000;
48        (linear_congruential_generator(seed) % (MAX as u64)) as i32
49    }
50}
51/// Implements Random trait for `u8`
52impl Random for u8 {
53    fn random(seed: &mut u64) -> Self {
54        const MAX: u8 = 10;
55        (linear_congruential_generator(seed) % (MAX as u64)) as u8
56    }
57}