1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use fehler::throws;
use snafu::ensure;

use crate::{
    engine::{
        helper_equation_traits::EquationOfOneVariable,
        quadrature::{FinalizeCalculation, GetQuadratureRange},
        CalculationResult,
    },
    errors::{self, Error},
};

pub struct FirstIntegrator;

impl FirstIntegrator {
    #[throws]
    pub fn integrate<E: EquationOfOneVariable, G: GetQuadratureRange + FinalizeCalculation>(
        a: f64,
        b: f64,
        h: f64,
        equation: E,
        quadrature: G,
    ) -> f64 {
        ensure!(a <= b, errors::BeginBoundGreaterThanEndBound { a, b });

        let mut result = CalculationResult::new();
        let mut range = if let Some(range) = G::get_range_generator(a, b, h)? {
            range
        } else {
            return result.common;
        };

        loop {
            let step = range.next()?;
            result += equation.calculate(step, (a, b))?;

            if step.is_last() {
                break;
            }
        }

        quadrature.finalize(result)?
    }
}