pub trait DynamicalSystem {
fn dimension(&self) -> usize;
fn derivatives(&self, t: f64, state: &[f64], out: &mut [f64]);
fn initial_state(&self) -> Vec<f64>;
fn time_span(&self) -> (f64, f64);
}
pub type SystemFn = Box<dyn Fn(f64, &[f64], &mut [f64])>;
pub struct SimpleModel {
y0: Vec<f64>,
t_span: (f64, f64),
f: SystemFn,
}
impl SimpleModel {
pub fn new(y0: Vec<f64>, t_span: (f64, f64), f: SystemFn) -> Self {
Self { y0, t_span, f }
}
}
impl DynamicalSystem for SimpleModel {
fn dimension(&self) -> usize {
self.y0.len()
}
fn derivatives(&self, t: f64, state: &[f64], out: &mut [f64]) {
(self.f)(t, state, out);
}
fn initial_state(&self) -> Vec<f64> {
self.y0.clone()
}
fn time_span(&self) -> (f64, f64) {
self.t_span
}
}
pub struct HarmonicOscillator {
pub omega: f64,
pub x0: f64,
pub v0: f64,
pub t_span: (f64, f64),
}
impl DynamicalSystem for HarmonicOscillator {
fn dimension(&self) -> usize {
2
}
fn derivatives(&self, _t: f64, state: &[f64], out: &mut [f64]) {
out[0] = state[1];
out[1] = -self.omega * self.omega * state[0];
}
fn initial_state(&self) -> Vec<f64> {
vec![self.x0, self.v0]
}
fn time_span(&self) -> (f64, f64) {
self.t_span
}
}
pub struct LotkaVolterra {
pub alpha: f64,
pub beta: f64,
pub delta: f64,
pub gamma: f64,
pub prey0: f64,
pub pred0: f64,
pub t_span: (f64, f64),
}
impl DynamicalSystem for LotkaVolterra {
fn dimension(&self) -> usize {
2
}
fn derivatives(&self, _t: f64, state: &[f64], out: &mut [f64]) {
let x = state[0];
let y = state[1];
out[0] = self.alpha * x - self.beta * x * y;
out[1] = self.delta * x * y - self.gamma * y;
}
fn initial_state(&self) -> Vec<f64> {
vec![self.prey0, self.pred0]
}
fn time_span(&self) -> (f64, f64) {
self.t_span
}
}