math_audio_optimisation/
init_sobol.rs1pub fn init_sobol(dimensions: usize, num_samples: usize, bounds: &[(f64, f64)]) -> Vec<Vec<f64>> {
14 let mut samples = Vec::with_capacity(num_samples);
15
16 for i in 0..num_samples {
17 let mut sample = Vec::with_capacity(dimensions);
18
19 for (dim, &(lower, upper)) in bounds.iter().enumerate().take(dimensions) {
20 let base = match dim {
21 0 => 2,
22 1 => 3,
23 2 => 5,
24 3 => 7,
25 4 => 11,
26 _ => 2 + (dim % 10),
27 };
28
29 let quasi_random = van_der_corput(i + 1, base);
30 sample.push(lower + quasi_random * (upper - lower));
31 }
32
33 samples.push(sample);
34 }
35
36 samples
37}
38
39fn van_der_corput(mut n: usize, base: usize) -> f64 {
41 let mut result = 0.0;
42 let mut f = 1.0 / base as f64;
43
44 while n > 0 {
45 result += (n % base) as f64 * f;
46 n /= base;
47 f /= base as f64;
48 }
49
50 result
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_van_der_corput() {
59 let val1 = van_der_corput(1, 2);
60 let val2 = van_der_corput(2, 2);
61 let val3 = van_der_corput(3, 2);
62
63 assert!((0.0..1.0).contains(&val1));
64 assert!((0.0..1.0).contains(&val2));
65 assert!((0.0..1.0).contains(&val3));
66
67 assert_ne!(val1, val2);
68 assert_ne!(val2, val3);
69 }
70
71 #[test]
72 fn test_init_sobol() {
73 let bounds = vec![(0.0, 10.0), (0.1, 5.0), (-12.0, 12.0)];
74 let samples = init_sobol(3, 5, &bounds);
75
76 assert_eq!(samples.len(), 5);
77 for sample in &samples {
78 assert_eq!(sample.len(), 3);
79 assert!((0.0..=10.0).contains(&sample[0]));
80 assert!((0.1..=5.0).contains(&sample[1]));
81 assert!((-12.0..=12.0).contains(&sample[2]));
82 }
83 }
84}