use std::cell::RefCell;
use rand::rngs::StdRng;
use rand::{RngExt, SeedableRng};
use rand_distr::StandardNormal;
thread_local! {
static RNG: RefCell<StdRng> = RefCell::new(rand::make_rng());
}
pub fn manual_seed(seed: u64) {
RNG.with(|r| *r.borrow_mut() = StdRng::seed_from_u64(seed));
}
pub fn with_rng<T>(f: impl FnOnce(&mut StdRng) -> T) -> T {
RNG.with(|r| f(&mut r.borrow_mut()))
}
pub fn uniform(n: usize, lo: f32, hi: f32) -> Vec<f32> {
with_rng(|rng| (0..n).map(|_| rng.random_range(lo..hi)).collect())
}
pub fn normal(n: usize) -> Vec<f32> {
with_rng(|rng| (0..n).map(|_| rng.sample(StandardNormal)).collect())
}
pub fn bernoulli(n: usize, p: f32) -> Vec<bool> {
with_rng(|rng| (0..n).map(|_| rng.random::<f32>() < p).collect())
}
pub fn shuffle<T>(items: &mut [T]) {
use rand::seq::SliceRandom;
with_rng(|rng| items.shuffle(rng));
}