diff --git a/benches/bimodal_ke.rs b/benches/bimodal_ke.rs index 68ef7701..c7d56a77 100644 --- a/benches/bimodal_ke.rs +++ b/benches/bimodal_ke.rs @@ -21,8 +21,8 @@ fn create_equation() -> equation::ODE { fn setup_simulation() -> Result<(Settings, equation::ODE, data::Data)> { let params = Parameters::new() - .add("ke", 0.001, 3.0, false) - .add("v", 25.0, 250.0, false); + .add("ke", 0.001, 3.0) + .add("v", 25.0, 250.0); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/bimodal_ke/main.rs b/examples/bimodal_ke/main.rs index 3cc80a8a..ab685a87 100644 --- a/examples/bimodal_ke/main.rs +++ b/examples/bimodal_ke/main.rs @@ -19,8 +19,8 @@ fn main() -> Result<()> { ); let params = Parameters::new() - .add("ke", 0.001, 3.0, false) - .add("v", 25.0, 250.0, false); + .add("ke", 0.001, 3.0) + .add("v", 25.0, 250.0); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/drusano/main.rs b/examples/drusano/main.rs index 7ae22a54..56359502 100644 --- a/examples/drusano/main.rs +++ b/examples/drusano/main.rs @@ -81,30 +81,30 @@ fn main() -> Result<()> { ); let params = Parameters::new() - .add("v1", 5.0, 160.0, false) - .add("cl1", 4.0, 9.0, false) - .add("v2", 100.0, 200.0, false) - .add("cl2", 25.0, 35.0, false) - .add("popmax", 100000000.0, 100000000000.0, false) - .add("kgs", 0.01, 0.25, false) - .add("kks", 0.01, 0.5, false) - .add("e50_1s", 0.1, 2.5, false) - .add("e50_2s", 0.1, 10.0, false) - .add("alpha_s", -8.0, 5.0, false) - .add("kgr1", 0.004, 0.1, false) - .add("kkr1", 0.08, 0.4, false) - .add("e50_1r1", 8.0, 17.0, false) - .add("alpha_r1", -8.0, 5.0, false) - .add("kgr2", 0.004, 0.3, false) - .add("kkr2", 0.1, 0.5, false) - .add("e50_2r2", 5.0, 8.0, false) - .add("alpha_r2", -5.0, 5.0, false) - .add("init_4", -1.0, 4.0, false) - .add("init_5", -1.0, 3.0, false) - .add("h1s", 0.5, 8.0, false) - .add("h2s", 0.1, 4.0, false) - .add("h1r1", 5.0, 25.0, false) - .add("h2r2", 10.0, 22.0, false); + .add("v1", 5.0, 160.0) + .add("cl1", 4.0, 9.0) + .add("v2", 100.0, 200.0) + .add("cl2", 25.0, 35.0) + .add("popmax", 100000000.0, 100000000000.0) + .add("kgs", 0.01, 0.25) + .add("kks", 0.01, 0.5) + .add("e50_1s", 0.1, 2.5) + .add("e50_2s", 0.1, 10.0) + .add("alpha_s", -8.0, 5.0) + .add("kgr1", 0.004, 0.1) + .add("kkr1", 0.08, 0.4) + .add("e50_1r1", 8.0, 17.0) + .add("alpha_r1", -8.0, 5.0) + .add("kgr2", 0.004, 0.3) + .add("kkr2", 0.1, 0.5) + .add("e50_2r2", 5.0, 8.0) + .add("alpha_r2", -5.0, 5.0) + .add("init_4", -1.0, 4.0) + .add("init_5", -1.0, 3.0) + .add("h1s", 0.5, 8.0) + .add("h2s", 0.1, 4.0) + .add("h1r1", 5.0, 25.0) + .add("h2r2", 10.0, 22.0); let mut settings = SettingsBuilder::new() .set_algorithm(Algorithm::NPAG) diff --git a/examples/iov/main.rs b/examples/iov/main.rs index f7c8c6a8..9e124116 100644 --- a/examples/iov/main.rs +++ b/examples/iov/main.rs @@ -29,7 +29,7 @@ fn main() -> Result<()> { 10000, ); - let params = Parameters::new().add("ke0", 0.001, 2.0, false); + let params = Parameters::new().add("ke0", 0.001, 2.0); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/meta/main.rs b/examples/meta/main.rs index 5e4d88a8..69ca5c41 100644 --- a/examples/meta/main.rs +++ b/examples/meta/main.rs @@ -33,13 +33,13 @@ fn main() { ); let params = Parameters::new() - .add("cls", 0.1, 10.0, true) - .add("fm", 0.0, 1.0, true) - .add("k20", 0.01, 1.0, true) - .add("relv", 0.1, 1.0, true) - .add("theta1", 0.1, 10.0, true) - .add("theta2", 0.1, 10.0, true) - .add("vs", 1.0, 10.0, true); + .add("cls", 0.1, 10.0) + .add("fm", 0.0, 1.0) + .add("k20", 0.01, 1.0) + .add("relv", 0.1, 1.0) + .add("theta1", 0.1, 10.0) + .add("theta2", 0.1, 10.0) + .add("vs", 1.0, 10.0); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/new_iov/main.rs b/examples/new_iov/main.rs index 16edea2c..65246941 100644 --- a/examples/new_iov/main.rs +++ b/examples/new_iov/main.rs @@ -30,8 +30,8 @@ fn main() { ); let params = Parameters::new() - .add("ke0", 0.0001, 2.4, false) - .add("ske", 0.0001, 0.2, false); + .add("ke0", 0.0001, 2.4) + .add("ske", 0.0001, 0.2); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/theophylline/main.rs b/examples/theophylline/main.rs index 9c31c69a..d1833834 100644 --- a/examples/theophylline/main.rs +++ b/examples/theophylline/main.rs @@ -31,9 +31,9 @@ fn main() { ); let params = Parameters::new() - .add("ka", 0.001, 3.0, false) - .add("ke", 0.001, 3.0, false) - .add("v", 0.001, 50.0, false); + .add("ka", 0.001, 3.0) + .add("ke", 0.001, 3.0) + .add("v", 0.001, 50.0); let settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/two_eq_lag/main.rs b/examples/two_eq_lag/main.rs index b6c5abda..663296ec 100644 --- a/examples/two_eq_lag/main.rs +++ b/examples/two_eq_lag/main.rs @@ -68,10 +68,10 @@ fn main() { // ); let params = Parameters::new() - .add("ka", 0.1, 0.9, false) - .add("ke", 0.001, 0.1, false) - .add("tlag", 0.0, 4.0, false) - .add("v", 30.0, 120.0, false); + .add("ka", 0.1, 0.9) + .add("ke", 0.001, 0.1) + .add("tlag", 0.0, 4.0) + .add("v", 30.0, 120.0); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/examples/vanco_sde/main.rs b/examples/vanco_sde/main.rs index 9fa90f85..4f753200 100644 --- a/examples/vanco_sde/main.rs +++ b/examples/vanco_sde/main.rs @@ -49,12 +49,12 @@ fn main() { // ); let params = Parameters::new() - .add("ka", 0.0001, 2.4, false) - .add("ke0", 0.0001, 2.7, false) - .add("kcp", 0.0001, 2.4, false) - .add("kpc", 0.0001, 2.4, false) - .add("vol", 0.2, 12.0, false) - .add("ske", 0.0001, 0.2, false); + .add("ka", 0.0001, 2.4) + .add("ke0", 0.0001, 2.7) + .add("kcp", 0.0001, 2.4) + .add("kpc", 0.0001, 2.4) + .add("vol", 0.2, 12.0) + .add("ske", 0.0001, 0.2); let mut settings = Settings::builder() .set_algorithm(Algorithm::NPAG) diff --git a/src/algorithms/mod.rs b/src/algorithms/mod.rs index b8e21b52..302c8e1b 100644 --- a/src/algorithms/mod.rs +++ b/src/algorithms/mod.rs @@ -261,6 +261,7 @@ pub trait Algorithms: Sync { Ok(self.into_npresult()) } + #[allow(clippy::wrong_self_convention)] fn into_npresult(&self) -> NPResult; } diff --git a/src/algorithms/npod.rs b/src/algorithms/npod.rs index ec81a775..838ad5ea 100644 --- a/src/algorithms/npod.rs +++ b/src/algorithms/npod.rs @@ -37,7 +37,6 @@ const THETA_D: f64 = 1e-4; pub struct NPOD { equation: E, - ranges: Vec<(f64, f64)>, psi: Psi, theta: Theta, lambda: Col, @@ -57,7 +56,6 @@ impl Algorithms for NPOD { fn new(settings: Settings, equation: E, data: Data) -> Result, anyhow::Error> { Ok(Box::new(Self { equation, - ranges: settings.parameters().ranges(), psi: Psi::new(), theta: Theta::new(), lambda: Col::zeros(0), @@ -360,8 +358,7 @@ impl Algorithms for NPOD { // re-define a new optimization }); for cp in candididate_points { - self.theta - .suggest_point(cp.to_vec().as_slice(), THETA_D, &self.ranges); + self.theta.suggest_point(cp.to_vec().as_slice(), THETA_D); } Ok(()) } diff --git a/src/routines/expansion/adaptative_grid.rs b/src/routines/expansion/adaptative_grid.rs index dcd4611f..4475622a 100644 --- a/src/routines/expansion/adaptative_grid.rs +++ b/src/routines/expansion/adaptative_grid.rs @@ -44,7 +44,7 @@ pub fn adaptative_grid(theta: &mut Theta, eps: f64, ranges: &[(f64, f64)], min_d // Option 1: Check all points against the original theta, then add them let keep = candidates .iter() - .filter(|point| theta.check_point(point, min_dist, ranges)) + .filter(|point| theta.check_point(point, min_dist)) .cloned() .collect::>(); diff --git a/src/routines/initialization/latin.rs b/src/routines/initialization/latin.rs index 9baffce8..335b2321 100644 --- a/src/routines/initialization/latin.rs +++ b/src/routines/initialization/latin.rs @@ -20,16 +20,9 @@ use crate::structs::theta::Theta; /// [Theta], a structure that holds the support point matrix /// pub fn generate(parameters: &Parameters, points: usize, seed: usize) -> Result { - let params: Vec<(String, f64, f64, bool)> = parameters + let params: Vec<(String, f64, f64)> = parameters .iter() - .map(|p| (p.name.clone(), p.lower, p.upper, p.fixed)) - .collect(); - - // Random parameters are sampled from the Sobol sequence - let random_params: Vec<(String, f64, f64)> = params - .iter() - .filter(|(_, _, _, fixed)| !fixed) - .map(|(name, lower, upper, _)| (name.clone(), *lower, *upper)) + .map(|p| (p.name.clone(), p.lower, p.upper)) .collect(); // Initialize random number generator with the provided seed @@ -37,31 +30,69 @@ pub fn generate(parameters: &Parameters, points: usize, seed: usize) -> Result = (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 rand_matrix = Mat::from_fn(points, params.len(), |i, j| { // Get the interval for this parameter and point let interval = intervals[j][i]; let random_offset = rng.random::(); // Calculate normalized value in [0,1] let unscaled = (interval + random_offset) / points as f64; // Scale to parameter range - let (_name, lower, upper) = random_params.get(j).unwrap(); // Fixed: use j instead of i + let (_name, lower, upper) = params.get(j).unwrap(); // Fixed: use j instead of i lower + unscaled * (upper - lower) }); - // Fixed parameters are initialized to the middle of their range - 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); + let theta = Theta::from_parts(rand_matrix, parameters.clone()); Ok(theta) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::prelude::Parameters; + use faer::mat; + + #[test] + fn test_latin_hypercube() { + let params = Parameters::new() + .add("a", 0.0, 1.0) + .add("b", 0.0, 1.0) + .add("c", 0.0, 1.0); + + let theta = generate(¶ms, 10, 22).unwrap(); + + assert_eq!(theta.nspp(), 10); + assert_eq!(theta.matrix().ncols(), 3); + } + + #[test] + fn test_latin_hypercube_values() { + let params = Parameters::new() + .add("a", 0.0, 1.0) + .add("b", 0.0, 1.0) + .add("c", 0.0, 1.0); + + let theta = generate(¶ms, 10, 22).unwrap(); + + let expected = mat![ + [0.9318592685623417, 0.5609665425179973, 0.3351914901515939], // + [0.5470144220416706, 0.13513808559222779, 0.1067962439473777], // + [0.34525902829190547, 0.4636722699673962, 0.9142146621998218], // + [0.24828355387285125, 0.8638104433695395, 0.41653980640777954], // + [0.7642037770085612, 0.6806932027789437, 0.5608053599272136], // + [0.19409389824004936, 0.9378790633419902, 0.6039530631991072], // + [0.04886813284275151, 0.7140428162864041, 0.7855069414226704], // + [0.6987026842780971, 0.32378779989236495, 0.8888807957183007], // + [0.4221279608793599, 0.08001464382386277, 0.20689573661666943], // + [0.8310112718320113, 0.29390050406905127, 0.04806137233953963], // + ]; + + assert_eq!(theta.matrix().to_owned(), expected); + } +} diff --git a/src/routines/initialization/mod.rs b/src/routines/initialization/mod.rs index b3c1b142..216171e4 100644 --- a/src/routines/initialization/mod.rs +++ b/src/routines/initialization/mod.rs @@ -139,16 +139,7 @@ pub fn parse_prior(path: &String, settings: &Settings) -> Result { let theta_matrix: Mat = Mat::from_fn(n_points, n_params, |i, j| theta_values[i * n_params + j]); - let random = settings - .parameters() - .iter() - .filter(|p| !p.fixed) - .collect::>() - .iter() - .map(|p| (p.name.clone(), p.lower, p.upper)) - .collect(); - - let theta = Theta::from_parts(theta_matrix, random, Vec::new()); + let theta = Theta::from_parts(theta_matrix, settings.parameters().clone()); Ok(theta) } diff --git a/src/routines/initialization/sobol.rs b/src/routines/initialization/sobol.rs index e1a1a579..514f225c 100644 --- a/src/routines/initialization/sobol.rs +++ b/src/routines/initialization/sobol.rs @@ -22,32 +22,18 @@ use crate::prelude::Parameters; /// pub fn generate(parameters: &Parameters, points: usize, seed: usize) -> Result { let seed = seed as u32; - let params: Vec<(String, f64, f64, bool)> = parameters + let params: Vec<(String, f64, f64)> = parameters .iter() - .map(|p| (p.name.clone(), p.lower, p.upper, p.fixed)) + .map(|p| (p.name.clone(), p.lower, p.upper)) .collect(); - // Random parameters are sampled from the Sobol sequence - let random_params: Vec<(String, f64, f64)> = params - .iter() - .filter(|(_, _, _, fixed)| !fixed) - .map(|(name, lower, upper, _)| (name.clone(), *lower, *upper)) - .collect(); - - let rand_matrix = Mat::from_fn(points, random_params.len(), |i, j| { + let rand_matrix = Mat::from_fn(points, params.len(), |i, j| { let unscaled = sample((i).try_into().unwrap(), j.try_into().unwrap(), seed) as f64; - let (_name, lower, upper) = random_params.get(j).unwrap(); + let (_name, lower, upper) = params.get(j).unwrap(); lower + unscaled * (upper - lower) }); - // Fixed parameters are initialized to the middle of their range - 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); + let theta = Theta::from_parts(rand_matrix, parameters.clone()); Ok(theta) } @@ -59,9 +45,9 @@ mod tests { #[test] fn test_sobol() { let params = Parameters::new() - .add("a", 0.0, 1.0, false) - .add("b", 0.0, 1.0, false) - .add("c", 0.0, 1.0, false); + .add("a", 0.0, 1.0) + .add("b", 0.0, 1.0) + .add("c", 0.0, 1.0); let theta = generate(¶ms, 10, 22).unwrap(); @@ -69,25 +55,12 @@ mod tests { assert_eq!(theta.matrix().ncols(), 3); } - #[test] - fn test_sobol_with_fixed() { - let params = Parameters::new() - .add("a", 0.0, 1.0, false) - .add("b", 0.0, 1.0, false) - .add("c", 0.0, 1.0, true); - - let theta = generate(¶ms, 10, 22).unwrap(); - - assert_eq!(theta.nspp(), 10); - assert_eq!(theta.matrix().ncols(), 2); - } - #[test] fn test_sobol_ranges() { let params = Parameters::new() - .add("a", 0.0, 1.0, false) - .add("b", 0.0, 1.0, false) - .add("c", 0.0, 1.0, false); + .add("a", 0.0, 1.0) + .add("b", 0.0, 1.0) + .add("c", 0.0, 1.0); let theta = generate(¶ms, 10, 22).unwrap(); @@ -102,9 +75,9 @@ mod tests { fn test_sobol_values() { use faer::mat; let params = Parameters::new() - .add("a", 0.0, 1.0, false) - .add("b", 0.0, 1.0, false) - .add("c", 0.0, 1.0, false); + .add("a", 0.0, 1.0) + .add("b", 0.0, 1.0) + .add("c", 0.0, 1.0); let theta = generate(¶ms, 10, 22).unwrap(); diff --git a/src/routines/output.rs b/src/routines/output.rs index 85accaae..2d3af77e 100644 --- a/src/routines/output.rs +++ b/src/routines/output.rs @@ -103,10 +103,8 @@ impl NPResult { self.write_pred(idelta, tad) .context("Failed to write predictions")?; self.write_covs().context("Failed to write covariates")?; - if !(self.w.nrows() == 0) { - self.write_posterior() - .context("Failed to write posterior")?; - } + self.write_posterior() + .context("Failed to write posterior")?; } Ok(()) } @@ -326,14 +324,9 @@ impl NPResult { writer.write_field(id.clone()).unwrap(); writer.write_field(i.to_string()).unwrap(); - theta - .matrix() - .row(spp) - .iter() - .enumerate() - .for_each(|(_, val)| { - writer.write_field(val.to_string()).unwrap(); - }); + theta.matrix().row(spp).iter().for_each(|val| { + writer.write_field(val.to_string()).unwrap(); + }); writer.write_field(prob.to_string()).unwrap(); writer.write_record(None::<&[u8]>).unwrap(); diff --git a/src/routines/settings.rs b/src/routines/settings.rs index 9d0b5754..8ddf9167 100644 --- a/src/routines/settings.rs +++ b/src/routines/settings.rs @@ -177,29 +177,26 @@ impl Default for Config { /// Defines a parameter to be estimated /// /// In non-parametric algorithms, parameters must be bounded. The lower and upper bounds are defined by the `lower` and `upper` fields, respectively. -/// Fixed parameters are unknown, but common among all subjects. -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] pub struct Parameter { pub(crate) name: String, pub(crate) lower: f64, pub(crate) upper: f64, - pub(crate) fixed: bool, } impl Parameter { /// Create a new parameter - pub fn new(name: impl Into, lower: f64, upper: f64, fixed: bool) -> Self { + pub fn new(name: impl Into, lower: f64, upper: f64) -> Self { Self { name: name.into(), lower, upper, - fixed, } } } /// This structure contains information on all [Parameter]s to be estimated -#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)] pub struct Parameters { pub(crate) parameters: Vec, } @@ -211,14 +208,8 @@ impl Parameters { } } - pub fn add( - mut self, - name: impl Into, - lower: f64, - upper: f64, - fixed: bool, - ) -> Parameters { - let parameter = Parameter::new(name, lower, upper, fixed); + pub fn add(mut self, name: impl Into, lower: f64, upper: f64) -> Parameters { + let parameter = Parameter::new(name, lower, upper); self.parameters.push(parameter); self } @@ -645,8 +636,7 @@ fn parse_output_folder(path: String) -> String { num += 1; } - let result = path.replace("#", &num.to_string()); - result + path.replace("#", &num.to_string()) } #[cfg(test)] @@ -657,9 +647,7 @@ mod tests { #[test] fn test_builder() { - let parameters = Parameters::new() - .add("Ke", 0.0, 5.0, false) - .add("V", 10.0, 200.0, true); + let parameters = Parameters::new().add("Ke", 0.0, 5.0).add("V", 10.0, 200.0); let mut settings = SettingsBuilder::new() .set_algorithm(Algorithm::NPAG) // Step 1: Define algorithm diff --git a/src/structs/psi.rs b/src/structs/psi.rs index 6f8330e4..610e6827 100644 --- a/src/structs/psi.rs +++ b/src/structs/psi.rs @@ -42,6 +42,16 @@ impl Psi { self.matrix = new; } + + /// Write the matrix to a CSV file + pub fn write(&self, path: &str) { + let mut writer = csv::Writer::from_path(path).unwrap(); + for row in self.matrix.row_iter() { + writer + .write_record(row.iter().map(|x| x.to_string())) + .unwrap(); + } + } } impl Default for Psi { diff --git a/src/structs/theta.rs b/src/structs/theta.rs index 7ab42f8f..326b03aa 100644 --- a/src/structs/theta.rs +++ b/src/structs/theta.rs @@ -2,6 +2,8 @@ use std::fmt::Debug; use faer::Mat; +use crate::prelude::Parameters; + /// [Theta] is a structure that holds the support points /// These represent the joint population parameter distribution /// @@ -9,16 +11,14 @@ use faer::Mat; #[derive(Clone, PartialEq)] pub struct Theta { matrix: Mat, - random: Vec<(String, f64, f64)>, - fixed: Vec<(String, f64)>, + parameters: Parameters, } impl Default for Theta { fn default() -> Self { Theta { matrix: Mat::new(), - random: Vec::new(), - fixed: Vec::new(), + parameters: Parameters::new(), } } } @@ -28,16 +28,8 @@ impl Theta { Theta::default() } - pub(crate) fn from_parts( - matrix: Mat, - random: Vec<(String, f64, f64)>, - fixed: Vec<(String, f64)>, - ) -> Self { - Theta { - matrix, - random, - fixed, - } + pub(crate) fn from_parts(matrix: Mat, parameters: Parameters) -> Self { + Theta { matrix, parameters } } /// Get the matrix containing parameter values @@ -59,10 +51,7 @@ impl Theta { /// Get the parameter names pub fn param_names(&self) -> Vec { - self.random - .iter() - .map(|(name, _, _)| name.clone()) - .collect() + self.parameters.names() } /// Modify the [Theta::matrix] to only include the rows specified by `indices` @@ -85,18 +74,20 @@ impl Theta { /// Suggest a new support point to add to the matrix /// The point is only added if it is at least `min_dist` away from all existing support points /// and within the limits specified by `limits` - pub(crate) fn suggest_point(&mut self, spp: &[f64], min_dist: f64, limits: &[(f64, f64)]) { - if self.check_point(spp, min_dist, limits) { + pub(crate) fn suggest_point(&mut self, spp: &[f64], min_dist: f64) { + if self.check_point(spp, min_dist) { self.add_point(spp); } } /// Check if a point is at least `min_dist` away from all existing support points - pub(crate) fn check_point(&self, spp: &[f64], min_dist: f64, limits: &[(f64, f64)]) -> bool { + pub(crate) fn check_point(&self, spp: &[f64], min_dist: f64) -> bool { if self.matrix.nrows() == 0 { return true; } + let limits = self.parameters.ranges(); + for row_idx in 0..self.matrix.nrows() { let mut squared_dist = 0.0; for (i, val) in spp.iter().enumerate() { @@ -146,7 +137,9 @@ mod tests { // Create a 4x2 matrix with recognizable values let matrix = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [7.0, 8.0]]; - let mut theta = Theta::from_parts(matrix, vec![], vec![]); + let parameters = Parameters::new().add("A", 0.0, 10.0).add("B", 0.0, 10.0); + + let mut theta = Theta::from_parts(matrix, parameters); theta.filter_indices(&[0, 3]); @@ -160,7 +153,9 @@ mod tests { fn test_add_point() { let matrix = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]; - let mut theta = Theta::from_parts(matrix, vec![], vec![]); + let parameters = Parameters::new().add("A", 0.0, 10.0).add("B", 0.0, 10.0); + + let mut theta = Theta::from_parts(matrix, parameters); theta.add_point(&[7.0, 8.0]); diff --git a/tests/onecomp.rs b/tests/onecomp.rs index 5047e8a7..83558c85 100644 --- a/tests/onecomp.rs +++ b/tests/onecomp.rs @@ -20,9 +20,7 @@ fn test_one_compartment() -> Result<()> { ); // Define parameters - let params = Parameters::new() - .add("ke", 0.1, 1.0, false) - .add("v", 1.0, 20.0, false); + let params = Parameters::new().add("ke", 0.1, 1.0).add("v", 1.0, 20.0); // Create settings let mut settings = Settings::builder() @@ -33,6 +31,7 @@ fn test_one_compartment() -> Result<()> { settings.set_prior(Prior::sobol(64, 22)); settings.set_cycles(300); + settings.set_progress(false); // Let known support points let spps: Vec<(f64, f64)> = vec![(0.85, 12.0), (0.52, 5.0), (0.15, 3.0)];