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(
10 any(target_arch = "nvptx", target_arch = "nvptx64"),
11 not(feature = "std"),
12 not(feature = "libm_force"),
13 feature = "cuda"
14))]
15use cuda_std::GpuFloat;
16#[cfg(all(not(feature = "std"), not(feature = "libm_force"), feature = "libm"))]
17use num::Float;
18macro_rules! complex_trait_methods(
22 ($RealField: ident $(, $prefix: ident)*) => {
23 paste::item! {
24 fn [<from_ $($prefix)* real>](re: Self::$RealField) -> Self;
26
27 fn [<$($prefix)* real>](self) -> Self::$RealField;
29
30 fn [<$($prefix)* imaginary>](self) -> Self::$RealField;
32
33 fn [<$($prefix)* modulus>](self) -> Self::$RealField;
35
36 fn [<$($prefix)* modulus_squared>](self) -> Self::$RealField;
38
39 fn [<$($prefix)* argument>](self) -> Self::$RealField;
41
42 fn [<$($prefix)* norm1>](self) -> Self::$RealField;
44
45 fn [<$($prefix)* scale>](self, factor: Self::$RealField) -> Self;
47
48 fn [<$($prefix)* unscale>](self, factor: Self::$RealField) -> Self;
50
51 fn [<$($prefix)* to_polar>](self) -> (Self::$RealField, Self::$RealField) {
53 (self.clone().[<$($prefix)* modulus>](), self.[<$($prefix)* argument>]())
54 }
55
56 fn [<$($prefix)* to_exp>](self) -> (Self::$RealField, Self) {
58 let m = self.clone().[<$($prefix)* modulus>]();
59
60 if !m.is_zero() {
61 (m.clone(), self.[<$($prefix)* unscale>](m))
62 } else {
63 (Self::$RealField::zero(), Self::one())
64 }
65 }
66
67 fn [<$($prefix)* signum>](self) -> Self {
69 self.[<$($prefix)* to_exp>]().1
70 }
71
72 fn [<$($prefix)* floor>](self) -> Self;
73 fn [<$($prefix)* ceil>](self) -> Self;
74 fn [<$($prefix)* round>](self) -> Self;
75 fn [<$($prefix)* trunc>](self) -> Self;
76 fn [<$($prefix)* fract>](self) -> Self;
77 fn [<$($prefix)* mul_add>](self, a: Self, b: Self) -> Self;
78
79 fn [<$($prefix)* abs>](self) -> Self::$RealField;
83
84 fn [<$($prefix)* hypot>](self, other: Self) -> Self::$RealField;
86
87 fn [<$($prefix)* recip>](self) -> Self;
88 fn [<$($prefix)* conjugate>](self) -> Self;
89 fn [<$($prefix)* sin>](self) -> Self;
90 fn [<$($prefix)* cos>](self) -> Self;
91 fn [<$($prefix)* sin_cos>](self) -> (Self, Self);
92 #[inline]
93 fn [<$($prefix)* sinh_cosh>](self) -> (Self, Self) {
94 (self.clone().[<$($prefix)* sinh>](), self.[<$($prefix)* cosh>]())
95 }
96 fn [<$($prefix)* tan>](self) -> Self;
97 fn [<$($prefix)* asin>](self) -> Self;
98 fn [<$($prefix)* acos>](self) -> Self;
99 fn [<$($prefix)* atan>](self) -> Self;
100 fn [<$($prefix)* sinh>](self) -> Self;
101 fn [<$($prefix)* cosh>](self) -> Self;
102 fn [<$($prefix)* tanh>](self) -> Self;
103 fn [<$($prefix)* asinh>](self) -> Self;
104 fn [<$($prefix)* acosh>](self) -> Self;
105 fn [<$($prefix)* atanh>](self) -> Self;
106
107 #[inline]
109 fn [<$($prefix)* sinc>](self) -> Self {
110 if self.is_zero() {
111 Self::one()
112 } else {
113 self.clone().[<$($prefix)* sin>]() / self
114 }
115 }
116
117 #[inline]
118 fn [<$($prefix)* sinhc>](self) -> Self {
119 if self.is_zero() {
120 Self::one()
121 } else {
122 self.clone().[<$($prefix)* sinh>]() / self
123 }
124 }
125
126 #[inline]
128 fn [<$($prefix)* cosc>](self) -> Self {
129 if self.is_zero() {
130 Self::one()
131 } else {
132 self.clone().[<$($prefix)* cos>]() / self
133 }
134 }
135
136 #[inline]
137 fn [<$($prefix)* coshc>](self) -> Self {
138 if self.is_zero() {
139 Self::one()
140 } else {
141 self.clone().[<$($prefix)* cosh>]() / self
142 }
143 }
144
145 fn [<$($prefix)* log>](self, base: Self::$RealField) -> Self;
146 fn [<$($prefix)* log2>](self) -> Self;
147 fn [<$($prefix)* log10>](self) -> Self;
148 fn [<$($prefix)* ln>](self) -> Self;
149 fn [<$($prefix)* ln_1p>](self) -> Self;
150 fn [<$($prefix)* sqrt>](self) -> Self;
151 fn [<$($prefix)* exp>](self) -> Self;
152 fn [<$($prefix)* exp2>](self) -> Self;
153 fn [<$($prefix)* exp_m1>](self) -> Self;
154 fn [<$($prefix)* powi>](self, n: i32) -> Self;
155 fn [<$($prefix)* powf>](self, n: Self::$RealField) -> Self;
156 fn [<$($prefix)* powc>](self, n: Self) -> Self;
157 fn [<$($prefix)* cbrt>](self) -> Self;
158 }
159 }
160);
161
162#[allow(missing_docs)]
169pub trait ComplexField:
170 SubsetOf<Self>
171 + SupersetOf<f64>
172 + FromPrimitive
173 + Field<Element = Self, SimdBool = bool>
174 + Neg<Output = Self>
175 + Clone
176+ Send
179 + Sync
180 + Any
181 + 'static
182 + Debug
183 + Display
184{
185 type RealField: RealField;
186 complex_trait_methods!(RealField);
187
188 fn is_finite(&self) -> bool;
189 fn try_sqrt(self) -> Option<Self>;
190}
191
192#[cfg(not(feature = "libm_force"))]
193macro_rules! impl_complex(
194 ($($T:ty, $M:ident, $libm: ident);*) => ($(
195 impl ComplexField for $T {
196 type RealField = $T;
197
198 #[inline]
199 fn from_real(re: Self::RealField) -> Self {
200 re
201 }
202
203 #[inline]
204 fn real(self) -> Self::RealField {
205 self
206 }
207
208 #[inline]
209 fn imaginary(self) -> Self::RealField {
210 Self::zero()
211 }
212
213 #[inline]
214 fn norm1(self) -> Self::RealField {
215 $libm::abs(self)
216 }
217
218 #[inline]
219 fn modulus(self) -> Self::RealField {
220 $libm::abs(self)
221 }
222
223 #[inline]
224 fn modulus_squared(self) -> Self::RealField {
225 self * self
226 }
227
228 #[inline]
229 fn argument(self) -> Self::RealField {
230 if self >= Self::zero() {
231 Self::zero()
232 } else {
233 Self::pi()
234 }
235 }
236
237 #[inline]
238 fn to_exp(self) -> (Self, Self) {
239 if self >= Self::zero() {
240 (self, Self::one())
241 } else {
242 (-self, -Self::one())
243 }
244 }
245
246 #[inline]
247 fn recip(self) -> Self {
248 $M::recip(self)
249 }
250
251 #[inline]
252 fn conjugate(self) -> Self {
253 self
254 }
255
256 #[inline]
257 fn scale(self, factor: Self::RealField) -> Self {
258 self * factor
259 }
260
261 #[inline]
262 fn unscale(self, factor: Self::RealField) -> Self {
263 self / factor
264 }
265
266 #[inline]
267 fn floor(self) -> Self {
268 $libm::floor(self)
269 }
270
271 #[inline]
272 fn ceil(self) -> Self {
273 $libm::ceil(self)
274 }
275
276 #[inline]
277 fn round(self) -> Self {
278 $libm::round(self)
279 }
280
281 #[inline]
282 fn trunc(self) -> Self {
283 $libm::trunc(self)
284 }
285
286 #[inline]
287 fn fract(self) -> Self {
288 $libm::fract(self)
289 }
290
291 #[inline]
292 fn abs(self) -> Self {
293 $libm::abs(self)
294 }
295
296 #[inline]
297 fn signum(self) -> Self {
298 Signed::signum(&self)
299 }
300
301 #[inline]
302 fn mul_add(self, a: Self, b: Self) -> Self {
303 $libm::mul_add(self, a, b)
304 }
305
306 #[cfg(feature = "std")]
307 #[inline]
308 fn powi(self, n: i32) -> Self {
309 self.powi(n)
310 }
311
312 #[cfg(not(feature = "std"))]
313 #[inline]
314 fn powi(self, n: i32) -> Self {
315 $libm::powf(self, n as $T)
317 }
318
319 #[inline]
320 fn powf(self, n: Self) -> Self {
321 $libm::powf(self, n)
322 }
323
324 #[inline]
325 fn powc(self, n: Self) -> Self {
326 $libm::powf(self, n)
328 }
329
330 #[inline]
331 fn sqrt(self) -> Self {
332 $libm::sqrt(self)
333 }
334
335 #[inline]
336 fn try_sqrt(self) -> Option<Self> {
337 if self >= Self::zero() {
338 Some($libm::sqrt(self))
339 } else {
340 None
341 }
342 }
343
344 #[inline]
345 fn exp(self) -> Self {
346 $libm::exp(self)
347 }
348
349 #[inline]
350 fn exp2(self) -> Self {
351 $libm::exp2(self)
352 }
353
354
355 #[inline]
356 fn exp_m1(self) -> Self {
357 $libm::exp_m1(self)
358 }
359
360 #[inline]
361 fn ln_1p(self) -> Self {
362 $libm::ln_1p(self)
363 }
364
365 #[inline]
366 fn ln(self) -> Self {
367 $libm::ln(self)
368 }
369
370 #[inline]
371 fn log(self, base: Self) -> Self {
372 $libm::log(self, base)
373 }
374
375 #[inline]
376 fn log2(self) -> Self {
377 $libm::log2(self)
378 }
379
380 #[inline]
381 fn log10(self) -> Self {
382 $libm::log10(self)
383 }
384
385 #[inline]
386 fn cbrt(self) -> Self {
387 $libm::cbrt(self)
388 }
389
390 #[inline]
391 fn hypot(self, other: Self) -> Self::RealField {
392 $libm::hypot(self, other)
393 }
394
395 #[inline]
396 fn sin(self) -> Self {
397 $libm::sin(self)
398 }
399
400 #[inline]
401 fn cos(self) -> Self {
402 $libm::cos(self)
403 }
404
405 #[inline]
406 fn tan(self) -> Self {
407 $libm::tan(self)
408 }
409
410 #[inline]
411 fn asin(self) -> Self {
412 $libm::asin(self)
413 }
414
415 #[inline]
416 fn acos(self) -> Self {
417 $libm::acos(self)
418 }
419
420 #[inline]
421 fn atan(self) -> Self {
422 $libm::atan(self)
423 }
424
425 #[inline]
426 fn sin_cos(self) -> (Self, Self) {
427 $libm::sin_cos(self)
428 }
429
430#[inline]
441 fn sinh(self) -> Self {
442 $libm::sinh(self)
443 }
444
445 #[inline]
446 fn cosh(self) -> Self {
447 $libm::cosh(self)
448 }
449
450 #[inline]
451 fn tanh(self) -> Self {
452 $libm::tanh(self)
453 }
454
455 #[inline]
456 fn asinh(self) -> Self {
457 $libm::asinh(self)
458 }
459
460 #[inline]
461 fn acosh(self) -> Self {
462 $libm::acosh(self)
463 }
464
465 #[inline]
466 fn atanh(self) -> Self {
467 $libm::atanh(self)
468 }
469
470 #[inline]
471 fn is_finite(&self) -> bool {
472 $M::is_finite(*self)
473 }
474 }
475 )*)
476);
477
478#[cfg(all(
479 not(target_arch = "nvptx"),
480 not(target_arch = "nvptx64"),
481 not(feature = "std"),
482 not(feature = "libm_force"),
483 feature = "libm"
484))]
485impl_complex!(
486 f32, f32, Float;
487 f64, f64, Float
488);
489
490#[cfg(all(feature = "std", not(feature = "libm_force")))]
491impl_complex!(
492 f32,f32,f32;
493 f64,f64,f64
494);
495
496#[cfg(all(
497 any(target_arch = "nvptx", target_arch = "nvptx64"),
498 not(feature = "std"),
499 not(feature = "libm_force"),
500 feature = "cuda"
501))]
502impl_complex!(
503 f32, f32, GpuFloat;
504 f64, f64, GpuFloat
505);
506
507#[cfg(feature = "libm_force")]
508impl ComplexField for f32 {
509 type RealField = f32;
510
511 #[inline]
512 fn from_real(re: Self::RealField) -> Self {
513 re
514 }
515
516 #[inline]
517 fn real(self) -> Self::RealField {
518 self
519 }
520
521 #[inline]
522 fn imaginary(self) -> Self::RealField {
523 Self::zero()
524 }
525
526 #[inline]
527 fn norm1(self) -> Self::RealField {
528 libm_force::fabsf(self)
529 }
530
531 #[inline]
532 fn modulus(self) -> Self::RealField {
533 libm_force::fabsf(self)
534 }
535
536 #[inline]
537 fn modulus_squared(self) -> Self::RealField {
538 self * self
539 }
540
541 #[inline]
542 fn argument(self) -> Self::RealField {
543 if self >= Self::zero() {
544 Self::zero()
545 } else {
546 Self::pi()
547 }
548 }
549
550 #[inline]
551 fn to_exp(self) -> (Self, Self) {
552 if self >= Self::zero() {
553 (self, Self::one())
554 } else {
555 (-self, -Self::one())
556 }
557 }
558
559 #[inline]
560 fn recip(self) -> Self {
561 f32::recip(self)
562 }
563
564 #[inline]
565 fn conjugate(self) -> Self {
566 self
567 }
568
569 #[inline]
570 fn scale(self, factor: Self::RealField) -> Self {
571 self * factor
572 }
573
574 #[inline]
575 fn unscale(self, factor: Self::RealField) -> Self {
576 self / factor
577 }
578
579 #[inline]
580 fn floor(self) -> Self {
581 libm_force::floorf(self)
582 }
583
584 #[inline]
585 fn ceil(self) -> Self {
586 libm_force::ceilf(self)
587 }
588
589 #[inline]
590 fn round(self) -> Self {
591 libm_force::roundf(self)
592 }
593
594 #[inline]
595 fn trunc(self) -> Self {
596 libm_force::truncf(self)
597 }
598
599 #[inline]
600 fn fract(self) -> Self {
601 self - libm_force::truncf(self)
602 }
603
604 #[inline]
605 fn abs(self) -> Self {
606 libm_force::fabsf(self)
607 }
608
609 #[inline]
610 fn signum(self) -> Self {
611 Signed::signum(&self)
612 }
613
614 #[inline]
615 fn mul_add(self, a: Self, b: Self) -> Self {
616 libm_force::fmaf(self, a, b)
617 }
618
619 #[inline]
620 fn powi(self, n: i32) -> Self {
621 libm_force::powf(self, n as f32)
623 }
624
625 #[inline]
626 fn powf(self, n: Self) -> Self {
627 libm_force::powf(self, n)
628 }
629
630 #[inline]
631 fn powc(self, n: Self) -> Self {
632 libm_force::powf(self, n)
634 }
635
636 #[inline]
637 fn sqrt(self) -> Self {
638 libm_force::sqrtf(self)
639 }
640
641 #[inline]
642 fn try_sqrt(self) -> Option<Self> {
643 if self >= Self::zero() {
644 Some(libm_force::sqrtf(self))
645 } else {
646 None
647 }
648 }
649
650 #[inline]
651 fn exp(self) -> Self {
652 libm_force::expf(self)
653 }
654
655 #[inline]
656 fn exp2(self) -> Self {
657 libm_force::exp2f(self)
658 }
659
660 #[inline]
661 fn exp_m1(self) -> Self {
662 libm_force::expm1f(self)
663 }
664
665 #[inline]
666 fn ln_1p(self) -> Self {
667 libm_force::log1pf(self)
668 }
669
670 #[inline]
671 fn ln(self) -> Self {
672 libm_force::logf(self)
673 }
674
675 #[inline]
676 fn log(self, base: Self) -> Self {
677 libm_force::logf(self) / libm_force::logf(base)
678 }
679
680 #[inline]
681 fn log2(self) -> Self {
682 libm_force::log2f(self)
683 }
684
685 #[inline]
686 fn log10(self) -> Self {
687 libm_force::log10f(self)
688 }
689
690 #[inline]
691 fn cbrt(self) -> Self {
692 libm_force::cbrtf(self)
693 }
694
695 #[inline]
696 fn hypot(self, other: Self) -> Self::RealField {
697 libm_force::hypotf(self, other)
698 }
699
700 #[inline]
701 fn sin(self) -> Self {
702 libm_force::sinf(self)
703 }
704
705 #[inline]
706 fn cos(self) -> Self {
707 libm_force::cosf(self)
708 }
709
710 #[inline]
711 fn tan(self) -> Self {
712 libm_force::tanf(self)
713 }
714
715 #[inline]
716 fn asin(self) -> Self {
717 libm_force::asinf(self)
718 }
719
720 #[inline]
721 fn acos(self) -> Self {
722 libm_force::acosf(self)
723 }
724
725 #[inline]
726 fn atan(self) -> Self {
727 libm_force::atanf(self)
728 }
729
730 #[inline]
731 fn sin_cos(self) -> (Self, Self) {
732 libm_force::sincosf(self)
733 }
734
735 #[inline]
746 fn sinh(self) -> Self {
747 libm_force::sinhf(self)
748 }
749
750 #[inline]
751 fn cosh(self) -> Self {
752 libm_force::coshf(self)
753 }
754
755 #[inline]
756 fn tanh(self) -> Self {
757 libm_force::tanhf(self)
758 }
759
760 #[inline]
761 fn asinh(self) -> Self {
762 libm_force::asinhf(self)
763 }
764
765 #[inline]
766 fn acosh(self) -> Self {
767 libm_force::acoshf(self)
768 }
769
770 #[inline]
771 fn atanh(self) -> Self {
772 libm_force::atanhf(self)
773 }
774
775 #[inline]
776 fn is_finite(&self) -> bool {
777 f32::is_finite(*self)
778 }
779}
780
781#[cfg(feature = "libm_force")]
782impl ComplexField for f64 {
783 type RealField = f64;
784
785 #[inline]
786 fn from_real(re: Self::RealField) -> Self {
787 re
788 }
789
790 #[inline]
791 fn real(self) -> Self::RealField {
792 self
793 }
794
795 #[inline]
796 fn imaginary(self) -> Self::RealField {
797 Self::zero()
798 }
799
800 #[inline]
801 fn norm1(self) -> Self::RealField {
802 libm_force::fabs(self)
803 }
804
805 #[inline]
806 fn modulus(self) -> Self::RealField {
807 libm_force::fabs(self)
808 }
809
810 #[inline]
811 fn modulus_squared(self) -> Self::RealField {
812 self * self
813 }
814
815 #[inline]
816 fn argument(self) -> Self::RealField {
817 if self >= Self::zero() {
818 Self::zero()
819 } else {
820 Self::pi()
821 }
822 }
823
824 #[inline]
825 fn to_exp(self) -> (Self, Self) {
826 if self >= Self::zero() {
827 (self, Self::one())
828 } else {
829 (-self, -Self::one())
830 }
831 }
832
833 #[inline]
834 fn recip(self) -> Self {
835 f64::recip(self)
836 }
837
838 #[inline]
839 fn conjugate(self) -> Self {
840 self
841 }
842
843 #[inline]
844 fn scale(self, factor: Self::RealField) -> Self {
845 self * factor
846 }
847
848 #[inline]
849 fn unscale(self, factor: Self::RealField) -> Self {
850 self / factor
851 }
852
853 #[inline]
854 fn floor(self) -> Self {
855 libm_force::floor(self)
856 }
857
858 #[inline]
859 fn ceil(self) -> Self {
860 libm_force::ceil(self)
861 }
862
863 #[inline]
864 fn round(self) -> Self {
865 libm_force::round(self)
866 }
867
868 #[inline]
869 fn trunc(self) -> Self {
870 libm_force::trunc(self)
871 }
872
873 #[inline]
874 fn fract(self) -> Self {
875 self - libm_force::trunc(self)
876 }
877
878 #[inline]
879 fn abs(self) -> Self {
880 libm_force::fabs(self)
881 }
882
883 #[inline]
884 fn signum(self) -> Self {
885 Signed::signum(&self)
886 }
887
888 #[inline]
889 fn mul_add(self, a: Self, b: Self) -> Self {
890 libm_force::fma(self, a, b)
891 }
892
893 #[inline]
894 fn powi(self, n: i32) -> Self {
895 libm_force::pow(self, n as f64)
897 }
898
899 #[inline]
900 fn powf(self, n: Self) -> Self {
901 libm_force::pow(self, n)
902 }
903
904 #[inline]
905 fn powc(self, n: Self) -> Self {
906 libm_force::pow(self, n)
908 }
909
910 #[inline]
911 fn sqrt(self) -> Self {
912 libm_force::sqrt(self)
913 }
914
915 #[inline]
916 fn try_sqrt(self) -> Option<Self> {
917 if self >= Self::zero() {
918 Some(libm_force::sqrt(self))
919 } else {
920 None
921 }
922 }
923
924 #[inline]
925 fn exp(self) -> Self {
926 libm_force::exp(self)
927 }
928
929 #[inline]
930 fn exp2(self) -> Self {
931 libm_force::exp2(self)
932 }
933
934 #[inline]
935 fn exp_m1(self) -> Self {
936 libm_force::expm1(self)
937 }
938
939 #[inline]
940 fn ln_1p(self) -> Self {
941 libm_force::log1p(self)
942 }
943
944 #[inline]
945 fn ln(self) -> Self {
946 libm_force::log(self)
947 }
948
949 #[inline]
950 fn log(self, base: Self) -> Self {
951 libm_force::log(self) / libm_force::log(base)
952 }
953
954 #[inline]
955 fn log2(self) -> Self {
956 libm_force::log2(self)
957 }
958
959 #[inline]
960 fn log10(self) -> Self {
961 libm_force::log10(self)
962 }
963
964 #[inline]
965 fn cbrt(self) -> Self {
966 libm_force::cbrt(self)
967 }
968
969 #[inline]
970 fn hypot(self, other: Self) -> Self::RealField {
971 libm_force::hypot(self, other)
972 }
973
974 #[inline]
975 fn sin(self) -> Self {
976 libm_force::sin(self)
977 }
978
979 #[inline]
980 fn cos(self) -> Self {
981 libm_force::cos(self)
982 }
983
984 #[inline]
985 fn tan(self) -> Self {
986 libm_force::tan(self)
987 }
988
989 #[inline]
990 fn asin(self) -> Self {
991 libm_force::asin(self)
992 }
993
994 #[inline]
995 fn acos(self) -> Self {
996 libm_force::acos(self)
997 }
998
999 #[inline]
1000 fn atan(self) -> Self {
1001 libm_force::atan(self)
1002 }
1003
1004 #[inline]
1005 fn sin_cos(self) -> (Self, Self) {
1006 libm_force::sincos(self)
1007 }
1008
1009 #[inline]
1020 fn sinh(self) -> Self {
1021 libm_force::sinh(self)
1022 }
1023
1024 #[inline]
1025 fn cosh(self) -> Self {
1026 libm_force::cosh(self)
1027 }
1028
1029 #[inline]
1030 fn tanh(self) -> Self {
1031 libm_force::tanh(self)
1032 }
1033
1034 #[inline]
1035 fn asinh(self) -> Self {
1036 libm_force::asinh(self)
1037 }
1038
1039 #[inline]
1040 fn acosh(self) -> Self {
1041 libm_force::acosh(self)
1042 }
1043
1044 #[inline]
1045 fn atanh(self) -> Self {
1046 libm_force::atanh(self)
1047 }
1048
1049 #[inline]
1050 fn is_finite(&self) -> bool {
1051 f64::is_finite(*self)
1052 }
1053}
1054
1055impl<N: RealField + PartialOrd> ComplexField for num_complex::Complex<N> {
1061 type RealField = N;
1062
1063 #[inline]
1064 fn from_real(re: Self::RealField) -> Self {
1065 Self::new(re, Self::RealField::zero())
1066 }
1067
1068 #[inline]
1069 fn real(self) -> Self::RealField {
1070 self.re
1071 }
1072
1073 #[inline]
1074 fn imaginary(self) -> Self::RealField {
1075 self.im
1076 }
1077
1078 #[inline]
1079 fn argument(self) -> Self::RealField {
1080 self.im.atan2(self.re)
1081 }
1082
1083 #[inline]
1084 fn modulus(self) -> Self::RealField {
1085 self.re.hypot(self.im)
1086 }
1087
1088 #[inline]
1089 fn modulus_squared(self) -> Self::RealField {
1090 self.re.clone() * self.re + self.im.clone() * self.im
1091 }
1092
1093 #[inline]
1094 fn norm1(self) -> Self::RealField {
1095 self.re.abs() + self.im.abs()
1096 }
1097
1098 #[inline]
1099 fn recip(self) -> Self {
1100 Self::one() / self
1101 }
1102
1103 #[inline]
1104 fn conjugate(self) -> Self {
1105 self.conj()
1106 }
1107
1108 #[inline]
1109 fn scale(self, factor: Self::RealField) -> Self {
1110 self * factor
1111 }
1112
1113 #[inline]
1114 fn unscale(self, factor: Self::RealField) -> Self {
1115 self / factor
1116 }
1117
1118 #[inline]
1119 fn floor(self) -> Self {
1120 Self::new(self.re.floor(), self.im.floor())
1121 }
1122
1123 #[inline]
1124 fn ceil(self) -> Self {
1125 Self::new(self.re.ceil(), self.im.ceil())
1126 }
1127
1128 #[inline]
1129 fn round(self) -> Self {
1130 Self::new(self.re.round(), self.im.round())
1131 }
1132
1133 #[inline]
1134 fn trunc(self) -> Self {
1135 Self::new(self.re.trunc(), self.im.trunc())
1136 }
1137
1138 #[inline]
1139 fn fract(self) -> Self {
1140 Self::new(self.re.fract(), self.im.fract())
1141 }
1142
1143 #[inline]
1144 fn mul_add(self, a: Self, b: Self) -> Self {
1145 self * a + b
1146 }
1147
1148 #[inline]
1149 fn abs(self) -> Self::RealField {
1150 self.modulus()
1151 }
1152
1153 #[inline]
1154 fn exp2(self) -> Self {
1155 let _2 = N::one() + N::one();
1156 num_complex::Complex::new(_2, N::zero()).powc(self)
1157 }
1158
1159 #[inline]
1160 fn exp_m1(self) -> Self {
1161 self.exp() - Self::one()
1162 }
1163
1164 #[inline]
1165 fn ln_1p(self) -> Self {
1166 (Self::one() + self).ln()
1167 }
1168
1169 #[inline]
1170 fn log2(self) -> Self {
1171 let _2 = N::one() + N::one();
1172 self.log(_2)
1173 }
1174
1175 #[inline]
1176 fn log10(self) -> Self {
1177 let _10 = N::from_subset(&10.0f64);
1178 self.log(_10)
1179 }
1180
1181 #[inline]
1182 fn cbrt(self) -> Self {
1183 let one_third = N::from_subset(&(1.0 / 3.0));
1184 self.powf(one_third)
1185 }
1186
1187 #[inline]
1188 fn powi(self, n: i32) -> Self {
1189 let n = N::from_subset(&(n as f64));
1191 self.powf(n)
1192 }
1193
1194 #[inline]
1195 fn is_finite(&self) -> bool {
1196 self.re.is_finite() && self.im.is_finite()
1197 }
1198
1199 #[inline]
1210 fn exp(self) -> Self {
1211 complex_from_polar(self.re.exp(), self.im)
1214 }
1215
1216 #[inline]
1224 fn ln(self) -> Self {
1225 let (r, theta) = self.to_polar();
1227 Self::new(r.ln(), theta)
1228 }
1229
1230 #[inline]
1238 fn sqrt(self) -> Self {
1239 let two = N::one() + N::one();
1241 let (r, theta) = self.to_polar();
1242 complex_from_polar(r.sqrt(), theta / two)
1243 }
1244
1245 #[inline]
1246 fn try_sqrt(self) -> Option<Self> {
1247 Some(self.sqrt())
1248 }
1249
1250 #[inline]
1251 fn hypot(self, b: Self) -> Self::RealField {
1252 (self.modulus_squared() + b.modulus_squared()).sqrt()
1253 }
1254
1255 #[inline]
1257 fn powf(self, exp: Self::RealField) -> Self {
1258 let (r, theta) = self.to_polar();
1261 complex_from_polar(r.powf(exp.clone()), theta * exp)
1262 }
1263
1264 #[inline]
1266 fn log(self, base: N) -> Self {
1267 let (r, theta) = self.to_polar();
1271 Self::new(r.log(base.clone()), theta / base.ln())
1272 }
1273
1274 #[inline]
1276 fn powc(self, exp: Self) -> Self {
1277 let (r, theta) = self.to_polar();
1289 complex_from_polar(
1290 r.clone().powf(exp.re.clone()) * (-exp.im.clone() * theta.clone()).exp(),
1291 exp.re * theta + exp.im * r.ln(),
1292 )
1293 }
1294
1295 #[inline]
1307 fn sin(self) -> Self {
1308 Self::new(
1310 self.re.clone().sin() * self.im.clone().cosh(),
1311 self.re.cos() * self.im.sinh(),
1312 )
1313 }
1314
1315 #[inline]
1317 fn cos(self) -> Self {
1318 Self::new(
1320 self.re.clone().cos() * self.im.clone().cosh(),
1321 -self.re.sin() * self.im.sinh(),
1322 )
1323 }
1324
1325 #[inline]
1326 fn sin_cos(self) -> (Self, Self) {
1327 let (rsin, rcos) = self.re.sin_cos();
1328 let (isinh, icosh) = self.im.sinh_cosh();
1329 let sin = Self::new(rsin.clone() * icosh.clone(), rcos.clone() * isinh.clone());
1330 let cos = Self::new(rcos * icosh, -rsin * isinh);
1331
1332 (sin, cos)
1333 }
1334
1335 #[inline]
1337 fn tan(self) -> Self {
1338 let (two_re, two_im) = (self.re.clone() + self.re, self.im.clone() + self.im);
1340 Self::new(two_re.clone().sin(), two_im.clone().sinh()).unscale(two_re.cos() + two_im.cosh())
1341 }
1342
1343 #[inline]
1352 fn asin(self) -> Self {
1353 let i = Self::i();
1355 -i.clone() * ((Self::one() - self.clone() * self.clone()).sqrt() + i * self).ln()
1356 }
1357
1358 #[inline]
1367 fn acos(self) -> Self {
1368 let i = Self::i();
1370 -i.clone() * (i * (Self::one() - self.clone() * self.clone()).sqrt() + self).ln()
1371 }
1372
1373 #[inline]
1382 fn atan(self) -> Self {
1383 let i = Self::i();
1385 let one = Self::one();
1386 let two = one.clone() + one.clone();
1387
1388 if self == i {
1389 return Self::new(N::zero(), N::one() / N::zero());
1390 } else if self == -i.clone() {
1391 return Self::new(N::zero(), -N::one() / N::zero());
1392 }
1393
1394 ((one.clone() + i.clone() * self.clone()).ln() - (one - i.clone() * self).ln()) / (two * i)
1395 }
1396
1397 #[inline]
1399 fn sinh(self) -> Self {
1400 Self::new(
1402 self.re.clone().sinh() * self.im.clone().cos(),
1403 self.re.cosh() * self.im.sin(),
1404 )
1405 }
1406
1407 #[inline]
1409 fn cosh(self) -> Self {
1410 Self::new(
1412 self.re.clone().cosh() * self.im.clone().cos(),
1413 self.re.sinh() * self.im.sin(),
1414 )
1415 }
1416
1417 #[inline]
1418 fn sinh_cosh(self) -> (Self, Self) {
1419 let (rsinh, rcosh) = self.re.sinh_cosh();
1420 let (isin, icos) = self.im.sin_cos();
1421 let sin = Self::new(rsinh.clone() * icos.clone(), rcosh.clone() * isin.clone());
1422 let cos = Self::new(rcosh * icos, rsinh * isin);
1423
1424 (sin, cos)
1425 }
1426
1427 #[inline]
1429 fn tanh(self) -> Self {
1430 let (two_re, two_im) = (self.re.clone() + self.re, self.im.clone() + self.im);
1432 Self::new(two_re.clone().sinh(), two_im.clone().sin()).unscale(two_re.cosh() + two_im.cos())
1433 }
1434
1435 #[inline]
1444 fn asinh(self) -> Self {
1445 let one = Self::one();
1447 (self.clone() + (one + self.clone() * self).sqrt()).ln()
1448 }
1449
1450 #[inline]
1458 fn acosh(self) -> Self {
1459 let one = Self::one();
1461 let two = one.clone() + one.clone();
1462 two.clone()
1463 * (((self.clone() + one.clone()) / two.clone()).sqrt() + ((self - one) / two).sqrt())
1464 .ln()
1465 }
1466
1467 #[inline]
1476 fn atanh(self) -> Self {
1477 let one = Self::one();
1479 let two = one.clone() + one.clone();
1480 if self == one {
1481 return Self::new(N::one() / N::zero(), N::zero());
1482 } else if self == -one.clone() {
1483 return Self::new(-N::one() / N::zero(), N::zero());
1484 }
1485 ((one.clone() + self.clone()).ln() - (one - self).ln()) / two
1486 }
1487}
1488
1489#[inline]
1490fn complex_from_polar<N: RealField>(r: N, theta: N) -> num_complex::Complex<N> {
1491 num_complex::Complex::new(r.clone() * theta.clone().cos(), r * theta.sin())
1492}