conspire 0.6.0

The Rust interface to conspire.
Documentation
macro_rules! test_implicit_fixed_step {
    ($integration: expr) => {
        use crate::{
            EPSILON,
            math::{
                Scalar, Tensor, Vector, assert_eq,
                integrate::{FixedStep, IntegrationError},
                test::TestError,
                test::assert_eq_from_fd,
            },
        };
        const TIME_STEP: Scalar = 0.1;
        const TOLERANCE: Scalar = TIME_STEP;
        #[test]
        fn finite_difference() -> Result<(), TestError> {
            use crate::math::integrate::{ImplicitFirstOrder, ImplicitZerothOrder};
            let t = 0.55_f64;
            let y = t.sin();
            let function =
                |_t: Scalar, y: &Scalar| Ok::<Scalar, IntegrationError>(-0.5 * t * y.powi(2));
            let jacobian = |_t: Scalar, y: &Scalar| Ok::<Scalar, IntegrationError>(-t * y);
            let dt = 0.1;
            let t_trial = t + dt;
            let y_trial = y + function(t, &y)? * dt;
            let finite_difference = (ImplicitZerothOrder::<Scalar, Vector>::residual(
                &$integration,
                &function,
                t,
                &y,
                t_trial,
                &(y_trial + 0.5 * EPSILON),
                dt,
            )? - ImplicitZerothOrder::<Scalar, Vector>::residual(
                &$integration,
                &function,
                t,
                &y,
                t_trial,
                &(y_trial - 0.5 * EPSILON),
                dt,
            )?) / EPSILON;
            assert_eq_from_fd(
                &ImplicitFirstOrder::<Scalar, Scalar, Vector>::hessian(
                    &$integration,
                    &jacobian,
                    t,
                    &y,
                    t_trial,
                    &y_trial,
                    dt,
                )?,
                &finite_difference,
            )
        }
        mod gradient_descent {
            use super::*;
            use crate::math::{integrate::ImplicitZerothOrder, optimize::GradientDescent};
            #[test]
            fn first_order_tensor_rank_0() -> Result<(), TestError> {
                assert_eq(&$integration.dt(), &TIME_STEP)?;
                let (time, solution, function): (Vector, Vector, _) = $integration.integrate(
                    |t: Scalar, _: &Scalar| Ok(t),
                    &[0.0, 1.0],
                    0.0,
                    GradientDescent::default(),
                )?;
                time.iter()
                    .zip(solution.iter().zip(function.iter()))
                    .for_each(|(t, (y, f))| {
                        assert!((0.5 * t * t - y).abs() < TOLERANCE && (t - f).abs() < TOLERANCE)
                    });
                Ok(())
            }
        }
        mod newton_raphson {
            use super::*;
            use crate::math::{integrate::ImplicitFirstOrder, optimize::NewtonRaphson};
            #[test]
            fn first_order_tensor_rank_0() -> Result<(), TestError> {
                assert_eq(&$integration.dt(), &TIME_STEP)?;
                let (time, solution, function): (Vector, Vector, _) = $integration.integrate(
                    |t: Scalar, _: &Scalar| Ok(t),
                    |_: Scalar, _: &Scalar| Ok(1.0),
                    &[0.0, 1.0],
                    0.0,
                    NewtonRaphson::default(),
                )?;
                time.iter()
                    .zip(solution.iter().zip(function.iter()))
                    .for_each(|(t, (y, f))| {
                        assert!((0.5 * t * t - y).abs() < TOLERANCE && (t - f).abs() < TOLERANCE)
                    });
                Ok(())
            }
        }
    };
}
pub(crate) use test_implicit_fixed_step;