qualia_core_db/
ode_solver.rs1pub struct PhysicalState {
6 pub time: f64,
7 pub values: Vec<f64>,
8}
9
10pub fn rk4_step<F>(state: &mut PhysicalState, step_size: f64, derivative: F)
13where
14 F: Fn(f64, &[f64]) -> Vec<f64>,
15{
16 let t = state.time;
17 let y = &state.values;
18 let n = y.len();
19
20 let k1 = derivative(t, y);
21
22 let mut y_k2 = vec![0.0; n];
23 for i in 0..n {
24 y_k2[i] = y[i] + 0.5 * step_size * k1[i];
25 }
26 let k2 = derivative(t + 0.5 * step_size, &y_k2);
27
28 let mut y_k3 = vec![0.0; n];
29 for i in 0..n {
30 y_k3[i] = y[i] + 0.5 * step_size * k2[i];
31 }
32 let k3 = derivative(t + 0.5 * step_size, &y_k3);
33
34 let mut y_k4 = vec![0.0; n];
35 for i in 0..n {
36 y_k4[i] = y[i] + step_size * k3[i];
37 }
38 let k4 = derivative(t + step_size, &y_k4);
39
40 for i in 0..n {
41 state.values[i] += (step_size / 6.0) * (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]);
42 }
43 state.time += step_size;
44}
45
46pub fn evaluate_continuous_dynamics(
48 initial_state: PhysicalState,
49 steps: usize,
50 dt: f64,
51) -> PhysicalState {
52 let mut current_state = initial_state;
53 let decay_func = |_t: f64, y: &[f64]| -> Vec<f64> { y.iter().map(|&val| -0.5 * val).collect() };
55
56 for _ in 0..steps {
57 rk4_step(&mut current_state, dt, &decay_func);
58 }
59 current_state
60}