gkquad 0.0.4

Numerical integration library for Rust
use super::super::common::{Integrand2, IntegrationConfig2};
use super::super::range::{DynamicY, Rectangle};
use super::Algorithm2;
use crate::single::algorithm::{Algorithm as Algorithm1, QAGS};
use crate::single::IntegrationConfig;
use crate::single::WorkSpace;
use crate::IntegrationResult;

pub struct QAGS2;

impl QAGS2 {
    pub fn new() -> Self {
        Self
    }
}

impl<F: Integrand2> Algorithm2<F, Rectangle> for QAGS2 {
    fn integrate(
        &mut self,
        f: &mut F,
        square: &Rectangle,
        config: &IntegrationConfig2,
    ) -> IntegrationResult {
        let config1 = IntegrationConfig {
            tolerance: config.tolerance.clone(),
            max_iters: config.max_iters,
            ..Default::default()
        };

        let mut inner_ws = WorkSpace::new();
        let mut inner = QAGS::with_workspace(&mut inner_ws);
        let mut error = None;

        let mut integrand = |x: f64| -> f64 {
            let mut integrand2 = |y: f64| f.apply((x, y));
            let result = inner.integrate(&mut integrand2, &square.yrange, &config1);
            if result.has_err() {
                error = result.err();
            }
            result.estimate().unwrap_or(core::f64::NAN)
        };

        let mut result = QAGS::new().integrate(&mut integrand, &square.xrange, &config1);
        if error.is_some() {
            result.error = error;
        }

        result
    }
}

impl<'a, F: Integrand2> Algorithm2<F, DynamicY<'a>> for QAGS2 {
    fn integrate(
        &mut self,
        f: &mut F,
        range: &DynamicY<'a>,
        config: &IntegrationConfig2,
    ) -> IntegrationResult {
        let config1 = IntegrationConfig {
            tolerance: config.tolerance.clone(),
            max_iters: config.max_iters,
            ..Default::default()
        };

        let mut inner_ws = WorkSpace::new();
        let mut inner = QAGS::with_workspace(&mut inner_ws);
        let mut error = None;

        let mut integrand = |x: f64| -> f64 {
            let mut integrand2 = |y: f64| f.apply((x, y));
            let result = inner.integrate(&mut integrand2, &(range.yrange)(x), &config1);
            if result.has_err() {
                error = result.err();
            }
            result.estimate().unwrap_or(core::f64::NAN)
        };

        let mut result = QAGS::new().integrate(&mut integrand, &range.xrange, &config1);
        if error.is_some() {
            result.error = error;
        }

        result
    }
}

extra_traits!(QAGS2);