Skip to main content

simba/scalar/
complex.rs

1use num::{One, Signed, Zero};
2use num_traits::FromPrimitive;
3use std::any::Any;
4use std::fmt::{Debug, Display};
5use std::ops::Neg;
6use std::{f32, f64};
7
8use crate::scalar::{Field, RealField, SubsetOf, SupersetOf};
9#[cfg(all(not(feature = "std"), not(feature = "libm_force"), feature = "libm"))]
10use num::Float;
11//#[cfg(feature = "decimal")]
12//use decimal::d128;
13
14/// Trait shared by all complex fields and its subfields (like real numbers).
15///
16/// Complex numbers are equipped with functions that are commonly used on complex numbers and reals.
17/// The results of those functions only have to be approximately equal to the actual theoretical values.
18// TODO: SubsetOf should be removed when specialization will be supported by rustc. This will
19// allow a blanket impl: impl<T: Clone> SubsetOf<T> for T { ... }
20#[allow(missing_docs)]
21pub trait ComplexField:
22SubsetOf<Self>
23+ SupersetOf<f32>
24+ SupersetOf<f64>
25+ FromPrimitive
26+ Field<Element=Self, SimdBool=bool>
27+ Neg<Output=Self>
28+ Clone
29//    + MeetSemilattice
30//    + JoinSemilattice
31+ Send
32+ Sync
33+ Any
34+ 'static
35+ Debug
36+ Display
37{
38    type RealField: RealField;/// Builds a pure-real complex number from the given value.
39    fn from_real(re: Self::RealField) -> Self;
40
41    /// The real part of this complex number.
42    fn real(self) -> Self::RealField;
43
44    /// The imaginary part of this complex number.
45    fn imaginary(self) -> Self::RealField;
46
47    /// The modulus of this complex number.
48    fn modulus(self) -> Self::RealField;
49
50    /// The squared modulus of this complex number.
51    fn modulus_squared(self) -> Self::RealField;
52
53    /// The argument of this complex number.
54    fn argument(self) -> Self::RealField;
55
56    /// The sum of the absolute value of this complex number's real and imaginary part.
57    fn norm1(self) -> Self::RealField;
58
59    /// Multiplies this complex number by `factor`.
60    fn scale(self, factor: Self::RealField) -> Self;
61
62    /// Divides this complex number by `factor`.
63    fn unscale(self, factor: Self::RealField) -> Self;
64
65    /// The polar form of this complex number: (modulus, arg)
66    fn to_polar(self) -> (Self::RealField, Self::RealField) {
67        (self.clone().modulus(), self.argument())
68    }
69
70    /// The exponential form of this complex number: (modulus, e^{i arg})
71    fn to_exp(self) -> (Self::RealField, Self) {
72        let m = self.clone().modulus();
73
74        if !m.is_zero() {
75            (m.clone(), self.unscale(m))
76        } else {
77            (Self::RealField::zero(), Self::one())
78        }
79    }
80
81    /// The exponential part of this complex number: `self / self.modulus()`
82    fn signum(self) -> Self {
83        self.to_exp().1
84    }
85
86    fn floor(self) -> Self;
87    fn ceil(self) -> Self;
88    fn round(self) -> Self;
89    fn trunc(self) -> Self;
90    fn fract(self) -> Self;
91    fn mul_add(self, a: Self, b: Self) -> Self;
92
93    /// The absolute value of this complex number: `self / self.signum()`.
94    ///
95    /// This is equivalent to `self.modulus()`.
96    fn abs(self) -> Self::RealField;
97
98    /// Computes (self.conjugate() * self + other.conjugate() * other).sqrt()
99    fn hypot(self, other: Self) -> Self::RealField;
100
101    fn recip(self) -> Self;
102    fn conjugate(self) -> Self;
103    fn sin(self) -> Self;
104    fn cos(self) -> Self;
105    fn sin_cos(self) -> (Self, Self);
106    #[inline]
107    fn sinh_cosh(self) -> (Self, Self) {
108        (self.clone().sinh(), self.cosh())
109    }
110    fn tan(self) -> Self;
111    fn asin(self) -> Self;
112    fn acos(self) -> Self;
113    fn atan(self) -> Self;
114    fn sinh(self) -> Self;
115    fn cosh(self) -> Self;
116    fn tanh(self) -> Self;
117    fn asinh(self) -> Self;
118    fn acosh(self) -> Self;
119    fn atanh(self) -> Self;
120
121    /// Cardinal sine
122    #[inline]
123    fn sinc(self) -> Self {
124        if self.is_zero() {
125            Self::one()
126        } else {
127            self.clone().sin() / self
128        }
129    }
130
131    #[inline]
132    fn sinhc(self) -> Self {
133        if self.is_zero() {
134            Self::one()
135        } else {
136            self.clone().sinh() / self
137        }
138    }
139
140    /// Cardinal cos
141    #[inline]
142    fn cosc(self) -> Self {
143        if self.is_zero() {
144            Self::one()
145        } else {
146            self.clone().cos() / self
147        }
148    }
149
150    #[inline]
151    fn coshc(self) -> Self {
152        if self.is_zero() {
153            Self::one()
154        } else {
155            self.clone().cosh() / self
156        }
157    }
158
159    fn log(self, base: Self::RealField) -> Self;
160    fn log2(self) -> Self;
161    fn log10(self) -> Self;
162    fn ln(self) -> Self;
163    fn ln_1p(self) -> Self;
164    fn sqrt(self) -> Self;
165    fn exp(self) -> Self;
166    fn exp2(self) -> Self;
167    fn exp_m1(self) -> Self;
168    fn powi(self, n: i32) -> Self;
169    fn powf(self, n: Self::RealField) -> Self;
170    fn powc(self, n: Self) -> Self;
171    fn cbrt(self) -> Self;
172    fn is_finite(&self) -> bool;
173    fn try_sqrt(self) -> Option<Self>;
174}
175
176#[cfg(not(feature = "libm_force"))]
177macro_rules! impl_complex (
178    ($($T:ty, $M:ident, $libm: ident);*) => ($(
179        impl ComplexField for $T {
180            type RealField = $T;
181
182            #[inline]
183            fn from_real(re: Self::RealField) -> Self {
184                re
185            }
186
187            #[inline]
188            fn real(self) -> Self::RealField {
189                self
190            }
191
192            #[inline]
193            fn imaginary(self) -> Self::RealField {
194                Self::zero()
195            }
196
197            #[inline]
198            fn norm1(self) -> Self::RealField {
199                $libm::abs(self)
200            }
201
202            #[inline]
203            fn modulus(self) -> Self::RealField {
204                $libm::abs(self)
205            }
206
207            #[inline]
208            fn modulus_squared(self) -> Self::RealField {
209                self * self
210            }
211
212            #[inline]
213            fn argument(self) -> Self::RealField {
214                if self >= Self::zero() {
215                    Self::zero()
216                } else {
217                    Self::pi()
218                }
219            }
220
221            #[inline]
222            fn to_exp(self) -> (Self, Self) {
223                if self >= Self::zero() {
224                    (self, Self::one())
225                } else {
226                    (-self, -Self::one())
227                }
228            }
229
230            #[inline]
231            fn recip(self) -> Self {
232                $M::recip(self)
233            }
234
235            #[inline]
236            fn conjugate(self) -> Self {
237                self
238            }
239
240            #[inline]
241            fn scale(self, factor: Self::RealField) -> Self {
242                self * factor
243            }
244
245            #[inline]
246            fn unscale(self, factor: Self::RealField) -> Self {
247                self / factor
248            }
249
250            #[inline]
251            fn floor(self) -> Self {
252                $libm::floor(self)
253            }
254
255            #[inline]
256            fn ceil(self) -> Self {
257                $libm::ceil(self)
258            }
259
260            #[inline]
261            fn round(self) -> Self {
262                $libm::round(self)
263            }
264
265            #[inline]
266            fn trunc(self) -> Self {
267                $libm::trunc(self)
268            }
269
270            #[inline]
271            fn fract(self) -> Self {
272                $libm::fract(self)
273            }
274
275            #[inline]
276            fn abs(self) -> Self {
277                $libm::abs(self)
278            }
279
280            #[inline]
281            fn signum(self) -> Self {
282                Signed::signum(&self)
283            }
284
285            #[inline]
286            fn mul_add(self, a: Self, b: Self) -> Self {
287                $libm::mul_add(self, a, b)
288            }
289
290            #[cfg(feature = "std")]
291            #[inline]
292            fn powi(self, n: i32) -> Self {
293                self.powi(n)
294            }
295
296            #[cfg(not(feature = "std"))]
297            #[inline]
298            fn powi(self, n: i32) -> Self {
299                // TODO: is there a more accurate solution?
300                $libm::powf(self, n as $T)
301            }
302
303            #[inline]
304            fn powf(self, n: Self) -> Self {
305                $libm::powf(self, n)
306            }
307
308            #[inline]
309            fn powc(self, n: Self) -> Self {
310                // Same as powf.
311                $libm::powf(self, n)
312            }
313
314            #[inline]
315            fn sqrt(self) -> Self {
316                $libm::sqrt(self)
317            }
318
319            #[inline]
320            fn try_sqrt(self) -> Option<Self> {
321                if self >= Self::zero() {
322                    Some($libm::sqrt(self))
323                } else {
324                    None
325                }
326            }
327
328            #[inline]
329            fn exp(self) -> Self {
330                $libm::exp(self)
331            }
332
333            #[inline]
334            fn exp2(self) -> Self {
335                $libm::exp2(self)
336            }
337
338
339            #[inline]
340            fn exp_m1(self) -> Self {
341                $libm::exp_m1(self)
342            }
343
344            #[inline]
345            fn ln_1p(self) -> Self {
346                $libm::ln_1p(self)
347            }
348
349            #[inline]
350            fn ln(self) -> Self {
351                $libm::ln(self)
352            }
353
354            #[inline]
355            fn log(self, base: Self) -> Self {
356                $libm::log(self, base)
357            }
358
359            #[inline]
360            fn log2(self) -> Self {
361                $libm::log2(self)
362            }
363
364            #[inline]
365            fn log10(self) -> Self {
366                $libm::log10(self)
367            }
368
369            #[inline]
370            fn cbrt(self) -> Self {
371                $libm::cbrt(self)
372            }
373
374            #[inline]
375            fn hypot(self, other: Self) -> Self::RealField {
376                $libm::hypot(self, other)
377            }
378
379            #[inline]
380            fn sin(self) -> Self {
381                $libm::sin(self)
382            }
383
384            #[inline]
385            fn cos(self) -> Self {
386                $libm::cos(self)
387            }
388
389            #[inline]
390            fn tan(self) -> Self {
391                $libm::tan(self)
392            }
393
394            #[inline]
395            fn asin(self) -> Self {
396                $libm::asin(self)
397            }
398
399            #[inline]
400            fn acos(self) -> Self {
401                $libm::acos(self)
402            }
403
404            #[inline]
405            fn atan(self) -> Self {
406                $libm::atan(self)
407            }
408
409            #[inline]
410            fn sin_cos(self) -> (Self, Self) {
411                $libm::sin_cos(self)
412            }
413
414//            #[inline]
415//            fn exp_m1(self) -> Self {
416//                $libm::exp_m1(self)
417//            }
418//
419//            #[inline]
420//            fn ln_1p(self) -> Self {
421//                $libm::ln_1p(self)
422//            }
423//
424            #[inline]
425            fn sinh(self) -> Self {
426                $libm::sinh(self)
427            }
428
429            #[inline]
430            fn cosh(self) -> Self {
431                $libm::cosh(self)
432            }
433
434            #[inline]
435            fn tanh(self) -> Self {
436                $libm::tanh(self)
437            }
438
439            #[inline]
440            fn asinh(self) -> Self {
441                $libm::asinh(self)
442            }
443
444            #[inline]
445            fn acosh(self) -> Self {
446                $libm::acosh(self)
447            }
448
449            #[inline]
450            fn atanh(self) -> Self {
451                $libm::atanh(self)
452            }
453
454            #[inline]
455            fn is_finite(&self) -> bool {
456                $M::is_finite(*self)
457            }
458        }
459    )*)
460);
461
462#[cfg(all(not(feature = "std"), not(feature = "libm_force"), feature = "libm"))]
463impl_complex!(
464    f32, f32, Float;
465    f64, f64, Float
466);
467
468#[cfg(all(feature = "std", not(feature = "libm_force")))]
469impl_complex!(
470    f32,f32,f32;
471    f64,f64,f64
472);
473
474#[cfg(feature = "libm_force")]
475impl ComplexField for f32 {
476    type RealField = f32;
477
478    #[inline]
479    fn from_real(re: Self::RealField) -> Self {
480        re
481    }
482
483    #[inline]
484    fn real(self) -> Self::RealField {
485        self
486    }
487
488    #[inline]
489    fn imaginary(self) -> Self::RealField {
490        Self::zero()
491    }
492
493    #[inline]
494    fn norm1(self) -> Self::RealField {
495        libm_force::fabsf(self)
496    }
497
498    #[inline]
499    fn modulus(self) -> Self::RealField {
500        libm_force::fabsf(self)
501    }
502
503    #[inline]
504    fn modulus_squared(self) -> Self::RealField {
505        self * self
506    }
507
508    #[inline]
509    fn argument(self) -> Self::RealField {
510        if self >= Self::zero() {
511            Self::zero()
512        } else {
513            Self::pi()
514        }
515    }
516
517    #[inline]
518    fn to_exp(self) -> (Self, Self) {
519        if self >= Self::zero() {
520            (self, Self::one())
521        } else {
522            (-self, -Self::one())
523        }
524    }
525
526    #[inline]
527    fn recip(self) -> Self {
528        f32::recip(self)
529    }
530
531    #[inline]
532    fn conjugate(self) -> Self {
533        self
534    }
535
536    #[inline]
537    fn scale(self, factor: Self::RealField) -> Self {
538        self * factor
539    }
540
541    #[inline]
542    fn unscale(self, factor: Self::RealField) -> Self {
543        self / factor
544    }
545
546    #[inline]
547    fn floor(self) -> Self {
548        libm_force::floorf(self)
549    }
550
551    #[inline]
552    fn ceil(self) -> Self {
553        libm_force::ceilf(self)
554    }
555
556    #[inline]
557    fn round(self) -> Self {
558        libm_force::roundf(self)
559    }
560
561    #[inline]
562    fn trunc(self) -> Self {
563        libm_force::truncf(self)
564    }
565
566    #[inline]
567    fn fract(self) -> Self {
568        self - libm_force::truncf(self)
569    }
570
571    #[inline]
572    fn abs(self) -> Self {
573        libm_force::fabsf(self)
574    }
575
576    #[inline]
577    fn signum(self) -> Self {
578        Signed::signum(&self)
579    }
580
581    #[inline]
582    fn mul_add(self, a: Self, b: Self) -> Self {
583        libm_force::fmaf(self, a, b)
584    }
585
586    #[inline]
587    fn powi(self, n: i32) -> Self {
588        // TODO: implement a more accurate/efficient solution?
589        libm_force::powf(self, n as f32)
590    }
591
592    #[inline]
593    fn powf(self, n: Self) -> Self {
594        libm_force::powf(self, n)
595    }
596
597    #[inline]
598    fn powc(self, n: Self) -> Self {
599        // Same as powf.
600        libm_force::powf(self, n)
601    }
602
603    #[inline]
604    fn sqrt(self) -> Self {
605        libm_force::sqrtf(self)
606    }
607
608    #[inline]
609    fn try_sqrt(self) -> Option<Self> {
610        if self >= Self::zero() {
611            Some(libm_force::sqrtf(self))
612        } else {
613            None
614        }
615    }
616
617    #[inline]
618    fn exp(self) -> Self {
619        libm_force::expf(self)
620    }
621
622    #[inline]
623    fn exp2(self) -> Self {
624        libm_force::exp2f(self)
625    }
626
627    #[inline]
628    fn exp_m1(self) -> Self {
629        libm_force::expm1f(self)
630    }
631
632    #[inline]
633    fn ln_1p(self) -> Self {
634        libm_force::log1pf(self)
635    }
636
637    #[inline]
638    fn ln(self) -> Self {
639        libm_force::logf(self)
640    }
641
642    #[inline]
643    fn log(self, base: Self) -> Self {
644        libm_force::logf(self) / libm_force::logf(base)
645    }
646
647    #[inline]
648    fn log2(self) -> Self {
649        libm_force::log2f(self)
650    }
651
652    #[inline]
653    fn log10(self) -> Self {
654        libm_force::log10f(self)
655    }
656
657    #[inline]
658    fn cbrt(self) -> Self {
659        libm_force::cbrtf(self)
660    }
661
662    #[inline]
663    fn hypot(self, other: Self) -> Self::RealField {
664        libm_force::hypotf(self, other)
665    }
666
667    #[inline]
668    fn sin(self) -> Self {
669        libm_force::sinf(self)
670    }
671
672    #[inline]
673    fn cos(self) -> Self {
674        libm_force::cosf(self)
675    }
676
677    #[inline]
678    fn tan(self) -> Self {
679        libm_force::tanf(self)
680    }
681
682    #[inline]
683    fn asin(self) -> Self {
684        libm_force::asinf(self)
685    }
686
687    #[inline]
688    fn acos(self) -> Self {
689        libm_force::acosf(self)
690    }
691
692    #[inline]
693    fn atan(self) -> Self {
694        libm_force::atanf(self)
695    }
696
697    #[inline]
698    fn sin_cos(self) -> (Self, Self) {
699        libm_force::sincosf(self)
700    }
701
702    //            #[inline]
703    //            fn exp_m1(self) -> Self {
704    //                libm_force::exp_m1(self)
705    //            }
706    //
707    //            #[inline]
708    //            fn ln_1p(self) -> Self {
709    //                libm_force::ln_1p(self)
710    //            }
711    //
712    #[inline]
713    fn sinh(self) -> Self {
714        libm_force::sinhf(self)
715    }
716
717    #[inline]
718    fn cosh(self) -> Self {
719        libm_force::coshf(self)
720    }
721
722    #[inline]
723    fn tanh(self) -> Self {
724        libm_force::tanhf(self)
725    }
726
727    #[inline]
728    fn asinh(self) -> Self {
729        libm_force::asinhf(self)
730    }
731
732    #[inline]
733    fn acosh(self) -> Self {
734        libm_force::acoshf(self)
735    }
736
737    #[inline]
738    fn atanh(self) -> Self {
739        libm_force::atanhf(self)
740    }
741
742    #[inline]
743    fn is_finite(&self) -> bool {
744        f32::is_finite(*self)
745    }
746}
747
748#[cfg(feature = "libm_force")]
749impl ComplexField for f64 {
750    type RealField = f64;
751
752    #[inline]
753    fn from_real(re: Self::RealField) -> Self {
754        re
755    }
756
757    #[inline]
758    fn real(self) -> Self::RealField {
759        self
760    }
761
762    #[inline]
763    fn imaginary(self) -> Self::RealField {
764        Self::zero()
765    }
766
767    #[inline]
768    fn norm1(self) -> Self::RealField {
769        libm_force::fabs(self)
770    }
771
772    #[inline]
773    fn modulus(self) -> Self::RealField {
774        libm_force::fabs(self)
775    }
776
777    #[inline]
778    fn modulus_squared(self) -> Self::RealField {
779        self * self
780    }
781
782    #[inline]
783    fn argument(self) -> Self::RealField {
784        if self >= Self::zero() {
785            Self::zero()
786        } else {
787            Self::pi()
788        }
789    }
790
791    #[inline]
792    fn to_exp(self) -> (Self, Self) {
793        if self >= Self::zero() {
794            (self, Self::one())
795        } else {
796            (-self, -Self::one())
797        }
798    }
799
800    #[inline]
801    fn recip(self) -> Self {
802        f64::recip(self)
803    }
804
805    #[inline]
806    fn conjugate(self) -> Self {
807        self
808    }
809
810    #[inline]
811    fn scale(self, factor: Self::RealField) -> Self {
812        self * factor
813    }
814
815    #[inline]
816    fn unscale(self, factor: Self::RealField) -> Self {
817        self / factor
818    }
819
820    #[inline]
821    fn floor(self) -> Self {
822        libm_force::floor(self)
823    }
824
825    #[inline]
826    fn ceil(self) -> Self {
827        libm_force::ceil(self)
828    }
829
830    #[inline]
831    fn round(self) -> Self {
832        libm_force::round(self)
833    }
834
835    #[inline]
836    fn trunc(self) -> Self {
837        libm_force::trunc(self)
838    }
839
840    #[inline]
841    fn fract(self) -> Self {
842        self - libm_force::trunc(self)
843    }
844
845    #[inline]
846    fn abs(self) -> Self {
847        libm_force::fabs(self)
848    }
849
850    #[inline]
851    fn signum(self) -> Self {
852        Signed::signum(&self)
853    }
854
855    #[inline]
856    fn mul_add(self, a: Self, b: Self) -> Self {
857        libm_force::fma(self, a, b)
858    }
859
860    #[inline]
861    fn powi(self, n: i32) -> Self {
862        // TODO: implement a more accurate solution?
863        libm_force::pow(self, n as f64)
864    }
865
866    #[inline]
867    fn powf(self, n: Self) -> Self {
868        libm_force::pow(self, n)
869    }
870
871    #[inline]
872    fn powc(self, n: Self) -> Self {
873        // Same as powf.
874        libm_force::pow(self, n)
875    }
876
877    #[inline]
878    fn sqrt(self) -> Self {
879        libm_force::sqrt(self)
880    }
881
882    #[inline]
883    fn try_sqrt(self) -> Option<Self> {
884        if self >= Self::zero() {
885            Some(libm_force::sqrt(self))
886        } else {
887            None
888        }
889    }
890
891    #[inline]
892    fn exp(self) -> Self {
893        libm_force::exp(self)
894    }
895
896    #[inline]
897    fn exp2(self) -> Self {
898        libm_force::exp2(self)
899    }
900
901    #[inline]
902    fn exp_m1(self) -> Self {
903        libm_force::expm1(self)
904    }
905
906    #[inline]
907    fn ln_1p(self) -> Self {
908        libm_force::log1p(self)
909    }
910
911    #[inline]
912    fn ln(self) -> Self {
913        libm_force::log(self)
914    }
915
916    #[inline]
917    fn log(self, base: Self) -> Self {
918        libm_force::log(self) / libm_force::log(base)
919    }
920
921    #[inline]
922    fn log2(self) -> Self {
923        libm_force::log2(self)
924    }
925
926    #[inline]
927    fn log10(self) -> Self {
928        libm_force::log10(self)
929    }
930
931    #[inline]
932    fn cbrt(self) -> Self {
933        libm_force::cbrt(self)
934    }
935
936    #[inline]
937    fn hypot(self, other: Self) -> Self::RealField {
938        libm_force::hypot(self, other)
939    }
940
941    #[inline]
942    fn sin(self) -> Self {
943        libm_force::sin(self)
944    }
945
946    #[inline]
947    fn cos(self) -> Self {
948        libm_force::cos(self)
949    }
950
951    #[inline]
952    fn tan(self) -> Self {
953        libm_force::tan(self)
954    }
955
956    #[inline]
957    fn asin(self) -> Self {
958        libm_force::asin(self)
959    }
960
961    #[inline]
962    fn acos(self) -> Self {
963        libm_force::acos(self)
964    }
965
966    #[inline]
967    fn atan(self) -> Self {
968        libm_force::atan(self)
969    }
970
971    #[inline]
972    fn sin_cos(self) -> (Self, Self) {
973        libm_force::sincos(self)
974    }
975
976    //            #[inline]
977    //            fn exp_m1(self) -> Self {
978    //                libm_force::exp_m1(self)
979    //            }
980    //
981    //            #[inline]
982    //            fn ln_1p(self) -> Self {
983    //                libm_force::ln_1p(self)
984    //            }
985    //
986    #[inline]
987    fn sinh(self) -> Self {
988        libm_force::sinh(self)
989    }
990
991    #[inline]
992    fn cosh(self) -> Self {
993        libm_force::cosh(self)
994    }
995
996    #[inline]
997    fn tanh(self) -> Self {
998        libm_force::tanh(self)
999    }
1000
1001    #[inline]
1002    fn asinh(self) -> Self {
1003        libm_force::asinh(self)
1004    }
1005
1006    #[inline]
1007    fn acosh(self) -> Self {
1008        libm_force::acosh(self)
1009    }
1010
1011    #[inline]
1012    fn atanh(self) -> Self {
1013        libm_force::atanh(self)
1014    }
1015
1016    #[inline]
1017    fn is_finite(&self) -> bool {
1018        f64::is_finite(*self)
1019    }
1020}
1021
1022//#[cfg(feature = "decimal")]
1023//impl_real!(d128, d128, d128);
1024
1025// NOTE: all those impls have been copied-pasted to `simd_impl.rs` to implement
1026// SimdComplexField for Complex.
1027impl<N: RealField + PartialOrd> ComplexField for num_complex::Complex<N> {
1028    type RealField = N;
1029
1030    #[inline]
1031    fn from_real(re: Self::RealField) -> Self {
1032        Self::new(re, Self::RealField::zero())
1033    }
1034
1035    #[inline]
1036    fn real(self) -> Self::RealField {
1037        self.re
1038    }
1039
1040    #[inline]
1041    fn imaginary(self) -> Self::RealField {
1042        self.im
1043    }
1044
1045    #[inline]
1046    fn argument(self) -> Self::RealField {
1047        self.im.atan2(self.re)
1048    }
1049
1050    #[inline]
1051    fn modulus(self) -> Self::RealField {
1052        self.re.hypot(self.im)
1053    }
1054
1055    #[inline]
1056    fn modulus_squared(self) -> Self::RealField {
1057        self.re.clone() * self.re + self.im.clone() * self.im
1058    }
1059
1060    #[inline]
1061    fn norm1(self) -> Self::RealField {
1062        self.re.abs() + self.im.abs()
1063    }
1064
1065    #[inline]
1066    fn recip(self) -> Self {
1067        Self::one() / self
1068    }
1069
1070    #[inline]
1071    fn conjugate(self) -> Self {
1072        self.conj()
1073    }
1074
1075    #[inline]
1076    fn scale(self, factor: Self::RealField) -> Self {
1077        self * factor
1078    }
1079
1080    #[inline]
1081    fn unscale(self, factor: Self::RealField) -> Self {
1082        self / factor
1083    }
1084
1085    #[inline]
1086    fn floor(self) -> Self {
1087        Self::new(self.re.floor(), self.im.floor())
1088    }
1089
1090    #[inline]
1091    fn ceil(self) -> Self {
1092        Self::new(self.re.ceil(), self.im.ceil())
1093    }
1094
1095    #[inline]
1096    fn round(self) -> Self {
1097        Self::new(self.re.round(), self.im.round())
1098    }
1099
1100    #[inline]
1101    fn trunc(self) -> Self {
1102        Self::new(self.re.trunc(), self.im.trunc())
1103    }
1104
1105    #[inline]
1106    fn fract(self) -> Self {
1107        Self::new(self.re.fract(), self.im.fract())
1108    }
1109
1110    #[inline]
1111    fn mul_add(self, a: Self, b: Self) -> Self {
1112        self * a + b
1113    }
1114
1115    #[inline]
1116    fn abs(self) -> Self::RealField {
1117        self.modulus()
1118    }
1119
1120    #[inline]
1121    fn exp2(self) -> Self {
1122        let _2 = N::one() + N::one();
1123        num_complex::Complex::new(_2, N::zero()).powc(self)
1124    }
1125
1126    #[inline]
1127    fn exp_m1(self) -> Self {
1128        self.exp() - Self::one()
1129    }
1130
1131    #[inline]
1132    fn ln_1p(self) -> Self {
1133        (Self::one() + self).ln()
1134    }
1135
1136    #[inline]
1137    fn log2(self) -> Self {
1138        let _2 = N::one() + N::one();
1139        self.log(_2)
1140    }
1141
1142    #[inline]
1143    fn log10(self) -> Self {
1144        let _10 = N::from_subset(&10.0f64);
1145        self.log(_10)
1146    }
1147
1148    #[inline]
1149    fn cbrt(self) -> Self {
1150        let one_third = N::from_subset(&(1.0 / 3.0));
1151        self.powf(one_third)
1152    }
1153
1154    #[inline]
1155    fn powi(self, n: i32) -> Self {
1156        // TODO: is there a more accurate solution?
1157        let n = N::from_subset(&(n as f64));
1158        self.powf(n)
1159    }
1160
1161    #[inline]
1162    fn is_finite(&self) -> bool {
1163        self.re.is_finite() && self.im.is_finite()
1164    }
1165
1166    /*
1167     *
1168     *
1169     * Unfortunately we are forced to copy-paste all
1170     * those impls from https://github.com/rust-num/num-complex/blob/master/src/lib.rs
1171     * to avoid requiring `std`.
1172     *
1173     *
1174     */
1175    /// Computes `e^(self)`, where `e` is the base of the natural logarithm.
1176    #[inline]
1177    fn exp(self) -> Self {
1178        // formula: e^(a + bi) = e^a (cos(b) + i*sin(b))
1179        // = from_polar(e^a, b)
1180        complex_from_polar(self.re.exp(), self.im)
1181    }
1182
1183    /// Computes the principal value of natural logarithm of `self`.
1184    ///
1185    /// This function has one branch cut:
1186    ///
1187    /// * `(-∞, 0]`, continuous from above.
1188    ///
1189    /// The branch satisfies `-π ≤ arg(ln(z)) ≤ π`.
1190    #[inline]
1191    fn ln(self) -> Self {
1192        // formula: ln(z) = ln|z| + i*arg(z)
1193        let (r, theta) = self.to_polar();
1194        Self::new(r.ln(), theta)
1195    }
1196
1197    /// Computes the principal value of the square root of `self`.
1198    ///
1199    /// This function has one branch cut:
1200    ///
1201    /// * `(-∞, 0)`, continuous from above.
1202    ///
1203    /// The branch satisfies `-π/2 ≤ arg(sqrt(z)) ≤ π/2`.
1204    #[inline]
1205    fn sqrt(self) -> Self {
1206        // formula: sqrt(r e^(it)) = sqrt(r) e^(it/2)
1207        let two = N::one() + N::one();
1208        let (r, theta) = self.to_polar();
1209        complex_from_polar(r.sqrt(), theta / two)
1210    }
1211
1212    #[inline]
1213    fn try_sqrt(self) -> Option<Self> {
1214        Some(self.sqrt())
1215    }
1216
1217    #[inline]
1218    fn hypot(self, b: Self) -> Self::RealField {
1219        (self.modulus_squared() + b.modulus_squared()).sqrt()
1220    }
1221
1222    /// Raises `self` to a floating point power.
1223    #[inline]
1224    fn powf(self, exp: Self::RealField) -> Self {
1225        // formula: x^y = (ρ e^(i θ))^y = ρ^y e^(i θ y)
1226        // = from_polar(ρ^y, θ y)
1227        let (r, theta) = self.to_polar();
1228        complex_from_polar(r.powf(exp.clone()), theta * exp)
1229    }
1230
1231    /// Returns the logarithm of `self` with respect to an arbitrary base.
1232    #[inline]
1233    fn log(self, base: N) -> Self {
1234        // formula: log_y(x) = log_y(ρ e^(i θ))
1235        // = log_y(ρ) + log_y(e^(i θ)) = log_y(ρ) + ln(e^(i θ)) / ln(y)
1236        // = log_y(ρ) + i θ / ln(y)
1237        let (r, theta) = self.to_polar();
1238        Self::new(r.log(base.clone()), theta / base.ln())
1239    }
1240
1241    /// Raises `self` to a complex power.
1242    #[inline]
1243    fn powc(self, exp: Self) -> Self {
1244        // formula: x^y = (a + i b)^(c + i d)
1245        // = (ρ e^(i θ))^c (ρ e^(i θ))^(i d)
1246        //    where ρ=|x| and θ=arg(x)
1247        // = ρ^c e^(−d θ) e^(i c θ) ρ^(i d)
1248        // = p^c e^(−d θ) (cos(c θ)
1249        //   + i sin(c θ)) (cos(d ln(ρ)) + i sin(d ln(ρ)))
1250        // = p^c e^(−d θ) (
1251        //   cos(c θ) cos(d ln(ρ)) − sin(c θ) sin(d ln(ρ))
1252        //   + i(cos(c θ) sin(d ln(ρ)) + sin(c θ) cos(d ln(ρ))))
1253        // = p^c e^(−d θ) (cos(c θ + d ln(ρ)) + i sin(c θ + d ln(ρ)))
1254        // = from_polar(p^c e^(−d θ), c θ + d ln(ρ))
1255        let (r, theta) = self.to_polar();
1256        complex_from_polar(
1257            r.clone().powf(exp.re.clone()) * (-exp.im.clone() * theta.clone()).exp(),
1258            exp.re * theta + exp.im * r.ln(),
1259        )
1260    }
1261
1262    /*
1263    /// Raises a floating point number to the complex power `self`.
1264    #[inline]
1265    fn expf(&self, base: T) -> Self {
1266        // formula: x^(a+bi) = x^a x^bi = x^a e^(b ln(x) i)
1267        // = from_polar(x^a, b ln(x))
1268        Self::from_polar(&base.powf(self.re), &(self.im * base.ln()))
1269    }
1270    */
1271
1272    /// Computes the sine of `self`.
1273    #[inline]
1274    fn sin(self) -> Self {
1275        // formula: sin(a + bi) = sin(a)cosh(b) + i*cos(a)sinh(b)
1276        Self::new(
1277            self.re.clone().sin() * self.im.clone().cosh(),
1278            self.re.cos() * self.im.sinh(),
1279        )
1280    }
1281
1282    /// Computes the cosine of `self`.
1283    #[inline]
1284    fn cos(self) -> Self {
1285        // formula: cos(a + bi) = cos(a)cosh(b) - i*sin(a)sinh(b)
1286        Self::new(
1287            self.re.clone().cos() * self.im.clone().cosh(),
1288            -self.re.sin() * self.im.sinh(),
1289        )
1290    }
1291
1292    #[inline]
1293    fn sin_cos(self) -> (Self, Self) {
1294        let (rsin, rcos) = self.re.sin_cos();
1295        let (isinh, icosh) = self.im.sinh_cosh();
1296        let sin = Self::new(rsin.clone() * icosh.clone(), rcos.clone() * isinh.clone());
1297        let cos = Self::new(rcos * icosh, -rsin * isinh);
1298
1299        (sin, cos)
1300    }
1301
1302    /// Computes the tangent of `self`.
1303    #[inline]
1304    fn tan(self) -> Self {
1305        // formula: tan(a + bi) = (sin(2a) + i*sinh(2b))/(cos(2a) + cosh(2b))
1306        let (two_re, two_im) = (self.re.clone() + self.re, self.im.clone() + self.im);
1307        Self::new(two_re.clone().sin(), two_im.clone().sinh()).unscale(two_re.cos() + two_im.cosh())
1308    }
1309
1310    /// Computes the principal value of the inverse sine of `self`.
1311    ///
1312    /// This function has two branch cuts:
1313    ///
1314    /// * `(-∞, -1)`, continuous from above.
1315    /// * `(1, ∞)`, continuous from below.
1316    ///
1317    /// The branch satisfies `-π/2 ≤ Re(asin(z)) ≤ π/2`.
1318    #[inline]
1319    fn asin(self) -> Self {
1320        // formula: arcsin(z) = -i ln(sqrt(1-z^2) + iz)
1321        let i = Self::i();
1322        -i.clone() * ((Self::one() - self.clone() * self.clone()).sqrt() + i * self).ln()
1323    }
1324
1325    /// Computes the principal value of the inverse cosine of `self`.
1326    ///
1327    /// This function has two branch cuts:
1328    ///
1329    /// * `(-∞, -1)`, continuous from above.
1330    /// * `(1, ∞)`, continuous from below.
1331    ///
1332    /// The branch satisfies `0 ≤ Re(acos(z)) ≤ π`.
1333    #[inline]
1334    fn acos(self) -> Self {
1335        // formula: arccos(z) = -i ln(i sqrt(1-z^2) + z)
1336        let i = Self::i();
1337        -i.clone() * (i * (Self::one() - self.clone() * self.clone()).sqrt() + self).ln()
1338    }
1339
1340    /// Computes the principal value of the inverse tangent of `self`.
1341    ///
1342    /// This function has two branch cuts:
1343    ///
1344    /// * `(-∞i, -i]`, continuous from the left.
1345    /// * `[i, ∞i)`, continuous from the right.
1346    ///
1347    /// The branch satisfies `-π/2 ≤ Re(atan(z)) ≤ π/2`.
1348    #[inline]
1349    fn atan(self) -> Self {
1350        // formula: arctan(z) = (ln(1+iz) - ln(1-iz))/(2i)
1351        let i = Self::i();
1352        let one = Self::one();
1353        let two = one.clone() + one.clone();
1354
1355        if self == i {
1356            return Self::new(N::zero(), N::one() / N::zero());
1357        } else if self == -i.clone() {
1358            return Self::new(N::zero(), -N::one() / N::zero());
1359        }
1360
1361        ((one.clone() + i.clone() * self.clone()).ln() - (one - i.clone() * self).ln()) / (two * i)
1362    }
1363
1364    /// Computes the hyperbolic sine of `self`.
1365    #[inline]
1366    fn sinh(self) -> Self {
1367        // formula: sinh(a + bi) = sinh(a)cos(b) + i*cosh(a)sin(b)
1368        Self::new(
1369            self.re.clone().sinh() * self.im.clone().cos(),
1370            self.re.cosh() * self.im.sin(),
1371        )
1372    }
1373
1374    /// Computes the hyperbolic cosine of `self`.
1375    #[inline]
1376    fn cosh(self) -> Self {
1377        // formula: cosh(a + bi) = cosh(a)cos(b) + i*sinh(a)sin(b)
1378        Self::new(
1379            self.re.clone().cosh() * self.im.clone().cos(),
1380            self.re.sinh() * self.im.sin(),
1381        )
1382    }
1383
1384    #[inline]
1385    fn sinh_cosh(self) -> (Self, Self) {
1386        let (rsinh, rcosh) = self.re.sinh_cosh();
1387        let (isin, icos) = self.im.sin_cos();
1388        let sin = Self::new(rsinh.clone() * icos.clone(), rcosh.clone() * isin.clone());
1389        let cos = Self::new(rcosh * icos, rsinh * isin);
1390
1391        (sin, cos)
1392    }
1393
1394    /// Computes the hyperbolic tangent of `self`.
1395    #[inline]
1396    fn tanh(self) -> Self {
1397        // formula: tanh(a + bi) = (sinh(2a) + i*sin(2b))/(cosh(2a) + cos(2b))
1398        let (two_re, two_im) = (self.re.clone() + self.re, self.im.clone() + self.im);
1399        Self::new(two_re.clone().sinh(), two_im.clone().sin()).unscale(two_re.cosh() + two_im.cos())
1400    }
1401
1402    /// Computes the principal value of inverse hyperbolic sine of `self`.
1403    ///
1404    /// This function has two branch cuts:
1405    ///
1406    /// * `(-∞i, -i)`, continuous from the left.
1407    /// * `(i, ∞i)`, continuous from the right.
1408    ///
1409    /// The branch satisfies `-π/2 ≤ Im(asinh(z)) ≤ π/2`.
1410    #[inline]
1411    fn asinh(self) -> Self {
1412        // formula: arcsinh(z) = ln(z + sqrt(1+z^2))
1413        let one = Self::one();
1414        (self.clone() + (one + self.clone() * self).sqrt()).ln()
1415    }
1416
1417    /// Computes the principal value of inverse hyperbolic cosine of `self`.
1418    ///
1419    /// This function has one branch cut:
1420    ///
1421    /// * `(-∞, 1)`, continuous from above.
1422    ///
1423    /// The branch satisfies `-π ≤ Im(acosh(z)) ≤ π` and `0 ≤ Re(acosh(z)) < ∞`.
1424    #[inline]
1425    fn acosh(self) -> Self {
1426        // formula: arccosh(z) = 2 ln(sqrt((z+1)/2) + sqrt((z-1)/2))
1427        let one = Self::one();
1428        let two = one.clone() + one.clone();
1429        two.clone()
1430            * (((self.clone() + one.clone()) / two.clone()).sqrt() + ((self - one) / two).sqrt())
1431                .ln()
1432    }
1433
1434    /// Computes the principal value of inverse hyperbolic tangent of `self`.
1435    ///
1436    /// This function has two branch cuts:
1437    ///
1438    /// * `(-∞, -1]`, continuous from above.
1439    /// * `[1, ∞)`, continuous from below.
1440    ///
1441    /// The branch satisfies `-π/2 ≤ Im(atanh(z)) ≤ π/2`.
1442    #[inline]
1443    fn atanh(self) -> Self {
1444        // formula: arctanh(z) = (ln(1+z) - ln(1-z))/2
1445        let one = Self::one();
1446        let two = one.clone() + one.clone();
1447        if self == one {
1448            return Self::new(N::one() / N::zero(), N::zero());
1449        } else if self == -one.clone() {
1450            return Self::new(-N::one() / N::zero(), N::zero());
1451        }
1452        ((one.clone() + self.clone()).ln() - (one - self).ln()) / two
1453    }
1454}
1455
1456#[inline]
1457fn complex_from_polar<N: RealField>(r: N, theta: N) -> num_complex::Complex<N> {
1458    num_complex::Complex::new(r.clone() * theta.clone().cos(), r * theta.sin())
1459}