fructose/algebra/
field.rs1use 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
9pub 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);