use crate::domain::{Qualitative, Quantitative, QuantitativeLimit};
use crate::fuzzy::membership::Trapezoidal;
use crate::valuation::{Interval, IntervalError, Numeric, Unified, UnifiedError};
use std::ops::{Add, Div, Mul, Sub};
impl<'domain, T: QuantitativeLimit + Into<f64>> Interval<'domain, T>
where
T: Mul<Output = T>,
T: Add<Output = T>,
T: Sub<Output = T>,
T: Div<Output = T>,
{
pub fn unification(
&self,
domain: &'domain Qualitative<Trapezoidal>,
) -> Result<Unified, UnifiedError> {
let (min, max) = self.normalize().value();
let min_f32 = min as f32;
let max_f32 = max as f32;
let measures = (0..domain.cardinality())
.map(|i| {
domain
.get_label_by_index(i)
.unwrap()
.membership()
.max_min(min_f32, max_f32)
})
.collect::<Vec<f32>>();
Unified::new(domain, measures)
}
pub fn transform_in_domain(&self, domain: &'domain Quantitative<T>) -> Interval<T> {
let (old_min, old_max) = self.value();
Interval::new(
domain,
crate::utilities::math::transform_range(
old_min,
self.domain().inf(),
self.domain().sup(),
domain.inf(),
domain.sup(),
),
crate::utilities::math::transform_range(
old_max,
self.domain().inf(),
self.domain().sup(),
domain.inf(),
domain.sup(),
),
)
.unwrap()
}
}
impl<'domain, T: QuantitativeLimit + Into<f64> + Add<Output = T> + Sub<Output = T>>
TryFrom<&Numeric<'domain, T>> for Interval<'domain, T>
{
type Error = IntervalError<T>;
fn try_from(value: &Numeric<'domain, T>) -> Result<Self, Self::Error> {
Interval::new(value.domain(), value.value(), value.value())
}
}
impl<'domain, T: QuantitativeLimit + Into<f64> + Add<Output = T> + Sub<Output = T>>
TryFrom<Numeric<'domain, T>> for Interval<'domain, T>
{
type Error = IntervalError<T>;
fn try_from(value: Numeric<'domain, T>) -> Result<Self, Self::Error> {
Interval::try_from(&value)
}
}