use crate::domain::{Qualitative, Quantitative, QuantitativeLimit};
use crate::fuzzy::membership::Trapezoidal;
use crate::valuation::{Interval, Numeric, NumericError, Unified, UnifiedError};
use std::ops::{Add, Div, Mul, Sub};
impl<'domain, T: QuantitativeLimit + Into<f64>> Numeric<'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 value = self.normalize().value() as f32;
let measures = (0..domain.cardinality())
.map(|i| {
domain
.get_label_by_index(i)
.unwrap()
.membership()
.membership_value(value)
})
.collect::<Vec<f32>>();
Unified::new(domain, measures)
}
pub fn transform_in_domain(&self, domain: &'domain Quantitative<T>) -> Numeric<T> {
Numeric::new(
domain,
crate::utilities::math::transform_range(
self.value(),
self.domain().inf(),
self.domain().sup(),
domain.inf(),
domain.sup(),
),
)
.unwrap()
}
}
impl<'domain> TryFrom<&Interval<'domain, f32>> for Numeric<'domain, f32> {
type Error = NumericError<f32>;
fn try_from(value: &Interval<'domain, f32>) -> Result<Self, Self::Error> {
Numeric::new(value.domain(), value.resume())
}
}
impl<'domain> TryFrom<&Interval<'domain, f64>> for Numeric<'domain, f64> {
type Error = NumericError<f64>;
fn try_from(value: &Interval<'domain, f64>) -> Result<Self, Self::Error> {
Numeric::new(value.domain(), value.resume())
}
}
impl<'domain> TryFrom<&Interval<'domain, i32>> for Numeric<'domain, i32> {
type Error = NumericError<i32>;
fn try_from(value: &Interval<'domain, i32>) -> Result<Self, Self::Error> {
Numeric::new(value.domain(), value.resume())
}
}
impl<'domain> TryFrom<Interval<'domain, f32>> for Numeric<'domain, f32> {
type Error = NumericError<f32>;
fn try_from(value: Interval<'domain, f32>) -> Result<Self, Self::Error> {
Numeric::try_from(&value)
}
}
impl<'domain> TryFrom<Interval<'domain, f64>> for Numeric<'domain, f64> {
type Error = NumericError<f64>;
fn try_from(value: Interval<'domain, f64>) -> Result<Self, Self::Error> {
Numeric::try_from(&value)
}
}
impl<'domain> TryFrom<Interval<'domain, i32>> for Numeric<'domain, i32> {
type Error = NumericError<i32>;
fn try_from(value: Interval<'domain, i32>) -> Result<Self, Self::Error> {
Numeric::try_from(&value)
}
}