mixed_num/complex/
cartesian_impl.rs

1use crate::*;
2use crate::complex::ops;
3
4#[macro_use]
5mod num_complex_impl;
6
7impl <T: MixedNum + MixedNumSigned> MixedComplex for Cartesian<T>
8{
9}
10
11impl<T> Cartesian<T>
12{
13    pub fn new(re:T, im:T) -> Self
14    {
15        return Cartesian{re:re, im:im};
16    }
17}
18
19impl <T: MixedNum + MixedNumSigned> NewFromCartesian<T> for Cartesian<T>
20{
21    /// Type cast from real number T to Complex<T>.
22    fn new_from_cartesian( re:T, im:T ) -> Self
23    {
24        return Self{re:re, im:im};
25    }
26}
27
28impl <T: MixedNum + MixedNumSigned + MixedWrapPhase + MixedTrigonometry + MixedOps> NewFromPolar<T> for Cartesian<T>
29{
30    fn new_from_polar( mag:T, ang:T ) -> Self
31    {
32        return ops::to_cartesian(Polar::new(mag, ang));
33    }
34}
35
36impl <T: MixedNum + MixedNumSigned> ToCartesian<T> for Cartesian<T>
37{
38    /// Converison to Complex<T>.
39    #[inline(always)]
40    fn to_cartesian( &self ) -> Cartesian<T>
41    {
42        return *self;
43    }
44}
45
46impl <T: MixedNum + MixedNumSigned + MixedSqrt + MixedOps + MixedAbs + MixedPowi + MixedAtan> ToPolar<T> for Cartesian<T>
47{
48    /// Complex<T> to Polar<T>.
49    #[inline(always)]
50    fn to_polar( &self ) -> Polar<T>
51    {
52        return ops::to_polar(*self);
53    }
54}
55
56impl <T: MixedNum + MixedZero> MixedZero for Cartesian<T>
57{
58    /// Return the zero value of type Self.
59    #[inline(always)]
60    fn mixed_zero() -> Self {
61        return Self{re:T::mixed_zero(), im:T::mixed_zero()};
62    }
63}
64
65impl <T: MixedNum + MixedZero + MixedOne> MixedOne for Cartesian<T>
66{
67    /// Return the zero value of type Self.
68    #[inline(always)]
69    fn mixed_one() -> Self {
70        return Self{re:T::mixed_one(), im:T::mixed_zero()};
71    }
72}
73
74impl <T: MixedNum + MixedZero> MixedComplexConversion<T>  for Cartesian<T>
75{
76    /// Type cast from real number T to Complex<T>.
77    fn mixed_to_complex( number:T ) -> Self {
78        return Self{re:number, im:T::mixed_zero()};
79    }
80}
81
82impl <T: MixedNum + MixedNumSigned + MixedSqrt + MixedPowi + MixedOps> Mag<T> for Cartesian<T>
83{
84    /// Magnitude of the complex number.
85    ///  
86    /// ```
87    /// use mixed_num::*;
88    /// use mixed_num::traits::*;
89    ///
90    /// let polar_num = Polar::new(0.5f32,0.5f32);
91    /// let cartesian_num = polar_num.to_cartesian();
92    ///  
93    /// let absolute = cartesian_num.mag();
94    /// 
95    /// assert_eq!{ absolute.to_string(), "0.5" };
96    /// ```
97    #[inline(always)]
98    fn mag( &self ) -> T
99    {
100        return (self.re.mixed_powi(2)+self.im.mixed_powi(2)).mixed_sqrt();
101    }
102    /// Magnitude of the complex number.
103    /// 
104    /// ```
105    /// use mixed_num::*;
106    /// use mixed_num::traits::*;
107    ///
108    /// let polar_num = Polar::new(0.5f32,0.5f32);
109    /// let cartesian_num = polar_num.to_cartesian();
110    ///  
111    /// let absolute = cartesian_num.abs();
112    /// 
113    /// assert_eq!{ absolute.to_string(), "0.5" };
114    /// ```
115    #[inline(always)]
116    fn abs( &self ) -> T
117    {
118        return self.mag();
119    }
120}
121
122impl <T: MixedNum + MixedNumSigned + MixedSqrt + MixedPowi + MixedOps + MixedZero> MixedAbs for Cartesian<T>
123{   
124    fn mixed_abs( &self ) -> Self
125    {
126        return Self::new(self.mag(), T::mixed_zero());
127    }
128}
129
130impl <T: MixedNum + MixedNumSigned + MixedAtan> Arg<T> for Cartesian<T>
131{
132    /// Argument of the complex number.
133    /// 
134    /// ## Example
135    /// 
136    /// ```
137    /// use mixed_num::*;
138    /// use mixed_num::traits::*;
139    ///
140    /// let polar_num = Polar::new(1f32,0.5f32);
141    ///  
142    /// let cartesian_num = polar_num.to_cartesian();
143    /// 
144    /// assert_eq!{ cartesian_num.arg().to_string(), "0.5" };
145    /// ``` 
146    #[inline(always)]
147    fn arg( &self ) -> T
148    {
149        return self.im.mixed_atan2(self.re);
150    }
151
152    /// Angle of the complex number.
153    /// 
154    /// ## Example
155    /// 
156    /// ```
157    /// use mixed_num::*;
158    /// use mixed_num::traits::*;
159    ///
160    /// let polar_num = Polar::new(1f32,0.5f32);
161    ///  
162    /// let cartesian_num = polar_num.to_cartesian();
163    /// 
164    /// assert_eq!{ cartesian_num.ang().to_string(), "0.5" };
165    /// ``` 
166    #[inline(always)]
167    fn ang( &self ) -> T
168    {
169        return self.arg();
170    }
171}
172
173impl <T: MixedNum + MixedNumSigned + MixedOps> core::ops::Mul<Cartesian<T>> for Cartesian<T> {
174    type Output = Self;
175    #[inline]
176    fn mul(self, rhs: Self) -> Self {
177        return ops::mul_cartesian(self, rhs);
178    }
179}
180
181macro_rules! impl_core_ops_cartesian_for_cartesian{
182    ( $T:ty ) => {
183        impl <T: MixedNum + MixedNumSigned + MixedOps> core::ops::Mul<$T> for Cartesian<T> {
184            type Output = Self;
185            #[inline]
186            fn mul(self, rhs: $T) -> Cartesian<T> {
187                return ops::mul_cartesian(self, *rhs);
188            }
189        }
190    }
191}
192
193impl_core_ops_cartesian_for_cartesian!(&Cartesian<T>);
194impl_core_ops_cartesian_for_cartesian!(&mut Cartesian<T>);
195
196
197
198impl <T1: MixedNum + MixedOps, T2: MixedNum + MixedOps + MixedNumConversion<T1>> core::ops::Mul<T1> for Cartesian<T2> {
199    type Output = Cartesian<T2>;
200    /// ## Example
201    /// 
202    /// ```
203    /// use mixed_num::*;
204    /// use mixed_num::traits::*;
205    /// 
206    /// let mut c_num = Cartesian::new(1f32,2f32);
207    /// 
208    /// c_num = c_num*2f64;
209    /// assert_eq!{ c_num.to_string(), "2+4i" };
210    /// 
211    /// let mut c_num = Cartesian::new(1f32,2f32);
212    /// c_num = c_num*2f32;
213    /// assert_eq!{ c_num.to_string(), "2+4i" };
214    /// ``` 
215    #[inline]
216    fn mul(self, rhs: T1) -> Self {
217        return Cartesian::new(self.re*T2::mixed_from_num(rhs), self.im*T2::mixed_from_num(rhs));
218    }
219}
220
221impl <T1: MixedNum, T2: MixedNum + MixedNumSigned + MixedNumConversion<T1>> MixedNumConversion<Cartesian<T1>> for Cartesian<T2>
222{
223    /// Only uses the real part.
224    #[inline(always)]
225    fn mixed_from_num( number:Cartesian<T1> ) -> Self {
226        let r_val = Self::new_from_cartesian(T2::mixed_from_num(number.re), T2::mixed_from_num(number.im));
227        return r_val;
228    }
229    #[inline(always)]
230    fn mixed_to_num( &self ) -> Cartesian<T1> {
231        return Cartesian::new(self.re.mixed_to_num(), self.im.mixed_to_num());
232    }
233}
234
235macro_rules! impl_core_ops_polar_for_cartesian{
236    ( $T:ty ) => {
237        impl <T: MixedNum + MixedNumSigned + MixedTrigonometry + MixedWrapPhase + MixedOps> core::ops::Mul<$T> for Cartesian<T> {
238            type Output = Self;
239            #[inline]
240            fn mul(self, rhs: $T) -> Self {
241                let rhs_cartesian = rhs.to_cartesian();
242                return ops::mul_cartesian(self, rhs_cartesian);
243            }
244        }
245        
246        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedTrigonometry + MixedWrapPhase> core::ops::MulAssign<$T> for Cartesian<T> {
247            #[inline]
248            fn mul_assign(&mut self, rhs: $T) {
249                let temp = *self* rhs.to_cartesian();
250                self.re = temp.re;
251                self.im = temp.im;
252            }
253        }
254    }
255}
256
257impl_core_ops_polar_for_cartesian!(Polar<T>);
258impl_core_ops_polar_for_cartesian!(&Polar<T>);
259impl_core_ops_polar_for_cartesian!(&mut Polar<T>);
260
261
262impl <T1: MixedNum + MixedOps + MixedZero, T2: MixedNum + MixedOps + MixedNumConversion<T1>> core::ops::Add<T1> for Cartesian<T2> {
263    type Output = Self;
264    /// ## Example
265    /// 
266    /// ```
267    /// use mixed_num::*;
268    /// use mixed_num::traits::*;
269    /// 
270    /// let mut c_num = Cartesian::new(1f32,2f32);
271    /// 
272    /// c_num = c_num+2f64;
273    /// assert_eq!{ c_num.to_string(), "3+2i" };
274    /// ```
275    #[inline]
276    fn add(self, rhs: T1) -> Self {
277        return Cartesian::new(self.re+T2::mixed_from_num(rhs), self.im);
278    }
279}
280
281impl <T1: MixedNum + MixedOps + MixedZero, T2: MixedOps + MixedNumConversion<T1>> core::ops::AddAssign<T1> for Cartesian<T2> {
282    /// ## Example
283    /// 
284    /// ```
285    /// use mixed_num::*;
286    /// use mixed_num::traits::*;
287    /// 
288    /// let mut c_num = Cartesian::new(1f32,2f32);
289    /// 
290    /// c_num += 2f64;
291    /// assert_eq!{ c_num.to_string(), "3+2i" };
292    /// ```
293    #[inline]
294    fn add_assign(&mut self, rhs: T1) {
295        self.re =  self.re+T2::mixed_from_num(rhs);
296    }
297}
298
299macro_rules! impl_core_ops_add_sub_for_cartesian{
300    ( $T:ty ) => {
301        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedZero> core::ops::Add<$T> for Cartesian<T> {
302            type Output = Self;
303            #[inline]
304            fn add(self, rhs: $T) -> Self {
305                return Cartesian::new(self.re+rhs.re, self.im+rhs.im);
306            }
307        }
308
309        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedZero> core::ops::AddAssign<$T> for Cartesian<T> {
310            #[inline]
311            fn add_assign(&mut self, rhs: $T) {
312                self.re =  self.re+rhs.re;
313                self.im =  self.re+rhs.im;
314            }
315        }
316        
317        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedZero> core::ops::Sub<$T> for Cartesian<T> {
318            type Output = Self;
319            #[inline]
320            fn sub(self, rhs: $T) -> Self {
321                return Cartesian::new(self.re-rhs.re, self.im-rhs.im);
322            }
323        }
324
325        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedZero> core::ops::SubAssign<$T> for Cartesian<T> {
326            #[inline]
327            fn sub_assign(&mut self, rhs: $T) {
328                self.re =  self.re-rhs.re;
329                self.im =  self.re-rhs.im;
330            }
331        }
332    }
333}
334
335impl_core_ops_add_sub_for_cartesian!(Cartesian<T>);
336impl_core_ops_add_sub_for_cartesian!(&Cartesian<T>);
337impl_core_ops_add_sub_for_cartesian!(&mut Cartesian<T>);
338
339impl_core_ops_add_sub_for_cartesian!(num::Complex<T>);
340impl_core_ops_add_sub_for_cartesian!(&num::Complex<T>);
341impl_core_ops_add_sub_for_cartesian!(&mut num::Complex<T>);
342
343
344impl <T1: MixedNum + MixedOps, T2: MixedOps + MixedNumConversion<T1>> core::ops::Sub<T1> for Cartesian<T2> {
345    type Output = Self;
346    /// ## Example
347    /// 
348    /// ```
349    /// use mixed_num::*;
350    /// use mixed_num::traits::*;
351    /// 
352    /// let mut c_num = Cartesian::new(1f32,2f32);
353    /// 
354    /// c_num = c_num-2f64;
355    /// assert_eq!{ c_num.to_string(), "-1+2i" };
356    /// ```
357    #[inline]
358    fn sub(self, rhs: T1) -> Self {
359        return Cartesian::new(self.re-T2::mixed_from_num(rhs), self.im);
360    }
361}
362
363impl <T1: MixedNum + MixedOps, T2: MixedOps + MixedNumConversion<T1>> core::ops::SubAssign<T1> for Cartesian<T2> {
364    /// ## Example
365    /// 
366    /// ```
367    /// use mixed_num::*;
368    /// use mixed_num::traits::*;
369    /// 
370    /// let mut c_num = Cartesian::new(1f32,2f32);
371    /// 
372    /// c_num = c_num-2f64;
373    /// assert_eq!{ c_num.to_string(), "-1+2i" };
374    /// ```
375    #[inline]
376    fn sub_assign(&mut self, rhs: T1) {
377        self.re =  self.re-T2::mixed_from_num(rhs);
378    }
379}
380
381macro_rules! impl_core_ops_div_cartesian_for_cartesian{
382    ( $T:ty ) => {
383        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedPowi> core::ops::Div<$T> for Cartesian<T> {
384            type Output = Self;
385            fn div(self, rhs: $T) -> Self {
386                //  ((a,bi))/((c,di))=((ac+bd)/(c^2+d^2),(bc-ad)/(c^2+d^2) i)
387        
388                let a = self.re;
389                let b = self.im;
390                let c = rhs.re;
391                let d = rhs.re;
392        
393                return Cartesian::new((a*c+b*d)/(c.mixed_powi(2)+d.mixed_powi(2)), (b*c-a*d)/(c.mixed_powi(2)+d.mixed_powi(2)));
394            }
395        }
396
397        impl <T: MixedNum + MixedNumSigned + MixedOps + MixedZero + MixedPowi> core::ops::DivAssign<$T> for Cartesian<T> {
398            fn div_assign(&mut self, rhs: $T) {
399                //  ((a,bi))/((c,di))=((ac+bd)/(c^2+d^2),(bc-ad)/(c^2+d^2) i)
400        
401                let a = self.re;
402                let b = self.im;
403                let c = rhs.re;
404                let d = rhs.re;
405        
406                self.re = (a*c+b*d)/(c.mixed_powi(2)+d.mixed_powi(2));
407                self.im = (b*c-a*d)/(c.mixed_powi(2)+d.mixed_powi(2));
408            }
409        }
410    }
411}
412
413impl_core_ops_div_cartesian_for_cartesian!(Cartesian<T>);
414impl_core_ops_div_cartesian_for_cartesian!(&Cartesian<T>);
415impl_core_ops_div_cartesian_for_cartesian!(&mut Cartesian<T>);
416
417impl_core_ops_div_cartesian_for_cartesian!(num::Complex<T>);
418impl_core_ops_div_cartesian_for_cartesian!(&num::Complex<T>);
419impl_core_ops_div_cartesian_for_cartesian!(&mut num::Complex<T>);
420
421
422impl <T1: MixedNumSigned + MixedOps + MixedZero, T2: MixedReal + MixedOps + MixedNumConversion<T1>> core::ops::Div<T1> for Cartesian<T2> {
423    type Output = Self;
424    /// ## Example
425    /// 
426    /// ```
427    /// use mixed_num::*;
428    /// use mixed_num::traits::*;
429    /// 
430    /// let mut c_num = Cartesian::new(-2f32,4f32);
431    /// 
432    /// c_num = c_num/2f64;
433    /// assert_eq!{ c_num.to_string(), "-1+2i" };
434    /// ```
435    #[inline]
436    fn div(self, rhs: T1) -> Self {
437        if rhs == T1::mixed_zero() {
438            return Cartesian::new(T2::mixed_max_value(), T2::mixed_max_value());
439        }
440        return Cartesian::new(self.re/T2::mixed_from_num(rhs), self.im/T2::mixed_from_num(rhs));
441    }
442}
443
444impl <T1: MixedNumSigned + MixedOps + MixedZero, T2: MixedReal + MixedOps + MixedNumConversion<T1>> core::ops::DivAssign<T1> for Cartesian<T2> {
445    /// ## Example
446    /// 
447    /// ```
448    /// use mixed_num::*;
449    /// use mixed_num::traits::*;
450    /// 
451    /// let mut c_num = Cartesian::new(-2f32,4f32);
452    /// 
453    /// c_num /= 2f64;
454    /// assert_eq!{ c_num.to_string(), "-1+2i" };
455    /// ```
456    #[inline]
457    fn div_assign(&mut self, rhs: T1) {
458        if rhs == T1::mixed_zero() {
459            self.re =T2::mixed_max_value();
460            self.im =T2::mixed_max_value();
461        }
462        self.re = self.re/T2::mixed_from_num(rhs);
463        self.im = self.im/T2::mixed_from_num(rhs);
464    }
465}
466
467impl <T: MixedComplex + NewFromCartesian<T2>, T2: MixedNum + MixedNumSigned> Conj<T> for Cartesian<T2>
468{
469    /// Complex Conjugate of T.
470    /// 
471    /// ## Example
472    /// 
473    /// ```
474    /// use mixed_num::*;
475    /// use mixed_num::traits::*;
476    /// 
477    /// let mut c_num = Cartesian::new(-2f32,-4f32);
478    /// 
479    /// c_num = c_num.conj();
480    /// assert_eq!{ c_num.to_string(), "-2+4i" };
481    /// ```
482    fn conj( &self ) -> T {
483        return T::new_from_cartesian(self.re, -self.im);
484    }
485}
486
487
488impl <T: MixedReal + MixedNumSigned + MixedSin + MixedExp + core::ops::MulAssign> MixedExp for Cartesian<T>
489{
490    /// ## Example
491    /// 
492    /// ```
493    /// use mixed_num::*;
494    /// use mixed_num::traits::*;
495    /// 
496    /// let mut c_num = Cartesian::new(0f32,f32::mixed_pi());
497    /// 
498    /// c_num = c_num.mixed_exp();
499    /// assert_eq!{ c_num.to_string(), "-1+-0i" };
500    /// 
501    /// let mut c_num = Cartesian::new(1f32,f32::mixed_pi());
502    /// 
503    /// c_num = c_num.mixed_exp();
504    /// assert_eq!{ c_num.to_string(), "-2.7182817+-0i" };
505    /// 
506    /// let mut c_num = Cartesian::new(1f32,0f32);
507    /// 
508    /// c_num = c_num.mixed_exp();
509    /// assert_eq!{ c_num.to_string(), "2.7182817+0i" };
510    /// ```
511    fn mixed_exp( &self ) -> Cartesian<T> {
512        let (im, re) = self.im.mixed_sincos();
513        let scale = self.re.mixed_exp();
514        let mut r_value =  Self::new_from_cartesian(re, im);
515        r_value.re *= scale;
516        r_value.im *= scale;
517        return r_value;
518    }
519}
520
521impl <T: MixedNum + MixedNumSigned> MixedNum for Cartesian<T>
522{
523}