argmin_math/vec/
random.rs1use crate::ArgminRandom;
9use rand::Rng;
10
11macro_rules! make_random {
12 ($t:ty) => {
13 impl ArgminRandom for Vec<$t> {
14 fn rand_from_range<R: Rng>(min: &Self, max: &Self, rng: &mut R) -> Vec<$t> {
15 assert!(!min.is_empty());
16 assert_eq!(min.len(), max.len());
17
18 min.iter()
19 .zip(max.iter())
20 .map(|(a, b)| {
21 #[allow(clippy::float_cmp)]
25 if a == b {
26 a.clone()
27 } else if a < b {
28 rng.gen_range(a.clone()..b.clone())
29 } else {
30 rng.gen_range(b.clone()..a.clone())
31 }
32 })
33 .collect()
34 }
35 }
36
37 impl ArgminRandom for Vec<Vec<$t>> {
38 fn rand_from_range<R: Rng>(min: &Self, max: &Self, rng: &mut R) -> Vec<Vec<$t>> {
39 assert!(!min.is_empty());
40 assert_eq!(min.len(), max.len());
41 min.iter()
42 .zip(max.iter())
43 .map(|(a, b)| Vec::<$t>::rand_from_range(a, b, rng))
44 .collect()
45 }
46 }
47 };
48}
49
50make_random!(f32);
51make_random!(f64);
52make_random!(i8);
53make_random!(i16);
54make_random!(i32);
55make_random!(i64);
56make_random!(u8);
57make_random!(u16);
58make_random!(u32);
59make_random!(u64);
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use paste::item;
65 use rand::SeedableRng;
66
67 macro_rules! make_test {
68 ($t:ty) => {
69 item! {
70 #[test]
71 fn [<test_random_vec_ $t>]() {
72 let a = vec![1 as $t, 2 as $t, 4 as $t];
73 let b = vec![2 as $t, 3 as $t, 5 as $t];
74 let mut rng = rand::rngs::StdRng::seed_from_u64(42);
75 let random = Vec::<$t>::rand_from_range(&a, &b, &mut rng);
76 for i in 0..3usize {
77 assert!(random[i] >= a[i]);
78 assert!(random[i] <= b[i]);
79 }
80 }
81 }
82
83 item! {
84 #[test]
85 fn [<test_random_mat_ $t>]() {
86 let a = vec![
87 vec![1 as $t, 2 as $t, 4 as $t],
88 vec![2 as $t, 3 as $t, 5 as $t]
89 ];
90 let b = vec![
91 vec![2 as $t, 3 as $t, 5 as $t],
92 vec![3 as $t, 4 as $t, 6 as $t]
93 ];
94 let mut rng = rand::rngs::StdRng::seed_from_u64(42);
95 let random = Vec::<Vec<$t>>::rand_from_range(&a, &b, &mut rng);
96 for i in 0..3 {
97 for j in 0..2 {
98 assert!(random[j][i] >= a[j][i]);
99 assert!(random[j][i] <= b[j][i]);
100 }
101 }
102 }
103 }
104 };
105 }
106
107 make_test!(i8);
108 make_test!(u8);
109 make_test!(i16);
110 make_test!(u16);
111 make_test!(i32);
112 make_test!(u32);
113 make_test!(i64);
114 make_test!(u64);
115 make_test!(f32);
116 make_test!(f64);
117}