use crate::domain::Qualitative;
use crate::fuzzy::membership::Trapezoidal;
use crate::fuzzy::LabelMembership;
use crate::utilities;
use crate::valuation::{Single, TwoTuple, TwoTupleError, Unified, UnifiedError};
use std::fmt::Display;
impl<'domain> TwoTuple<'domain, Trapezoidal> {
pub fn unification_in_domain(
&self,
domain: &'domain Qualitative<Trapezoidal>,
) -> Result<Unified, UnifiedError<'domain>> {
let beta = (self.inverse_delta() * (domain.cardinality() - 1) as f32)
/ (self.domain().cardinality() - 1) as f32;
let index = beta.round() as usize;
let alpha = utilities::math::round_f32(beta - index as f32, 5);
let mut measures: Vec<f32> = vec![0.; domain.cardinality()];
measures[index] = 1. - alpha.abs();
if alpha != 0. {
measures[if alpha > 0. { index + 1 } else { index - 1 }] = alpha.abs()
}
Unified::new(domain, measures)
}
pub fn transform_in_domain(
&self,
domain: &'domain Qualitative<Trapezoidal>,
) -> Result<Self, UnifiedError<'domain>> {
if !domain.is_blts() {
Err(UnifiedError::NonBLTSDomain { domain })
} else {
Ok(TwoTuple::delta(
domain,
(self.inverse_delta() * (domain.cardinality() - 1) as f32)
/ (self.domain().cardinality() - 1) as f32,
)
.unwrap())
}
}
}
impl<'domain> TryFrom<&TwoTuple<'domain, Trapezoidal>> for Unified<'domain> {
type Error = UnifiedError<'domain>;
fn try_from(value: &TwoTuple<'domain, Trapezoidal>) -> Result<Self, Self::Error> {
let mut measures: Vec<f32> = vec![0.; value.domain().cardinality()];
let index = value.index();
let alpha = value.alpha();
measures[index] = utilities::math::round_f32(1. - alpha.abs(), 5);
if alpha != 0. {
measures[if alpha > 0. { index + 1 } else { index - 1 }] = alpha.abs()
}
Unified::new(value.domain(), measures)
}
}
impl<'domain> TryFrom<&Unified<'domain>> for TwoTuple<'domain, Trapezoidal> {
type Error = TwoTupleError<'domain, Trapezoidal>;
fn try_from(value: &Unified<'domain>) -> Result<Self, Self::Error> {
TwoTuple::delta(value.domain(), value.chi())
}
}
impl<'domain, T: LabelMembership + Display> TryFrom<&Single<'domain, T>> for TwoTuple<'domain, T> {
type Error = TwoTupleError<'domain, T>;
fn try_from(value: &Single<'domain, T>) -> Result<Self, Self::Error> {
TwoTuple::new_by_label_index(value.domain(), value.index(), 0.)
}
}
impl<'domain> TryFrom<TwoTuple<'domain, Trapezoidal>> for Unified<'domain> {
type Error = UnifiedError<'domain>;
fn try_from(value: TwoTuple<'domain, Trapezoidal>) -> Result<Self, Self::Error> {
Unified::try_from(&value)
}
}
impl<'domain> TryFrom<Unified<'domain>> for TwoTuple<'domain, Trapezoidal> {
type Error = TwoTupleError<'domain, Trapezoidal>;
fn try_from(value: Unified<'domain>) -> Result<Self, Self::Error> {
TwoTuple::try_from(&value)
}
}
impl<'domain, T: LabelMembership + Display> TryFrom<Single<'domain, T>> for TwoTuple<'domain, T> {
type Error = TwoTupleError<'domain, T>;
fn try_from(value: Single<'domain, T>) -> Result<Self, Self::Error> {
TwoTuple::try_from(&value)
}
}