Skip to main content

pmcore/estimation/nonparametric/sampling/
sobol.rs

1use anyhow::Result;
2use faer::Mat;
3use sobol_burley::sample;
4
5use crate::estimation::nonparametric::Theta;
6use crate::model::{BoundedParameter, ParameterSpace};
7
8pub fn generate(
9    parameters: &ParameterSpace<BoundedParameter>,
10    points: usize,
11    seed: usize,
12) -> Result<Theta> {
13    let seed = seed as u32;
14    let ranges = parameters.finite_ranges();
15
16    let rand_matrix = Mat::from_fn(points, ranges.len(), |i, j| {
17        let unscaled = sample((i).try_into().unwrap(), j.try_into().unwrap(), seed) as f64;
18        let (lower, upper) = ranges[j];
19        lower + unscaled * (upper - lower)
20    });
21
22    Theta::from_parts(rand_matrix, parameters.clone())
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[test]
30    fn sobol_generate_produces_requested_shape() {
31        let params = ParameterSpace::<BoundedParameter>::new()
32            .add("a", 0.0, 1.0)
33            .add("b", 0.0, 1.0)
34            .add("c", 0.0, 1.0);
35
36        let theta = generate(&params, 10, 22).unwrap();
37        assert_eq!(theta.nspp(), 10);
38        assert_eq!(theta.matrix().ncols(), 3);
39    }
40}