fructose/algebra/
field.rs

1use crate::algebra::lattice::Lattice;
2use crate::algebra::ring::{DivisionRing, EuclideanDomain};
3use crate::operators::exp::Exponentiation;
4use crate::operators::trig::TrigOps;
5use crate::operators::{Additive, ClosedOps, Multiplicative, Operator};
6use crate::properties::archimedean::ArchimedeanDiv;
7use crate::properties::helpers::identity::{One, Zero};
8
9// (alias) All Fields are Division Rings
10pub trait Field<A: Operator = Additive, M: Operator = Multiplicative>: DivisionRing<A, M> {}
11
12pub trait PartiallyOrderedField<A: Operator = Additive, M: Operator = Multiplicative>:
13    Field<A, M> + Lattice
14{
15}
16
17pub trait RealField:
18    Field + TrigOps + EuclideanDomain + ArchimedeanDiv + Lattice + Exponentiation
19{
20}
21
22pub trait ComplexField:
23    Field + TrigOps + EuclideanDomain + ArchimedeanDiv + Lattice + Exponentiation
24{
25    type RealField: RealField;
26
27    fn from_real(re: Self::RealField) -> Self;
28
29    fn from_imaginary(im: Self::RealField) -> Self;
30
31    fn real(&self) -> Self::RealField;
32
33    fn imaginary(&self) -> Self::RealField;
34
35    fn modulus(&self) -> Self::RealField;
36
37    fn modulus_squared(&self) -> Self::RealField;
38
39    fn argument(&self) -> Self::RealField;
40
41    fn scale(&self, scalar: Self::RealField) -> Self;
42
43    fn unscale(&self, scalar: Self::RealField) -> Self;
44
45    fn to_polar(&self) -> (Self::RealField, Self::RealField) {
46        (self.modulus(), self.argument())
47    }
48
49    fn to_exponential(&self) -> (Self::RealField, Self);
50
51    fn signum(&self) -> Self {
52        self.to_exponential().1
53    }
54}
55
56impl<T, A: Operator, M: Operator> Field<A, M> for T where T: DivisionRing<A, M> + ClosedOps {}
57
58impl<T, A: Operator, M: Operator> PartiallyOrderedField<A, M> for T where T: Field<A, M> + Lattice {}
59
60impl<T> RealField for T where
61    T: Field + TrigOps + Exponentiation + EuclideanDomain + ArchimedeanDiv + Lattice
62{
63}
64
65macro_rules! impl_complex {
66    ($($set:ty)*) => {
67        $(
68            impl ComplexField for $set {
69                type RealField = $set;
70
71                #[inline]
72                fn from_real(re: Self::RealField) -> Self {
73                    re
74                }
75
76                #[inline]
77                fn from_imaginary(_: Self::RealField) -> Self {
78                    Self::zero()
79                }
80
81                #[inline]
82                fn real(&self) -> Self::RealField {
83                    *self
84                }
85
86                #[inline]
87                fn imaginary(&self) -> Self::RealField {
88                    Self::zero()
89                }
90
91                #[inline]
92                fn modulus(&self) -> Self::RealField {
93                    self.abs()
94                }
95
96                #[inline]
97                fn modulus_squared(&self) -> Self::RealField {
98                    self * self
99                }
100
101                #[inline]
102                fn argument(&self) -> Self::RealField {
103                    if *self >= Self::zero() {
104                        Self::zero()
105                    } else {
106                        Self::PI
107                    }
108                }
109
110                #[inline]
111                fn scale(&self, scalar: Self::RealField) -> Self {
112                    self * scalar
113                }
114
115                #[inline]
116                fn unscale(&self, scalar: Self::RealField) -> Self {
117                    self / scalar
118                }
119
120                #[inline]
121                fn to_exponential(&self) -> (Self::RealField, Self) {
122                    let m = self.modulus();
123
124                    if !m.is_zero() {
125                        (m, self.unscale(m))
126                    } else {
127                        (Self::RealField::zero(), Self::one())
128                    }
129                }
130            }
131        )*
132    }
133}
134
135impl_complex!(f32 f64);