1 #![allow(missing_docs)]
2 #![allow(non_camel_case_types)] // For the simd type aliases.
3 
4 //! Traits for SIMD values.
5 
6 use crate::scalar::{ComplexField, Field, SubsetOf, SupersetOf};
7 use crate::simd::{
8     PrimitiveSimdValue, SimdBool, SimdComplexField, SimdPartialOrd, SimdRealField, SimdSigned,
9     SimdValue,
10 };
11 use approx::AbsDiffEq;
12 #[cfg(feature = "decimal")]
13 use decimal::d128;
14 use num::{FromPrimitive, Num, One, Zero};
15 use std::{
16     fmt,
17     ops::{
18         Add, AddAssign, BitAnd, BitOr, BitXor, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem,
19         RemAssign, Sub, SubAssign,
20     },
21 };
22 
23 // This is a hack to allow use to reuse `_0` as integers or as identifier,
24 // depending on whether or not `ident_to_value` has been called in scope.
25 // This helps writing macros that define both `::new` and `From([T; lanes()])`.
26 macro_rules! ident_to_value(
27     () => {
28         const _0: usize = 0; const _1: usize = 1; const _2: usize = 2; const _3: usize = 3; const _4: usize = 4; const _5: usize = 5; const _6: usize = 6; const _7: usize = 7;
29         const _8: usize = 8; const _9: usize = 9; const _10: usize = 10; const _11: usize = 11; const _12: usize = 12; const _13: usize = 13; const _14: usize = 14; const _15: usize = 15;
30         const _16: usize = 16; const _17: usize = 17; const _18: usize = 18; const _19: usize = 19; const _20: usize = 20; const _21: usize = 21; const _22: usize = 22; const _23: usize = 23;
31         const _24: usize = 24; const _25: usize = 25; const _26: usize = 26; const _27: usize = 27; const _28: usize = 28; const _29: usize = 29; const _30: usize = 30; const _31: usize = 31;
32         const _32: usize = 32; const _33: usize = 33; const _34: usize = 34; const _35: usize = 35; const _36: usize = 36; const _37: usize = 37; const _38: usize = 38; const _39: usize = 39;
33         const _40: usize = 40; const _41: usize = 41; const _42: usize = 42; const _43: usize = 43; const _44: usize = 44; const _45: usize = 45; const _46: usize = 46; const _47: usize = 47;
34         const _48: usize = 48; const _49: usize = 49; const _50: usize = 50; const _51: usize = 51; const _52: usize = 52; const _53: usize = 53; const _54: usize = 54; const _55: usize = 55;
35         const _56: usize = 56; const _57: usize = 57; const _58: usize = 58; const _59: usize = 59; const _60: usize = 60; const _61: usize = 61; const _62: usize = 62; const _63: usize = 63;
36     }
37 );
38 
39 /// An Simd structure that implements all the relevant traits from `num` an `simba`.
40 ///
41 /// This is needed to overcome the orphan rules.
42 #[repr(transparent)]
43 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
44 pub struct Simd<N>(pub N);
45 
46 macro_rules! impl_bool_simd(
47     ($($t: ty, $($i: ident),*;)*) => {$(
48         impl_simd_value!($t, bool, Simd<$t> $(, $i)*;);
49 
50         impl From<[bool; <$t>::lanes()]> for Simd<$t> {
51             #[inline(always)]
52             fn from(vals: [bool; <$t>::lanes()]) -> Self {
53                 ident_to_value!();
54                 Simd(<$t>::new($(vals[$i]),*))
55             }
56         }
57 
58         impl Not for Simd<$t> {
59             type Output = Self;
60 
61             #[inline]
62             fn not(self) -> Self {
63                 Self(!self.0)
64             }
65         }
66 
67         impl BitAnd<Simd<$t>> for Simd<$t> {
68             type Output = Self;
69             fn bitand(self, rhs: Self) -> Self {
70                 Simd(self.0.bitand(rhs.0))
71             }
72         }
73 
74         impl BitOr<Simd<$t>> for Simd<$t> {
75             type Output = Self;
76             fn bitor(self, rhs: Self) -> Self {
77                 Simd(self.0.bitor(rhs.0))
78             }
79         }
80 
81         impl BitXor<Simd<$t>> for Simd<$t> {
82             type Output = Self;
83             fn bitxor(self, rhs: Self) -> Self {
84                 Simd(self.0.bitxor(rhs.0))
85             }
86         }
87 
88         impl SimdBool for Simd<$t> {
89             #[inline(always)]
90             fn bitmask(self) -> u64 {
91                 self.0.bitmask() as u64
92             }
93 
94             #[inline(always)]
95             fn and(self) -> bool {
96                 self.0.and()
97             }
98 
99             #[inline(always)]
100             fn or(self) -> bool {
101                 self.0.or()
102             }
103 
104             #[inline(always)]
105             fn xor(self) -> bool {
106                 self.0.xor()
107             }
108 
109             #[inline(always)]
110             fn all(self) -> bool {
111                 self.0.all()
112             }
113 
114             #[inline(always)]
115             fn any(self) -> bool {
116                 self.0.any()
117             }
118 
119             #[inline(always)]
120             fn none(self) -> bool {
121                 self.0.none()
122             }
123 
124             #[inline(always)]
125             fn if_else<Res: SimdValue<SimdBool = Self>>(
126                 self,
127                 if_value: impl FnOnce() -> Res,
128                 else_value: impl FnOnce() -> Res,
129             ) -> Res {
130                 let a = if_value();
131                 let b = else_value();
132                 a.select(self, b)
133             }
134 
135             #[inline(always)]
136             fn if_else2<Res: SimdValue<SimdBool = Self>>(
137                 self,
138                 if_value: impl FnOnce() -> Res,
139                 else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
140                 else_value: impl FnOnce() -> Res,
141             ) -> Res {
142                 let a = if_value();
143                 let b = else_if.1();
144                 let c = else_value();
145 
146                 let cond_a = self;
147                 let cond_b = else_if.0();
148 
149                 a.select(cond_a, b.select(cond_b, c))
150             }
151 
152             #[inline(always)]
153             fn if_else3<Res: SimdValue<SimdBool = Self>>(
154                 self,
155                 if_value: impl FnOnce() -> Res,
156                 else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
157                 else_else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
158                 else_value: impl FnOnce() -> Res,
159             ) -> Res {
160                 let a = if_value();
161                 let b = else_if.1();
162                 let c = else_else_if.1();
163                 let d = else_value();
164 
165                 let cond_a = self;
166                 let cond_b = else_if.0();
167                 let cond_c = else_else_if.0();
168 
169                 a.select(cond_a, b.select(cond_b, c.select(cond_c, d)))
170             }
171         }
172     )*}
173 );
174 
175 macro_rules! impl_scalar_subset_of_simd(
176     ($($t: ty),*) => {$(
177         impl<N2> SubsetOf<Simd<N2>> for $t
178             where Simd<N2>: SimdValue + Copy,
179                   <Simd<N2> as SimdValue>::Element: SupersetOf<$t> + PartialEq, {
180             #[inline(always)]
181             fn to_superset(&self) -> Simd<N2> {
182                 Simd::<N2>::splat(<Simd<N2> as SimdValue>::Element::from_subset(self))
183             }
184 
185             #[inline(always)]
186             fn from_superset_unchecked(element: &Simd<N2>) -> $t {
187                 element.extract(0).to_subset_unchecked()
188             }
189 
190             #[inline(always)]
191             fn is_in_subset(c: &Simd<N2>) -> bool {
192                 let elt0 = c.extract(0);
193                 elt0.is_in_subset() &&
194                 (1..Simd::<N2>::lanes()).all(|i| c.extract(i) == elt0)
195             }
196         }
197     )*}
198 );
199 
200 impl_scalar_subset_of_simd!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
201 #[cfg(feature = "decimal")]
202 impl_scalar_subset_of_simd!(d128);
203 
204 macro_rules! impl_simd_value(
205     ($($t: ty, $elt: ty, $bool: ty, $($i: ident),*;)*) => ($(
206         impl fmt::Display for Simd<$t> {
207             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208                 if Self::lanes() == 1 {
209                     return self.extract(0).fmt(f);
210                 }
211 
212                 write!(f, "({}", self.extract(0))?;
213 
214                 for i in 1..Self::lanes() {
215                     write!(f, ", {}", self.extract(i))?;
216                 }
217 
218                 write!(f, ")")
219             }
220         }
221 
222         impl Simd<$t> {
223             #[inline]
224             pub fn new($($i: $elt),*) -> Self {
225                 Simd(<$t>::new($($i),*))
226             }
227         }
228 
229         impl PrimitiveSimdValue for Simd<$t> {}
230 
231         impl SimdValue for Simd<$t> {
232             type Element = $elt;
233             type SimdBool = $bool;
234 
235             #[inline(always)]
236             fn lanes() -> usize {
237                 <$t>::lanes()
238             }
239 
240             #[inline(always)]
241             fn splat(val: Self::Element) -> Self {
242                 Simd(<$t>::splat(val))
243             }
244 
245             #[inline(always)]
246             fn extract(&self, i: usize) -> Self::Element {
247                 <$t>::extract(self.0, i)
248             }
249 
250             #[inline(always)]
251             unsafe fn extract_unchecked(&self, i: usize) -> Self::Element {
252                 <$t>::extract_unchecked(self.0, i)
253             }
254 
255             #[inline(always)]
256             fn replace(&mut self, i: usize, val: Self::Element) {
257                 *self = Simd(<$t>::replace(self.0, i, val))
258             }
259 
260             #[inline(always)]
261             unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) {
262                 *self = Simd(<$t>::replace_unchecked(self.0, i, val))
263             }
264 
265             #[inline(always)]
266             fn select(self, cond: Self::SimdBool, other: Self) -> Self {
267                 Self(cond.0.select(self.0, other.0))
268             }
269         }
270     )*)
271 );
272 
273 macro_rules! impl_uint_simd(
274     ($($t: ty, $elt: ty, $bool: ty, $($i: ident),*;)*) => ($(
275         impl_simd_value!($t, $elt, $bool $(, $i)*;);
276 
277         impl Simd<$t> {
278             /// Instantiates a new vector with the values of the `slice`.
279             ///
280             /// # Panics
281             ///
282             /// If `slice.len() < Self::lanes()`.
283             #[inline]
284             pub fn from_slice_unaligned(slice: &[$elt]) -> Self {
285                 Simd(<$t>::from_slice_unaligned(slice))
286             }
287         }
288 
289         impl From<[$elt; <$t>::lanes()]> for Simd<$t> {
290             #[inline(always)]
291             fn from(vals: [$elt; <$t>::lanes()]) -> Self {
292                 Simd(<$t>::from(vals))
293             }
294         }
295 
296         impl From<Simd<$t>> for [$elt; <$t>::lanes()] {
297             #[inline(always)]
298             fn from(val: Simd<$t>) -> [$elt; <$t>::lanes()] {
299                 let mut res = [<$elt>::zero(); <$t>::lanes()];
300                 val.0.write_to_slice_unaligned(&mut res[..]);
301                 res
302             }
303         }
304 
305         impl SubsetOf<Simd<$t>> for Simd<$t> {
306             #[inline(always)]
307             fn to_superset(&self) -> Self {
308                 *self
309             }
310 
311             #[inline(always)]
312             fn from_superset(element: &Self) -> Option<Self> {
313                 Some(*element)
314             }
315 
316             #[inline(always)]
317             fn from_superset_unchecked(element: &Self) -> Self {
318                 *element
319             }
320 
321             #[inline(always)]
322             fn is_in_subset(_: &Self) -> bool {
323                 true
324             }
325         }
326 
327         impl Num for Simd<$t> {
328             type FromStrRadixErr = <$elt as Num>::FromStrRadixErr;
329 
330             #[inline(always)]
331             fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
332                 <$elt>::from_str_radix(str, radix).map(Self::splat)
333             }
334         }
335 
336         impl FromPrimitive for Simd<$t> {
337             #[inline(always)]
338             fn from_i64(n: i64) -> Option<Self> {
339                 <$elt>::from_i64(n).map(Self::splat)
340             }
341 
342             #[inline(always)]
343             fn from_u64(n: u64) -> Option<Self> {
344                 <$elt>::from_u64(n).map(Self::splat)
345             }
346 
347             #[inline(always)]
348             fn from_isize(n: isize) -> Option<Self>  {
349                 <$elt>::from_isize(n).map(Self::splat)
350             }
351 
352             #[inline(always)]
353             fn from_i8(n: i8) -> Option<Self>  {
354                 <$elt>::from_i8(n).map(Self::splat)
355             }
356 
357             #[inline(always)]
358             fn from_i16(n: i16) -> Option<Self>  {
359                 <$elt>::from_i16(n).map(Self::splat)
360             }
361 
362             #[inline(always)]
363             fn from_i32(n: i32) -> Option<Self>  {
364                 <$elt>::from_i32(n).map(Self::splat)
365             }
366 
367             #[inline(always)]
368             fn from_usize(n: usize) -> Option<Self>  {
369                 <$elt>::from_usize(n).map(Self::splat)
370             }
371 
372             #[inline(always)]
373             fn from_u8(n: u8) -> Option<Self>  {
374                 <$elt>::from_u8(n).map(Self::splat)
375             }
376 
377             #[inline(always)]
378             fn from_u16(n: u16) -> Option<Self>  {
379                 <$elt>::from_u16(n).map(Self::splat)
380             }
381 
382             #[inline(always)]
383             fn from_u32(n: u32) -> Option<Self>  {
384                 <$elt>::from_u32(n).map(Self::splat)
385             }
386 
387             #[inline(always)]
388             fn from_f32(n: f32) -> Option<Self>  {
389                 <$elt>::from_f32(n).map(Self::splat)
390             }
391 
392             #[inline(always)]
393             fn from_f64(n: f64) -> Option<Self>  {
394                 <$elt>::from_f64(n).map(Self::splat)
395             }
396         }
397 
398 
399         impl Zero for Simd<$t> {
400             #[inline(always)]
401             fn zero() -> Self {
402                 Simd(<$t>::splat(<$elt>::zero()))
403             }
404 
405             #[inline(always)]
406             fn is_zero(&self) -> bool {
407                 *self == Self::zero()
408             }
409         }
410 
411         impl One for Simd<$t> {
412             #[inline(always)]
413             fn one() -> Self {
414                 Simd(<$t>::splat(<$elt>::one()))
415             }
416         }
417 
418         impl Add<Simd<$t>> for Simd<$t> {
419             type Output = Self;
420 
421             #[inline(always)]
422             fn add(self, rhs: Self) -> Self {
423                 Self(self.0 + rhs.0)
424             }
425         }
426 
427         impl Sub<Simd<$t>> for Simd<$t> {
428             type Output = Self;
429 
430             #[inline(always)]
431             fn sub(self, rhs: Self) -> Self {
432                 Self(self.0 - rhs.0)
433             }
434         }
435 
436         impl Mul<Simd<$t>> for Simd<$t> {
437             type Output = Self;
438 
439             #[inline(always)]
440             fn mul(self, rhs: Self) -> Self {
441                 Self(self.0 * rhs.0)
442             }
443         }
444 
445         impl Div<Simd<$t>> for Simd<$t> {
446             type Output = Self;
447 
448             #[inline(always)]
449             fn div(self, rhs: Self) -> Self {
450                 Self(self.0 / rhs.0)
451             }
452         }
453 
454         impl Rem<Simd<$t>> for Simd<$t> {
455             type Output = Self;
456 
457             #[inline(always)]
458             fn rem(self, rhs: Self) -> Self {
459                 Self(self.0 % rhs.0)
460             }
461         }
462 
463         impl AddAssign<Simd<$t>> for Simd<$t> {
464             #[inline(always)]
465             fn add_assign(&mut self, rhs: Self) {
466                 self.0 += rhs.0
467             }
468         }
469 
470         impl SubAssign<Simd<$t>> for Simd<$t> {
471             #[inline(always)]
472             fn sub_assign(&mut self, rhs: Self) {
473                 self.0 -= rhs.0
474             }
475         }
476 
477         impl DivAssign<Simd<$t>> for Simd<$t> {
478             #[inline(always)]
479             fn div_assign(&mut self, rhs: Self) {
480                 self.0 /= rhs.0
481             }
482         }
483 
484         impl MulAssign<Simd<$t>> for Simd<$t> {
485             #[inline(always)]
486             fn mul_assign(&mut self, rhs: Self) {
487                 self.0 *= rhs.0
488             }
489         }
490 
491         impl RemAssign<Simd<$t>> for Simd<$t> {
492             #[inline(always)]
493             fn rem_assign(&mut self, rhs: Self) {
494                 self.0 %= rhs.0
495             }
496         }
497 
498         impl SimdPartialOrd for Simd<$t> {
499             #[inline(always)]
500             fn simd_gt(self, other: Self) -> Self::SimdBool {
501                 Simd(self.0.gt(other.0))
502             }
503 
504             #[inline(always)]
505             fn simd_lt(self, other: Self) -> Self::SimdBool {
506                 Simd(self.0.lt(other.0))
507             }
508 
509             #[inline(always)]
510             fn simd_ge(self, other: Self) -> Self::SimdBool {
511                 Simd(self.0.ge(other.0))
512             }
513 
514             #[inline(always)]
515             fn simd_le(self, other: Self) -> Self::SimdBool {
516                 Simd(self.0.le(other.0))
517             }
518 
519             #[inline(always)]
520             fn simd_eq(self, other: Self) -> Self::SimdBool {
521                 Simd(self.0.eq(other.0))
522             }
523 
524             #[inline(always)]
525             fn simd_ne(self, other: Self) -> Self::SimdBool {
526                 Simd(self.0.ne(other.0))
527             }
528 
529             #[inline(always)]
530             fn simd_max(self, other: Self) -> Self {
531                 Simd(self.0.max(other.0))
532             }
533             #[inline(always)]
534             fn simd_min(self, other: Self) -> Self {
535                 Simd(self.0.min(other.0))
536             }
537 
538             #[inline(always)]
539             fn simd_clamp(self, min: Self, max: Self) -> Self {
540                 self.simd_max(min).simd_min(max)
541             }
542 
543             #[inline(always)]
544             fn simd_horizontal_min(self) -> Self::Element {
545                 self.0.min_element()
546             }
547 
548             #[inline(always)]
549             fn simd_horizontal_max(self) -> Self::Element {
550                 self.0.max_element()
551             }
552         }
553 
554 //        impl MeetSemilattice for Simd<$t> {
555 //            #[inline(always)]
556 //            fn meet(&self, other: &Self) -> Self {
557 //                Simd(self.0.min(other.0))
558 //            }
559 //        }
560 //
561 //        impl JoinSemilattice for Simd<$t> {
562 //            #[inline(always)]
563 //            fn join(&self, other: &Self) -> Self {
564 //                Simd(self.0.max(other.0))
565 //            }
566 //        }
567     )*)
568 );
569 
570 macro_rules! impl_int_simd(
571     ($($t: ty, $elt: ty, $bool: ty, $($i: ident),*;)*) => ($(
572         impl_uint_simd!($t, $elt, $bool $(, $i)*;);
573 
574         impl Neg for Simd<$t> {
575             type Output = Self;
576 
577             #[inline(always)]
578             fn neg(self) -> Self {
579                 Self(-self.0)
580             }
581         }
582     )*)
583 );
584 
585 macro_rules! impl_float_simd(
586     ($($t: ty, $elt: ty, $int: ty, $bool: ty, $($i: ident),*;)*) => ($(
587         impl_int_simd!($t, $elt, $bool $(, $i)*;);
588 
589         // FIXME: this should be part of impl_int_simd
590         // but those methods do not seem to be implemented
591         // by packed_simd for integers.
592         impl SimdSigned for Simd<$t> {
593             #[inline(always)]
594             fn simd_abs(&self) -> Self {
595                 Simd(self.0.abs())
596             }
597 
598             #[inline(always)]
599             fn simd_abs_sub(&self, other: &Self) -> Self {
600                 Simd((self.0 - other.0).max(Self::zero().0))
601             }
602 
603             #[inline(always)]
604             fn simd_signum(&self) -> Self {
605                 // NOTE: is there a more efficient way of doing this?
606                 let zero = Self::zero().0;
607                 let one = Self::one().0;
608                 let gt = self.0.gt(zero);
609                 let lt = self.0.lt(zero);
610                 Simd(lt.select(-one, gt.select(one, zero)))
611             }
612 
613             #[inline(always)]
614             fn is_simd_positive(&self) -> Self::SimdBool {
615                 self.simd_gt(Self::zero())
616             }
617 
618             #[inline(always)]
619             fn is_simd_negative(&self) -> Self::SimdBool {
620                 self.simd_lt(Self::zero())
621             }
622         }
623 
624         impl Field for Simd<$t> {}
625 
626         impl SimdRealField for Simd<$t> {
627             #[inline(always)]
628             fn simd_atan2(self, other: Self) -> Self {
629                 self.zip_map_lanes(other, |a, b| a.atan2(b))
630             }
631 
632             #[inline(always)]
633             fn simd_copysign(self, sign: Self) -> Self {
634                 use packed_simd::FromBits;
635                 let sign_bits = <$int>::from_bits(<$t>::splat(-0.0));
636                 let ref_bits = <$int>::from_bits(sign.0);
637                 let self_bits = <$int>::from_bits(self.0);
638                 let result =
639                     <$t>::from_bits((sign_bits & ref_bits) | ((!sign_bits) & self_bits));
640                 Simd(result)
641             }
642 
643             #[inline(always)]
644             fn simd_default_epsilon() -> Self {
645                 Self::splat(<$elt>::default_epsilon())
646             }
647 
648             #[inline(always)]
649             fn simd_pi() -> Self {
650                 Simd(<$t>::PI)
651             }
652 
653             #[inline(always)]
654             fn simd_two_pi() -> Self {
655                 Simd(<$t>::PI + <$t>::PI)
656             }
657 
658             #[inline(always)]
659             fn simd_frac_pi_2() -> Self {
660                 Simd(<$t>::FRAC_PI_2)
661             }
662 
663             #[inline(always)]
664             fn simd_frac_pi_3() -> Self {
665                 Simd(<$t>::FRAC_PI_3)
666             }
667 
668             #[inline(always)]
669             fn simd_frac_pi_4() -> Self {
670                 Simd(<$t>::FRAC_PI_4)
671             }
672 
673             #[inline(always)]
674             fn simd_frac_pi_6() -> Self {
675                 Simd(<$t>::FRAC_PI_6)
676             }
677 
678             #[inline(always)]
679             fn simd_frac_pi_8() -> Self {
680                 Simd(<$t>::FRAC_PI_8)
681             }
682 
683             #[inline(always)]
684             fn simd_frac_1_pi() -> Self {
685                 Simd(<$t>::FRAC_1_PI)
686             }
687 
688             #[inline(always)]
689             fn simd_frac_2_pi() -> Self {
690                 Simd(<$t>::FRAC_2_PI)
691             }
692 
693             #[inline(always)]
694             fn simd_frac_2_sqrt_pi() -> Self {
695                 Simd(<$t>::FRAC_2_SQRT_PI)
696             }
697 
698 
699             #[inline(always)]
700             fn simd_e() -> Self {
701                 Simd(<$t>::E)
702             }
703 
704             #[inline(always)]
705             fn simd_log2_e() -> Self {
706                 Simd(<$t>::LOG2_E)
707             }
708 
709             #[inline(always)]
710             fn simd_log10_e() -> Self {
711                 Simd(<$t>::LOG10_E)
712             }
713 
714             #[inline(always)]
715             fn simd_ln_2() -> Self {
716                 Simd(<$t>::LN_2)
717             }
718 
719             #[inline(always)]
720             fn simd_ln_10() -> Self {
721                 Simd(<$t>::LN_10)
722             }
723         }
724 
725         impl SimdComplexField for Simd<$t> {
726             type SimdRealField = Self;
727 
728             #[inline(always)]
729             fn simd_horizontal_sum(self) -> Self::Element {
730                 self.0.sum()
731             }
732 
733             #[inline(always)]
734             fn simd_horizontal_product(self) -> Self::Element {
735                 self.0.product()
736             }
737 
738             #[inline(always)]
739             fn from_simd_real(re: Self::SimdRealField) -> Self {
740                 re
741             }
742 
743             #[inline(always)]
744             fn simd_real(self) -> Self::SimdRealField {
745                 self
746             }
747 
748             #[inline(always)]
749             fn simd_imaginary(self) -> Self::SimdRealField {
750                 Self::zero()
751             }
752 
753             #[inline(always)]
754             fn simd_norm1(self) -> Self::SimdRealField {
755                 Simd(self.0.abs())
756             }
757 
758             #[inline(always)]
759             fn simd_modulus(self) -> Self::SimdRealField {
760                 Simd(self.0.abs())
761             }
762 
763             #[inline(always)]
764             fn simd_modulus_squared(self) -> Self::SimdRealField {
765                 self * self
766             }
767 
768             #[inline(always)]
769             fn simd_argument(self) -> Self::SimdRealField {
770                 self.map_lanes(|e| e.argument())
771             }
772 
773             #[inline(always)]
774             fn simd_to_exp(self) -> (Self::SimdRealField, Self) {
775                 let ge = self.0.ge(Self::one().0);
776                 let exp = ge.select(Self::one().0, -Self::one().0);
777                 (Simd(self.0 * exp), Simd(exp))
778             }
779 
780             #[inline(always)]
781             fn simd_recip(self) -> Self {
782                 Self::one() / self
783             }
784 
785             #[inline(always)]
786             fn simd_conjugate(self) -> Self {
787                 self
788             }
789 
790             #[inline(always)]
791             fn simd_scale(self, factor: Self::SimdRealField) -> Self {
792                 Simd(self.0 * factor.0)
793             }
794 
795             #[inline(always)]
796             fn simd_unscale(self, factor: Self::SimdRealField) -> Self {
797                 Simd(self.0 / factor.0)
798             }
799 
800             #[inline(always)]
801             fn simd_floor(self) -> Self {
802                 self.map_lanes(|e| e.floor())
803             }
804 
805             #[inline(always)]
806             fn simd_ceil(self) -> Self {
807                 self.map_lanes(|e| e.ceil())
808             }
809 
810             #[inline(always)]
811             fn simd_round(self) -> Self {
812                 self.map_lanes(|e| e.round())
813             }
814 
815             #[inline(always)]
816             fn simd_trunc(self) -> Self {
817                 self.map_lanes(|e| e.trunc())
818             }
819 
820             #[inline(always)]
821             fn simd_fract(self) -> Self {
822                 self.map_lanes(|e| e.fract())
823             }
824 
825             #[inline(always)]
826             fn simd_abs(self) -> Self {
827                 Simd(self.0.abs())
828             }
829 
830             #[inline(always)]
831             fn simd_signum(self) -> Self {
832                 self.map_lanes(|e| e.signum())
833             }
834 
835             #[inline(always)]
836             fn simd_mul_add(self, a: Self, b: Self) -> Self {
837                 Simd(self.0.mul_add(a.0, b.0))
838             }
839 
840             #[inline(always)]
841             fn simd_powi(self, n: i32) -> Self {
842                Simd(self.0.powf(<$t>::splat(n as $elt)))
843             }
844 
845             #[inline(always)]
846             fn simd_powf(self, n: Self) -> Self {
847                 Simd(self.0.powf(n.0))
848             }
849 
850             #[inline(always)]
851             fn simd_powc(self, n: Self) -> Self {
852                Simd(self.0.powf(n.0))
853             }
854 
855             #[inline(always)]
856             fn simd_sqrt(self) -> Self {
857                 Simd(self.0.sqrt())
858             }
859 
860             #[inline(always)]
861             fn simd_exp(self) -> Self {
862                 Simd(self.0.exp())
863             }
864 
865             #[inline(always)]
866             fn simd_exp2(self) -> Self {
867                 self.map_lanes(|e| e.exp2())
868             }
869 
870 
871             #[inline(always)]
872             fn simd_exp_m1(self) -> Self {
873                 self.map_lanes(|e| e.exp_m1())
874             }
875 
876             #[inline(always)]
877             fn simd_ln_1p(self) -> Self {
878                 self.map_lanes(|e| e.ln_1p())
879             }
880 
881             #[inline(always)]
882             fn simd_ln(self) -> Self {
883                 Simd(self.0.ln())
884             }
885 
886             #[inline(always)]
887             fn simd_log(self, base: Self) -> Self {
888                 self.zip_map_lanes(base, |e, b| e.log(b))
889             }
890 
891             #[inline(always)]
892             fn simd_log2(self) -> Self {
893                 self.map_lanes(|e| e.log2())
894             }
895 
896             #[inline(always)]
897             fn simd_log10(self) -> Self {
898                 self.map_lanes(|e| e.log10())
899             }
900 
901             #[inline(always)]
902             fn simd_cbrt(self) -> Self {
903                 self.map_lanes(|e| e.cbrt())
904             }
905 
906             #[inline(always)]
907             fn simd_hypot(self, other: Self) -> Self::SimdRealField {
908                 self.zip_map_lanes(other, |e, o| e.hypot(o))
909             }
910 
911             #[inline(always)]
912             fn simd_sin(self) -> Self {
913                 Simd(self.0.sin())
914             }
915 
916             #[inline(always)]
917             fn simd_cos(self) -> Self {
918                 Simd(self.0.cos())
919             }
920 
921             #[inline(always)]
922             fn simd_tan(self) -> Self {
923                 self.map_lanes(|e| e.tan())
924             }
925 
926             #[inline(always)]
927             fn simd_asin(self) -> Self {
928                 self.map_lanes(|e| e.asin())
929             }
930 
931             #[inline(always)]
932             fn simd_acos(self) -> Self {
933                 self.map_lanes(|e| e.acos())
934             }
935 
936             #[inline(always)]
937             fn simd_atan(self) -> Self {
938                 self.map_lanes(|e| e.atan())
939             }
940 
941             #[inline(always)]
942             fn simd_sin_cos(self) -> (Self, Self) {
943                 (self.simd_sin(), self.simd_cos())
944             }
945 
946 //            #[inline(always]
947 //            fn simd_exp_m1(self) -> Self {
948 //                $libm::exp_m1(self)
949 //            }
950 //
951 //            #[inline(always]
952 //            fn simd_ln_1p(self) -> Self {
953 //                $libm::ln_1p(self)
954 //            }
955 //
956             #[inline(always)]
957             fn simd_sinh(self) -> Self {
958                 self.map_lanes(|e| e.sinh())
959             }
960 
961             #[inline(always)]
962             fn simd_cosh(self) -> Self {
963                 self.map_lanes(|e| e.cosh())
964             }
965 
966             #[inline(always)]
967             fn simd_tanh(self) -> Self {
968                 self.map_lanes(|e| e.tanh())
969             }
970 
971             #[inline(always)]
972             fn simd_asinh(self) -> Self {
973                 self.map_lanes(|e| e.asinh())
974             }
975 
976             #[inline(always)]
977             fn simd_acosh(self) -> Self {
978                 self.map_lanes(|e| e.acosh())
979             }
980 
981             #[inline(always)]
982             fn simd_atanh(self) -> Self {
983                 self.map_lanes(|e| e.atanh())
984             }
985         }
986 
987         // NOTE: most of the impls in there are copy-paste from the implementation of
988         // ComplexField for num_complex::Complex. Unfortunately, we can't reuse the implementations
989         // so easily.
990         impl SimdComplexField for num_complex::Complex<Simd<$t>> {
991             type SimdRealField = Simd<$t>;
992 
993             #[inline(always)]
994             fn simd_horizontal_sum(self) -> Self::Element {
995                 num_complex::Complex::new(self.re.simd_horizontal_sum(), self.im.simd_horizontal_sum())
996             }
997 
998             #[inline(always)]
999             fn simd_horizontal_product(self) -> Self::Element {
1000                 let mut prod = self.extract(0);
1001                 for ii in 1..Self::lanes() {
1002                     prod = prod * self.extract(ii)
1003                 }
1004                 prod
1005             }
1006 
1007             #[inline]
1008             fn from_simd_real(re: Self::SimdRealField) -> Self {
1009                 Self::new(re, Self::SimdRealField::zero())
1010             }
1011 
1012             #[inline]
1013             fn simd_real(self) -> Self::SimdRealField {
1014                 self.re
1015             }
1016 
1017             #[inline]
1018             fn simd_imaginary(self) -> Self::SimdRealField {
1019                 self.im
1020             }
1021 
1022             #[inline]
1023             fn simd_argument(self) -> Self::SimdRealField {
1024                 self.im.simd_atan2(self.re)
1025             }
1026 
1027             #[inline]
1028             fn simd_modulus(self) -> Self::SimdRealField {
1029                 self.re.simd_hypot(self.im)
1030             }
1031 
1032             #[inline]
1033             fn simd_modulus_squared(self) -> Self::SimdRealField {
1034                 self.re * self.re + self.im * self.im
1035             }
1036 
1037             #[inline]
1038             fn simd_norm1(self) -> Self::SimdRealField {
1039                 self.re.simd_abs() + self.im.simd_abs()
1040             }
1041 
1042             #[inline]
1043             fn simd_recip(self) -> Self {
1044                 Self::one() / self
1045             }
1046 
1047             #[inline]
1048             fn simd_conjugate(self) -> Self {
1049                 self.conj()
1050             }
1051 
1052             #[inline]
1053             fn simd_scale(self, factor: Self::SimdRealField) -> Self {
1054                 self * factor
1055             }
1056 
1057             #[inline]
1058             fn simd_unscale(self, factor: Self::SimdRealField) -> Self {
1059                 self / factor
1060             }
1061 
1062             #[inline]
1063             fn simd_floor(self) -> Self {
1064                 Self::new(self.re.simd_floor(), self.im.simd_floor())
1065             }
1066 
1067             #[inline]
1068             fn simd_ceil(self) -> Self {
1069                 Self::new(self.re.simd_ceil(), self.im.simd_ceil())
1070             }
1071 
1072             #[inline]
1073             fn simd_round(self) -> Self {
1074                 Self::new(self.re.simd_round(), self.im.simd_round())
1075             }
1076 
1077             #[inline]
1078             fn simd_trunc(self) -> Self {
1079                 Self::new(self.re.simd_trunc(), self.im.simd_trunc())
1080             }
1081 
1082             #[inline]
1083             fn simd_fract(self) -> Self {
1084                 Self::new(self.re.simd_fract(), self.im.simd_fract())
1085             }
1086 
1087             #[inline]
1088             fn simd_mul_add(self, a: Self, b: Self) -> Self {
1089                 self * a + b
1090             }
1091 
1092             #[inline]
1093             fn simd_abs(self) -> Self::SimdRealField {
1094                 self.simd_modulus()
1095             }
1096 
1097             #[inline]
1098             fn simd_exp2(self) -> Self {
1099                 let _2 = Simd::<$t>::one() + Simd::<$t>::one();
1100                 num_complex::Complex::new(_2, Simd::<$t>::zero()).simd_powc(self)
1101             }
1102 
1103             #[inline]
1104             fn simd_exp_m1(self) -> Self {
1105                 self.simd_exp() - Self::one()
1106             }
1107 
1108             #[inline]
1109             fn simd_ln_1p(self) -> Self {
1110                 (Self::one() + self).simd_ln()
1111             }
1112 
1113             #[inline]
1114             fn simd_log2(self) -> Self {
1115                 let _2 = Simd::<$t>::one() + Simd::<$t>::one();
1116                 self.simd_log(_2)
1117             }
1118 
1119             #[inline]
1120             fn simd_log10(self) -> Self {
1121                 let _10 = Simd::<$t>::from_subset(&10.0f64);
1122                 self.simd_log(_10)
1123             }
1124 
1125             #[inline]
1126             fn simd_cbrt(self) -> Self {
1127                 let one_third = Simd::<$t>::from_subset(&(1.0 / 3.0));
1128                 self.simd_powf(one_third)
1129             }
1130 
1131             #[inline]
1132             fn simd_powi(self, n: i32) -> Self {
1133                 // FIXME: is there a more accurate solution?
1134                 let n = Simd::<$t>::from_subset(&(n as f64));
1135                 self.simd_powf(n)
1136             }
1137 
1138             /*
1139              *
1140              *
1141              * Unfortunately we are forced to copy-paste all
1142              * those impls from https://github.com/rust-num/num-complex/blob/master/src/lib.rs
1143              * to avoid requiring `std`.
1144              *
1145              *
1146              */
1147             /// Computes `e^(self)`, where `e` is the base of the natural logarithm.
1148             #[inline]
1149             fn simd_exp(self) -> Self {
1150                 // formula: e^(a + bi) = e^a (cos(b) + i*sin(b))
1151                 // = from_polar(e^a, b)
1152                 simd_complex_from_polar(self.re.simd_exp(), self.im)
1153             }
1154 
1155             /// Computes the principal value of natural logarithm of `self`.
1156             ///
1157             /// This function has one branch cut:
1158             ///
1159             /// * `(-∞, 0]`, continuous from above.
1160             ///
1161             /// The branch satisfies `-π ≤ arg(ln(z)) ≤ π`.
1162             #[inline]
1163             fn simd_ln(self) -> Self {
1164                 // formula: ln(z) = ln|z| + i*arg(z)
1165                 let (r, theta) = self.simd_to_polar();
1166                 Self::new(r.simd_ln(), theta)
1167             }
1168 
1169             /// Computes the principal value of the square root of `self`.
1170             ///
1171             /// This function has one branch cut:
1172             ///
1173             /// * `(-∞, 0)`, continuous from above.
1174             ///
1175             /// The branch satisfies `-π/2 ≤ arg(sqrt(z)) ≤ π/2`.
1176             #[inline]
1177             fn simd_sqrt(self) -> Self {
1178                 // formula: sqrt(r e^(it)) = sqrt(r) e^(it/2)
1179                 let two = Simd::<$t>::one() + Simd::<$t>::one();
1180                 let (r, theta) = self.simd_to_polar();
1181                 simd_complex_from_polar(r.simd_sqrt(), theta / two)
1182             }
1183 
1184             #[inline]
1185             fn simd_hypot(self, b: Self) -> Self::SimdRealField {
1186                 (self.simd_modulus_squared() + b.simd_modulus_squared()).simd_sqrt()
1187             }
1188 
1189             /// Raises `self` to a floating point power.
1190             #[inline]
1191             fn simd_powf(self, exp: Self::SimdRealField) -> Self {
1192                 // formula: x^y = (ρ e^(i θ))^y = ρ^y e^(i θ y)
1193                 // = from_polar(ρ^y, θ y)
1194                 let (r, theta) = self.simd_to_polar();
1195                 simd_complex_from_polar(r.simd_powf(exp), theta * exp)
1196             }
1197 
1198             /// Returns the logarithm of `self` with respect to an arbitrary base.
1199             #[inline]
1200             fn simd_log(self, base: Simd<$t>) -> Self {
1201                 // formula: log_y(x) = log_y(ρ e^(i θ))
1202                 // = log_y(ρ) + log_y(e^(i θ)) = log_y(ρ) + ln(e^(i θ)) / ln(y)
1203                 // = log_y(ρ) + i θ / ln(y)
1204                 let (r, theta) = self.simd_to_polar();
1205                 Self::new(r.simd_log(base), theta / base.simd_ln())
1206             }
1207 
1208             /// Raises `self` to a complex power.
1209             #[inline]
1210             fn simd_powc(self, exp: Self) -> Self {
1211                 // formula: x^y = (a + i b)^(c + i d)
1212                 // = (ρ e^(i θ))^c (ρ e^(i θ))^(i d)
1213                 //    where ρ=|x| and θ=arg(x)
1214                 // = ρ^c e^(−d θ) e^(i c θ) ρ^(i d)
1215                 // = p^c e^(−d θ) (cos(c θ)
1216                 //   + i sin(c θ)) (cos(d ln(ρ)) + i sin(d ln(ρ)))
1217                 // = p^c e^(−d θ) (
1218                 //   cos(c θ) cos(d ln(ρ)) − sin(c θ) sin(d ln(ρ))
1219                 //   + i(cos(c θ) sin(d ln(ρ)) + sin(c θ) cos(d ln(ρ))))
1220                 // = p^c e^(−d θ) (cos(c θ + d ln(ρ)) + i sin(c θ + d ln(ρ)))
1221                 // = from_polar(p^c e^(−d θ), c θ + d ln(ρ))
1222                 let (r, theta) = self.simd_to_polar();
1223                 simd_complex_from_polar(
1224                     r.simd_powf(exp.re) * (-exp.im * theta).simd_exp(),
1225                     exp.re * theta + exp.im * r.simd_ln(),
1226                 )
1227             }
1228 
1229             /*
1230             /// Raises a floating point number to the complex power `self`.
1231             #[inline]
1232             fn simd_expf(&self, base: T) -> Self {
1233                 // formula: x^(a+bi) = x^a x^bi = x^a e^(b ln(x) i)
1234                 // = from_polar(x^a, b ln(x))
1235                 Self::from_polar(&base.powf(self.re), &(self.im * base.ln()))
1236             }
1237             */
1238 
1239             /// Computes the sine of `self`.
1240             #[inline]
1241             fn simd_sin(self) -> Self {
1242                 // formula: sin(a + bi) = sin(a)cosh(b) + i*cos(a)sinh(b)
1243                 Self::new(
1244                     self.re.simd_sin() * self.im.simd_cosh(),
1245                     self.re.simd_cos() * self.im.simd_sinh(),
1246                 )
1247             }
1248 
1249             /// Computes the cosine of `self`.
1250             #[inline]
1251             fn simd_cos(self) -> Self {
1252                 // formula: cos(a + bi) = cos(a)cosh(b) - i*sin(a)sinh(b)
1253                 Self::new(
1254                     self.re.simd_cos() * self.im.simd_cosh(),
1255                     -self.re.simd_sin() * self.im.simd_sinh(),
1256                 )
1257             }
1258 
1259             #[inline]
1260             fn simd_sin_cos(self) -> (Self, Self) {
1261                 let (rsin, rcos) = self.re.simd_sin_cos();
1262                 let (isinh, icosh) = self.im.simd_sinh_cosh();
1263                 let sin = Self::new(rsin * icosh, rcos * isinh);
1264                 let cos = Self::new(rcos * icosh, -rsin * isinh);
1265 
1266                 (sin, cos)
1267             }
1268 
1269             /// Computes the tangent of `self`.
1270             #[inline]
1271             fn simd_tan(self) -> Self {
1272                 // formula: tan(a + bi) = (sin(2a) + i*sinh(2b))/(cos(2a) + cosh(2b))
1273                 let (two_re, two_im) = (self.re + self.re, self.im + self.im);
1274                 Self::new(two_re.simd_sin(), two_im.simd_sinh()).unscale(two_re.simd_cos() + two_im.simd_cosh())
1275             }
1276 
1277             /// Computes the principal value of the inverse sine of `self`.
1278             ///
1279             /// This function has two branch cuts:
1280             ///
1281             /// * `(-∞, -1)`, continuous from above.
1282             /// * `(1, ∞)`, continuous from below.
1283             ///
1284             /// The branch satisfies `-π/2 ≤ Re(asin(z)) ≤ π/2`.
1285             #[inline]
1286             fn simd_asin(self) -> Self {
1287                 // formula: arcsin(z) = -i ln(sqrt(1-z^2) + iz)
1288                 let i = Self::i();
1289                 -i * ((Self::one() - self * self).simd_sqrt() + i * self).simd_ln()
1290             }
1291 
1292             /// Computes the principal value of the inverse cosine of `self`.
1293             ///
1294             /// This function has two branch cuts:
1295             ///
1296             /// * `(-∞, -1)`, continuous from above.
1297             /// * `(1, ∞)`, continuous from below.
1298             ///
1299             /// The branch satisfies `0 ≤ Re(acos(z)) ≤ π`.
1300             #[inline]
1301             fn simd_acos(self) -> Self {
1302                 // formula: arccos(z) = -i ln(i sqrt(1-z^2) + z)
1303                 let i = Self::i();
1304                 -i * (i * (Self::one() - self * self).simd_sqrt() + self).simd_ln()
1305             }
1306 
1307             /// Computes the principal value of the inverse tangent of `self`.
1308             ///
1309             /// This function has two branch cuts:
1310             ///
1311             /// * `(-∞i, -i]`, continuous from the left.
1312             /// * `[i, ∞i)`, continuous from the right.
1313             ///
1314             /// The branch satisfies `-π/2 ≤ Re(atan(z)) ≤ π/2`.
1315             #[inline]
1316             fn simd_atan(self) -> Self {
1317                 // formula: arctan(z) = (ln(1+iz) - ln(1-iz))/(2i)
1318                 let i = Self::i();
1319                 let one = Self::one();
1320                 let two = one + one;
1321 
1322                 if self == i {
1323                     return Self::new(Simd::<$t>::zero(), Simd::<$t>::one() / Simd::<$t>::zero());
1324                 } else if self == -i {
1325                     return Self::new(Simd::<$t>::zero(), -Simd::<$t>::one() / Simd::<$t>::zero());
1326                 }
1327 
1328                 ((one + i * self).simd_ln() - (one - i * self).simd_ln()) / (two * i)
1329             }
1330 
1331             /// Computes the hyperbolic sine of `self`.
1332             #[inline]
1333             fn simd_sinh(self) -> Self {
1334                 // formula: sinh(a + bi) = sinh(a)cos(b) + i*cosh(a)sin(b)
1335                 Self::new(
1336                     self.re.simd_sinh() * self.im.simd_cos(),
1337                     self.re.simd_cosh() * self.im.simd_sin(),
1338                 )
1339             }
1340 
1341             /// Computes the hyperbolic cosine of `self`.
1342             #[inline]
1343             fn simd_cosh(self) -> Self {
1344                 // formula: cosh(a + bi) = cosh(a)cos(b) + i*sinh(a)sin(b)
1345                 Self::new(
1346                     self.re.simd_cosh() * self.im.simd_cos(),
1347                     self.re.simd_sinh() * self.im.simd_sin(),
1348                 )
1349             }
1350 
1351             #[inline]
1352             fn simd_sinh_cosh(self) -> (Self, Self) {
1353                 let (rsinh, rcosh) = self.re.simd_sinh_cosh();
1354                 let (isin, icos) = self.im.simd_sin_cos();
1355                 let sin = Self::new(rsinh * icos, rcosh * isin);
1356                 let cos = Self::new(rcosh * icos, rsinh * isin);
1357 
1358                 (sin, cos)
1359             }
1360 
1361             /// Computes the hyperbolic tangent of `self`.
1362             #[inline]
1363             fn simd_tanh(self) -> Self {
1364                 // formula: tanh(a + bi) = (sinh(2a) + i*sin(2b))/(cosh(2a) + cos(2b))
1365                 let (two_re, two_im) = (self.re + self.re, self.im + self.im);
1366                 Self::new(two_re.simd_sinh(), two_im.simd_sin()).unscale(two_re.simd_cosh() + two_im.simd_cos())
1367             }
1368 
1369             /// Computes the principal value of inverse hyperbolic sine of `self`.
1370             ///
1371             /// This function has two branch cuts:
1372             ///
1373             /// * `(-∞i, -i)`, continuous from the left.
1374             /// * `(i, ∞i)`, continuous from the right.
1375             ///
1376             /// The branch satisfies `-π/2 ≤ Im(asinh(z)) ≤ π/2`.
1377             #[inline]
1378             fn simd_asinh(self) -> Self {
1379                 // formula: arcsinh(z) = ln(z + sqrt(1+z^2))
1380                 let one = Self::one();
1381                 (self + (one + self * self).simd_sqrt()).simd_ln()
1382             }
1383 
1384             /// Computes the principal value of inverse hyperbolic cosine of `self`.
1385             ///
1386             /// This function has one branch cut:
1387             ///
1388             /// * `(-∞, 1)`, continuous from above.
1389             ///
1390             /// The branch satisfies `-π ≤ Im(acosh(z)) ≤ π` and `0 ≤ Re(acosh(z)) < ∞`.
1391             #[inline]
1392             fn simd_acosh(self) -> Self {
1393                 // formula: arccosh(z) = 2 ln(sqrt((z+1)/2) + sqrt((z-1)/2))
1394                 let one = Self::one();
1395                 let two = one + one;
1396                 two * (((self + one) / two).simd_sqrt() + ((self - one) / two).simd_sqrt()).simd_ln()
1397             }
1398 
1399             /// Computes the principal value of inverse hyperbolic tangent of `self`.
1400             ///
1401             /// This function has two branch cuts:
1402             ///
1403             /// * `(-∞, -1]`, continuous from above.
1404             /// * `[1, ∞)`, continuous from below.
1405             ///
1406             /// The branch satisfies `-π/2 ≤ Im(atanh(z)) ≤ π/2`.
1407             #[inline]
1408             fn simd_atanh(self) -> Self {
1409                 // formula: arctanh(z) = (ln(1+z) - ln(1-z))/2
1410                 let one = Self::one();
1411                 let two = one + one;
1412                 if self == one {
1413                     return Self::new(Simd::<$t>::one() / Simd::<$t>::zero(), Simd::<$t>::zero());
1414                 } else if self == -one {
1415                     return Self::new(-Simd::<$t>::one() / Simd::<$t>::zero(), Simd::<$t>::zero());
1416                 }
1417                 ((one + self).simd_ln() - (one - self).simd_ln()) / two
1418             }
1419         }
1420     )*)
1421 );
1422 
1423 #[inline]
simd_complex_from_polar<N: SimdRealField>(r: N, theta: N) -> num_complex::Complex<N>1424 fn simd_complex_from_polar<N: SimdRealField>(r: N, theta: N) -> num_complex::Complex<N> {
1425     num_complex::Complex::new(r.clone() * theta.clone().simd_cos(), r * theta.simd_sin())
1426 }
1427 
1428 impl_float_simd!(
1429     packed_simd::f32x2, f32, packed_simd::i32x2, m32x2, _0, _1;
1430     packed_simd::f32x4, f32, packed_simd::i32x4, m32x4, _0, _1, _2, _3;
1431     packed_simd::f32x8, f32, packed_simd::i32x8, m32x8, _0, _1, _2, _3, _4, _5, _6, _7;
1432     packed_simd::f32x16, f32, packed_simd::i32x16, m32x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1433     packed_simd::f64x2, f64, packed_simd::i64x2, m64x2, _0, _1;
1434     packed_simd::f64x4, f64, packed_simd::i64x4, m64x4, _0, _1, _2, _3;
1435     packed_simd::f64x8, f64, packed_simd::i64x8, m64x8, _0, _1, _2, _3, _4, _5, _6, _7;
1436 );
1437 
1438 impl_int_simd!(
1439     packed_simd::i128x1, i128, m128x1, _0;
1440     packed_simd::i128x2, i128, m128x2, _0, _1;
1441     packed_simd::i128x4, i128, m128x4, _0, _1, _2, _3;
1442     packed_simd::i16x2, i16, m16x2, _0, _1;
1443     packed_simd::i16x4, i16, m16x4, _0, _1, _2, _3;
1444     packed_simd::i16x8, i16, m16x8, _0, _1, _2, _3, _4, _5, _6, _7;
1445     packed_simd::i16x16, i16, m16x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1446     packed_simd::i16x32, i16, m16x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1447     packed_simd::i32x2, i32, m32x2, _0, _1;
1448     packed_simd::i32x4, i32, m32x4, _0, _1, _2, _3;
1449     packed_simd::i32x8, i32, m32x8, _0, _1, _2, _3, _4, _5, _6, _7;
1450     packed_simd::i32x16, i32, m32x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1451     packed_simd::i64x2, i64, m64x2, _0, _1;
1452     packed_simd::i64x4, i64, m64x4, _0, _1, _2, _3;
1453     packed_simd::i64x8, i64, m64x8, _0, _1, _2, _3, _4, _5, _6, _7;
1454     packed_simd::i8x2, i8, m8x2, _0, _1;
1455     packed_simd::i8x4, i8, m8x4, _0, _1, _2, _3;
1456     packed_simd::i8x8, i8, m8x8, _0, _1, _2, _3, _4, _5, _6, _7;
1457     packed_simd::i8x16, i8, m8x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1458     packed_simd::i8x32, i8, m8x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1459     packed_simd::i8x64, i8, m8x64, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63;
1460     packed_simd::isizex2, isize, msizex2, _0, _1;
1461     packed_simd::isizex4, isize, msizex4, _0, _1, _2, _3;
1462     packed_simd::isizex8, isize, msizex8, _0, _1, _2, _3, _4, _5, _6, _7;
1463 );
1464 
1465 impl_uint_simd!(
1466     packed_simd::u128x1, u128, m128x1, _0;
1467     packed_simd::u128x2, u128, m128x2, _0, _1;
1468     packed_simd::u128x4, u128, m128x4, _0, _1, _2, _3;
1469     packed_simd::u16x2, u16, m16x2, _0, _1;
1470     packed_simd::u16x4, u16, m16x4, _0, _1, _2, _3;
1471     packed_simd::u16x8, u16, m16x8, _0, _1, _2, _3, _4, _5, _6, _7;
1472     packed_simd::u16x16, u16, m16x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1473     packed_simd::u16x32, u16, m16x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1474     packed_simd::u32x2, u32, m32x2, _0, _1;
1475     packed_simd::u32x4, u32, m32x4, _0, _1, _2, _3;
1476     packed_simd::u32x8, u32, m32x8, _0, _1, _2, _3, _4, _5, _6, _7;
1477     packed_simd::u32x16, u32, m32x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1478     packed_simd::u64x2, u64, m64x2, _0, _1;
1479     packed_simd::u64x4, u64, m64x4, _0, _1, _2, _3;
1480     packed_simd::u64x8, u64, m64x8, _0, _1, _2, _3, _4, _5, _6, _7;
1481     packed_simd::u8x2, u8, m8x2, _0, _1;
1482     packed_simd::u8x4, u8, m8x4, _0, _1, _2, _3;
1483     packed_simd::u8x8, u8, m8x8, _0, _1, _2, _3, _4, _5, _6, _7;
1484     packed_simd::u8x16, u8, m8x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1485     packed_simd::u8x32, u8, m8x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1486     packed_simd::u8x64, u8, m8x64, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63;
1487     packed_simd::usizex2, usize, msizex2, _0, _1;
1488     packed_simd::usizex4, usize, msizex4, _0, _1, _2, _3;
1489     packed_simd::usizex8, usize, msizex8, _0, _1, _2, _3, _4, _5, _6, _7;
1490 );
1491 
1492 impl_bool_simd!(
1493     packed_simd::m128x1, _0;
1494     packed_simd::m128x2, _0, _1;
1495     packed_simd::m128x4, _0, _1, _2, _3;
1496     packed_simd::m16x2, _0, _1;
1497     packed_simd::m16x4, _0, _1, _2, _3;
1498     packed_simd::m16x8, _0, _1, _2, _3, _4, _5, _6, _7;
1499     packed_simd::m16x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1500     packed_simd::m16x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1501     packed_simd::m32x2, _0, _1;
1502     packed_simd::m32x4, _0, _1, _2, _3;
1503     packed_simd::m32x8, _0, _1, _2, _3, _4, _5, _6, _7;
1504     packed_simd::m32x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1505     packed_simd::m64x2, _0, _1;
1506     packed_simd::m64x4, _0, _1, _2, _3;
1507     packed_simd::m64x8, _0, _1, _2, _3, _4, _5, _6, _7;
1508     packed_simd::m8x2, _0, _1;
1509     packed_simd::m8x4, _0, _1, _2, _3;
1510     packed_simd::m8x8, _0, _1, _2, _3, _4, _5, _6, _7;
1511     packed_simd::m8x16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1512     packed_simd::m8x32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1513     packed_simd::m8x64, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63;
1514     packed_simd::msizex2, _0, _1;
1515     packed_simd::msizex4, _0, _1, _2, _3;
1516     packed_simd::msizex8, _0, _1, _2, _3, _4, _5, _6, _7;
1517 );
1518 
1519 //
1520 // NOTE: the following does not work because of the orphan rules.
1521 //
1522 //macro_rules! impl_simd_complex_from(
1523 //    ($($t: ty, $elt: ty $(, $i: expr)*;)*) => ($(
1524 //        impl From<[num_complex::Complex<$elt>; <$t>::lanes()]> for num_complex::Complex<Simd<$t>> {
1525 //            #[inline(always)]
1526 //            fn from(vals: [num_complex::Complex<$elt>; <$t>::lanes()]) -> Self {
1527 //                num_complex::Complex {
1528 //                    re: <$t>::from([$(vals[$i].re),*]),
1529 //                    im: <$t>::from([$(vals[$i].im),*]),
1530 //                }
1531 //            }
1532 //        }
1533 //    )*)
1534 //);
1535 //
1536 //impl_simd_complex_from!(
1537 //    packed_simd::f32x2, f32, 0, 1;
1538 //    packed_simd::f32x4, f32, 0, 1, 2, 3;
1539 //    packed_simd::f32x8, f32, 0, 1, 2, 3, 4, 5, 6, 7;
1540 //    packed_simd::f32x16, f32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15;
1541 //);
1542 
1543 //////////////////////////////////////////
1544 //               Aliases                //
1545 //////////////////////////////////////////
1546 
1547 pub type f32x2 = Simd<packed_simd::f32x2>;
1548 pub type f32x4 = Simd<packed_simd::f32x4>;
1549 pub type f32x8 = Simd<packed_simd::f32x8>;
1550 pub type f32x16 = Simd<packed_simd::f32x16>;
1551 pub type f64x2 = Simd<packed_simd::f64x2>;
1552 pub type f64x4 = Simd<packed_simd::f64x4>;
1553 pub type f64x8 = Simd<packed_simd::f64x8>;
1554 pub type i128x1 = Simd<packed_simd::i128x1>;
1555 pub type i128x2 = Simd<packed_simd::i128x2>;
1556 pub type i128x4 = Simd<packed_simd::i128x4>;
1557 pub type i16x2 = Simd<packed_simd::i16x2>;
1558 pub type i16x4 = Simd<packed_simd::i16x4>;
1559 pub type i16x8 = Simd<packed_simd::i16x8>;
1560 pub type i16x16 = Simd<packed_simd::i16x16>;
1561 pub type i16x32 = Simd<packed_simd::i16x32>;
1562 pub type i32x2 = Simd<packed_simd::i32x2>;
1563 pub type i32x4 = Simd<packed_simd::i32x4>;
1564 pub type i32x8 = Simd<packed_simd::i32x8>;
1565 pub type i32x16 = Simd<packed_simd::i32x16>;
1566 pub type i64x2 = Simd<packed_simd::i64x2>;
1567 pub type i64x4 = Simd<packed_simd::i64x4>;
1568 pub type i64x8 = Simd<packed_simd::i64x8>;
1569 pub type i8x2 = Simd<packed_simd::i8x2>;
1570 pub type i8x4 = Simd<packed_simd::i8x4>;
1571 pub type i8x8 = Simd<packed_simd::i8x8>;
1572 pub type i8x16 = Simd<packed_simd::i8x16>;
1573 pub type i8x32 = Simd<packed_simd::i8x32>;
1574 pub type i8x64 = Simd<packed_simd::i8x64>;
1575 pub type isizex2 = Simd<packed_simd::isizex2>;
1576 pub type isizex4 = Simd<packed_simd::isizex4>;
1577 pub type isizex8 = Simd<packed_simd::isizex8>;
1578 pub type u128x1 = Simd<packed_simd::u128x1>;
1579 pub type u128x2 = Simd<packed_simd::u128x2>;
1580 pub type u128x4 = Simd<packed_simd::u128x4>;
1581 pub type u16x2 = Simd<packed_simd::u16x2>;
1582 pub type u16x4 = Simd<packed_simd::u16x4>;
1583 pub type u16x8 = Simd<packed_simd::u16x8>;
1584 pub type u16x16 = Simd<packed_simd::u16x16>;
1585 pub type u16x32 = Simd<packed_simd::u16x32>;
1586 pub type u32x2 = Simd<packed_simd::u32x2>;
1587 pub type u32x4 = Simd<packed_simd::u32x4>;
1588 pub type u32x8 = Simd<packed_simd::u32x8>;
1589 pub type u32x16 = Simd<packed_simd::u32x16>;
1590 pub type u64x2 = Simd<packed_simd::u64x2>;
1591 pub type u64x4 = Simd<packed_simd::u64x4>;
1592 pub type u64x8 = Simd<packed_simd::u64x8>;
1593 pub type u8x2 = Simd<packed_simd::u8x2>;
1594 pub type u8x4 = Simd<packed_simd::u8x4>;
1595 pub type u8x8 = Simd<packed_simd::u8x8>;
1596 pub type u8x16 = Simd<packed_simd::u8x16>;
1597 pub type u8x32 = Simd<packed_simd::u8x32>;
1598 pub type u8x64 = Simd<packed_simd::u8x64>;
1599 pub type usizex2 = Simd<packed_simd::usizex2>;
1600 pub type usizex4 = Simd<packed_simd::usizex4>;
1601 pub type usizex8 = Simd<packed_simd::usizex8>;
1602 
1603 pub type m128x1 = Simd<packed_simd::m128x1>;
1604 pub type m128x2 = Simd<packed_simd::m128x2>;
1605 pub type m128x4 = Simd<packed_simd::m128x4>;
1606 pub type m16x16 = Simd<packed_simd::m16x16>;
1607 pub type m16x2 = Simd<packed_simd::m16x2>;
1608 pub type m16x32 = Simd<packed_simd::m16x32>;
1609 pub type m16x4 = Simd<packed_simd::m16x4>;
1610 pub type m16x8 = Simd<packed_simd::m16x8>;
1611 pub type m32x16 = Simd<packed_simd::m32x16>;
1612 pub type m32x2 = Simd<packed_simd::m32x2>;
1613 pub type m32x4 = Simd<packed_simd::m32x4>;
1614 pub type m32x8 = Simd<packed_simd::m32x8>;
1615 pub type m64x2 = Simd<packed_simd::m64x2>;
1616 pub type m64x4 = Simd<packed_simd::m64x4>;
1617 pub type m64x8 = Simd<packed_simd::m64x8>;
1618 pub type m8x16 = Simd<packed_simd::m8x16>;
1619 pub type m8x2 = Simd<packed_simd::m8x2>;
1620 pub type m8x32 = Simd<packed_simd::m8x32>;
1621 pub type m8x4 = Simd<packed_simd::m8x4>;
1622 pub type m8x64 = Simd<packed_simd::m8x64>;
1623 pub type m8x8 = Simd<packed_simd::m8x8>;
1624 pub type msizex2 = Simd<packed_simd::msizex2>;
1625 pub type msizex4 = Simd<packed_simd::msizex4>;
1626 pub type msizex8 = Simd<packed_simd::msizex8>;
1627