path_planning/rng/
linear.rs1use nalgebra::{SVector, Scalar};
4use rand::distributions::uniform::{SampleUniform, Uniform};
5use rand::distributions::Distribution;
6use rand::Rng;
7
8use crate::util::bounds::Bounds;
9
10pub struct LinearCoordinates<X: SampleUniform, const N: usize>(Vec<Uniform<X>>);
12
13impl<X: SampleUniform, const N: usize> LinearCoordinates<X, N> {
14 pub fn new(mins: SVector<X, N>, maxs: SVector<X, N>) -> Self {
15 let mut dists = Vec::with_capacity(N);
16
17 for (a, b) in mins.iter().zip(maxs.iter()) {
18 dists.push(Uniform::new(a, b));
19 }
20 Self(dists)
21 }
22}
23
24impl<X: SampleUniform, const N: usize> From<Bounds<X, N>>
25 for LinearCoordinates<X, N>
26{
27 fn from(bounds: Bounds<X, N>) -> Self {
28 Self::new(bounds.mins, bounds.maxs)
29 }
30}
31
32impl<X: Scalar + SampleUniform, const N: usize> Distribution<SVector<X, N>>
33 for LinearCoordinates<X, N>
34{
35 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> SVector<X, N> {
36 SVector::<X, N>::from_fn(|i, _| self.0[i].sample(rng))
37 }
38}
39
40#[cfg(test)]
41mod tests {
42
43 use nalgebra::vector;
44 use rand::SeedableRng;
45 use rand_pcg::Pcg32;
46
47 use super::*;
48
49 const SEED: u64 = 0xe580e2e93fd6b040;
50
51 #[test]
52 fn test_sample_f32() {
53 let mins: [f32; 4] = [0.0, 0.0, 0.0, 0.0];
54 let maxs: [f32; 4] = [1.0, 1.0, 2.0, 2.0];
55 let dist = LinearCoordinates::new(mins.into(), maxs.into());
56 let mut rng = Pcg32::seed_from_u64(SEED);
57 assert_eq!(
58 dist.sample(&mut rng),
59 vector![0.9118717, 0.16728437, 1.772038, 0.30819774]
60 );
61 }
62
63 #[test]
64 fn test_sample_f64() {
65 let mins: [f64; 3] = [0.0, 0.0, -1.0];
66 let maxs: [f64; 3] = [1.0, 2.0, 0.0];
67 let dist = LinearCoordinates::new(mins.into(), maxs.into());
68 let mut rng = Pcg32::seed_from_u64(SEED);
69 assert_eq!(
70 dist.sample(&mut rng),
71 vector![0.16728437317346012, 0.3081977641610516, -0.6118928084775344]
72 );
73 }
74}