conspire/math/integrate/ode/explicit/fixed_step/euler/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::math::{
5    Scalar, Tensor, TensorVec, Vector,
6    integrate::{Explicit, FixedStep, FixedStepExplicit, IntegrationError, OdeIntegrator},
7};
8use std::ops::Mul;
9
10#[doc = include_str!("doc.md")]
11#[derive(Debug, Default)]
12pub struct Euler {
13    /// Fixed value for the time step.
14    dt: Scalar,
15}
16
17impl<Y, U> OdeIntegrator<Y, U> for Euler
18where
19    Y: Tensor,
20    U: TensorVec<Item = Y>,
21{
22}
23
24impl FixedStep for Euler {
25    fn dt(&self) -> Scalar {
26        self.dt
27    }
28}
29
30impl<Y, U> Explicit<Y, U> for Euler
31where
32    Y: Tensor,
33    for<'a> &'a Y: Mul<Scalar, Output = Y>,
34    U: TensorVec<Item = Y>,
35{
36    const SLOPES: usize = 1;
37    fn integrate(
38        &self,
39        function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
40        time: &[Scalar],
41        initial_condition: Y,
42    ) -> Result<(Vector, U, U), IntegrationError> {
43        self.integrate_fixed_step(function, time, initial_condition)
44    }
45}
46
47impl<Y, U> FixedStepExplicit<Y, U> for Euler
48where
49    Y: Tensor,
50    for<'a> &'a Y: Mul<Scalar, Output = Y>,
51    U: TensorVec<Item = Y>,
52{
53    fn step(
54        &self,
55        mut function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
56        y: &Y,
57        t: Scalar,
58        dt: Scalar,
59        k: &mut [Y],
60        y_trial: &mut Y,
61    ) -> Result<(), String> {
62        k[0] = function(t, y)?;
63        *y_trial = &k[0] * dt + y;
64        Ok(())
65    }
66}