Skip to main content

math_audio_optimisation/
init_latin_hypercube.rs

1use ndarray::{Array1, Array2};
2use rand::Rng;
3use rand::seq::SliceRandom;
4
5pub(crate) fn init_latin_hypercube<R: Rng + ?Sized>(
6    n: usize,
7    npop: usize,
8    lower: &Array1<f64>,
9    upper: &Array1<f64>,
10    is_free: &[bool],
11    rng: &mut R,
12) -> Array2<f64> {
13    let mut samples = Array2::<f64>::zeros((npop, n));
14    // For each dimension, create stratified samples and permute
15    for j in 0..n {
16        if !is_free[j] {
17            // fixed variable
18            for i in 0..npop {
19                samples[(i, j)] = 0.0;
20            }
21            continue;
22        }
23        let mut vals = Vec::with_capacity(npop);
24        for k in 0..npop {
25            let u: f64 = rng.random::<f64>();
26            vals.push(((k as f64) + u) / (npop as f64));
27        }
28        vals.shuffle(rng);
29        for i in 0..npop {
30            samples[(i, j)] = vals[i];
31        }
32    }
33    // Scale to [lower, upper]
34    for i in 0..npop {
35        for j in 0..n {
36            if is_free[j] {
37                samples[(i, j)] = lower[j] + samples[(i, j)] * (upper[j] - lower[j]);
38            } else {
39                samples[(i, j)] = lower[j];
40            }
41        }
42    }
43    samples
44}