pmcore/estimation/nonparametric/sampling/
sobol.rs1use 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(¶ms, 10, 22).unwrap();
37 assert_eq!(theta.nspp(), 10);
38 assert_eq!(theta.matrix().ncols(), 3);
39 }
40}