rds_tensors/types/
complex.rs1use std::cmp::{Eq,PartialEq};
2use std::f32;
3use std::f64;
4use std::fmt;
5use std::ops::{Add,AddAssign,Div,DivAssign,Mul,MulAssign,Neg,Sub,SubAssign};
6use std::num::ParseFloatError;
7use std::str::FromStr;
8
9pub trait Complex<T> where Self : Sized + Copy {
11
12    fn cartesian(re : T, im : T) -> Self;
14        
15    fn polar(abs : T, arg : T) -> Self;
17
18    fn re(self) -> T; 
20
21    fn im(self) -> T; 
23
24    fn abs(self) -> T;
26
27    fn arg(self) -> T; 
29
30    fn to_polar(self) -> (T,T)  {
32        (self.abs(), self.arg())
33    }
34
35    fn conj(self) -> Self;
37
38    fn reciprocal(self) -> Self;
40}
41
42#[repr(C)]
43#[derive(Clone,Copy,Debug)]
44pub struct c32 {
45    pub re : f32,
46    pub im : f32
47}
48
49#[repr(C)]
50#[derive(Clone,Copy,Debug)]
51pub struct c64 {
52    pub re : f64,
53    pub im : f64
54}
55
56impl c32 {
59    pub fn new(re : f32, im : f32) -> c32 {
60        c32 {
61            re : re,
62            im : im,
63        }
64    }
65}
66
67impl Complex<f32> for c32 {
68
69    fn cartesian(re : f32, im : f32) -> c32{
70        c32::new(re, im)
71    }
72
73    fn polar(arg : f32, abs : f32) -> c32 {
74        c32::new(arg * abs.cos(), arg * abs.sin())
75    }
76    
77    fn re(self) -> f32 {
78        self.re
79    }
80
81    fn im(self) -> f32 {
82        self.im
83    }
84
85    fn abs(self) -> f32 {
86        return (self.re * self.re + self.im * self.im).sqrt();
87    }
88
89    fn arg(self) -> f32 {
90        self.im.atan2(self.re)
91    }
92
93    fn conj(self) -> c32 {
94        c32::new(self.re, -self.im)
95    }
96
97    fn reciprocal(self) -> c32 {
98        let base = self.re * self.re + self.im * self.im;
99        c32::new(self.re / base, -self.im / base)
100    }
101}
102
103impl Add for c32 {
104    type Output = c32;
105
106    fn add(self, rhs: c32) -> c32 {
107        c32::new(self.re + rhs.re, self.im + rhs.im)
108    }
109}
110
111impl AddAssign for c32 {
112
113    fn add_assign(&mut self, rhs: c32) {
114        self.re += rhs.re;
115        self.im += rhs.im;
116    }
117}
118
119impl Div for c32 {
120    type Output = c32;
121
122    fn div(self, rhs: c32) -> c32 {
123        self * rhs.reciprocal()
124    }
125}
126
127impl DivAssign for c32 {
128
129    fn div_assign(&mut self, rhs: c32) {
130        *self *= rhs.reciprocal();
131    }
132}
133
134impl Mul for c32 {
135    type Output = c32;
136
137    fn mul(self, rhs: c32) -> c32 {
138        let re = self.re * rhs.re - self.im * rhs.im;
139        let im = self.re * rhs.im + self.im * rhs.re;
140        c32::new(re, im)
141    }
142}
143
144impl MulAssign for c32 {
145
146    fn mul_assign(&mut self, rhs: c32) {
147        let re = self.re * rhs.re - self.im * rhs.im;
148        let im = self.re * rhs.im + self.im * rhs.re;
149        self.re = re;
150        self.im = im; 
151    }
152}
153
154impl Neg for c32 {
155    type Output = c32;
156
157    fn neg(self) -> c32 {
158        c32::new(-self.re, -self.im)
159    }
160}
161
162impl Sub for c32 {
163    type Output = c32;
164
165    fn sub(self, rhs: c32) -> c32 {
166        c32::new(self.re - rhs.re, self.im - rhs.im)
167    }
168}
169
170impl SubAssign for c32 {
171
172    fn sub_assign(&mut self, rhs: c32) {
173        self.re -= rhs.re;
174        self.im -= rhs.im;
175    }
176}
177
178impl PartialEq<c32> for c32 {
179
180    fn eq(&self, rhs : &c32) -> bool {
181        self.re == rhs.re && self.im == rhs.im
182    }
183}
184
185impl Eq for c32 {
186}
187
188impl FromStr for c32 {
189    type Err = ParseFloatError;
190
191    fn from_str(s: &str) -> Result<c32, Self::Err> {
192        let mut v = c32::new(0.0, 0.0);
193        if s.ends_with('i') || s.ends_with('j') {
194            let imend = s.len()-1;
195            let mut imstart = 0usize;
196
197            if let Some(p) = s.rfind('-') {
198                if p > 0 {
199                    imstart = p;
200                }
201            }
202            if let Some(p) = s.rfind('+') {
203                if p > 0 {
204                    imstart = p;
205                }
206            }
207
208            if imstart > 0 {
209                v.re = match f32::from_str(&s[0..imstart]) {
210                    Ok(re) => re,
211                    Err(e) => {
212                        return Err(e);
213                    }
214                };
215            }
216            v.im = match f32::from_str(&s[imstart..imend]) {
217                Ok(im) => im,
218                Err(e) => {
219                    return Err(e);
220                }
221            };
222        }
223        else {
225            v.re = match f32::from_str(s) {
226                Ok(re) => re,
227                Err(e) => {
228                    return Err(e);
229                }
230            };
231        }
232        return Ok(v);
233    }
234}
235
236impl fmt::Display for c32 {
237    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238        write!(f, "{}{:+}j", self.re, self.im)
239    }
240}
241
242impl c64 {
245    pub fn new(re : f64, im : f64) -> c64 {
246        c64 {
247            re : re,
248            im : im,
249        }
250    }
251}
252
253impl Complex<f64> for c64 {
254
255    fn cartesian(re : f64, im : f64) -> c64{
256        c64::new(re, im)
257    }
258
259    fn polar(arg : f64, abs : f64) -> c64{
260        c64::new(arg * abs.cos(), arg * abs.sin())
261    }
262    
263    fn re(self) -> f64 {
264        self.re
265    }
266
267    fn im(self) -> f64 {
268        self.im
269    }
270
271    fn abs(self) -> f64 {
272        return (self.re * self.re + self.im * self.im).sqrt();
273    }
274
275    fn arg(self) -> f64 {
276        self.im.atan2(self.re)
277    }
278
279    fn conj(self) -> c64 {
280        c64::new(self.re, -self.im)
281    }
282
283    fn reciprocal(self) -> c64 {
284        let base = self.re * self.re + self.im * self.im;
285        c64::new(self.re / base, -self.im / base)
286    }
287}
288
289impl Add for c64 {
290    type Output = c64;
291
292    fn add(self, rhs: c64) -> c64 {
293        c64::new(self.re + rhs.re, self.im + rhs.im)
294    }
295}
296
297impl AddAssign for c64 {
298
299    fn add_assign(&mut self, rhs: c64) {
300        self.re += rhs.re;
301        self.im += rhs.im;
302    }
303}
304
305impl Div for c64 {
306    type Output = c64;
307
308    fn div(self, rhs: c64) -> c64 {
309        self * rhs.reciprocal()
310    }
311}
312
313impl DivAssign for c64 {
314
315    fn div_assign(&mut self, rhs: c64) {
316        *self *= rhs.reciprocal();
317    }
318}
319
320impl Mul for c64 {
321    type Output = c64;
322
323    fn mul(self, rhs: c64) -> c64 {
324        let re = self.re * rhs.re - self.im * rhs.im;
325        let im = self.re * rhs.im + self.im * rhs.re;
326        c64::new(re, im)
327    }
328}
329
330impl MulAssign for c64 {
331
332    fn mul_assign(&mut self, rhs: c64) {
333        let re = self.re * rhs.re - self.im * rhs.im;
334        let im = self.re * rhs.im + self.im * rhs.re;
335        self.re = re;
336        self.im = im; 
337    }
338}
339
340impl Neg for c64 {
341    type Output = c64;
342
343    fn neg(self) -> c64 {
344        c64::new(-self.re, -self.im)
345    }
346}
347
348impl Sub for c64 {
349    type Output = c64;
350
351    fn sub(self, rhs: c64) -> c64 {
352        c64::new(self.re - rhs.re, self.im - rhs.im)
353    }
354}
355
356impl SubAssign for c64 {
357
358    fn sub_assign(&mut self, rhs: c64) {
359        self.re -= rhs.re;
360        self.im -= rhs.im;
361    }
362}
363
364impl PartialEq<c64> for c64 {
365
366    fn eq(&self, rhs : &c64) -> bool {
367        self.re == rhs.re && self.im == rhs.im
368    }
369}
370
371impl Eq for c64 {
372}
373
374impl FromStr for c64 {
375    type Err = ParseFloatError;
376
377    fn from_str(s: &str) -> Result<c64, Self::Err> {
378        let mut v = c64::new(0.0, 0.0);
379        if s.ends_with('i') || s.ends_with('j') {
380            let imend = s.len()-1;
381            let mut imstart = 0usize;
382
383            if let Some(p) = s.rfind('-') {
384                if p > 0 {
385                    imstart = p;
386                }
387            }
388            if let Some(p) = s.rfind('+') {
389                if p > 0 {
390                    imstart = p;
391                }
392            }
393
394            if imstart > 0 {
395                v.re = match f64::from_str(&s[0..imstart]) {
396                    Ok(re) => re,
397                    Err(e) => {
398                        return Err(e);
399                    }
400                };
401            }
402            v.im = match f64::from_str(&s[imstart..imend]) {
403                Ok(im) => im,
404                Err(e) => {
405                    return Err(e);
406                }
407            };
408        }
409        else {
411            v.re = match f64::from_str(s) {
412                Ok(re) => re,
413                Err(e) => {
414                    return Err(e);
415                }
416            };
417        }
418        return Ok(v);
419    }
420}
421
422impl fmt::Display for c64 {
423    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
424        write!(f, "{}{:+}j", self.re, self.im)
425    }
426}