Skip to main content

inertia_algebra/
operator.rs

1//! Operators traits and structures.
2
3use crate::structures::AbstractMagmaElement;
4
5/// Trait implemented by types representing abstract operators.
6pub trait Operator: Copy {
7    /// Returns the structure that identifies the operator.
8    fn operator_token() -> Self;
9}
10
11pub trait Operation<O: Operator>: Sized {
12    fn operate(&self, rhs: &Self) -> Self;
13
14    #[inline]
15    fn op(&self, _: O, rhs: &Self) -> Self {
16        self.operate(rhs)
17    }
18}
19
20/// Trait used to define the two_sided_inverse element relative to the given operator.
21///
22/// The operator, e.g., `Additive` or `Multiplicative`, is identified by the type parameter `O`.
23pub trait TwoSidedInverse<O: Operator>: Sized {
24    /// Returns the two_sided_inverse of `self`, relative to the operator `O`.
25    ///
26    /// The parameter `O` is generally either `Additive` or `Multiplicative`.
27    fn two_sided_inverse(&self) -> Self;
28
29    /// In-place inversion of `self`, relative to the operator `O`.
30    ///
31    /// The parameter `O` is generally either `Additive` or `Multiplicative`.
32    #[inline]
33    fn two_sided_inverse_mut(&mut self) {
34        *self = self.two_sided_inverse()
35    }
36}
37
38pub trait IsIdentity<O: Operator>: Sized {
39    fn is_identity(&self) -> bool;
40}
41
42pub trait IsZero: AbstractMagmaElement<Additive> + IsIdentity<Additive> {
43    fn is_zero(&self) -> bool {
44        self.is_identity()
45    }
46}
47
48impl<T> IsZero for T
49where
50    T: AbstractMagmaElement<Additive> + IsIdentity<Additive>
51{}
52
53pub trait IsOne: AbstractMagmaElement<Multiplicative> + IsIdentity<Multiplicative> {
54    fn is_one(&self) -> bool {
55        self.is_identity()
56    }
57}
58
59impl<T> IsOne for T
60where
61    T: AbstractMagmaElement<Multiplicative> + IsIdentity<Multiplicative>
62{}
63
64/*
65 *
66 * Implementations.
67 *
68 */
69
70#[derive(Clone, Copy)]
71/// The addition operator, commonly symbolized by `+`.
72pub struct Additive;
73
74#[derive(Clone, Copy)]
75/// The multiplication operator, commonly symbolized by `×`.
76pub struct Multiplicative;
77
78#[derive(Clone, Copy)]
79/// The default abstract operator.
80pub struct AbstractOperator;
81
82impl Operator for Additive {
83    #[inline]
84    fn operator_token() -> Self {
85        Additive
86    }
87}
88
89impl Operator for Multiplicative {
90    #[inline]
91    fn operator_token() -> Self {
92        Multiplicative
93    }
94}
95
96impl Operator for AbstractOperator {
97    #[inline]
98    fn operator_token() -> Self {
99        AbstractOperator
100    }
101}
102
103/*
104macro_rules! impl_additive_inverse(
105    ($($T:ty),* $(,)*) => {$(
106        impl TwoSidedInverse<Additive> for $T {
107            fn two_sided_inverse(&self) -> Self {
108                -*self
109            }
110        }
111    )*}
112);
113
114impl_additive_inverse!(i8, i16, i32, i64, i128, isize, f32, f64);
115#[cfg(feature = "decimal")]
116impl_additive_inverse!(d128);
117
118impl<N: TwoSidedInverse<Additive>> TwoSidedInverse<Additive> for Complex<N> {
119    #[inline]
120    fn two_sided_inverse(&self) -> Complex<N> {
121        Complex {
122            re: self.re.two_sided_inverse(),
123            im: self.im.two_sided_inverse(),
124        }
125    }
126}
127
128impl TwoSidedInverse<Multiplicative> for f32 {
129    #[inline]
130    fn two_sided_inverse(&self) -> f32 {
131        1.0 / self
132    }
133}
134
135impl TwoSidedInverse<Multiplicative> for f64 {
136    #[inline]
137    fn two_sided_inverse(&self) -> f64 {
138        1.0 / self
139    }
140}
141
142#[cfg(feature = "decimal")]
143impl TwoSidedInverse<Multiplicative> for d128 {
144    #[inline]
145    fn two_sided_inverse(&self) -> d128 {
146        d128!(1.0) / self
147    }
148}
149
150impl<N: Num + Clone + ClosedNeg> TwoSidedInverse<Multiplicative> for Complex<N> {
151    #[inline]
152    fn two_sided_inverse(&self) -> Self {
153        self.inv()
154    }
155}
156*/
157
158/*
159/// [Alias] Trait alias for `Add` and `AddAssign` with result of type `Self`.
160pub trait ClosedAdd<Right = Self>: Sized + Add<Right, Output = Self> + AddAssign<Right> {}
161
162/// [Alias] Trait alias for `Sub` and `SubAssign` with result of type `Self`.
163pub trait ClosedSub<Right = Self>: Sized + Sub<Right, Output = Self> + SubAssign<Right> {}
164
165/// [Alias] Trait alias for `Mul` and `MulAssign` with result of type `Self`.
166pub trait ClosedMul<Right = Self>: Sized + Mul<Right, Output = Self> + MulAssign<Right> {}
167
168/// [Alias] Trait alias for `Div` and `DivAssign` with result of type `Self`.
169pub trait ClosedDiv<Right = Self>: Sized + Div<Right, Output = Self> + DivAssign<Right> {}
170
171/// [Alias] Trait alias for `Neg` with result of type `Self`.
172pub trait ClosedNeg: Sized + Neg<Output = Self> {}
173
174impl<T, Right> ClosedAdd<Right> for T where T: Add<Right, Output = T> + AddAssign<Right> {}
175impl<T, Right> ClosedSub<Right> for T where T: Sub<Right, Output = T> + SubAssign<Right> {}
176impl<T, Right> ClosedMul<Right> for T where T: Mul<Right, Output = T> + MulAssign<Right> {}
177impl<T, Right> ClosedDiv<Right> for T where T: Div<Right, Output = T> + DivAssign<Right> {}
178impl<T> ClosedNeg for T where T: Neg<Output = T> {}
179*/