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*/