pmcore/routines/initialization/
latin.rsuse anyhow::Result;
use faer::Mat;
use rand::prelude::*;
use rand::rngs::StdRng;
use rand::Rng;
use crate::prelude::Parameters;
use crate::structs::theta::Theta;
pub fn generate(parameters: &Parameters, points: usize, seed: usize) -> Result<Theta> {
let params: Vec<(String, f64, f64, bool)> = parameters
.iter()
.map(|p| (p.name.clone(), p.lower, p.upper, p.fixed))
.collect();
let random_params: Vec<(String, f64, f64)> = params
.iter()
.filter(|(_, _, _, fixed)| !fixed)
.map(|(name, lower, upper, _)| (name.clone(), *lower, *upper))
.collect();
let mut rng = StdRng::seed_from_u64(seed as u64);
let mut intervals = Vec::new();
for _ in 0..random_params.len() {
let mut param_intervals: Vec<f64> = (0..points).map(|i| i as f64).collect();
param_intervals.shuffle(&mut rng);
intervals.push(param_intervals);
}
let rand_matrix = Mat::from_fn(points, random_params.len(), |i, j| {
let interval = intervals[j][i];
let random_offset = rng.random::<f64>();
let unscaled = (interval + random_offset) / points as f64;
let (_name, lower, upper) = random_params.get(j).unwrap(); lower + unscaled * (upper - lower)
});
let fixed_params: Vec<(String, f64)> = params
.iter()
.filter(|(_, _, _, fixed)| *fixed)
.map(|(name, lower, upper, _)| (name.clone(), (upper - lower) / 2.0))
.collect();
let theta = Theta::from_parts(rand_matrix, random_params, fixed_params);
Ok(theta)
}