mod checked;
use std::marker::PhantomData;
pub use checked::*;
mod ordered;
pub use ordered::*;
use crate::{
error::Fallible,
traits::{Float, InfAdd},
};
pub struct Sequential<T>(PhantomData<T>);
pub struct Pairwise<T>(PhantomData<T>);
#[doc(hidden)]
pub trait SumRelaxation {
type Item: Float;
fn error(size: usize, lower: Self::Item, upper: Self::Item) -> Fallible<Self::Item>;
fn relaxation(size: usize, lower: Self::Item, upper: Self::Item) -> Fallible<Self::Item> {
let error = Self::error(size, lower, upper)?;
error.inf_add(&error)
}
}
impl<T: Float> SumRelaxation for Sequential<T> {
type Item = T;
fn error(size: usize, lower: Self::Item, upper: Self::Item) -> Fallible<Self::Item> {
let size = T::exact_int_cast(size)?;
let mantissa_bits = T::exact_int_cast(T::MANTISSA_BITS)?;
let _2 = T::exact_int_cast(2)?;
size.inf_mul(&size)?
.inf_div(&_2.inf_pow(&mantissa_bits)?)?
.inf_mul(&lower.alerting_abs()?.total_max(upper)?)
}
}
impl<T: Float> SumRelaxation for Pairwise<T> {
type Item = T;
fn error(size: usize, lower: Self::Item, upper: Self::Item) -> Fallible<Self::Item> {
let size = T::exact_int_cast(size)?;
let mantissa_bits = T::exact_int_cast(T::MANTISSA_BITS)?;
let _2 = T::exact_int_cast(2)?;
let uk = size.inf_log2()?.inf_div(&_2.inf_pow(&mantissa_bits)?)?;
uk.inf_div(&T::one().neg_inf_sub(&uk)?)?
.inf_mul(&size)?
.inf_mul(&lower.alerting_abs()?.total_max(upper)?)
}
}