use sciforge::hub::prelude::biology::population::logistic_growth;
pub struct Population {
pub speciesname: &'static str,
pub count: f64,
pub carryingcapacity: f64,
pub intrinsicgrowthrate: f64,
pub bodymasskg: f64,
}
impl Population {
pub fn growthrate(&self) -> f64 {
logistic_growth(self.intrinsicgrowthrate, self.count, self.carryingcapacity)
}
pub fn projectforward(&self, dtyears: f64) -> f64 {
let r = self.intrinsicgrowthrate;
let k = self.carryingcapacity;
let n = self.count;
k / (1.0 + ((k - n) / n) * (-r * dtyears).exp())
}
pub fn metabolicratew(&self) -> f64 {
crate::KLEIBERA * self.bodymasskg.powf(0.75)
}
pub fn homerangekm2(&self) -> f64 {
crate::MCNABA * self.bodymasskg.powf(1.0)
}
pub fn generationtimeyears(&self) -> f64 {
crate::GENTIMEA * self.bodymasskg.powf(0.25)
}
pub fn maxlifespanyears(&self) -> f64 {
crate::LIFESPANA * self.bodymasskg.powf(0.20)
}
}
pub struct PredatorPrey {
pub prey: Population,
pub predator: Population,
pub attackrate: f64,
pub conversionefficiency: f64,
pub predatordeathrate: f64,
}
impl PredatorPrey {
pub fn preygrowthrate(&self) -> f64 {
let preylogistic = self.prey.growthrate();
let predation = self.attackrate * self.prey.count * self.predator.count;
preylogistic - predation
}
pub fn predatorgrowthrate(&self) -> f64 {
let births =
self.conversionefficiency * self.attackrate * self.prey.count * self.predator.count;
let deaths = self.predatordeathrate * self.predator.count;
births - deaths
}
pub fn step(&mut self, dt: f64) {
let (n, p) = (self.prey.count, self.predator.count);
let deriv = |prey: f64, pred: f64| -> (f64, f64) {
let preylogistic =
self.prey.intrinsicgrowthrate * prey * (1.0 - prey / self.prey.carryingcapacity);
let predation = self.attackrate * prey * pred;
let dn = preylogistic - predation;
let dp = self.conversionefficiency * self.attackrate * prey * pred
- self.predatordeathrate * pred;
(dn, dp)
};
let (k1n, k1p) = deriv(n, p);
let (k2n, k2p) = deriv(n + 0.5 * dt * k1n, p + 0.5 * dt * k1p);
let (k3n, k3p) = deriv(n + 0.5 * dt * k2n, p + 0.5 * dt * k2p);
let (k4n, k4p) = deriv(n + dt * k3n, p + dt * k3p);
self.prey.count = (n + dt / 6.0 * (k1n + 2.0 * k2n + 2.0 * k3n + k4n)).max(0.0);
self.predator.count = (p + dt / 6.0 * (k1p + 2.0 * k2p + 2.0 * k3p + k4p)).max(0.0);
}
}
pub fn africanelephant() -> Population {
Population {
speciesname: "African Elephant",
count: 415000.0,
carryingcapacity: 1000000.0,
intrinsicgrowthrate: 0.05,
bodymasskg: 6000.0,
}
}
pub fn bluewhale() -> Population {
Population {
speciesname: "Blue Whale",
count: 25000.0,
carryingcapacity: 350000.0,
intrinsicgrowthrate: 0.04,
bodymasskg: 150000.0,
}
}