Coverage Report

Created: 2026-10-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/simba-0.10.2/src/scalar/complex.rs
Line
Count
Source
1
use num::{One, Signed, Zero};
2
use num_traits::FromPrimitive;
3
use std::any::Any;
4
use std::fmt::{Debug, Display};
5
use std::ops::Neg;
6
use std::{f32, f64};
7
8
use crate::scalar::{Field, RealField, SubsetOf, SupersetOf};
9
#[cfg(all(not(feature = "std"), not(feature = "libm_force"), feature = "libm"))]
10
use 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)]
21
pub trait ComplexField:
22
SubsetOf<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"))]
177
macro_rules! impl_complex (
178
    ($($T:ty, $M:ident, $libm: ident);*) => ($(
179
        impl ComplexField for $T {
180
            type RealField = $T;
181
182
            #[inline]
183
0
            fn from_real(re: Self::RealField) -> Self {
184
0
                re
185
0
            }
186
187
            #[inline]
188
458
            fn real(self) -> Self::RealField {
189
458
                self
190
458
            }
191
192
            #[inline]
193
            fn imaginary(self) -> Self::RealField {
194
                Self::zero()
195
            }
196
197
            #[inline]
198
0
            fn norm1(self) -> Self::RealField {
199
0
                $libm::abs(self)
200
0
            }
201
202
            #[inline]
203
0
            fn modulus(self) -> Self::RealField {
204
0
                $libm::abs(self)
205
0
            }
206
207
            #[inline]
208
0
            fn modulus_squared(self) -> Self::RealField {
209
0
                self * self
210
0
            }
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
0
            fn to_exp(self) -> (Self, Self) {
223
0
                if self >= Self::zero() {
224
0
                    (self, Self::one())
225
                } else {
226
0
                    (-self, -Self::one())
227
                }
228
0
            }
229
230
            #[inline]
231
            fn recip(self) -> Self {
232
                $M::recip(self)
233
            }
234
235
            #[inline]
236
1.37k
            fn conjugate(self) -> Self {
237
1.37k
                self
238
1.37k
            }
239
240
            #[inline]
241
0
            fn scale(self, factor: Self::RealField) -> Self {
242
0
                self * factor
243
0
            }
244
245
            #[inline]
246
0
            fn unscale(self, factor: Self::RealField) -> Self {
247
0
                self / factor
248
0
            }
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
0
            fn abs(self) -> Self {
277
0
                $libm::abs(self)
278
0
            }
279
280
            #[inline]
281
0
            fn signum(self) -> Self {
282
0
                Signed::signum(&self)
283
0
            }
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
164
            fn sqrt(self) -> Self {
316
164
                $libm::sqrt(self)
317
164
            }
318
319
            #[inline]
320
0
            fn try_sqrt(self) -> Option<Self> {
321
0
                if self >= Self::zero() {
322
0
                    Some($libm::sqrt(self))
323
                } else {
324
0
                    None
325
                }
326
0
            }
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
0
            fn acos(self) -> Self {
401
0
                $libm::acos(self)
402
0
            }
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"))]
463
impl_complex!(
464
    f32, f32, Float;
465
    f64, f64, Float
466
);
467
468
#[cfg(all(feature = "std", not(feature = "libm_force")))]
469
impl_complex!(
470
    f32,f32,f32;
471
    f64,f64,f64
472
);
473
474
#[cfg(feature = "libm_force")]
475
impl 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")]
749
impl 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.
1027
impl<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]
1457
fn 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
}