Newer
Older
extern crate ini;
pub mod estimators {
pub mod ratios;
pub mod exponential;
pub mod gompertz;
pub mod search {
pub mod ternary;
use estimators::exponential::estimate_exponential;
use estimators::gompertz::{estimate_gompertz_with_recovery};
use search::golden_section_search::golden_section_search;
let saturation_percentage = 66.0;
let population = 83019213;
let plateau = population as f64 / 100.0 * saturation_percentage;
let days = crate::data::berliner_morgenpost_deutschland();
/*
* https://www.imperial.ac.uk/media/imperial-college/medicine/sph/ide/gida-fellowships/Imperial-College-2019-nCoV-severity-10-02-2020.pdf
*/
let recovery_period = 12.0;
let gompertz_reconstruction = |rate: f64| {
let initial_infected = days[0].infected as f64;
ret.push(estimate_gompertz_with_recovery(initial_infected, rate, plateau, recovery_period, day));
let gompertz_squared_errors = |rate: f64| {
let mut ret = Vec::new();
let reconstruction = gompertz_reconstruction(rate);
let mut actual = Vec::new();
for each in &days {
actual.push(each.infected as f64);
}
for (a, b) in reconstruction.iter().zip(actual.iter()) {
ret.push((a - b).powi(2));
}
let gompertz_root_mean_squared_error = |rate: f64| -> f64 {
let errors = gompertz_squared_errors(rate);
let sample_size = errors.len() as f64;
let sum: f64 = errors.iter().sum();
(sum / sample_size).sqrt()
let find_gompertz_rate = |start: f64, end:f64| -> f64 {
golden_section_search(&gompertz_root_mean_squared_error, start, end, 0.00000000000001)
let gompertz_rate = find_gompertz_rate(0.0, 0.1);
let gompertz_squared_error = gompertz_root_mean_squared_error(gompertz_rate);
println!("gompertz rate: {}, rms: {}", gompertz_rate, gompertz_squared_error.sqrt());
let mean = estimate_growth_rate(&days);
println!("estimated growth rate: {:.0}%±{:.0}%\n\n", (mean.geometric_mean * 100.0).round(), (mean.geometric_mean_stderr * 100.0).round());
use std::fs::File;
let buffer = File::create("corona.csv")?;
let mut writer = csv::Writer::from_writer(buffer);
let day = day as f64;
let initial_infected = days[0].infected as f64;
let estimate_exponential = |rate| { estimate_exponential(initial_infected, rate, day) };
let exponential_estimate = estimate_exponential(rate);
let gompertz_estimate = estimate_gompertz_with_recovery(initial_infected, gompertz_rate, plateau, recovery_period, day).round();
let date = date.format("%Y-%m-%d").to_string();
let exponential_estimate = exponential_estimate.to_string();
let gompertz_estimate = gompertz_estimate.to_string();
let actual_infected = if (day as usize) < days.len() {
days[day as usize].infected.to_string()
} else {
"".to_string()
};
writer.write_record(&[date, actual_infected, exponential_estimate, gompertz_estimate]).unwrap();
if (day as usize) < days.len() {
let date = days[day as usize].day;
} else {
let date = days[days.len() - 1].day;
let date = date.checked_add_signed(chrono::Duration::days(day as i64 - days.len() as i64 + 1)).unwrap();
let mut conf = ini::Ini::new();
let last_day_index = days.len() - 1;
let infected = days[last_day_index].infected;
let dead = days[last_day_index].dead;
let mortality_rate_percent = 0.6;
let severe_cases_rate_percent = 5.0;
// https://www.medicalnewstoday.com/articles/coronavirus-81-of-cases-are-mild-study-says
let medically_relevant_cases_percent = 19.1;
let available_icus = 28000 + 8000;
let available_beds = 497000;
conf.with_section(Some("most_recent_values"))
.set("infected", infected.to_string())
.set("dead", dead.to_string())
.set("current_day", last_day_index.to_string())
.set("data_source", "Berliner Morgenpost");
conf.with_section(Some("assumptions"))
.set("mortality_rate_percent", mortality_rate_percent.to_string())
.set("severe_cases_rate_percent", severe_cases_rate_percent.to_string())
.set("medically_relevant_cases_percent", medically_relevant_cases_percent.to_string())
.set("available_icus", available_icus.to_string())
.set("available_beds", available_beds.to_string())
.set("recovery_period", recovery_period.to_string());
conf.with_section(Some("exponential"))
.set("rate", mean.geometric_mean.to_string())
.set("rate_stderr", mean.geometric_mean_stderr.to_string());
conf.with_section(Some("gompertz"))
.set("rate", gompertz_rate.to_string())
.set("rmserror", gompertz_squared_error.sqrt().to_string())
.set("saturation_percentage", saturation_percentage.to_string())
.set("population", population.to_string());
conf.write_to_file("estimates.ini").unwrap();