1use scirs2_core::numeric::{One, Zero};
7use std::fmt;
8use std::ops::{Add, Div, Mul, Neg, Sub};
9
10#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct Complex32 {
13 pub real: f32,
14 pub imag: f32,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq)]
19pub struct Complex64 {
20 pub real: f64,
21 pub imag: f64,
22}
23
24impl Complex32 {
25 pub fn new(real: f32, imag: f32) -> Self {
27 Self { real, imag }
28 }
29
30 pub fn from_real(real: f32) -> Self {
32 Self { real, imag: 0.0 }
33 }
34
35 pub fn from_imag(imag: f32) -> Self {
37 Self { real: 0.0, imag }
38 }
39
40 pub fn magnitude(&self) -> f32 {
42 (self.real * self.real + self.imag * self.imag).sqrt()
43 }
44
45 pub fn phase(&self) -> f32 {
47 self.imag.atan2(self.real)
48 }
49
50 pub fn conjugate(&self) -> Self {
52 Self {
53 real: self.real,
54 imag: -self.imag,
55 }
56 }
57
58 pub fn to_polar(&self) -> (f32, f32) {
60 (self.magnitude(), self.phase())
61 }
62
63 pub fn from_polar(magnitude: f32, phase: f32) -> Self {
65 Self {
66 real: magnitude * phase.cos(),
67 imag: magnitude * phase.sin(),
68 }
69 }
70}
71
72impl Complex64 {
73 pub fn new(real: f64, imag: f64) -> Self {
75 Self { real, imag }
76 }
77
78 pub fn from_real(real: f64) -> Self {
80 Self { real, imag: 0.0 }
81 }
82
83 pub fn from_imag(imag: f64) -> Self {
85 Self { real: 0.0, imag }
86 }
87
88 pub fn magnitude(&self) -> f64 {
90 (self.real * self.real + self.imag * self.imag).sqrt()
91 }
92
93 pub fn phase(&self) -> f64 {
95 self.imag.atan2(self.real)
96 }
97
98 pub fn conjugate(&self) -> Self {
100 Self {
101 real: self.real,
102 imag: -self.imag,
103 }
104 }
105
106 pub fn to_polar(&self) -> (f64, f64) {
108 (self.magnitude(), self.phase())
109 }
110
111 pub fn from_polar(magnitude: f64, phase: f64) -> Self {
113 Self {
114 real: magnitude * phase.cos(),
115 imag: magnitude * phase.sin(),
116 }
117 }
118}
119
120impl Add for Complex32 {
122 type Output = Self;
123
124 fn add(self, other: Self) -> Self {
125 Self {
126 real: self.real + other.real,
127 imag: self.imag + other.imag,
128 }
129 }
130}
131
132impl Sub for Complex32 {
133 type Output = Self;
134
135 fn sub(self, other: Self) -> Self {
136 Self {
137 real: self.real - other.real,
138 imag: self.imag - other.imag,
139 }
140 }
141}
142
143impl Mul for Complex32 {
144 type Output = Self;
145
146 fn mul(self, other: Self) -> Self {
147 Self {
148 real: self.real * other.real - self.imag * other.imag,
149 imag: self.real * other.imag + self.imag * other.real,
150 }
151 }
152}
153
154impl Div for Complex32 {
155 type Output = Self;
156
157 fn div(self, other: Self) -> Self {
158 let denom = other.real * other.real + other.imag * other.imag;
159 Self {
160 real: (self.real * other.real + self.imag * other.imag) / denom,
161 imag: (self.imag * other.real - self.real * other.imag) / denom,
162 }
163 }
164}
165
166impl Neg for Complex32 {
167 type Output = Self;
168
169 fn neg(self) -> Self {
170 Self {
171 real: -self.real,
172 imag: -self.imag,
173 }
174 }
175}
176
177impl Add for Complex64 {
179 type Output = Self;
180
181 fn add(self, other: Self) -> Self {
182 Self {
183 real: self.real + other.real,
184 imag: self.imag + other.imag,
185 }
186 }
187}
188
189impl Sub for Complex64 {
190 type Output = Self;
191
192 fn sub(self, other: Self) -> Self {
193 Self {
194 real: self.real - other.real,
195 imag: self.imag - other.imag,
196 }
197 }
198}
199
200impl Mul for Complex64 {
201 type Output = Self;
202
203 fn mul(self, other: Self) -> Self {
204 Self {
205 real: self.real * other.real - self.imag * other.imag,
206 imag: self.real * other.imag + self.imag * other.real,
207 }
208 }
209}
210
211impl Div for Complex64 {
212 type Output = Self;
213
214 fn div(self, other: Self) -> Self {
215 let denom = other.real * other.real + other.imag * other.imag;
216 Self {
217 real: (self.real * other.real + self.imag * other.imag) / denom,
218 imag: (self.imag * other.real - self.real * other.imag) / denom,
219 }
220 }
221}
222
223impl Neg for Complex64 {
224 type Output = Self;
225
226 fn neg(self) -> Self {
227 Self {
228 real: -self.real,
229 imag: -self.imag,
230 }
231 }
232}
233
234impl Zero for Complex32 {
236 fn zero() -> Self {
237 Self {
238 real: 0.0,
239 imag: 0.0,
240 }
241 }
242
243 fn is_zero(&self) -> bool {
244 self.real == 0.0 && self.imag == 0.0
245 }
246}
247
248impl One for Complex32 {
249 fn one() -> Self {
250 Self {
251 real: 1.0,
252 imag: 0.0,
253 }
254 }
255}
256
257impl Zero for Complex64 {
259 fn zero() -> Self {
260 Self {
261 real: 0.0,
262 imag: 0.0,
263 }
264 }
265
266 fn is_zero(&self) -> bool {
267 self.real == 0.0 && self.imag == 0.0
268 }
269}
270
271impl One for Complex64 {
272 fn one() -> Self {
273 Self {
274 real: 1.0,
275 imag: 0.0,
276 }
277 }
278}
279
280impl Default for Complex32 {
282 fn default() -> Self {
283 Self::zero()
284 }
285}
286
287impl Default for Complex64 {
288 fn default() -> Self {
289 Self::zero()
290 }
291}
292
293impl fmt::Display for Complex32 {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 if self.imag >= 0.0 {
297 write!(f, "{}+{}i", self.real, self.imag)
298 } else {
299 write!(f, "{}{}i", self.real, self.imag)
300 }
301 }
302}
303
304impl fmt::Display for Complex64 {
305 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
306 if self.imag >= 0.0 {
307 write!(f, "{}+{}i", self.real, self.imag)
308 } else {
309 write!(f, "{}{}i", self.real, self.imag)
310 }
311 }
312}
313
314impl From<f32> for Complex32 {
316 fn from(real: f32) -> Self {
317 Self::from_real(real)
318 }
319}
320
321impl From<f64> for Complex64 {
322 fn from(real: f64) -> Self {
323 Self::from_real(real)
324 }
325}
326
327impl From<Complex32> for Complex64 {
328 fn from(c: Complex32) -> Self {
329 Self {
330 real: c.real as f64,
331 imag: c.imag as f64,
332 }
333 }
334}
335
336impl From<Complex64> for Complex32 {
337 fn from(c: Complex64) -> Self {
338 Self {
339 real: c.real as f32,
340 imag: c.imag as f32,
341 }
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 #[test]
350 fn test_complex32_arithmetic() {
351 let a = Complex32::new(3.0, 4.0);
352 let b = Complex32::new(1.0, 2.0);
353
354 let sum = a + b;
355 assert_eq!(sum.real, 4.0);
356 assert_eq!(sum.imag, 6.0);
357
358 let product = a * b;
359 assert_eq!(product.real, -5.0);
360 assert_eq!(product.imag, 10.0);
361 }
362
363 #[test]
364 fn test_complex64_magnitude() {
365 let c = Complex64::new(3.0, 4.0);
366 assert_eq!(c.magnitude(), 5.0);
367 }
368
369 #[test]
370 fn test_complex_conjugate() {
371 let c = Complex32::new(3.0, 4.0);
372 let conj = c.conjugate();
373 assert_eq!(conj.real, 3.0);
374 assert_eq!(conj.imag, -4.0);
375 }
376}