1use ndarray::{Array2, Ix2, ShapeBuilder};
4use ndarray_rand::RandomExt;
5use rand::rngs::StdRng;
6use rand::{Rng, SeedableRng};
7use rand_distr::Distribution;
8use std::cell::RefCell;
9
10thread_local! {
11 static RNG: RefCell<StdRng> = RefCell::new(StdRng::from_entropy());
12}
13
14pub fn seed(seed: u64) {
20 RNG.with(|rng| *rng.borrow_mut() = StdRng::seed_from_u64(seed));
21}
22
23pub(crate) fn with_rng<T>(f: impl FnOnce(&mut StdRng) -> T) -> T {
24 RNG.with(|rng| f(&mut rng.borrow_mut()))
25}
26
27pub(crate) fn random_array<Sh, D>(shape: Sh, dist: D) -> Array2<f64>
28where
29 Sh: ShapeBuilder<Dim = Ix2>,
30 D: Distribution<f64>,
31{
32 with_rng(|rng| Array2::random_using(shape, dist, rng))
33}
34
35pub(crate) fn unit() -> f64 {
37 with_rng(|rng| rng.gen())
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use ndarray_rand::rand_distr::Uniform;
44
45 #[test]
46 fn same_seed_gives_same_values() {
47 seed(7);
48 let a = random_array((3, 4), Uniform::new(0.0, 1.0));
49 seed(7);
50 let b = random_array((3, 4), Uniform::new(0.0, 1.0));
51 seed(8);
52 let c = random_array((3, 4), Uniform::new(0.0, 1.0));
53 assert_eq!(a, b);
54 assert_ne!(a, c);
55 }
56}