1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use core::{
mem::size_of,
sync::atomic::{AtomicU64, Ordering},
};
use getrandom::getrandom;
use oorandom::Rand32;
static STATE1: AtomicU64 = AtomicU64::new(0);
static STATE2: AtomicU64 = AtomicU64::new(0);
pub fn rand() -> f64 {
let mut gen = if STATE1.load(Ordering::SeqCst) == 0 && STATE2.load(Ordering::SeqCst) == 0 {
let mut buf = [0; size_of::<u64>()];
getrandom(&mut buf).unwrap();
Rand32::new(u64::from_le_bytes(buf))
} else {
Rand32::from_state((STATE1.load(Ordering::SeqCst), STATE2.load(Ordering::SeqCst)))
};
let v = gen.rand_float() as f64;
let state = gen.state();
STATE1.store(state.0, Ordering::SeqCst);
STATE2.store(state.1, Ordering::SeqCst);
v
}
#[inline]
pub fn maybe(v: f64) -> bool {
rand() < v
}
#[inline]
pub fn rand_float(lb: f64, ub: f64) -> f64 {
rand() * (ub - lb) + lb
}
#[inline]
pub fn rand_int(lb: usize, ub: usize) -> usize {
(rand() * (ub - lb) as f64) as usize + lb
}
pub fn rand_vector(v: &mut [usize], start: usize, lb: usize, ub: usize) {
for i in start..v.len() {
v[i] = rand_int(lb, ub);
while v[..i].contains(&v[i]) {
v[i] = rand_int(lb, ub);
}
}
}