Skip to main content

oxiblas_core/scalar/
complex_impl.rs

1//! Scalar, ComplexScalar, and Field implementations for Complex32 and Complex64.
2
3use num_complex::{Complex32, Complex64};
4
5use super::traits::{ComplexScalar, Field, Scalar};
6
7// =============================================================================
8// Implementations for Complex32
9// =============================================================================
10
11impl Scalar for Complex32 {
12    type Real = f32;
13
14    #[inline]
15    fn abs(self) -> Self::Real {
16        self.norm()
17    }
18
19    #[inline]
20    fn conj(self) -> Self {
21        Complex32::conj(&self)
22    }
23
24    #[inline]
25    fn is_real() -> bool {
26        false
27    }
28
29    #[inline]
30    fn real(self) -> Self::Real {
31        self.re
32    }
33
34    #[inline]
35    fn imag(self) -> Self::Real {
36        self.im
37    }
38
39    #[inline]
40    fn from_real_imag(re: Self::Real, im: Self::Real) -> Self {
41        Complex32::new(re, im)
42    }
43
44    #[inline]
45    fn abs_sq(self) -> Self::Real {
46        self.norm_sqr()
47    }
48
49    #[inline]
50    fn epsilon() -> Self::Real {
51        f32::EPSILON
52    }
53
54    #[inline]
55    fn min_positive() -> Self::Real {
56        f32::MIN_POSITIVE
57    }
58
59    #[inline]
60    fn max_value() -> Self::Real {
61        f32::MAX
62    }
63}
64
65impl ComplexScalar for Complex32 {
66    #[inline]
67    fn new(re: Self::Real, im: Self::Real) -> Self {
68        Complex32::new(re, im)
69    }
70
71    #[inline]
72    fn arg(self) -> Self::Real {
73        self.arg()
74    }
75
76    #[inline]
77    fn from_polar(r: Self::Real, theta: Self::Real) -> Self {
78        Complex32::from_polar(r, theta)
79    }
80
81    #[inline]
82    fn cexp(self) -> Self {
83        self.exp()
84    }
85
86    #[inline]
87    fn cln(self) -> Self {
88        self.ln()
89    }
90
91    #[inline]
92    fn csqrt(self) -> Self {
93        self.sqrt()
94    }
95}
96
97impl Field for Complex32 {
98    #[inline]
99    fn mul_conj(self, other: Self) -> Self {
100        self * other.conj()
101    }
102
103    #[inline]
104    fn conj_mul(self, other: Self) -> Self {
105        self.conj() * other
106    }
107
108    #[inline]
109    fn recip(self) -> Self {
110        Complex32::new(1.0, 0.0) / self
111    }
112
113    #[inline]
114    fn powi(self, n: i32) -> Self {
115        self.powu(n.unsigned_abs())
116            * if n < 0 {
117                self.recip().powu(n.unsigned_abs())
118            } else {
119                Complex32::new(1.0, 0.0)
120            }
121    }
122}
123
124// =============================================================================
125// Implementations for Complex64
126// =============================================================================
127
128impl Scalar for Complex64 {
129    type Real = f64;
130
131    #[inline]
132    fn abs(self) -> Self::Real {
133        self.norm()
134    }
135
136    #[inline]
137    fn conj(self) -> Self {
138        Complex64::conj(&self)
139    }
140
141    #[inline]
142    fn is_real() -> bool {
143        false
144    }
145
146    #[inline]
147    fn real(self) -> Self::Real {
148        self.re
149    }
150
151    #[inline]
152    fn imag(self) -> Self::Real {
153        self.im
154    }
155
156    #[inline]
157    fn from_real_imag(re: Self::Real, im: Self::Real) -> Self {
158        Complex64::new(re, im)
159    }
160
161    #[inline]
162    fn abs_sq(self) -> Self::Real {
163        self.norm_sqr()
164    }
165
166    #[inline]
167    fn epsilon() -> Self::Real {
168        f64::EPSILON
169    }
170
171    #[inline]
172    fn min_positive() -> Self::Real {
173        f64::MIN_POSITIVE
174    }
175
176    #[inline]
177    fn max_value() -> Self::Real {
178        f64::MAX
179    }
180}
181
182impl ComplexScalar for Complex64 {
183    #[inline]
184    fn new(re: Self::Real, im: Self::Real) -> Self {
185        Complex64::new(re, im)
186    }
187
188    #[inline]
189    fn arg(self) -> Self::Real {
190        self.arg()
191    }
192
193    #[inline]
194    fn from_polar(r: Self::Real, theta: Self::Real) -> Self {
195        Complex64::from_polar(r, theta)
196    }
197
198    #[inline]
199    fn cexp(self) -> Self {
200        self.exp()
201    }
202
203    #[inline]
204    fn cln(self) -> Self {
205        self.ln()
206    }
207
208    #[inline]
209    fn csqrt(self) -> Self {
210        self.sqrt()
211    }
212}
213
214impl Field for Complex64 {
215    #[inline]
216    fn mul_conj(self, other: Self) -> Self {
217        self * other.conj()
218    }
219
220    #[inline]
221    fn conj_mul(self, other: Self) -> Self {
222        self.conj() * other
223    }
224
225    #[inline]
226    fn recip(self) -> Self {
227        Complex64::new(1.0, 0.0) / self
228    }
229
230    #[inline]
231    fn powi(self, n: i32) -> Self {
232        if n >= 0 {
233            self.powu(n as u32)
234        } else {
235            self.recip().powu((-n) as u32)
236        }
237    }
238}