sequential-integration 1.0.2

Lightweight library for sequential integration
Documentation
use core::marker::PhantomData;
use fehler::throws;

use super::utils as integrator_utils;
use crate::{
    engine::{
        helper_equation_traits::{EquationOfOneVariable, EquationOfTwoVariable},
        quadrature::GetQuadratureRange,
        Bounds, CalculationResult, CalculationStep,
    },
    errors::Error,
};

pub struct SecondIntegrator<
    'a,
    G: GetQuadratureRange,
    E: EquationOfTwoVariable,
    F1: Fn(f64) -> f64,
    F2: Fn(f64) -> f64,
> {
    a_equation: F1,
    b_equation: F2,
    h: f64,
    equation: &'a E,
    _p: PhantomData<G>,
}

impl<
        'a,
        G: GetQuadratureRange,
        E: EquationOfTwoVariable,
        F1: Fn(f64) -> f64,
        F2: Fn(f64) -> f64,
    > SecondIntegrator<'a, G, E, F1, F2>
{
    #[throws]
    pub fn new(a_equation: F1, b_equation: F2, h: f64, equation: &'a E) -> Self {
        Self {
            a_equation,
            b_equation,
            h,
            equation,
            _p: PhantomData,
        }
    }
}

impl<
        'a,
        G: GetQuadratureRange,
        E: EquationOfTwoVariable,
        F1: Fn(f64) -> f64,
        F2: Fn(f64) -> f64,
    > EquationOfOneVariable for SecondIntegrator<'a, G, E, F1, F2>
{
    #[throws]
    fn calculate(&self, x: CalculationStep, bounds: Bounds) -> CalculationResult {
        let a = (self.a_equation)(*x);
        let b = (self.b_equation)(*x);
        let borders_config = integrator_utils::BoundsConfigurator::configurate(a, b)?;

        let mut result = CalculationResult::new();
        let mut range = if let Some(range) = G::get_range_generator(borders_config.bounds, self.h)?
        {
            range
        } else {
            return result;
        };

        loop {
            let step = range.next()?;
            result += self
                .equation
                .calculate(x, bounds, step, borders_config.bounds)?
                * borders_config.direction_coeff;

            if step.is_last() {
                break;
            }
        }

        result
    }
}