use rand::prelude::*;
use markovian::prelude::*;
use markovian::BranchingProcess;
use preexplorer::prelude::*;
use rayon::prelude::*;
const BIRTH: f64 = 0.2;
const DEATH: f64 = 0.1;
const TIME: usize = 100;
const SAMPLES: usize = 100;
fn main() {
let monte_carlo_approx: Vec<f64> = (0..TIME).map(|time| {
let simulations = sample_population(BIRTH, DEATH, time, SAMPLES);
extinction_prob(simulations)
}).collect();
monte_carlo_approx.preexplore()
.set_title("Approximate extinction probability")
.set_xlabel("time")
.set_ylabel("extinction_probability")
.plot("extinction")
.unwrap();
}
fn extinction_prob(population_samples: Vec<u32>) -> f64 {
let samples = population_samples.len();
population_samples
.into_iter()
.filter(|&x| x == 0_u32)
.count() as f64
/ samples as f64
}
fn sample_population(
birth_prob: f64,
death_prob: f64,
iterations: usize,
samples: usize,
) -> Vec<u32> {
(0..samples)
.collect::<Vec<usize>>()
.par_iter()
.map(|_| {
let init_state: u32 = 1;
let density = raw_dist![
(death_prob, 0),
(birth_prob, 2),
(1.0 - birth_prob - death_prob, 1)
];
let mut branching_process = BranchingProcess::new(init_state, density, thread_rng());
branching_process.nth(iterations).unwrap()
})
.collect()
}