qualia_core_db/specialized_libs/physics_simulation/
population.rs1use super::*;
2
3impl PhysicsSimulationLibrary {
4 pub fn run_logistic_growth(
8 &self,
9 n0: f64,
10 growth_rate: f64,
11 carrying_capacity: f64,
12 total_time: f64,
13 num_samples: usize,
14 ) -> Result<PopulationDynamicsResult, PhysicsError> {
15 if !(n0 >= 0.0 && carrying_capacity > 0.0 && total_time > 0.0) {
16 return Err(PhysicsError::InvalidConfiguration(
17 "require n0 >= 0, carrying_capacity > 0, total_time > 0".to_string(),
18 ));
19 }
20 let r = growth_rate;
21 let k = carrying_capacity;
22 let deriv = move |_t: f64, y: &[f64], dy: &mut [f64]| -> Result<(), OdeError> {
23 dy[0] = r * y[0] * (1.0 - y[0] / k);
24 Ok(())
25 };
26 let (_final, snapshots, accepted, rejected) =
27 self.integrate_ode_samples(vec![n0], total_time, num_samples, deriv)?;
28 let n_pts = snapshots.len();
29 let times: Vec<f64> = (0..n_pts)
30 .map(|kk| total_time * kk as f64 / (n_pts - 1).max(1) as f64)
31 .collect();
32 let population: Vec<f64> = snapshots.iter().map(|s| s[0]).collect();
33 Ok(PopulationDynamicsResult {
34 times,
35 population,
36 carrying_capacity: k,
37 growth_rate: r,
38 steps_accepted: accepted,
39 steps_rejected: rejected,
40 })
41 }
42}