numeric_algs/integration/
rk4.rs1use super::{Integrator, StepSize};
2use crate::traits::State;
3
4pub struct RK4Integrator {
5 default_step: f64,
6}
7
8impl RK4Integrator {
9 pub fn new(step_size: f64) -> Self {
10 RK4Integrator {
11 default_step: step_size,
12 }
13 }
14
15 pub fn set_default_step(&mut self, step: f64) {
16 self.default_step = step;
17 }
18}
19
20impl<S: State> Integrator<S> for RK4Integrator {
21 fn propagate_in_place<D>(&mut self, start: &mut S, diff_eq: D, step_size: StepSize)
22 where
23 D: Fn(&S) -> S::Derivative,
24 {
25 let h = match step_size {
26 StepSize::UseDefault => self.default_step,
27 StepSize::Step(x) => x,
28 };
29
30 let k1 = diff_eq(start);
31 let k2 = diff_eq(&start.shift(&k1, h / 2.0));
32 let k3 = diff_eq(&start.shift(&k2, h / 2.0));
33 let k4 = diff_eq(&start.shift(&k3, h));
34
35 start.shift_in_place(&(k1 + k2 * 2.0 + k3 * 2.0 + k4), h / 6.0);
36 }
37}