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#[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+ Send
32+ Sync
33+ Any
34+ 'static
35+ Debug
36+ Display
37{
38 type RealField: RealField;fn from_real(re: Self::RealField) -> Self;
40
41 fn real(self) -> Self::RealField;
43
44 fn imaginary(self) -> Self::RealField;
46
47 fn modulus(self) -> Self::RealField;
49
50 fn modulus_squared(self) -> Self::RealField;
52
53 fn argument(self) -> Self::RealField;
55
56 fn norm1(self) -> Self::RealField;
58
59 fn scale(self, factor: Self::RealField) -> Self;
61
62 fn unscale(self, factor: Self::RealField) -> Self;
64
65 fn to_polar(self) -> (Self::RealField, Self::RealField) {
67 (self.clone().modulus(), self.argument())
68 }
69
70 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 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 fn abs(self) -> Self::RealField;
97
98 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 #[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 #[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 $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 $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]
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 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 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]
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 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 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]
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
1022impl<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 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 #[inline]
1177 fn exp(self) -> Self {
1178 complex_from_polar(self.re.exp(), self.im)
1181 }
1182
1183 #[inline]
1191 fn ln(self) -> Self {
1192 let (r, theta) = self.to_polar();
1194 Self::new(r.ln(), theta)
1195 }
1196
1197 #[inline]
1205 fn sqrt(self) -> Self {
1206 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 #[inline]
1224 fn powf(self, exp: Self::RealField) -> Self {
1225 let (r, theta) = self.to_polar();
1228 complex_from_polar(r.powf(exp.clone()), theta * exp)
1229 }
1230
1231 #[inline]
1233 fn log(self, base: N) -> Self {
1234 let (r, theta) = self.to_polar();
1238 Self::new(r.log(base.clone()), theta / base.ln())
1239 }
1240
1241 #[inline]
1243 fn powc(self, exp: Self) -> Self {
1244 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 #[inline]
1274 fn sin(self) -> Self {
1275 Self::new(
1277 self.re.clone().sin() * self.im.clone().cosh(),
1278 self.re.cos() * self.im.sinh(),
1279 )
1280 }
1281
1282 #[inline]
1284 fn cos(self) -> Self {
1285 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 #[inline]
1304 fn tan(self) -> Self {
1305 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 #[inline]
1319 fn asin(self) -> Self {
1320 let i = Self::i();
1322 -i.clone() * ((Self::one() - self.clone() * self.clone()).sqrt() + i * self).ln()
1323 }
1324
1325 #[inline]
1334 fn acos(self) -> Self {
1335 let i = Self::i();
1337 -i.clone() * (i * (Self::one() - self.clone() * self.clone()).sqrt() + self).ln()
1338 }
1339
1340 #[inline]
1349 fn atan(self) -> Self {
1350 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 #[inline]
1366 fn sinh(self) -> Self {
1367 Self::new(
1369 self.re.clone().sinh() * self.im.clone().cos(),
1370 self.re.cosh() * self.im.sin(),
1371 )
1372 }
1373
1374 #[inline]
1376 fn cosh(self) -> Self {
1377 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 #[inline]
1396 fn tanh(self) -> Self {
1397 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 #[inline]
1411 fn asinh(self) -> Self {
1412 let one = Self::one();
1414 (self.clone() + (one + self.clone() * self).sqrt()).ln()
1415 }
1416
1417 #[inline]
1425 fn acosh(self) -> Self {
1426 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 #[inline]
1443 fn atanh(self) -> Self {
1444 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}