use super::algorithm::*;
use super::common::{Integrand2, IntegrationConfig2, Points2};
use super::range::IntoRange2;
use crate::{IntegrationResult, Tolerance};
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Integrator2<F: Integrand2, A> {
integrand: F,
algorithm: A,
config: IntegrationConfig2,
}
impl<F: Integrand2, A> Integrator2<F, A> {
#[inline]
pub fn with_algorithm(integrand: F, algorithm: A) -> Integrator2<F, A> {
Self {
integrand,
algorithm,
config: IntegrationConfig2::default(),
}
}
#[inline]
pub fn tolerance(mut self, t: Tolerance) -> Self {
assert!(!t.contains_nan(), "Tolerance must not contain NAN.");
self.config.tolerance = t;
self
}
#[inline]
pub fn max_iters(mut self, max_iters: usize) -> Self {
self.config.max_iters = max_iters;
self
}
pub fn points(mut self, pts: &[(f64, f64)]) -> Self {
assert!(
pts.iter().all(|(x, y)| !x.is_nan() && !y.is_nan()),
"cannot include NAN value in singular points: {:?}",
pts
);
self.config.points = Points2::from(pts);
self
}
#[inline]
pub fn get_algorithm(&self) -> &A {
&self.algorithm
}
#[inline]
pub fn run<'a, T>(&mut self, range: T) -> IntegrationResult
where
T: IntoRange2,
A: Algorithm2<F, T::IntoRange>,
{
self.algorithm
.integrate(&mut self.integrand, &range.into_range(), &self.config)
}
}