use aphreco::prelude::*;
fn main() {
let model = Model::new();
let stepper_options = StepOptions::Default;
let stepper = Stepper::Dopri45(stepper_options);
let simulator = Simulator::new(model, stepper);
let data = Data::new(obs());
let mut objective = Objective::new(simulator, data);
let ga_options = OptOptions::GeneticAlgorithm {
max_gen: 10,
n_pop: 50,
mutation_rate: 0.5,
verbose: true,
};
let optimizer = Optimizer::GeneticAlgorithm(ga_options);
clock!(let optres = optimizer.run(&mut objective));
objective.setx(&optres.x);
let nm_options = OptOptions::NelderMead {
max_iter: 0,
adaptive: true,
x_abstol: 1e-6,
f_abstol: 1e-6,
verbose: true,
};
let optimizer = Optimizer::NelderMead(nm_options);
clock!(let optres = optimizer.run(&mut objective));
optres.save("./");
}
const LEN_Y: usize = 4;
const LEN_P: usize = 11;
const LEN_B: usize = 2;
#[allow(dead_code)]
#[derive(Clone)]
pub struct Model {
pub p: [f64; LEN_P],
}
#[allow(dead_code)]
impl SimModelTrait<LEN_Y, LEN_P, LEN_B> for Model {
fn new() -> Self {
let p = [
0.1, 0.1, 0.0, 1e12, 0.1, 1.0, 1e12, 0.2, 2.0, 10.0, 500.0, ];
Self { p }
}
fn init(&self) -> (f64, [f64; LEN_Y]) {
let t0 = 0.0;
let y0 = [
100.0, 0.0, 10.0, 0.0, ];
(t0, y0)
}
#[allow(unused_variables)]
fn ode(&self, t: &f64, y: &[f64; LEN_Y], deriv_y: &mut [f64; LEN_Y]) {
deriv_y[0] = -self.p[0] * y[0] + self.p[1] * y[1];
deriv_y[1] = self.p[0] * y[0] - self.p[1] * y[1];
}
#[allow(unused_variables)]
fn rec(&self, t: &f64, y: &[f64; LEN_Y], delta_y: &mut [f64; LEN_Y], act: &[bool; LEN_B]) {
if act[0] {
delta_y[2] += self.p[8];
}
if act[1] {
delta_y[2] -= self.p[8];
}
}
#[allow(unused_variables)]
fn cond(
&self,
dec_t: &Decimal,
act: &mut [bool; LEN_B],
next_t: &[Decimal; LEN_B],
y: &[f64; LEN_Y],
) {
act[0] = if *dec_t == next_t[0] { true } else { false };
act[1] = if *dec_t == next_t[1] { true } else { false };
}
#[allow(unused_variables)]
fn beat(&self, t: &f64, y: &[f64; LEN_Y]) -> [[Decimal; 3]; LEN_B] {
[
beat![self.p[2], self.p[3], self.p[4]],
beat![self.p[5], self.p[6], self.p[7]],
]
}
#[allow(unused_variables)]
fn cre(&self, t: &f64, y: &mut [f64; LEN_Y]) {
y[3] = self.p[8] * t;
}
}
#[allow(dead_code)]
fn sampling_time() -> Vec<f64> {
let mut vec_smp_t = Vec::new();
for i in 0..=5000 {
vec_smp_t.push(i as f64 / 100.0);
}
vec_smp_t
}
const LEN_X: usize = 2;
impl OptModelTrait<LEN_Y, LEN_P, LEN_B, LEN_X> for Model {
fn getx(&self) -> (Vec<usize>, Option<Vec<(f64, f64)>>) {
let x_index = vec![0, 1];
let x_bounds = Some(vec![(1e-4, 1e0), (1e-4, 1e0)]);
(x_index, x_bounds)
}
fn getp(&self) -> &[f64; LEN_P] {
&self.p
}
fn setp(&mut self, index: usize, value: f64) {
self.p[index] = value;
}
}
#[allow(dead_code)]
fn obs() -> Vec<(usize, f64, f64, Option<f64>, Option<f64>)> {
vec![
(0, 0.0, 100.0, None, None), (0, 0.1, 98.0247929622666, None, None), (0, 0.2, 96.0983539600571, None, None), (0, 0.5, 90.5997522067676, None, None), (0, 1.0, 82.3040626457124, None, None), (0, 2.0, 68.5224527770107, None, None), (0, 5.0, 42.9203837488152, None, None), (0, 10.0, 26.5667998899119, None, None), (0, 20.0, 20.5390357599268, None, None), (0, 50.0, 20.0002981322538, None, None), (1, 0.0, 0.0, None, None), (1, 0.1, 1.97520703773339, None, None), (1, 0.2, 3.90164603994288, None, None), (1, 0.5, 9.40024779323236, None, None), (1, 1.0, 17.6959373542876, None, None), (1, 2.0, 31.4775472229893, None, None), (1, 5.0, 57.0796162511848, None, None), (1, 10.0, 73.4332001100881, None, None), (1, 20.0, 79.4609642400732, None, None), (1, 50.0, 79.9997018677462, None, None), ]
}