conspire/math/integrate/ode/implicit/midpoint/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::math::{
5 Scalar, Tensor, TensorArray, TensorVec,
6 integrate::{
7 FixedStep, ImplicitFirstOrder, ImplicitZerothOrder, IntegrationError, OdeIntegrator,
8 },
9};
10use std::{
11 fmt::Debug,
12 ops::{Add, Mul, Sub},
13};
14
15#[doc = include_str!("doc.md")]
16#[derive(Debug, Default)]
17pub struct Midpoint {
18 dt: Scalar,
20}
21
22impl<Y, U> OdeIntegrator<Y, U> for Midpoint
23where
24 Y: Tensor,
25 U: TensorVec<Item = Y>,
26{
27}
28
29impl FixedStep for Midpoint {
30 fn dt(&self) -> Scalar {
31 self.dt
32 }
33}
34
35impl<Y, U> ImplicitZerothOrder<Y, U> for Midpoint
36where
37 Y: Tensor,
38 for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<&'a Y, Output = Y> + Sub<&'a Y, Output = Y>,
39 U: TensorVec<Item = Y>,
40{
41 fn residual(
42 &self,
43 mut function: impl FnMut(Scalar, &Y) -> Result<Y, IntegrationError>,
44 t: Scalar,
45 y: &Y,
46 _t_trial: Scalar,
47 y_trial: &Y,
48 dt: Scalar,
49 ) -> Result<Y, String> {
50 Ok(y_trial - y - function(t + 0.5 * dt, &((y + y_trial) * 0.5))? * dt)
51 }
52}
53
54impl<Y, J, U> ImplicitFirstOrder<Y, J, U> for Midpoint
55where
56 Y: Tensor,
57 for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<&'a Y, Output = Y> + Sub<&'a Y, Output = Y>,
58 J: Tensor + TensorArray,
59 U: TensorVec<Item = Y>,
60{
61 fn hessian(
62 &self,
63 mut jacobian: impl FnMut(Scalar, &Y) -> Result<J, IntegrationError>,
64 t: Scalar,
65 y: &Y,
66 _t_trial: Scalar,
67 y_trial: &Y,
68 dt: Scalar,
69 ) -> Result<J, String> {
70 Ok(J::identity() - jacobian(t + 0.5 * dt, &((y + y_trial) * 0.5))? * (dt * 0.5))
71 }
72}