faer_entity/
lib.rs

1#![allow(clippy::type_complexity)]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4pub use pulp;
5
6use bytemuck::Pod;
7use core::{fmt::Debug, marker::PhantomData, mem::ManuallyDrop, ptr::addr_of_mut};
8use num_complex::Complex;
9use pulp::Simd;
10use reborrow::*;
11
12fn sqrt_impl<E: RealField>(re: E, im: E) -> (E, E) {
13    let im_sign = if im >= E::faer_zero() {
14        E::faer_one()
15    } else {
16        E::faer_one().faer_neg()
17    };
18    let half = E::faer_from_f64(0.5);
19
20    let abs = (re.faer_abs2().faer_add(im.faer_abs2())).faer_sqrt();
21    let sum = re.faer_add(abs);
22    // to avoid the sum being negative with inexact floating point arithmetic (i.e., double-double)
23    let sum = if sum > E::faer_zero() {
24        sum
25    } else {
26        E::faer_zero()
27    };
28    let a = (sum.faer_scale_power_of_two(half)).faer_sqrt();
29    let b = ((re.faer_neg().faer_add(abs)).faer_scale_power_of_two(half))
30        .faer_sqrt()
31        .faer_scale_power_of_two(im_sign);
32
33    (a, b)
34}
35
36#[inline(always)]
37pub fn slice_as_simd<E: ComplexField, S: Simd>(
38    slice: GroupFor<E, &[UnitFor<E>]>,
39) -> (
40    GroupFor<E, &[SimdUnitFor<E, S>]>,
41    GroupFor<E, &[UnitFor<E>]>,
42) {
43    let (a_head, a_tail) = E::faer_unzip(E::faer_map(
44        slice,
45        #[inline(always)]
46        |slice| E::faer_slice_as_simd::<S>(slice),
47    ));
48    (a_head, a_tail)
49}
50
51#[inline(always)]
52pub fn slice_as_mut_simd<E: ComplexField, S: Simd>(
53    slice: GroupFor<E, &mut [UnitFor<E>]>,
54) -> (
55    GroupFor<E, &mut [SimdUnitFor<E, S>]>,
56    GroupFor<E, &mut [UnitFor<E>]>,
57) {
58    let (a_head, a_tail) = E::faer_unzip(E::faer_map(
59        slice,
60        #[inline(always)]
61        |slice| E::faer_slice_as_simd_mut::<S>(slice),
62    ));
63    (a_head, a_tail)
64}
65
66#[inline(always)]
67pub fn simd_as_slice_unit<E: ComplexField, S: Simd>(values: &[SimdUnitFor<E, S>]) -> &[UnitFor<E>] {
68    unsafe {
69        core::slice::from_raw_parts(
70            values.as_ptr() as *const UnitFor<E>,
71            values.len()
72                * (core::mem::size_of::<SimdUnitFor<E, S>>() / core::mem::size_of::<UnitFor<E>>()),
73        )
74    }
75}
76
77#[inline(always)]
78pub fn simd_as_slice<E: ComplexField, S: Simd>(
79    values: GroupFor<E, &[SimdUnitFor<E, S>]>,
80) -> GroupFor<E, &[UnitFor<E>]> {
81    E::faer_map(
82        values,
83        #[inline(always)]
84        |values| simd_as_slice_unit::<E, S>(values),
85    )
86}
87
88#[inline(always)]
89pub fn one_simd_as_slice<E: ComplexField, S: Simd>(
90    values: GroupFor<E, &SimdUnitFor<E, S>>,
91) -> GroupFor<E, &[UnitFor<E>]> {
92    E::faer_map(
93        values,
94        #[inline(always)]
95        |values| simd_as_slice_unit::<E, S>(core::slice::from_ref(values)),
96    )
97}
98
99#[inline(always)]
100pub fn simd_index_as_slice<E: RealField, S: Simd>(
101    indices: &[SimdIndexFor<E, S>],
102) -> &[IndexFor<E>] {
103    unsafe {
104        core::slice::from_raw_parts(
105            indices.as_ptr() as *const IndexFor<E>,
106            indices.len()
107                * (core::mem::size_of::<SimdIndexFor<E, S>>()
108                    / core::mem::size_of::<IndexFor<E>>()),
109        )
110    }
111}
112
113#[inline(always)]
114#[doc(hidden)]
115pub unsafe fn transmute_unchecked<From, To>(t: From) -> To {
116    assert!(core::mem::size_of::<From>() == core::mem::size_of::<To>());
117    assert!(core::mem::align_of::<From>() == core::mem::align_of::<To>());
118    core::mem::transmute_copy(&ManuallyDrop::new(t))
119}
120
121pub trait ForType {
122    type FaerOf<T>;
123}
124pub trait ForCopyType: ForType {
125    type FaerOfCopy<T: Copy>: Copy;
126}
127pub trait ForDebugType: ForType {
128    type FaerOfDebug<T: Debug>: Debug;
129}
130
131pub struct IdentityGroup {
132    __private: (),
133}
134impl ForDebugType for IdentityGroup {
135    type FaerOfDebug<T: Debug> = T;
136}
137impl ForCopyType for IdentityGroup {
138    type FaerOfCopy<T: Copy> = T;
139}
140impl ForType for IdentityGroup {
141    type FaerOf<T> = T;
142}
143
144pub struct ComplexGroup<Group> {
145    __private: PhantomData<Group>,
146}
147pub struct ComplexConjGroup<Group> {
148    __private: PhantomData<Group>,
149}
150
151impl<Group: ForDebugType> ForDebugType for ComplexConjGroup<Group> {
152    type FaerOfDebug<T: Debug> = ComplexConj<Group::FaerOfDebug<T>>;
153}
154impl<Group: ForCopyType> ForCopyType for ComplexConjGroup<Group> {
155    type FaerOfCopy<T: Copy> = ComplexConj<Group::FaerOfCopy<T>>;
156}
157impl<Group: ForType> ForType for ComplexConjGroup<Group> {
158    type FaerOf<T> = ComplexConj<Group::FaerOf<T>>;
159}
160impl<Group: ForDebugType> ForDebugType for ComplexGroup<Group> {
161    type FaerOfDebug<T: Debug> = Complex<Group::FaerOfDebug<T>>;
162}
163impl<Group: ForCopyType> ForCopyType for ComplexGroup<Group> {
164    type FaerOfCopy<T: Copy> = Complex<Group::FaerOfCopy<T>>;
165}
166impl<Group: ForType> ForType for ComplexGroup<Group> {
167    type FaerOf<T> = Complex<Group::FaerOf<T>>;
168}
169
170pub type PtrConst<E> = GroupFor<E, *const <E as Entity>::Unit>;
171pub type PtrMut<E> = GroupFor<E, *mut <E as Entity>::Unit>;
172pub type Ref<'a, E> = GroupFor<E, &'a <E as Entity>::Unit>;
173pub type Mut<'a, E> = GroupFor<E, &'a mut <E as Entity>::Unit>;
174pub type Slice<'a, E> = GroupFor<E, &'a [<E as Entity>::Unit]>;
175pub type SliceMut<'a, E> = GroupFor<E, &'a mut [<E as Entity>::Unit]>;
176pub type UninitSliceMut<'a, E> = GroupFor<E, &'a mut [core::mem::MaybeUninit<<E as Entity>::Unit>]>;
177
178extern crate alloc;
179pub type Vector<E> = GroupFor<E, alloc::vec::Vec<<E as Entity>::Unit>>;
180
181pub type GroupFor<E, T> = <<E as Entity>::Group as ForType>::FaerOf<T>;
182pub type GroupCopyFor<E, T> = <<E as Entity>::Group as ForCopyType>::FaerOfCopy<T>;
183pub type GroupDebugFor<E, T> = <<E as Entity>::Group as ForDebugType>::FaerOfDebug<T>;
184pub type UnitFor<E> = <E as Entity>::Unit;
185pub type IndexFor<E> = <E as Entity>::Index;
186
187pub type SimdUnitFor<E, S> = <E as Entity>::SimdUnit<S>;
188pub type SimdMaskFor<E, S> = <E as Entity>::SimdMask<S>;
189pub type SimdIndexFor<E, S> = <E as Entity>::SimdIndex<S>;
190
191pub type SimdGroupFor<E, S> = GroupCopyFor<E, SimdUnitFor<E, S>>;
192
193#[inline(always)]
194pub fn into_copy<E: Entity, T: Copy>(x: GroupFor<E, T>) -> GroupCopyFor<E, T> {
195    unsafe { transmute_unchecked(x) }
196}
197#[inline(always)]
198pub fn from_copy<E: Entity, T: Copy>(x: GroupCopyFor<E, T>) -> GroupFor<E, T> {
199    unsafe { transmute_unchecked(x) }
200}
201
202pub trait UniversalReborrow: for<'a> Reborrow<'a> {}
203pub trait UniversalReborrowMut: for<'a> ReborrowMut<'a> {}
204
205impl<T> UniversalReborrow for T where for<'a> T: Reborrow<'a> {}
206impl<T> UniversalReborrowMut for T where for<'a> T: ReborrowMut<'a> {}
207
208/// Unstable core trait for describing how a scalar value may be split up into individual
209/// component.
210///
211/// For example, `f64` is treated as a single indivisible unit, but [`num_complex::Complex<f64>`]
212/// is split up into its real and imaginary components, with each one being stored in a separate
213/// container.
214///
215/// # Safety
216/// The associated types and functions must fulfill their respective contracts.
217pub unsafe trait Entity: Copy + Pod + PartialEq + Send + Sync + Debug + 'static {
218    #[doc(hidden)]
219    const IS_F64: bool = false;
220    #[doc(hidden)]
221    const IS_F32: bool = false;
222    #[doc(hidden)]
223    const IS_C64: bool = false;
224    #[doc(hidden)]
225    const IS_C32: bool = false;
226    #[doc(hidden)]
227    const IS_NUM_COMPLEX: bool = false;
228
229    const IS_REAL: bool = true;
230
231    type Group: ForType + ForCopyType + ForDebugType;
232
233    type Unit: Copy + Pod + PartialEq + Send + Sync + Debug + 'static;
234    type Index: Copy + Pod + Send + Sync + Debug + 'static;
235    type SimdUnit<S: Simd>: Copy + Pod + Send + Sync + Debug + 'static;
236    type SimdMask<S: Simd>: Copy + Send + Sync + Debug + 'static;
237    type SimdIndex<S: Simd>: Copy + Pod + Send + Sync + Debug + 'static;
238    type Iter<I: Iterator>: Iterator<Item = GroupFor<Self, I::Item>>;
239
240    type PrefixUnit<'a, S: Simd>: Copy + pulp::Read<Output = SimdUnitFor<Self, S>> + Copy;
241    type SuffixUnit<'a, S: Simd>: Copy + pulp::Read<Output = SimdUnitFor<Self, S>> + Copy;
242    type PrefixMutUnit<'a, S: Simd>: pulp::Write<Output = SimdUnitFor<Self, S>>
243        + IntoConst<Target = Self::PrefixUnit<'a, S>>
244        + UniversalReborrow
245        + UniversalReborrowMut;
246    type SuffixMutUnit<'a, S: Simd>: pulp::Write<Output = SimdUnitFor<Self, S>>
247        + IntoConst<Target = Self::SuffixUnit<'a, S>>
248        + UniversalReborrow
249        + UniversalReborrowMut;
250
251    const N_COMPONENTS: usize;
252    const UNIT: GroupFor<Self, ()>;
253
254    fn faer_first<T>(group: GroupFor<Self, T>) -> T;
255
256    fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self;
257    fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>>;
258
259    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T>;
260    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T>;
261    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T>;
262    fn faer_map_impl<T, U>(
263        group: GroupFor<Self, T>,
264        f: &mut impl FnMut(T) -> U,
265    ) -> GroupFor<Self, U>;
266    fn faer_map<T, U>(group: GroupFor<Self, T>, f: impl FnMut(T) -> U) -> GroupFor<Self, U> {
267        Self::faer_map_impl(group, &mut { f })
268    }
269    fn faer_zip<T, U>(
270        first: GroupFor<Self, T>,
271        second: GroupFor<Self, U>,
272    ) -> GroupFor<Self, (T, U)>;
273    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>);
274
275    #[inline(always)]
276    fn faer_unzip2<T>(zipped: GroupFor<Self, [T; 2]>) -> [GroupFor<Self, T>; 2] {
277        let (a, b) = Self::faer_unzip(Self::faer_map(
278            zipped,
279            #[inline(always)]
280            |[a, b]| (a, b),
281        ));
282        [a, b]
283    }
284
285    #[inline(always)]
286    fn faer_unzip4<T>(zipped: GroupFor<Self, [T; 4]>) -> [GroupFor<Self, T>; 4] {
287        let (ab, cd) = Self::faer_unzip(Self::faer_map(
288            zipped,
289            #[inline(always)]
290            |[a, b, c, d]| ([a, b], [c, d]),
291        ));
292        let [a, b] = Self::faer_unzip2(ab);
293        let [c, d] = Self::faer_unzip2(cd);
294        [a, b, c, d]
295    }
296
297    #[inline(always)]
298    fn faer_unzip8<T>(zipped: GroupFor<Self, [T; 8]>) -> [GroupFor<Self, T>; 8] {
299        let (abcd, efgh) = Self::faer_unzip(Self::faer_map(
300            zipped,
301            #[inline(always)]
302            |[a, b, c, d, e, f, g, h]| ([a, b, c, d], [e, f, g, h]),
303        ));
304        let [a, b, c, d] = Self::faer_unzip4(abcd);
305        let [e, f, g, h] = Self::faer_unzip4(efgh);
306        [a, b, c, d, e, f, g, h]
307    }
308
309    #[inline(always)]
310    fn faer_as_arrays<const N: usize, T>(
311        group: GroupFor<Self, &[T]>,
312    ) -> (GroupFor<Self, &[[T; N]]>, GroupFor<Self, &[T]>) {
313        #[inline(always)]
314        fn do_as_arrays<const N: usize, T>() -> impl Fn(&[T]) -> (&[[T; N]], &[T]) {
315            #[inline(always)]
316            |slice| pulp::as_arrays(slice)
317        }
318        Self::faer_unzip(Self::faer_map(group, do_as_arrays()))
319    }
320
321    #[inline(always)]
322    fn faer_as_arrays_mut<const N: usize, T>(
323        group: GroupFor<Self, &mut [T]>,
324    ) -> (GroupFor<Self, &mut [[T; N]]>, GroupFor<Self, &mut [T]>) {
325        #[inline(always)]
326        fn do_as_arrays_mut<const N: usize, T>() -> impl Fn(&mut [T]) -> (&mut [[T; N]], &mut [T]) {
327            #[inline(always)]
328            |slice| pulp::as_arrays_mut(slice)
329        }
330        Self::faer_unzip(Self::faer_map(group, do_as_arrays_mut()))
331    }
332
333    #[inline(always)]
334    fn faer_deref<T: Copy>(group: GroupFor<Self, &T>) -> GroupFor<Self, T> {
335        #[inline(always)]
336        fn do_deref<T: Copy>() -> impl FnMut(&T) -> T {
337            #[inline(always)]
338            |group| *group
339        }
340        Self::faer_map(group, do_deref())
341    }
342    #[inline(always)]
343    fn faer_rb<'short, T: Reborrow<'short>>(
344        value: GroupFor<Self, &'short T>,
345    ) -> GroupFor<Self, T::Target> {
346        Self::faer_map(
347            value,
348            #[inline(always)]
349            |value| value.rb(),
350        )
351    }
352
353    #[inline(always)]
354    fn faer_rb_mut<'short, T: ReborrowMut<'short>>(
355        value: GroupFor<Self, &'short mut T>,
356    ) -> GroupFor<Self, T::Target> {
357        Self::faer_map(
358            value,
359            #[inline(always)]
360            |value| value.rb_mut(),
361        )
362    }
363    #[inline(always)]
364    fn faer_into_const<T: IntoConst>(value: GroupFor<Self, T>) -> GroupFor<Self, T::Target> {
365        Self::faer_map(
366            value,
367            #[inline(always)]
368            |value| value.into_const(),
369        )
370    }
371
372    fn faer_map_with_context<Ctx, T, U>(
373        ctx: Ctx,
374        group: GroupFor<Self, T>,
375        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
376    ) -> (Ctx, GroupFor<Self, U>);
377
378    #[inline(always)]
379    fn faer_copy<T: Copy>(x: &GroupFor<Self, T>) -> GroupFor<Self, T> {
380        unsafe { core::mem::transmute_copy(x) }
381    }
382
383    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter>;
384}
385
386/// Trait for types that may be implicitly conjugated.
387///
388/// # Safety
389/// The associated types and functions must fulfill their respective contracts.
390pub unsafe trait Conjugate: Entity {
391    const IS_CANONICAL: bool = true;
392
393    /// Must have the same layout as `Self`, and `Conj::Unit` must have the same layout as `Unit`.
394    type Conj: Entity + Conjugate<Conj = Self, Canonical = Self::Canonical>;
395    /// Must have the same layout as `Self`, and `Canonical::Unit` must have the same layout as
396    /// `Unit`.
397    type Canonical: Entity + Conjugate<Canonical = Self::Canonical>;
398
399    /// Performs the implicit conjugation operation on the given value, returning the canonical
400    /// form.
401    fn canonicalize(self) -> Self::Canonical;
402}
403
404pub trait SimdCtx: core::fmt::Debug + Copy + Send + Sync + 'static + Default {
405    fn dispatch<Op: pulp::WithSimd>(self, f: Op) -> Op::Output;
406}
407
408#[derive(Default, Clone, Copy, Debug)]
409pub struct NoSimd;
410
411impl SimdCtx for pulp::Arch {
412    #[inline(always)]
413    fn dispatch<Op: pulp::WithSimd>(self, f: Op) -> Op::Output {
414        self.dispatch(f)
415    }
416}
417
418impl SimdCtx for pulp::ScalarArch {
419    #[inline(always)]
420    fn dispatch<Op: pulp::WithSimd>(self, f: Op) -> Op::Output {
421        self.dispatch(f)
422    }
423}
424
425impl SimdCtx for NoSimd {
426    #[inline(always)]
427    fn dispatch<Op: pulp::WithSimd>(self, f: Op) -> Op::Output {
428        f.with_simd(pulp::Scalar::new())
429    }
430}
431
432/// Unstable trait containing the operations that a number type needs to implement.
433pub trait ComplexField:
434    Entity
435    + Conjugate<Canonical = Self>
436    + core::ops::Neg<Output = Self>
437    + core::ops::Add<Self, Output = Self>
438    + core::ops::Sub<Self, Output = Self>
439    + core::ops::Mul<Self, Output = Self>
440    + core::ops::AddAssign<Self>
441    + core::ops::SubAssign<Self>
442    + core::ops::MulAssign<Self>
443{
444    type Real: RealField;
445    type Simd: SimdCtx;
446    type ScalarSimd: SimdCtx;
447    type PortableSimd: SimdCtx;
448
449    /// Converts `value` from `f64` to `Self`.  
450    /// The conversion may be lossy when converting to a type with less precision.
451    fn faer_from_f64(value: f64) -> Self;
452
453    /// Returns `self + rhs`.
454    fn faer_add(self, rhs: Self) -> Self;
455    /// Returns `self - rhs`.
456    fn faer_sub(self, rhs: Self) -> Self;
457    /// Returns `self * rhs`.
458    fn faer_mul(self, rhs: Self) -> Self;
459
460    /// Returns `-self`.
461    fn faer_neg(self) -> Self;
462    /// Returns `1.0/self`.
463    fn faer_inv(self) -> Self;
464    /// Returns `conjugate(self)`.
465    fn faer_conj(self) -> Self;
466    /// Returns the square root of `self`.
467    fn faer_sqrt(self) -> Self;
468
469    /// Returns the input, scaled by `rhs`.
470    fn faer_scale_real(self, rhs: Self::Real) -> Self;
471
472    /// Returns the input, scaled by `rhs`.
473    fn faer_scale_power_of_two(self, rhs: Self::Real) -> Self;
474
475    /// Returns either the norm or squared norm of the number.
476    ///
477    /// An implementation may choose either, so long as it chooses consistently.
478    fn faer_score(self) -> Self::Real;
479    /// Returns the absolute value of `self`.
480    fn faer_abs(self) -> Self::Real;
481    /// Returns the squared absolute value of `self`.
482    fn faer_abs2(self) -> Self::Real;
483
484    /// Returns a NaN value.
485    fn faer_nan() -> Self;
486
487    /// Returns true if `self` is a NaN value, or false otherwise.
488    #[inline(always)]
489    fn faer_is_nan(&self) -> bool {
490        #[allow(clippy::eq_op)]
491        {
492            self != self
493        }
494    }
495
496    /// Returns true if `self` is a NaN value, or false otherwise.
497    #[inline(always)]
498    fn faer_is_finite(&self) -> bool {
499        let inf = Self::Real::faer_zero().faer_inv();
500        if coe::is_same::<Self, Self::Real>() {
501            self.faer_real().faer_abs() < inf
502        } else {
503            (self.faer_real().faer_abs() < inf) & (self.faer_imag().faer_abs() < inf)
504        }
505    }
506
507    /// Returns a complex number whose real part is equal to `real`, and a zero imaginary part.
508    fn faer_from_real(real: Self::Real) -> Self;
509
510    /// Returns the real part.
511    fn faer_real(self) -> Self::Real;
512    /// Returns the imaginary part.
513    fn faer_imag(self) -> Self::Real;
514
515    /// Returns `0.0`.
516    fn faer_zero() -> Self;
517    /// Returns `1.0`.
518    fn faer_one() -> Self;
519
520    fn faer_align_offset<S: Simd>(
521        simd: S,
522        ptr: *const UnitFor<Self>,
523        len: usize,
524    ) -> pulp::Offset<SimdMaskFor<Self, S>>;
525
526    fn faer_slice_as_aligned_simd<S: Simd>(
527        simd: S,
528        slice: &[UnitFor<Self>],
529        offset: pulp::Offset<SimdMaskFor<Self, S>>,
530    ) -> (
531        Self::PrefixUnit<'_, S>,
532        &[SimdUnitFor<Self, S>],
533        Self::SuffixUnit<'_, S>,
534    );
535    fn faer_slice_as_aligned_simd_mut<S: Simd>(
536        simd: S,
537        slice: &mut [UnitFor<Self>],
538        offset: pulp::Offset<SimdMaskFor<Self, S>>,
539    ) -> (
540        Self::PrefixMutUnit<'_, S>,
541        &mut [SimdUnitFor<Self, S>],
542        Self::SuffixMutUnit<'_, S>,
543    );
544
545    fn faer_slice_as_simd<S: Simd>(
546        slice: &[UnitFor<Self>],
547    ) -> (&[SimdUnitFor<Self, S>], &[UnitFor<Self>]);
548    fn faer_slice_as_simd_mut<S: Simd>(
549        slice: &mut [UnitFor<Self>],
550    ) -> (&mut [SimdUnitFor<Self, S>], &mut [UnitFor<Self>]);
551
552    fn faer_partial_load_unit<S: Simd>(simd: S, slice: &[UnitFor<Self>]) -> SimdUnitFor<Self, S>;
553    fn faer_partial_store_unit<S: Simd>(
554        simd: S,
555        slice: &mut [UnitFor<Self>],
556        values: SimdUnitFor<Self, S>,
557    );
558    fn faer_partial_load_last_unit<S: Simd>(
559        simd: S,
560        slice: &[UnitFor<Self>],
561    ) -> SimdUnitFor<Self, S>;
562    fn faer_partial_store_last_unit<S: Simd>(
563        simd: S,
564        slice: &mut [UnitFor<Self>],
565        values: SimdUnitFor<Self, S>,
566    );
567
568    fn faer_simd_splat_unit<S: Simd>(simd: S, unit: UnitFor<Self>) -> SimdUnitFor<Self, S>;
569
570    #[inline(always)]
571    fn faer_partial_load<S: Simd>(
572        simd: S,
573        slice: GroupFor<Self, &[UnitFor<Self>]>,
574    ) -> SimdGroupFor<Self, S> {
575        into_copy::<Self, _>(Self::faer_map(
576            slice,
577            #[inline(always)]
578            |slice| Self::faer_partial_load_unit(simd, slice),
579        ))
580    }
581    #[inline(always)]
582    fn faer_partial_store<S: Simd>(
583        simd: S,
584        slice: GroupFor<Self, &mut [UnitFor<Self>]>,
585        values: SimdGroupFor<Self, S>,
586    ) {
587        Self::faer_map(
588            Self::faer_zip(slice, from_copy::<Self, _>(values)),
589            #[inline(always)]
590            |(slice, unit)| Self::faer_partial_store_unit(simd, slice, unit),
591        );
592    }
593    #[inline(always)]
594    fn faer_partial_load_last<S: Simd>(
595        simd: S,
596        slice: GroupFor<Self, &[UnitFor<Self>]>,
597    ) -> SimdGroupFor<Self, S> {
598        into_copy::<Self, _>(Self::faer_map(
599            slice,
600            #[inline(always)]
601            |slice| Self::faer_partial_load_last_unit(simd, slice),
602        ))
603    }
604    #[inline(always)]
605    fn faer_partial_store_last<S: Simd>(
606        simd: S,
607        slice: GroupFor<Self, &mut [UnitFor<Self>]>,
608        values: SimdGroupFor<Self, S>,
609    ) {
610        Self::faer_map(
611            Self::faer_zip(slice, from_copy::<Self, _>(values)),
612            #[inline(always)]
613            |(slice, unit)| Self::faer_partial_store_last_unit(simd, slice, unit),
614        );
615    }
616    #[inline(always)]
617    fn faer_simd_splat<S: Simd>(simd: S, value: Self) -> SimdGroupFor<Self, S> {
618        into_copy::<Self, _>(Self::faer_map(
619            Self::faer_into_units(value),
620            #[inline(always)]
621            |unit| Self::faer_simd_splat_unit(simd, unit),
622        ))
623    }
624
625    fn faer_simd_scalar_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self;
626    fn faer_simd_scalar_conj_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self;
627    fn faer_simd_scalar_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self;
628    fn faer_simd_scalar_conj_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self;
629
630    fn faer_simd_neg<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S>;
631    fn faer_simd_conj<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S>;
632    fn faer_simd_rotate_left<S: Simd>(
633        simd: S,
634        values: SimdGroupFor<Self, S>,
635        amount: usize,
636    ) -> SimdGroupFor<Self, S>;
637
638    fn faer_simd_add<S: Simd>(
639        simd: S,
640        lhs: SimdGroupFor<Self, S>,
641        rhs: SimdGroupFor<Self, S>,
642    ) -> SimdGroupFor<Self, S>;
643    fn faer_simd_sub<S: Simd>(
644        simd: S,
645        lhs: SimdGroupFor<Self, S>,
646        rhs: SimdGroupFor<Self, S>,
647    ) -> SimdGroupFor<Self, S>;
648
649    fn faer_simd_mul<S: Simd>(
650        simd: S,
651        lhs: SimdGroupFor<Self, S>,
652        rhs: SimdGroupFor<Self, S>,
653    ) -> SimdGroupFor<Self, S>;
654    fn faer_simd_scale_real<S: Simd>(
655        simd: S,
656        lhs: SimdGroupFor<Self::Real, S>,
657        rhs: SimdGroupFor<Self, S>,
658    ) -> SimdGroupFor<Self, S>;
659    fn faer_simd_conj_mul<S: Simd>(
660        simd: S,
661        lhs: SimdGroupFor<Self, S>,
662        rhs: SimdGroupFor<Self, S>,
663    ) -> SimdGroupFor<Self, S>;
664    fn faer_simd_mul_adde<S: Simd>(
665        simd: S,
666        lhs: SimdGroupFor<Self, S>,
667        rhs: SimdGroupFor<Self, S>,
668        acc: SimdGroupFor<Self, S>,
669    ) -> SimdGroupFor<Self, S>;
670    fn faer_simd_conj_mul_adde<S: Simd>(
671        simd: S,
672        lhs: SimdGroupFor<Self, S>,
673        rhs: SimdGroupFor<Self, S>,
674        acc: SimdGroupFor<Self, S>,
675    ) -> SimdGroupFor<Self, S>;
676
677    fn faer_simd_abs2_adde<S: Simd>(
678        simd: S,
679        values: SimdGroupFor<Self, S>,
680        acc: SimdGroupFor<Self::Real, S>,
681    ) -> SimdGroupFor<Self::Real, S>;
682    fn faer_simd_abs2<S: Simd>(
683        simd: S,
684        values: SimdGroupFor<Self, S>,
685    ) -> SimdGroupFor<Self::Real, S>;
686    fn faer_simd_score<S: Simd>(
687        simd: S,
688        values: SimdGroupFor<Self, S>,
689    ) -> SimdGroupFor<Self::Real, S>;
690
691    #[inline(always)]
692    fn faer_simd_reduce_add<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> Self {
693        let _ = simd;
694        let mut acc = Self::faer_zero();
695        let values = from_copy::<Self, _>(values);
696
697        let slice = simd_as_slice::<Self, S>(Self::faer_map(
698            Self::faer_as_ref(&values),
699            #[allow(clippy::redundant_closure)]
700            #[inline(always)]
701            |ptr| core::slice::from_ref(ptr),
702        ));
703        for units in Self::faer_into_iter(slice) {
704            let value = Self::faer_from_units(Self::faer_deref(units));
705            acc = acc.faer_add(value);
706        }
707
708        acc
709    }
710}
711
712/// Unstable trait containing the operations that a real number type needs to implement.
713pub trait RealField:
714    ComplexField<Real = Self> + PartialOrd + num_traits::Num + num_traits::NumAssignOps
715{
716    fn faer_epsilon() -> Self;
717    fn faer_zero_threshold() -> Self;
718
719    fn faer_min_positive() -> Self;
720    fn faer_min_positive_inv() -> Self;
721    fn faer_min_positive_sqrt() -> Self;
722    fn faer_min_positive_sqrt_inv() -> Self;
723
724    fn faer_div(self, rhs: Self) -> Self;
725
726    fn faer_usize_to_index(a: usize) -> IndexFor<Self>;
727    fn faer_index_to_usize(a: IndexFor<Self>) -> usize;
728    fn faer_max_index() -> IndexFor<Self>;
729
730    fn faer_simd_less_than<S: Simd>(
731        simd: S,
732        a: SimdGroupFor<Self, S>,
733        b: SimdGroupFor<Self, S>,
734    ) -> SimdMaskFor<Self, S>;
735    fn faer_simd_less_than_or_equal<S: Simd>(
736        simd: S,
737        a: SimdGroupFor<Self, S>,
738        b: SimdGroupFor<Self, S>,
739    ) -> SimdMaskFor<Self, S>;
740    fn faer_simd_greater_than<S: Simd>(
741        simd: S,
742        a: SimdGroupFor<Self, S>,
743        b: SimdGroupFor<Self, S>,
744    ) -> SimdMaskFor<Self, S>;
745    fn faer_simd_greater_than_or_equal<S: Simd>(
746        simd: S,
747        a: SimdGroupFor<Self, S>,
748        b: SimdGroupFor<Self, S>,
749    ) -> SimdMaskFor<Self, S>;
750
751    fn faer_simd_select<S: Simd>(
752        simd: S,
753        mask: SimdMaskFor<Self, S>,
754        if_true: SimdGroupFor<Self, S>,
755        if_false: SimdGroupFor<Self, S>,
756    ) -> SimdGroupFor<Self, S>;
757    fn faer_simd_index_select<S: Simd>(
758        simd: S,
759        mask: SimdMaskFor<Self, S>,
760        if_true: SimdIndexFor<Self, S>,
761        if_false: SimdIndexFor<Self, S>,
762    ) -> SimdIndexFor<Self, S>;
763    fn faer_simd_index_seq<S: Simd>(simd: S) -> SimdIndexFor<Self, S>;
764    fn faer_simd_index_splat<S: Simd>(simd: S, value: IndexFor<Self>) -> SimdIndexFor<Self, S>;
765    fn faer_simd_index_add<S: Simd>(
766        simd: S,
767        a: SimdIndexFor<Self, S>,
768        b: SimdIndexFor<Self, S>,
769    ) -> SimdIndexFor<Self, S>;
770
771    fn faer_simd_index_rotate_left<S: Simd>(
772        simd: S,
773        values: SimdIndexFor<Self, S>,
774        amount: usize,
775    ) -> SimdIndexFor<Self, S>;
776
777    fn faer_simd_abs<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S>;
778}
779
780impl ComplexField for f32 {
781    type Real = Self;
782    type Simd = pulp::Arch;
783    type ScalarSimd = NoSimd;
784    type PortableSimd = pulp::Arch;
785
786    #[inline(always)]
787    fn faer_from_f64(value: f64) -> Self {
788        value as _
789    }
790
791    #[inline(always)]
792    fn faer_add(self, rhs: Self) -> Self {
793        self + rhs
794    }
795
796    #[inline(always)]
797    fn faer_sub(self, rhs: Self) -> Self {
798        self - rhs
799    }
800
801    #[inline(always)]
802    fn faer_mul(self, rhs: Self) -> Self {
803        self * rhs
804    }
805
806    #[inline(always)]
807    fn faer_neg(self) -> Self {
808        -self
809    }
810
811    #[inline(always)]
812    fn faer_inv(self) -> Self {
813        self.recip()
814    }
815
816    #[inline(always)]
817    fn faer_conj(self) -> Self {
818        self
819    }
820
821    #[inline(always)]
822    fn faer_sqrt(self) -> Self {
823        #[cfg(feature = "std")]
824        {
825            self.sqrt()
826        }
827        #[cfg(not(feature = "std"))]
828        {
829            libm::sqrtf(self)
830        }
831    }
832
833    #[inline(always)]
834    fn faer_scale_real(self, rhs: Self::Real) -> Self {
835        self * rhs
836    }
837
838    #[inline(always)]
839    fn faer_scale_power_of_two(self, rhs: Self::Real) -> Self {
840        self * rhs
841    }
842
843    #[inline(always)]
844    fn faer_score(self) -> Self::Real {
845        self.faer_abs()
846    }
847
848    #[inline(always)]
849    fn faer_abs(self) -> Self::Real {
850        #[cfg(feature = "std")]
851        {
852            self.abs()
853        }
854        #[cfg(not(feature = "std"))]
855        {
856            libm::fabsf(self)
857        }
858    }
859
860    #[inline(always)]
861    fn faer_abs2(self) -> Self::Real {
862        self * self
863    }
864
865    #[inline(always)]
866    fn faer_nan() -> Self {
867        Self::NAN
868    }
869
870    #[inline(always)]
871    fn faer_from_real(real: Self::Real) -> Self {
872        real
873    }
874
875    #[inline(always)]
876    fn faer_real(self) -> Self::Real {
877        self
878    }
879
880    #[inline(always)]
881    fn faer_imag(self) -> Self::Real {
882        0.0
883    }
884
885    #[inline(always)]
886    fn faer_zero() -> Self {
887        0.0
888    }
889
890    #[inline(always)]
891    fn faer_one() -> Self {
892        1.0
893    }
894
895    #[inline(always)]
896    fn faer_align_offset<S: Simd>(
897        simd: S,
898        ptr: *const UnitFor<Self>,
899        len: usize,
900    ) -> pulp::Offset<SimdMaskFor<Self, S>> {
901        simd.f32s_align_offset(ptr, len)
902    }
903
904    #[inline(always)]
905    fn faer_slice_as_aligned_simd<S: Simd>(
906        simd: S,
907        slice: &[UnitFor<Self>],
908        offset: pulp::Offset<SimdMaskFor<Self, S>>,
909    ) -> (
910        pulp::Prefix<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
911        &[SimdUnitFor<Self, S>],
912        pulp::Suffix<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
913    ) {
914        simd.f32s_as_aligned_simd(slice, offset)
915    }
916    #[inline(always)]
917    fn faer_slice_as_aligned_simd_mut<S: Simd>(
918        simd: S,
919        slice: &mut [UnitFor<Self>],
920        offset: pulp::Offset<SimdMaskFor<Self, S>>,
921    ) -> (
922        pulp::PrefixMut<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
923        &mut [SimdUnitFor<Self, S>],
924        pulp::SuffixMut<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
925    ) {
926        simd.f32s_as_aligned_mut_simd(slice, offset)
927    }
928
929    #[inline(always)]
930    fn faer_slice_as_simd<S: Simd>(
931        slice: &[UnitFor<Self>],
932    ) -> (&[SimdUnitFor<Self, S>], &[UnitFor<Self>]) {
933        S::f32s_as_simd(slice)
934    }
935
936    #[inline(always)]
937    fn faer_slice_as_simd_mut<S: Simd>(
938        slice: &mut [UnitFor<Self>],
939    ) -> (&mut [SimdUnitFor<Self, S>], &mut [UnitFor<Self>]) {
940        S::f32s_as_mut_simd(slice)
941    }
942
943    #[inline(always)]
944    fn faer_partial_load_last_unit<S: Simd>(
945        simd: S,
946        slice: &[UnitFor<Self>],
947    ) -> SimdUnitFor<Self, S> {
948        simd.f32s_partial_load_last(slice)
949    }
950
951    #[inline(always)]
952    fn faer_partial_store_last_unit<S: Simd>(
953        simd: S,
954        slice: &mut [UnitFor<Self>],
955        values: SimdUnitFor<Self, S>,
956    ) {
957        simd.f32s_partial_store_last(slice, values)
958    }
959
960    #[inline(always)]
961    fn faer_partial_load_unit<S: Simd>(simd: S, slice: &[UnitFor<Self>]) -> SimdUnitFor<Self, S> {
962        simd.f32s_partial_load(slice)
963    }
964
965    #[inline(always)]
966    fn faer_partial_store_unit<S: Simd>(
967        simd: S,
968        slice: &mut [UnitFor<Self>],
969        values: SimdUnitFor<Self, S>,
970    ) {
971        simd.f32s_partial_store(slice, values)
972    }
973
974    #[inline(always)]
975    fn faer_simd_splat_unit<S: Simd>(simd: S, unit: UnitFor<Self>) -> SimdUnitFor<Self, S> {
976        simd.f32s_splat(unit)
977    }
978
979    #[inline(always)]
980    fn faer_simd_neg<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
981        simd.f32s_neg(values)
982    }
983
984    #[inline(always)]
985    fn faer_simd_conj<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
986        let _ = simd;
987        values
988    }
989
990    #[inline(always)]
991    fn faer_simd_rotate_left<S: Simd>(
992        simd: S,
993        values: SimdGroupFor<Self, S>,
994        amount: usize,
995    ) -> SimdGroupFor<Self, S> {
996        simd.f32s_rotate_left(values, amount)
997    }
998
999    #[inline(always)]
1000    fn faer_simd_add<S: Simd>(
1001        simd: S,
1002        lhs: SimdGroupFor<Self, S>,
1003        rhs: SimdGroupFor<Self, S>,
1004    ) -> SimdGroupFor<Self, S> {
1005        simd.f32s_add(lhs, rhs)
1006    }
1007
1008    #[inline(always)]
1009    fn faer_simd_sub<S: Simd>(
1010        simd: S,
1011        lhs: SimdGroupFor<Self, S>,
1012        rhs: SimdGroupFor<Self, S>,
1013    ) -> SimdGroupFor<Self, S> {
1014        simd.f32s_sub(lhs, rhs)
1015    }
1016
1017    #[inline(always)]
1018    fn faer_simd_mul<S: Simd>(
1019        simd: S,
1020        lhs: SimdGroupFor<Self, S>,
1021        rhs: SimdGroupFor<Self, S>,
1022    ) -> SimdGroupFor<Self, S> {
1023        simd.f32s_mul(lhs, rhs)
1024    }
1025    #[inline(always)]
1026    fn faer_simd_scale_real<S: Simd>(
1027        simd: S,
1028        lhs: SimdGroupFor<Self::Real, S>,
1029        rhs: SimdGroupFor<Self, S>,
1030    ) -> SimdGroupFor<Self, S> {
1031        Self::faer_simd_mul(simd, lhs, rhs)
1032    }
1033    #[inline(always)]
1034    fn faer_simd_conj_mul<S: Simd>(
1035        simd: S,
1036        lhs: SimdGroupFor<Self, S>,
1037        rhs: SimdGroupFor<Self, S>,
1038    ) -> SimdGroupFor<Self, S> {
1039        simd.f32s_mul(lhs, rhs)
1040    }
1041
1042    #[inline(always)]
1043    fn faer_simd_mul_adde<S: Simd>(
1044        simd: S,
1045        lhs: SimdGroupFor<Self, S>,
1046        rhs: SimdGroupFor<Self, S>,
1047        acc: SimdGroupFor<Self, S>,
1048    ) -> SimdGroupFor<Self, S> {
1049        simd.f32s_mul_add_e(lhs, rhs, acc)
1050    }
1051
1052    #[inline(always)]
1053    fn faer_simd_conj_mul_adde<S: Simd>(
1054        simd: S,
1055        lhs: SimdGroupFor<Self, S>,
1056        rhs: SimdGroupFor<Self, S>,
1057        acc: SimdGroupFor<Self, S>,
1058    ) -> SimdGroupFor<Self, S> {
1059        simd.f32s_mul_add_e(lhs, rhs, acc)
1060    }
1061
1062    #[inline(always)]
1063    fn faer_simd_reduce_add<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> Self {
1064        simd.f32s_reduce_sum(values)
1065    }
1066
1067    #[inline(always)]
1068    fn faer_simd_abs2<S: Simd>(
1069        simd: S,
1070        values: SimdGroupFor<Self, S>,
1071    ) -> SimdGroupFor<Self::Real, S> {
1072        simd.f32s_mul(values, values)
1073    }
1074    #[inline(always)]
1075    fn faer_simd_abs2_adde<S: Simd>(
1076        simd: S,
1077        values: SimdGroupFor<Self, S>,
1078        acc: SimdGroupFor<Self::Real, S>,
1079    ) -> SimdGroupFor<Self::Real, S> {
1080        simd.f32s_mul_add_e(values, values, acc)
1081    }
1082    #[inline(always)]
1083    fn faer_simd_score<S: Simd>(
1084        simd: S,
1085        values: SimdGroupFor<Self, S>,
1086    ) -> SimdGroupFor<Self::Real, S> {
1087        simd.f32s_abs(values)
1088    }
1089
1090    #[inline(always)]
1091    fn faer_simd_scalar_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
1092        let _ = simd;
1093        lhs * rhs
1094    }
1095    #[inline(always)]
1096    fn faer_simd_scalar_conj_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
1097        let _ = simd;
1098        lhs * rhs
1099    }
1100    #[inline(always)]
1101    fn faer_simd_scalar_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
1102        simd.f32_scalar_mul_add_e(lhs, rhs, acc)
1103    }
1104    #[inline(always)]
1105    fn faer_simd_scalar_conj_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
1106        simd.f32_scalar_mul_add_e(lhs, rhs, acc)
1107    }
1108}
1109impl ComplexField for f64 {
1110    type Real = Self;
1111    type Simd = pulp::Arch;
1112    type ScalarSimd = NoSimd;
1113    type PortableSimd = pulp::Arch;
1114
1115    #[inline(always)]
1116    fn faer_from_f64(value: f64) -> Self {
1117        value
1118    }
1119
1120    #[inline(always)]
1121    fn faer_add(self, rhs: Self) -> Self {
1122        self + rhs
1123    }
1124
1125    #[inline(always)]
1126    fn faer_sub(self, rhs: Self) -> Self {
1127        self - rhs
1128    }
1129
1130    #[inline(always)]
1131    fn faer_mul(self, rhs: Self) -> Self {
1132        self * rhs
1133    }
1134
1135    #[inline(always)]
1136    fn faer_neg(self) -> Self {
1137        -self
1138    }
1139
1140    #[inline(always)]
1141    fn faer_inv(self) -> Self {
1142        self.recip()
1143    }
1144
1145    #[inline(always)]
1146    fn faer_conj(self) -> Self {
1147        self
1148    }
1149
1150    #[inline(always)]
1151    fn faer_sqrt(self) -> Self {
1152        #[cfg(feature = "std")]
1153        {
1154            self.sqrt()
1155        }
1156        #[cfg(not(feature = "std"))]
1157        {
1158            libm::sqrt(self)
1159        }
1160    }
1161
1162    #[inline(always)]
1163    fn faer_scale_real(self, rhs: Self::Real) -> Self {
1164        self * rhs
1165    }
1166
1167    #[inline(always)]
1168    fn faer_scale_power_of_two(self, rhs: Self::Real) -> Self {
1169        self * rhs
1170    }
1171
1172    #[inline(always)]
1173    fn faer_score(self) -> Self::Real {
1174        self.faer_abs()
1175    }
1176
1177    #[inline(always)]
1178    fn faer_abs(self) -> Self::Real {
1179        #[cfg(feature = "std")]
1180        {
1181            self.abs()
1182        }
1183        #[cfg(not(feature = "std"))]
1184        {
1185            libm::fabs(self)
1186        }
1187    }
1188
1189    #[inline(always)]
1190    fn faer_abs2(self) -> Self::Real {
1191        self * self
1192    }
1193
1194    #[inline(always)]
1195    fn faer_nan() -> Self {
1196        Self::NAN
1197    }
1198
1199    #[inline(always)]
1200    fn faer_from_real(real: Self::Real) -> Self {
1201        real
1202    }
1203
1204    #[inline(always)]
1205    fn faer_real(self) -> Self::Real {
1206        self
1207    }
1208
1209    #[inline(always)]
1210    fn faer_imag(self) -> Self::Real {
1211        0.0
1212    }
1213
1214    #[inline(always)]
1215    fn faer_zero() -> Self {
1216        0.0
1217    }
1218
1219    #[inline(always)]
1220    fn faer_one() -> Self {
1221        1.0
1222    }
1223
1224    #[inline(always)]
1225    fn faer_align_offset<S: Simd>(
1226        simd: S,
1227        ptr: *const UnitFor<Self>,
1228        len: usize,
1229    ) -> pulp::Offset<SimdMaskFor<Self, S>> {
1230        simd.f64s_align_offset(ptr, len)
1231    }
1232
1233    #[inline(always)]
1234    fn faer_slice_as_aligned_simd<S: Simd>(
1235        simd: S,
1236        slice: &[UnitFor<Self>],
1237        offset: pulp::Offset<SimdMaskFor<Self, S>>,
1238    ) -> (
1239        pulp::Prefix<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
1240        &[SimdUnitFor<Self, S>],
1241        pulp::Suffix<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
1242    ) {
1243        simd.f64s_as_aligned_simd(slice, offset)
1244    }
1245    #[inline(always)]
1246    fn faer_slice_as_aligned_simd_mut<S: Simd>(
1247        simd: S,
1248        slice: &mut [UnitFor<Self>],
1249        offset: pulp::Offset<SimdMaskFor<Self, S>>,
1250    ) -> (
1251        pulp::PrefixMut<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
1252        &mut [SimdUnitFor<Self, S>],
1253        pulp::SuffixMut<'_, UnitFor<Self>, S, SimdMaskFor<Self, S>>,
1254    ) {
1255        simd.f64s_as_aligned_mut_simd(slice, offset)
1256    }
1257
1258    #[inline(always)]
1259    fn faer_slice_as_simd<S: Simd>(
1260        slice: &[UnitFor<Self>],
1261    ) -> (&[SimdUnitFor<Self, S>], &[UnitFor<Self>]) {
1262        S::f64s_as_simd(slice)
1263    }
1264
1265    #[inline(always)]
1266    fn faer_slice_as_simd_mut<S: Simd>(
1267        slice: &mut [UnitFor<Self>],
1268    ) -> (&mut [SimdUnitFor<Self, S>], &mut [UnitFor<Self>]) {
1269        S::f64s_as_mut_simd(slice)
1270    }
1271
1272    #[inline(always)]
1273    fn faer_partial_load_last_unit<S: Simd>(
1274        simd: S,
1275        slice: &[UnitFor<Self>],
1276    ) -> SimdUnitFor<Self, S> {
1277        simd.f64s_partial_load_last(slice)
1278    }
1279
1280    #[inline(always)]
1281    fn faer_partial_store_last_unit<S: Simd>(
1282        simd: S,
1283        slice: &mut [UnitFor<Self>],
1284        values: SimdUnitFor<Self, S>,
1285    ) {
1286        simd.f64s_partial_store_last(slice, values)
1287    }
1288    #[inline(always)]
1289    fn faer_partial_load_unit<S: Simd>(simd: S, slice: &[UnitFor<Self>]) -> SimdUnitFor<Self, S> {
1290        simd.f64s_partial_load(slice)
1291    }
1292
1293    #[inline(always)]
1294    fn faer_partial_store_unit<S: Simd>(
1295        simd: S,
1296        slice: &mut [UnitFor<Self>],
1297        values: SimdUnitFor<Self, S>,
1298    ) {
1299        simd.f64s_partial_store(slice, values)
1300    }
1301
1302    #[inline(always)]
1303    fn faer_simd_splat_unit<S: Simd>(simd: S, unit: UnitFor<Self>) -> SimdUnitFor<Self, S> {
1304        simd.f64s_splat(unit)
1305    }
1306
1307    #[inline(always)]
1308    fn faer_simd_neg<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
1309        simd.f64s_neg(values)
1310    }
1311
1312    #[inline(always)]
1313    fn faer_simd_conj<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
1314        let _ = simd;
1315        values
1316    }
1317
1318    #[inline(always)]
1319    fn faer_simd_rotate_left<S: Simd>(
1320        simd: S,
1321        values: SimdGroupFor<Self, S>,
1322        amount: usize,
1323    ) -> SimdGroupFor<Self, S> {
1324        simd.f64s_rotate_left(values, amount)
1325    }
1326
1327    #[inline(always)]
1328    fn faer_simd_add<S: Simd>(
1329        simd: S,
1330        lhs: SimdGroupFor<Self, S>,
1331        rhs: SimdGroupFor<Self, S>,
1332    ) -> SimdGroupFor<Self, S> {
1333        simd.f64s_add(lhs, rhs)
1334    }
1335
1336    #[inline(always)]
1337    fn faer_simd_sub<S: Simd>(
1338        simd: S,
1339        lhs: SimdGroupFor<Self, S>,
1340        rhs: SimdGroupFor<Self, S>,
1341    ) -> SimdGroupFor<Self, S> {
1342        simd.f64s_sub(lhs, rhs)
1343    }
1344
1345    #[inline(always)]
1346    fn faer_simd_mul<S: Simd>(
1347        simd: S,
1348        lhs: SimdGroupFor<Self, S>,
1349        rhs: SimdGroupFor<Self, S>,
1350    ) -> SimdGroupFor<Self, S> {
1351        simd.f64s_mul(lhs, rhs)
1352    }
1353    #[inline(always)]
1354    fn faer_simd_scale_real<S: Simd>(
1355        simd: S,
1356        lhs: SimdGroupFor<Self::Real, S>,
1357        rhs: SimdGroupFor<Self, S>,
1358    ) -> SimdGroupFor<Self, S> {
1359        Self::faer_simd_mul(simd, lhs, rhs)
1360    }
1361    #[inline(always)]
1362    fn faer_simd_conj_mul<S: Simd>(
1363        simd: S,
1364        lhs: SimdGroupFor<Self, S>,
1365        rhs: SimdGroupFor<Self, S>,
1366    ) -> SimdGroupFor<Self, S> {
1367        simd.f64s_mul(lhs, rhs)
1368    }
1369
1370    #[inline(always)]
1371    fn faer_simd_mul_adde<S: Simd>(
1372        simd: S,
1373        lhs: SimdGroupFor<Self, S>,
1374        rhs: SimdGroupFor<Self, S>,
1375        acc: SimdGroupFor<Self, S>,
1376    ) -> SimdGroupFor<Self, S> {
1377        simd.f64s_mul_add_e(lhs, rhs, acc)
1378    }
1379
1380    #[inline(always)]
1381    fn faer_simd_conj_mul_adde<S: Simd>(
1382        simd: S,
1383        lhs: SimdGroupFor<Self, S>,
1384        rhs: SimdGroupFor<Self, S>,
1385        acc: SimdGroupFor<Self, S>,
1386    ) -> SimdGroupFor<Self, S> {
1387        simd.f64s_mul_add_e(lhs, rhs, acc)
1388    }
1389
1390    #[inline(always)]
1391    fn faer_simd_reduce_add<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> Self {
1392        simd.f64s_reduce_sum(values)
1393    }
1394
1395    #[inline(always)]
1396    fn faer_simd_abs2<S: Simd>(
1397        simd: S,
1398        values: SimdGroupFor<Self, S>,
1399    ) -> SimdGroupFor<Self::Real, S> {
1400        simd.f64s_mul(values, values)
1401    }
1402    #[inline(always)]
1403    fn faer_simd_abs2_adde<S: Simd>(
1404        simd: S,
1405        values: SimdGroupFor<Self, S>,
1406        acc: SimdGroupFor<Self::Real, S>,
1407    ) -> SimdGroupFor<Self::Real, S> {
1408        simd.f64s_mul_add_e(values, values, acc)
1409    }
1410    #[inline(always)]
1411    fn faer_simd_score<S: Simd>(
1412        simd: S,
1413        values: SimdGroupFor<Self, S>,
1414    ) -> SimdGroupFor<Self::Real, S> {
1415        simd.f64s_abs(values)
1416    }
1417
1418    #[inline(always)]
1419    fn faer_simd_scalar_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
1420        let _ = simd;
1421        lhs * rhs
1422    }
1423    #[inline(always)]
1424    fn faer_simd_scalar_conj_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
1425        let _ = simd;
1426        lhs * rhs
1427    }
1428    #[inline(always)]
1429    fn faer_simd_scalar_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
1430        simd.f64_scalar_mul_add_e(lhs, rhs, acc)
1431    }
1432    #[inline(always)]
1433    fn faer_simd_scalar_conj_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
1434        simd.f64_scalar_mul_add_e(lhs, rhs, acc)
1435    }
1436}
1437impl RealField for f32 {
1438    #[inline(always)]
1439    fn faer_epsilon() -> Self {
1440        Self::EPSILON
1441    }
1442    #[inline(always)]
1443    fn faer_zero_threshold() -> Self {
1444        Self::MIN_POSITIVE
1445    }
1446
1447    #[inline(always)]
1448    fn faer_div(self, rhs: Self) -> Self {
1449        self / rhs
1450    }
1451
1452    #[inline(always)]
1453    fn faer_usize_to_index(a: usize) -> IndexFor<Self> {
1454        a as _
1455    }
1456    #[inline(always)]
1457    fn faer_index_to_usize(a: IndexFor<Self>) -> usize {
1458        a as _
1459    }
1460    #[inline(always)]
1461    fn faer_max_index() -> IndexFor<Self> {
1462        IndexFor::<Self>::MAX
1463    }
1464
1465    #[inline(always)]
1466    fn faer_simd_less_than<S: Simd>(
1467        simd: S,
1468        a: SimdGroupFor<Self, S>,
1469        b: SimdGroupFor<Self, S>,
1470    ) -> SimdMaskFor<Self, S> {
1471        simd.f32s_less_than(a, b)
1472    }
1473
1474    #[inline(always)]
1475    fn faer_simd_less_than_or_equal<S: Simd>(
1476        simd: S,
1477        a: SimdGroupFor<Self, S>,
1478        b: SimdGroupFor<Self, S>,
1479    ) -> SimdMaskFor<Self, S> {
1480        simd.f32s_less_than_or_equal(a, b)
1481    }
1482
1483    #[inline(always)]
1484    fn faer_simd_greater_than<S: Simd>(
1485        simd: S,
1486        a: SimdGroupFor<Self, S>,
1487        b: SimdGroupFor<Self, S>,
1488    ) -> SimdMaskFor<Self, S> {
1489        simd.f32s_greater_than(a, b)
1490    }
1491
1492    #[inline(always)]
1493    fn faer_simd_greater_than_or_equal<S: Simd>(
1494        simd: S,
1495        a: SimdGroupFor<Self, S>,
1496        b: SimdGroupFor<Self, S>,
1497    ) -> SimdMaskFor<Self, S> {
1498        simd.f32s_greater_than_or_equal(a, b)
1499    }
1500
1501    #[inline(always)]
1502    fn faer_simd_select<S: Simd>(
1503        simd: S,
1504        mask: SimdMaskFor<Self, S>,
1505        if_true: SimdGroupFor<Self, S>,
1506        if_false: SimdGroupFor<Self, S>,
1507    ) -> SimdGroupFor<Self, S> {
1508        simd.m32s_select_f32s(mask, if_true, if_false)
1509    }
1510
1511    #[inline(always)]
1512    fn faer_simd_index_select<S: Simd>(
1513        simd: S,
1514        mask: SimdMaskFor<Self, S>,
1515        if_true: SimdIndexFor<Self, S>,
1516        if_false: SimdIndexFor<Self, S>,
1517    ) -> SimdIndexFor<Self, S> {
1518        simd.m32s_select_u32s(mask, if_true, if_false)
1519    }
1520
1521    #[inline(always)]
1522    fn faer_simd_index_seq<S: Simd>(simd: S) -> SimdIndexFor<Self, S> {
1523        let _ = simd;
1524        pulp::cast_lossy([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15_u32])
1525    }
1526
1527    #[inline(always)]
1528    fn faer_simd_index_splat<S: Simd>(simd: S, value: IndexFor<Self>) -> SimdIndexFor<Self, S> {
1529        simd.u32s_splat(value)
1530    }
1531
1532    #[inline(always)]
1533    fn faer_simd_index_add<S: Simd>(
1534        simd: S,
1535        a: SimdIndexFor<Self, S>,
1536        b: SimdIndexFor<Self, S>,
1537    ) -> SimdIndexFor<Self, S> {
1538        simd.u32s_add(a, b)
1539    }
1540
1541    #[inline(always)]
1542    fn faer_simd_index_rotate_left<S: Simd>(
1543        simd: S,
1544        values: SimdIndexFor<Self, S>,
1545        amount: usize,
1546    ) -> SimdIndexFor<Self, S> {
1547        simd.u32s_rotate_left(values, amount)
1548    }
1549
1550    #[inline(always)]
1551    fn faer_min_positive() -> Self {
1552        Self::MIN_POSITIVE
1553    }
1554    #[inline(always)]
1555    fn faer_min_positive_inv() -> Self {
1556        Self::MIN_POSITIVE.recip()
1557    }
1558    #[inline(always)]
1559    fn faer_min_positive_sqrt() -> Self {
1560        Self::MIN_POSITIVE.faer_sqrt()
1561    }
1562    #[inline(always)]
1563    fn faer_min_positive_sqrt_inv() -> Self {
1564        Self::MIN_POSITIVE.faer_sqrt().recip()
1565    }
1566
1567    #[inline(always)]
1568    fn faer_simd_abs<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
1569        simd.f32s_abs(values)
1570    }
1571}
1572impl RealField for f64 {
1573    #[inline(always)]
1574    fn faer_epsilon() -> Self {
1575        Self::EPSILON
1576    }
1577    #[inline(always)]
1578    fn faer_zero_threshold() -> Self {
1579        Self::MIN_POSITIVE
1580    }
1581    #[inline(always)]
1582    fn faer_div(self, rhs: Self) -> Self {
1583        self / rhs
1584    }
1585
1586    #[inline(always)]
1587    fn faer_usize_to_index(a: usize) -> IndexFor<Self> {
1588        a as _
1589    }
1590    #[inline(always)]
1591    fn faer_index_to_usize(a: IndexFor<Self>) -> usize {
1592        a as _
1593    }
1594    #[inline(always)]
1595    fn faer_max_index() -> IndexFor<Self> {
1596        IndexFor::<Self>::MAX
1597    }
1598
1599    #[inline(always)]
1600    fn faer_simd_less_than<S: Simd>(
1601        simd: S,
1602        a: SimdGroupFor<Self, S>,
1603        b: SimdGroupFor<Self, S>,
1604    ) -> SimdMaskFor<Self, S> {
1605        simd.f64s_less_than(a, b)
1606    }
1607
1608    #[inline(always)]
1609    fn faer_simd_less_than_or_equal<S: Simd>(
1610        simd: S,
1611        a: SimdGroupFor<Self, S>,
1612        b: SimdGroupFor<Self, S>,
1613    ) -> SimdMaskFor<Self, S> {
1614        simd.f64s_less_than_or_equal(a, b)
1615    }
1616
1617    #[inline(always)]
1618    fn faer_simd_greater_than<S: Simd>(
1619        simd: S,
1620        a: SimdGroupFor<Self, S>,
1621        b: SimdGroupFor<Self, S>,
1622    ) -> SimdMaskFor<Self, S> {
1623        simd.f64s_greater_than(a, b)
1624    }
1625
1626    #[inline(always)]
1627    fn faer_simd_greater_than_or_equal<S: Simd>(
1628        simd: S,
1629        a: SimdGroupFor<Self, S>,
1630        b: SimdGroupFor<Self, S>,
1631    ) -> SimdMaskFor<Self, S> {
1632        simd.f64s_greater_than_or_equal(a, b)
1633    }
1634
1635    #[inline(always)]
1636    fn faer_simd_select<S: Simd>(
1637        simd: S,
1638        mask: SimdMaskFor<Self, S>,
1639        if_true: SimdGroupFor<Self, S>,
1640        if_false: SimdGroupFor<Self, S>,
1641    ) -> SimdGroupFor<Self, S> {
1642        simd.m64s_select_f64s(mask, if_true, if_false)
1643    }
1644
1645    #[inline(always)]
1646    fn faer_simd_index_select<S: Simd>(
1647        simd: S,
1648        mask: SimdMaskFor<Self, S>,
1649        if_true: SimdIndexFor<Self, S>,
1650        if_false: SimdIndexFor<Self, S>,
1651    ) -> SimdIndexFor<Self, S> {
1652        simd.m64s_select_u64s(mask, if_true, if_false)
1653    }
1654
1655    #[inline(always)]
1656    fn faer_simd_index_seq<S: Simd>(simd: S) -> SimdIndexFor<Self, S> {
1657        let _ = simd;
1658        pulp::cast_lossy([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15_u64])
1659    }
1660
1661    #[inline(always)]
1662    fn faer_simd_index_splat<S: Simd>(simd: S, value: IndexFor<Self>) -> SimdIndexFor<Self, S> {
1663        simd.u64s_splat(value)
1664    }
1665
1666    #[inline(always)]
1667    fn faer_simd_index_add<S: Simd>(
1668        simd: S,
1669        a: SimdIndexFor<Self, S>,
1670        b: SimdIndexFor<Self, S>,
1671    ) -> SimdIndexFor<Self, S> {
1672        simd.u64s_add(a, b)
1673    }
1674
1675    #[inline(always)]
1676    fn faer_simd_index_rotate_left<S: Simd>(
1677        simd: S,
1678        values: SimdIndexFor<Self, S>,
1679        amount: usize,
1680    ) -> SimdIndexFor<Self, S> {
1681        simd.u64s_rotate_left(values, amount)
1682    }
1683
1684    #[inline(always)]
1685    fn faer_min_positive() -> Self {
1686        Self::MIN_POSITIVE
1687    }
1688    #[inline(always)]
1689    fn faer_min_positive_inv() -> Self {
1690        Self::MIN_POSITIVE.recip()
1691    }
1692    #[inline(always)]
1693    fn faer_min_positive_sqrt() -> Self {
1694        Self::MIN_POSITIVE.faer_sqrt()
1695    }
1696    #[inline(always)]
1697    fn faer_min_positive_sqrt_inv() -> Self {
1698        Self::MIN_POSITIVE.faer_sqrt().recip()
1699    }
1700    #[inline(always)]
1701    fn faer_simd_abs<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
1702        simd.f64s_abs(values)
1703    }
1704}
1705
1706unsafe impl Conjugate for f32 {
1707    type Conj = f32;
1708    type Canonical = f32;
1709
1710    #[inline(always)]
1711    fn canonicalize(self) -> Self::Canonical {
1712        self
1713    }
1714}
1715
1716unsafe impl Conjugate for f64 {
1717    type Conj = f64;
1718    type Canonical = f64;
1719
1720    #[inline(always)]
1721    fn canonicalize(self) -> Self::Canonical {
1722        self
1723    }
1724}
1725
1726pub trait SimpleEntity: Entity<Group = IdentityGroup, Unit = Self> {}
1727impl<E: Entity<Group = IdentityGroup, Unit = Self>> SimpleEntity for E {}
1728
1729const _: () = {
1730    const fn __assert_simple_entity<E: SimpleEntity>() {}
1731    __assert_simple_entity::<f32>();
1732};
1733
1734unsafe impl Entity for f32 {
1735    const IS_F32: bool = true;
1736
1737    type Unit = Self;
1738    type Index = u32;
1739    type SimdUnit<S: Simd> = S::f32s;
1740    type SimdMask<S: Simd> = S::m32s;
1741    type SimdIndex<S: Simd> = S::u32s;
1742    type Group = IdentityGroup;
1743    type Iter<I: Iterator> = I;
1744
1745    type PrefixUnit<'a, S: Simd> = pulp::Prefix<'a, f32, S, S::m32s>;
1746    type SuffixUnit<'a, S: Simd> = pulp::Suffix<'a, f32, S, S::m32s>;
1747    type PrefixMutUnit<'a, S: Simd> = pulp::PrefixMut<'a, f32, S, S::m32s>;
1748    type SuffixMutUnit<'a, S: Simd> = pulp::SuffixMut<'a, f32, S, S::m32s>;
1749
1750    const N_COMPONENTS: usize = 1;
1751    const UNIT: GroupFor<Self, ()> = ();
1752
1753    #[inline(always)]
1754    fn faer_first<T>(group: GroupFor<Self, T>) -> T {
1755        group
1756    }
1757
1758    #[inline(always)]
1759    fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self {
1760        group
1761    }
1762
1763    #[inline(always)]
1764    fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>> {
1765        self
1766    }
1767
1768    #[inline(always)]
1769    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
1770        group
1771    }
1772
1773    #[inline(always)]
1774    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
1775        group
1776    }
1777
1778    #[inline(always)]
1779    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
1780        group
1781    }
1782
1783    #[inline(always)]
1784    fn faer_map_impl<T, U>(
1785        group: GroupFor<Self, T>,
1786        f: &mut impl FnMut(T) -> U,
1787    ) -> GroupFor<Self, U> {
1788        (*f)(group)
1789    }
1790    #[inline(always)]
1791    fn faer_map_with_context<Ctx, T, U>(
1792        ctx: Ctx,
1793        group: GroupFor<Self, T>,
1794        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
1795    ) -> (Ctx, GroupFor<Self, U>) {
1796        (*f)(ctx, group)
1797    }
1798
1799    #[inline(always)]
1800    fn faer_zip<T, U>(
1801        first: GroupFor<Self, T>,
1802        second: GroupFor<Self, U>,
1803    ) -> GroupFor<Self, (T, U)> {
1804        (first, second)
1805    }
1806    #[inline(always)]
1807    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
1808        zipped
1809    }
1810
1811    #[inline(always)]
1812    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
1813        iter.into_iter()
1814    }
1815}
1816
1817unsafe impl Entity for f64 {
1818    const IS_F64: bool = true;
1819
1820    type Unit = Self;
1821    type Index = u64;
1822    type SimdUnit<S: Simd> = S::f64s;
1823    type SimdMask<S: Simd> = S::m64s;
1824    type SimdIndex<S: Simd> = S::u64s;
1825    type Group = IdentityGroup;
1826    type Iter<I: Iterator> = I;
1827
1828    type PrefixUnit<'a, S: Simd> = pulp::Prefix<'a, f64, S, S::m64s>;
1829    type SuffixUnit<'a, S: Simd> = pulp::Suffix<'a, f64, S, S::m64s>;
1830    type PrefixMutUnit<'a, S: Simd> = pulp::PrefixMut<'a, f64, S, S::m64s>;
1831    type SuffixMutUnit<'a, S: Simd> = pulp::SuffixMut<'a, f64, S, S::m64s>;
1832
1833    const N_COMPONENTS: usize = 1;
1834    const UNIT: GroupFor<Self, ()> = ();
1835
1836    #[inline(always)]
1837    fn faer_first<T>(group: GroupFor<Self, T>) -> T {
1838        group
1839    }
1840
1841    #[inline(always)]
1842    fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self {
1843        group
1844    }
1845
1846    #[inline(always)]
1847    fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>> {
1848        self
1849    }
1850
1851    #[inline(always)]
1852    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
1853        group
1854    }
1855
1856    #[inline(always)]
1857    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
1858        group
1859    }
1860
1861    #[inline(always)]
1862    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
1863        group
1864    }
1865
1866    #[inline(always)]
1867    fn faer_map_impl<T, U>(
1868        group: GroupFor<Self, T>,
1869        f: &mut impl FnMut(T) -> U,
1870    ) -> GroupFor<Self, U> {
1871        (*f)(group)
1872    }
1873    #[inline(always)]
1874    fn faer_map_with_context<Ctx, T, U>(
1875        ctx: Ctx,
1876        group: GroupFor<Self, T>,
1877        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
1878    ) -> (Ctx, GroupFor<Self, U>) {
1879        (*f)(ctx, group)
1880    }
1881
1882    #[inline(always)]
1883    fn faer_zip<T, U>(
1884        first: GroupFor<Self, T>,
1885        second: GroupFor<Self, U>,
1886    ) -> GroupFor<Self, (T, U)> {
1887        (first, second)
1888    }
1889    #[inline(always)]
1890    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
1891        zipped
1892    }
1893
1894    #[inline(always)]
1895    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
1896        iter.into_iter()
1897    }
1898}
1899
1900macro_rules! impl_for_int {
1901    ($($int: ty),* $(,)?) => {$(
1902        unsafe impl Entity for $int {
1903            type Unit = Self;
1904            type Index = usize;
1905            type SimdUnit<S: Simd> = Self;
1906            type SimdMask<S: Simd> = bool;
1907            type SimdIndex<S: Simd> = Self;
1908            type Group = IdentityGroup;
1909            type Iter<I: Iterator> = I;
1910
1911            type PrefixUnit<'a, S: Simd> = &'a [Self];
1912            type SuffixUnit<'a, S: Simd> = &'a [Self];
1913            type PrefixMutUnit<'a, S: Simd> = &'a mut [Self];
1914            type SuffixMutUnit<'a, S: Simd> = &'a mut [Self];
1915
1916            const N_COMPONENTS: usize = 1;
1917            const UNIT: GroupFor<Self, ()> = ();
1918
1919            #[inline(always)]
1920            fn faer_first<T>(group: GroupFor<Self, T>) -> T {
1921                group
1922            }
1923
1924            #[inline(always)]
1925            fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self {
1926                group
1927            }
1928
1929            #[inline(always)]
1930            fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>> {
1931                self
1932            }
1933
1934            #[inline(always)]
1935            fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
1936                group
1937            }
1938
1939            #[inline(always)]
1940            fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
1941                group
1942            }
1943
1944            #[inline(always)]
1945            fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
1946                group
1947            }
1948
1949            #[inline(always)]
1950            fn faer_map_impl<T, U>(
1951                group: GroupFor<Self, T>,
1952                f: &mut impl FnMut(T) -> U,
1953            ) -> GroupFor<Self, U> {
1954                (*f)(group)
1955            }
1956            #[inline(always)]
1957            fn faer_map_with_context<Ctx, T, U>(
1958                ctx: Ctx,
1959                group: GroupFor<Self, T>,
1960                f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
1961            ) -> (Ctx, GroupFor<Self, U>) {
1962                (*f)(ctx, group)
1963            }
1964
1965            #[inline(always)]
1966            fn faer_zip<T, U>(
1967                first: GroupFor<Self, T>,
1968                second: GroupFor<Self, U>,
1969            ) -> GroupFor<Self, (T, U)> {
1970                (first, second)
1971            }
1972            #[inline(always)]
1973            fn faer_unzip<T, U>(
1974                zipped: GroupFor<Self, (T, U)>,
1975            ) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
1976                zipped
1977            }
1978
1979            #[inline(always)]
1980            fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
1981                iter.into_iter()
1982            }
1983        }
1984    )*};
1985}
1986
1987impl_for_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
1988
1989unsafe impl<E: Entity> Entity for Complex<E> {
1990    const IS_NUM_COMPLEX: bool = true;
1991    const IS_REAL: bool = false;
1992
1993    type Unit = UnitFor<E>;
1994    type Index = IndexFor<E>;
1995    type SimdUnit<S: Simd> = SimdUnitFor<E, S>;
1996    type SimdMask<S: Simd> = E::SimdMask<S>;
1997    type SimdIndex<S: Simd> = SimdIndexFor<E, S>;
1998    type Group = ComplexGroup<E::Group>;
1999    type Iter<I: Iterator> = ComplexIter<E::Iter<I>>;
2000
2001    type PrefixUnit<'a, S: Simd> = E::PrefixUnit<'a, S>;
2002    type SuffixUnit<'a, S: Simd> = E::SuffixUnit<'a, S>;
2003    type PrefixMutUnit<'a, S: Simd> = E::PrefixMutUnit<'a, S>;
2004    type SuffixMutUnit<'a, S: Simd> = E::SuffixMutUnit<'a, S>;
2005
2006    const N_COMPONENTS: usize = E::N_COMPONENTS * 2;
2007    const UNIT: GroupFor<Self, ()> = Complex {
2008        re: E::UNIT,
2009        im: E::UNIT,
2010    };
2011
2012    #[inline(always)]
2013    fn faer_first<T>(group: GroupFor<Self, T>) -> T {
2014        E::faer_first(group.re)
2015    }
2016
2017    #[inline(always)]
2018    fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self {
2019        let re = E::faer_from_units(group.re);
2020        let im = E::faer_from_units(group.im);
2021        Self { re, im }
2022    }
2023
2024    #[inline(always)]
2025    fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>> {
2026        let Self { re, im } = self;
2027        Complex {
2028            re: re.faer_into_units(),
2029            im: im.faer_into_units(),
2030        }
2031    }
2032
2033    #[inline(always)]
2034    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
2035        Complex {
2036            re: E::faer_as_ref(&group.re),
2037            im: E::faer_as_ref(&group.im),
2038        }
2039    }
2040
2041    #[inline(always)]
2042    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
2043        Complex {
2044            re: E::faer_as_mut(&mut group.re),
2045            im: E::faer_as_mut(&mut group.im),
2046        }
2047    }
2048
2049    #[inline(always)]
2050    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
2051        unsafe {
2052            Complex {
2053                re: E::faer_as_ptr(addr_of_mut!((*group).re)),
2054                im: E::faer_as_ptr(addr_of_mut!((*group).im)),
2055            }
2056        }
2057    }
2058
2059    #[inline(always)]
2060    fn faer_map_impl<T, U>(
2061        group: GroupFor<Self, T>,
2062        f: &mut impl FnMut(T) -> U,
2063    ) -> GroupFor<Self, U> {
2064        Complex {
2065            re: E::faer_map_impl(group.re, f),
2066            im: E::faer_map_impl(group.im, f),
2067        }
2068    }
2069    #[inline(always)]
2070    fn faer_map_with_context<Ctx, T, U>(
2071        ctx: Ctx,
2072        group: GroupFor<Self, T>,
2073        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
2074    ) -> (Ctx, GroupFor<Self, U>) {
2075        let (ctx, re) = E::faer_map_with_context(ctx, group.re, f);
2076        let (ctx, im) = E::faer_map_with_context(ctx, group.im, f);
2077        (ctx, Complex { re, im })
2078    }
2079
2080    #[inline(always)]
2081    fn faer_zip<T, U>(
2082        first: GroupFor<Self, T>,
2083        second: GroupFor<Self, U>,
2084    ) -> GroupFor<Self, (T, U)> {
2085        Complex {
2086            re: E::faer_zip(first.re, second.re),
2087            im: E::faer_zip(first.im, second.im),
2088        }
2089    }
2090    #[inline(always)]
2091    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
2092        let (re0, re1) = E::faer_unzip(zipped.re);
2093        let (im0, im1) = E::faer_unzip(zipped.im);
2094        (Complex { re: re0, im: im0 }, Complex { re: re1, im: im1 })
2095    }
2096
2097    #[inline(always)]
2098    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
2099        ComplexIter {
2100            re: E::faer_into_iter(iter.re),
2101            im: E::faer_into_iter(iter.im),
2102        }
2103    }
2104}
2105
2106unsafe impl<E: Entity> Entity for ComplexConj<E> {
2107    type Unit = UnitFor<E>;
2108    type Index = IndexFor<E>;
2109    type SimdUnit<S: Simd> = SimdUnitFor<E, S>;
2110    type SimdMask<S: Simd> = E::SimdMask<S>;
2111    type SimdIndex<S: Simd> = SimdIndexFor<E, S>;
2112    type Group = ComplexConjGroup<E::Group>;
2113    type Iter<I: Iterator> = ComplexConjIter<E::Iter<I>>;
2114
2115    type PrefixUnit<'a, S: Simd> = E::PrefixUnit<'a, S>;
2116    type SuffixUnit<'a, S: Simd> = E::SuffixUnit<'a, S>;
2117    type PrefixMutUnit<'a, S: Simd> = E::PrefixMutUnit<'a, S>;
2118    type SuffixMutUnit<'a, S: Simd> = E::SuffixMutUnit<'a, S>;
2119
2120    const N_COMPONENTS: usize = E::N_COMPONENTS * 2;
2121    const UNIT: GroupFor<Self, ()> = ComplexConj {
2122        re: E::UNIT,
2123        neg_im: E::UNIT,
2124    };
2125
2126    #[inline(always)]
2127    fn faer_first<T>(group: GroupFor<Self, T>) -> T {
2128        E::faer_first(group.re)
2129    }
2130
2131    #[inline(always)]
2132    fn faer_from_units(group: GroupFor<Self, UnitFor<Self>>) -> Self {
2133        let re = E::faer_from_units(group.re);
2134        let neg_im = E::faer_from_units(group.neg_im);
2135        Self { re, neg_im }
2136    }
2137
2138    #[inline(always)]
2139    fn faer_into_units(self) -> GroupFor<Self, UnitFor<Self>> {
2140        let Self { re, neg_im } = self;
2141        ComplexConj {
2142            re: re.faer_into_units(),
2143            neg_im: neg_im.faer_into_units(),
2144        }
2145    }
2146
2147    #[inline(always)]
2148    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
2149        ComplexConj {
2150            re: E::faer_as_ref(&group.re),
2151            neg_im: E::faer_as_ref(&group.neg_im),
2152        }
2153    }
2154
2155    #[inline(always)]
2156    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
2157        ComplexConj {
2158            re: E::faer_as_mut(&mut group.re),
2159            neg_im: E::faer_as_mut(&mut group.neg_im),
2160        }
2161    }
2162
2163    #[inline(always)]
2164    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
2165        unsafe {
2166            ComplexConj {
2167                re: E::faer_as_ptr(addr_of_mut!((*group).re)),
2168                neg_im: E::faer_as_ptr(addr_of_mut!((*group).neg_im)),
2169            }
2170        }
2171    }
2172
2173    #[inline(always)]
2174    fn faer_map_impl<T, U>(
2175        group: GroupFor<Self, T>,
2176        f: &mut impl FnMut(T) -> U,
2177    ) -> GroupFor<Self, U> {
2178        ComplexConj {
2179            re: E::faer_map_impl(group.re, f),
2180            neg_im: E::faer_map_impl(group.neg_im, f),
2181        }
2182    }
2183    #[inline(always)]
2184    fn faer_map_with_context<Ctx, T, U>(
2185        ctx: Ctx,
2186        group: GroupFor<Self, T>,
2187        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
2188    ) -> (Ctx, GroupFor<Self, U>) {
2189        let (ctx, re) = E::faer_map_with_context(ctx, group.re, f);
2190        let (ctx, neg_im) = E::faer_map_with_context(ctx, group.neg_im, f);
2191        (ctx, ComplexConj { re, neg_im })
2192    }
2193
2194    #[inline(always)]
2195    fn faer_zip<T, U>(
2196        first: GroupFor<Self, T>,
2197        second: GroupFor<Self, U>,
2198    ) -> GroupFor<Self, (T, U)> {
2199        ComplexConj {
2200            re: E::faer_zip(first.re, second.re),
2201            neg_im: E::faer_zip(first.neg_im, second.neg_im),
2202        }
2203    }
2204    #[inline(always)]
2205    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
2206        let (re0, re1) = E::faer_unzip(zipped.re);
2207        let (neg_im0, neg_im1) = E::faer_unzip(zipped.neg_im);
2208        (
2209            ComplexConj {
2210                re: re0,
2211                neg_im: neg_im0,
2212            },
2213            ComplexConj {
2214                re: re1,
2215                neg_im: neg_im1,
2216            },
2217        )
2218    }
2219
2220    #[inline(always)]
2221    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
2222        ComplexConjIter {
2223            re: E::faer_into_iter(iter.re),
2224            neg_im: E::faer_into_iter(iter.neg_im),
2225        }
2226    }
2227}
2228
2229impl<E: RealField> ComplexField for Complex<E> {
2230    type Real = E;
2231    type Simd = <E as ComplexField>::Simd;
2232    type ScalarSimd = <E as ComplexField>::ScalarSimd;
2233    type PortableSimd = <E as ComplexField>::PortableSimd;
2234
2235    #[inline(always)]
2236    fn faer_from_f64(value: f64) -> Self {
2237        Self {
2238            re: Self::Real::faer_from_f64(value),
2239            im: Self::Real::faer_zero(),
2240        }
2241    }
2242
2243    #[inline(always)]
2244    fn faer_add(self, rhs: Self) -> Self {
2245        Self {
2246            re: self.re.faer_add(rhs.re),
2247            im: self.im.faer_add(rhs.im),
2248        }
2249    }
2250
2251    #[inline(always)]
2252    fn faer_sub(self, rhs: Self) -> Self {
2253        Self {
2254            re: self.re.faer_sub(rhs.re),
2255            im: self.im.faer_sub(rhs.im),
2256        }
2257    }
2258
2259    #[inline(always)]
2260    fn faer_mul(self, rhs: Self) -> Self {
2261        Self {
2262            re: Self::Real::faer_sub(self.re.faer_mul(rhs.re), self.im.faer_mul(rhs.im)),
2263            im: Self::Real::faer_add(self.re.faer_mul(rhs.im), self.im.faer_mul(rhs.re)),
2264        }
2265    }
2266
2267    #[inline(always)]
2268    fn faer_neg(self) -> Self {
2269        Self {
2270            re: self.re.faer_neg(),
2271            im: self.im.faer_neg(),
2272        }
2273    }
2274
2275    #[inline(always)]
2276    fn faer_inv(self) -> Self {
2277        let inf = Self::Real::faer_zero().faer_inv();
2278        if self.faer_is_nan() {
2279            // NAN
2280            Self::faer_nan()
2281        } else if self == Self::faer_zero() {
2282            // zero
2283            Self { re: inf, im: inf }
2284        } else if self.re == inf || self.im == inf {
2285            Self::faer_zero()
2286        } else {
2287            let half_small = E::faer_min_positive_sqrt();
2288            let half_big = E::faer_min_positive_sqrt_inv();
2289            let one = E::faer_one();
2290
2291            let re = self.faer_real().faer_abs();
2292            let im = self.faer_imag().faer_abs();
2293
2294            if re > half_big || im > half_big {
2295                let x = self.faer_scale_real(half_small);
2296                x.faer_conj()
2297                    .faer_scale_real(x.faer_abs2().faer_inv())
2298                    .faer_scale_real(half_small)
2299            } else if re > one || im > one {
2300                let x = self;
2301                x.faer_conj().faer_scale_real(x.faer_abs2().faer_inv())
2302            } else {
2303                let x = self.faer_scale_real(half_big);
2304                x.faer_conj()
2305                    .faer_scale_real(x.faer_abs2().faer_inv())
2306                    .faer_scale_real(half_big)
2307            }
2308        }
2309    }
2310
2311    #[inline(always)]
2312    fn faer_conj(self) -> Self {
2313        Self {
2314            re: self.re,
2315            im: self.im.faer_neg(),
2316        }
2317    }
2318
2319    #[inline(always)]
2320    fn faer_sqrt(self) -> Self {
2321        let (re, im) = sqrt_impl(self.re, self.im);
2322        Self { re, im }
2323    }
2324
2325    #[inline(always)]
2326    fn faer_scale_real(self, rhs: Self::Real) -> Self {
2327        Self {
2328            re: self.re.faer_scale_real(rhs),
2329            im: self.im.faer_scale_real(rhs),
2330        }
2331    }
2332
2333    #[inline(always)]
2334    fn faer_scale_power_of_two(self, rhs: Self::Real) -> Self {
2335        Self {
2336            re: self.re.faer_scale_power_of_two(rhs),
2337            im: self.im.faer_scale_power_of_two(rhs),
2338        }
2339    }
2340
2341    #[inline(always)]
2342    fn faer_score(self) -> Self::Real {
2343        self.faer_abs2()
2344    }
2345
2346    #[inline(always)]
2347    fn faer_abs(self) -> Self::Real {
2348        let half_small = E::faer_min_positive_sqrt();
2349        let half_big = E::faer_min_positive_sqrt_inv();
2350        let one = E::faer_one();
2351        let re = self.faer_real().faer_abs();
2352        let im = self.faer_imag().faer_abs();
2353
2354        if re > half_big || im > half_big {
2355            self.faer_scale_real(half_small)
2356                .faer_abs2()
2357                .faer_sqrt()
2358                .faer_scale_real(half_big)
2359        } else if re > one || im > one {
2360            self.faer_abs2().faer_sqrt()
2361        } else {
2362            self.faer_scale_real(half_big)
2363                .faer_abs2()
2364                .faer_sqrt()
2365                .faer_scale_real(half_small)
2366        }
2367    }
2368
2369    #[inline(always)]
2370    fn faer_abs2(self) -> Self::Real {
2371        Self::Real::faer_add(self.re.faer_mul(self.re), self.im.faer_mul(self.im))
2372    }
2373
2374    #[inline(always)]
2375    fn faer_nan() -> Self {
2376        Self {
2377            re: Self::Real::faer_nan(),
2378            im: Self::Real::faer_nan(),
2379        }
2380    }
2381
2382    #[inline(always)]
2383    fn faer_from_real(real: Self::Real) -> Self {
2384        Self {
2385            re: real,
2386            im: Self::Real::faer_zero(),
2387        }
2388    }
2389
2390    #[inline(always)]
2391    fn faer_real(self) -> Self::Real {
2392        self.re
2393    }
2394
2395    #[inline(always)]
2396    fn faer_imag(self) -> Self::Real {
2397        self.im
2398    }
2399
2400    #[inline(always)]
2401    fn faer_zero() -> Self {
2402        Self {
2403            re: Self::Real::faer_zero(),
2404            im: Self::Real::faer_zero(),
2405        }
2406    }
2407
2408    #[inline(always)]
2409    fn faer_one() -> Self {
2410        Self {
2411            re: Self::Real::faer_one(),
2412            im: Self::Real::faer_zero(),
2413        }
2414    }
2415
2416    #[inline(always)]
2417    fn faer_align_offset<S: Simd>(
2418        simd: S,
2419        ptr: *const UnitFor<Self>,
2420        len: usize,
2421    ) -> pulp::Offset<SimdMaskFor<Self, S>> {
2422        E::faer_align_offset(simd, ptr, len)
2423    }
2424
2425    #[inline(always)]
2426    fn faer_slice_as_aligned_simd<S: Simd>(
2427        simd: S,
2428        slice: &[UnitFor<Self>],
2429        offset: pulp::Offset<SimdMaskFor<Self, S>>,
2430    ) -> (
2431        Self::PrefixUnit<'_, S>,
2432        &[SimdUnitFor<Self, S>],
2433        Self::SuffixUnit<'_, S>,
2434    ) {
2435        E::faer_slice_as_aligned_simd(simd, slice, offset)
2436    }
2437    #[inline(always)]
2438    fn faer_slice_as_aligned_simd_mut<S: Simd>(
2439        simd: S,
2440        slice: &mut [UnitFor<Self>],
2441        offset: pulp::Offset<SimdMaskFor<Self, S>>,
2442    ) -> (
2443        Self::PrefixMutUnit<'_, S>,
2444        &mut [SimdUnitFor<Self, S>],
2445        Self::SuffixMutUnit<'_, S>,
2446    ) {
2447        E::faer_slice_as_aligned_simd_mut(simd, slice, offset)
2448    }
2449
2450    #[inline(always)]
2451    fn faer_slice_as_simd<S: Simd>(
2452        slice: &[UnitFor<Self>],
2453    ) -> (&[SimdUnitFor<Self, S>], &[UnitFor<Self>]) {
2454        E::faer_slice_as_simd(slice)
2455    }
2456
2457    #[inline(always)]
2458    fn faer_slice_as_simd_mut<S: Simd>(
2459        slice: &mut [UnitFor<Self>],
2460    ) -> (&mut [SimdUnitFor<Self, S>], &mut [UnitFor<Self>]) {
2461        E::faer_slice_as_simd_mut(slice)
2462    }
2463
2464    #[inline(always)]
2465    fn faer_partial_load_last_unit<S: Simd>(
2466        simd: S,
2467        slice: &[UnitFor<Self>],
2468    ) -> SimdUnitFor<Self, S> {
2469        E::faer_partial_load_last_unit(simd, slice)
2470    }
2471
2472    #[inline(always)]
2473    fn faer_partial_store_last_unit<S: Simd>(
2474        simd: S,
2475        slice: &mut [UnitFor<Self>],
2476        values: SimdUnitFor<Self, S>,
2477    ) {
2478        E::faer_partial_store_last_unit(simd, slice, values)
2479    }
2480
2481    #[inline(always)]
2482    fn faer_partial_load_unit<S: Simd>(simd: S, slice: &[UnitFor<Self>]) -> SimdUnitFor<Self, S> {
2483        E::faer_partial_load_unit(simd, slice)
2484    }
2485
2486    #[inline(always)]
2487    fn faer_partial_store_unit<S: Simd>(
2488        simd: S,
2489        slice: &mut [UnitFor<Self>],
2490        values: SimdUnitFor<Self, S>,
2491    ) {
2492        E::faer_partial_store_unit(simd, slice, values)
2493    }
2494
2495    #[inline(always)]
2496    fn faer_simd_splat_unit<S: Simd>(simd: S, unit: UnitFor<Self>) -> SimdUnitFor<Self, S> {
2497        E::faer_simd_splat_unit(simd, unit)
2498    }
2499
2500    #[inline(always)]
2501    fn faer_simd_neg<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
2502        Complex {
2503            re: E::faer_simd_neg(simd, values.re),
2504            im: E::faer_simd_neg(simd, values.im),
2505        }
2506    }
2507
2508    #[inline(always)]
2509    fn faer_simd_conj<S: Simd>(simd: S, values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
2510        Complex {
2511            re: values.re,
2512            im: E::faer_simd_neg(simd, values.im),
2513        }
2514    }
2515
2516    #[inline(always)]
2517    fn faer_simd_rotate_left<S: Simd>(
2518        simd: S,
2519        values: SimdGroupFor<Self, S>,
2520        amount: usize,
2521    ) -> SimdGroupFor<Self, S> {
2522        Complex {
2523            re: E::faer_simd_rotate_left(simd, values.re, amount),
2524            im: E::faer_simd_rotate_left(simd, values.im, amount),
2525        }
2526    }
2527
2528    #[inline(always)]
2529    fn faer_simd_add<S: Simd>(
2530        simd: S,
2531        lhs: SimdGroupFor<Self, S>,
2532        rhs: SimdGroupFor<Self, S>,
2533    ) -> SimdGroupFor<Self, S> {
2534        Complex {
2535            re: E::faer_simd_add(simd, lhs.re, rhs.re),
2536            im: E::faer_simd_add(simd, lhs.im, rhs.im),
2537        }
2538    }
2539
2540    #[inline(always)]
2541    fn faer_simd_sub<S: Simd>(
2542        simd: S,
2543        lhs: SimdGroupFor<Self, S>,
2544        rhs: SimdGroupFor<Self, S>,
2545    ) -> SimdGroupFor<Self, S> {
2546        Complex {
2547            re: E::faer_simd_sub(simd, lhs.re, rhs.re),
2548            im: E::faer_simd_sub(simd, lhs.im, rhs.im),
2549        }
2550    }
2551
2552    #[inline(always)]
2553    fn faer_simd_scalar_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
2554        Complex {
2555            re: E::faer_simd_scalar_mul_adde(
2556                simd,
2557                lhs.re,
2558                rhs.re,
2559                E::faer_simd_scalar_mul(simd, lhs.im.faer_neg(), rhs.im),
2560            ),
2561            im: E::faer_simd_scalar_mul_adde(
2562                simd,
2563                lhs.re,
2564                rhs.im,
2565                E::faer_simd_scalar_mul(simd, lhs.im, rhs.re),
2566            ),
2567        }
2568    }
2569
2570    #[inline(always)]
2571    fn faer_simd_scalar_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
2572        Complex {
2573            re: E::faer_simd_scalar_mul_adde(
2574                simd,
2575                lhs.re,
2576                rhs.re,
2577                E::faer_simd_scalar_mul_adde(simd, lhs.im.faer_neg(), rhs.im, acc.re),
2578            ),
2579            im: E::faer_simd_scalar_mul_adde(
2580                simd,
2581                lhs.re,
2582                rhs.im,
2583                E::faer_simd_scalar_mul_adde(simd, lhs.im, rhs.re, acc.im),
2584            ),
2585        }
2586    }
2587
2588    #[inline(always)]
2589    fn faer_simd_scalar_conj_mul_adde<S: Simd>(simd: S, lhs: Self, rhs: Self, acc: Self) -> Self {
2590        Complex {
2591            re: E::faer_simd_scalar_mul_adde(
2592                simd,
2593                lhs.re,
2594                rhs.re,
2595                E::faer_simd_scalar_mul_adde(simd, lhs.im, rhs.im, acc.re),
2596            ),
2597            im: E::faer_simd_scalar_mul_adde(
2598                simd,
2599                lhs.re,
2600                rhs.im,
2601                E::faer_simd_scalar_mul_adde(simd, lhs.im.faer_neg(), rhs.re, acc.im),
2602            ),
2603        }
2604    }
2605
2606    #[inline(always)]
2607    fn faer_simd_scalar_conj_mul<S: Simd>(simd: S, lhs: Self, rhs: Self) -> Self {
2608        Complex {
2609            re: E::faer_simd_scalar_mul_adde(
2610                simd,
2611                lhs.re,
2612                rhs.re,
2613                E::faer_simd_scalar_mul(simd, lhs.im, rhs.im),
2614            ),
2615            im: E::faer_simd_scalar_mul_adde(
2616                simd,
2617                lhs.re,
2618                rhs.im,
2619                E::faer_simd_scalar_mul(simd, lhs.im.faer_neg(), rhs.re),
2620            ),
2621        }
2622    }
2623
2624    #[inline(always)]
2625    fn faer_simd_mul<S: Simd>(
2626        simd: S,
2627        lhs: SimdGroupFor<Self, S>,
2628        rhs: SimdGroupFor<Self, S>,
2629    ) -> SimdGroupFor<Self, S> {
2630        Complex {
2631            re: E::faer_simd_mul_adde(
2632                simd,
2633                lhs.re,
2634                rhs.re,
2635                E::faer_simd_mul(simd, E::faer_simd_neg(simd, lhs.im), rhs.im),
2636            ),
2637            im: E::faer_simd_mul_adde(simd, lhs.re, rhs.im, E::faer_simd_mul(simd, lhs.im, rhs.re)),
2638        }
2639    }
2640
2641    #[inline(always)]
2642    fn faer_simd_scale_real<S: Simd>(
2643        simd: S,
2644        lhs: SimdGroupFor<Self::Real, S>,
2645        rhs: SimdGroupFor<Self, S>,
2646    ) -> SimdGroupFor<Self, S> {
2647        Complex {
2648            re: E::faer_simd_mul(simd, lhs, rhs.re),
2649            im: E::faer_simd_mul(simd, lhs, rhs.im),
2650        }
2651    }
2652
2653    #[inline(always)]
2654    fn faer_simd_conj_mul<S: Simd>(
2655        simd: S,
2656        lhs: SimdGroupFor<Self, S>,
2657        rhs: SimdGroupFor<Self, S>,
2658    ) -> SimdGroupFor<Self, S> {
2659        Complex {
2660            re: E::faer_simd_mul_adde(simd, lhs.re, rhs.re, E::faer_simd_mul(simd, lhs.im, rhs.im)),
2661            im: E::faer_simd_mul_adde(
2662                simd,
2663                lhs.re,
2664                rhs.im,
2665                E::faer_simd_mul(simd, E::faer_simd_neg(simd, lhs.im), rhs.re),
2666            ),
2667        }
2668    }
2669
2670    #[inline(always)]
2671    fn faer_simd_mul_adde<S: Simd>(
2672        simd: S,
2673        lhs: SimdGroupFor<Self, S>,
2674        rhs: SimdGroupFor<Self, S>,
2675        acc: SimdGroupFor<Self, S>,
2676    ) -> SimdGroupFor<Self, S> {
2677        Complex {
2678            re: E::faer_simd_mul_adde(
2679                simd,
2680                lhs.re,
2681                rhs.re,
2682                E::faer_simd_mul_adde(simd, E::faer_simd_neg(simd, lhs.im), rhs.im, acc.re),
2683            ),
2684            im: E::faer_simd_mul_adde(
2685                simd,
2686                lhs.re,
2687                rhs.im,
2688                E::faer_simd_mul_adde(simd, lhs.im, rhs.re, acc.im),
2689            ),
2690        }
2691    }
2692
2693    #[inline(always)]
2694    fn faer_simd_conj_mul_adde<S: Simd>(
2695        simd: S,
2696        lhs: SimdGroupFor<Self, S>,
2697        rhs: SimdGroupFor<Self, S>,
2698        acc: SimdGroupFor<Self, S>,
2699    ) -> SimdGroupFor<Self, S> {
2700        Complex {
2701            re: E::faer_simd_mul_adde(
2702                simd,
2703                lhs.re,
2704                rhs.re,
2705                E::faer_simd_mul_adde(simd, lhs.im, rhs.im, acc.re),
2706            ),
2707            im: E::faer_simd_mul_adde(
2708                simd,
2709                lhs.re,
2710                rhs.im,
2711                E::faer_simd_mul_adde(simd, E::faer_simd_neg(simd, lhs.im), rhs.re, acc.im),
2712            ),
2713        }
2714    }
2715
2716    #[inline(always)]
2717    fn faer_simd_abs2_adde<S: Simd>(
2718        simd: S,
2719        values: SimdGroupFor<Self, S>,
2720        acc: SimdGroupFor<Self::Real, S>,
2721    ) -> SimdGroupFor<Self::Real, S> {
2722        E::faer_simd_mul_adde(
2723            simd,
2724            values.re,
2725            values.re,
2726            E::faer_simd_mul_adde(simd, values.im, values.im, acc),
2727        )
2728    }
2729    #[inline(always)]
2730    fn faer_simd_abs2<S: Simd>(
2731        simd: S,
2732        values: SimdGroupFor<Self, S>,
2733    ) -> SimdGroupFor<Self::Real, S> {
2734        Self::faer_simd_score(simd, values)
2735    }
2736    #[inline(always)]
2737    fn faer_simd_score<S: Simd>(
2738        simd: S,
2739        values: SimdGroupFor<Self, S>,
2740    ) -> SimdGroupFor<Self::Real, S> {
2741        E::faer_simd_mul_adde(
2742            simd,
2743            values.re,
2744            values.re,
2745            E::faer_simd_mul(simd, values.im, values.im),
2746        )
2747    }
2748}
2749
2750impl<I: Iterator> Iterator for ComplexIter<I> {
2751    type Item = Complex<I::Item>;
2752
2753    #[inline(always)]
2754    fn next(&mut self) -> Option<Self::Item> {
2755        match (self.re.next(), self.im.next()) {
2756            (None, None) => None,
2757            (Some(re), Some(im)) => Some(Complex { re, im }),
2758            _ => panic!(),
2759        }
2760    }
2761}
2762impl<I: Iterator> Iterator for ComplexConjIter<I> {
2763    type Item = ComplexConj<I::Item>;
2764
2765    #[inline(always)]
2766    fn next(&mut self) -> Option<Self::Item> {
2767        match (self.re.next(), self.neg_im.next()) {
2768            (None, None) => None,
2769            (Some(re), Some(neg_im)) => Some(ComplexConj { re, neg_im }),
2770            _ => panic!(),
2771        }
2772    }
2773}
2774
2775/// Utilities for split complex number types whose real and imaginary parts are stored separately.
2776pub mod complex_split {
2777
2778    /// This structure contains the real and imaginary parts of an implicitly conjugated value.
2779    #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2780    #[repr(C)]
2781    pub struct ComplexConj<T> {
2782        pub re: T,
2783        pub neg_im: T,
2784    }
2785
2786    unsafe impl<T: bytemuck::Zeroable> bytemuck::Zeroable for ComplexConj<T> {}
2787    unsafe impl<T: bytemuck::Pod> bytemuck::Pod for ComplexConj<T> {}
2788
2789    /// This structure contains a pair of iterators that allow simultaneous iteration over the real
2790    /// and imaginary parts of a collection of complex values.
2791    #[derive(Clone, Debug)]
2792    pub struct ComplexIter<I> {
2793        pub(crate) re: I,
2794        pub(crate) im: I,
2795    }
2796
2797    /// This structure contains a pair of iterators that allow simultaneous iteration over the real
2798    /// and imaginary parts of a collection of implicitly conjugated complex values.
2799    #[derive(Clone, Debug)]
2800    pub struct ComplexConjIter<I> {
2801        pub(crate) re: I,
2802        pub(crate) neg_im: I,
2803    }
2804}
2805
2806use complex_split::*;
2807
2808unsafe impl<E: Entity + ComplexField> Conjugate for Complex<E> {
2809    type Conj = ComplexConj<E>;
2810    type Canonical = Complex<E>;
2811
2812    #[inline(always)]
2813    fn canonicalize(self) -> Self::Canonical {
2814        self
2815    }
2816}
2817
2818unsafe impl<E: Entity + ComplexField> Conjugate for ComplexConj<E> {
2819    const IS_CANONICAL: bool = false;
2820
2821    type Conj = Complex<E>;
2822    type Canonical = Complex<E>;
2823
2824    #[inline(always)]
2825    fn canonicalize(self) -> Self::Canonical {
2826        Complex {
2827            re: self.re,
2828            im: self.neg_im.faer_neg(),
2829        }
2830    }
2831}
2832
2833#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2834pub struct Symbolic;
2835impl Symbolic {
2836    #[inline(always)]
2837    pub fn materialize(n: usize) -> &'static mut [Self] {
2838        unsafe {
2839            core::slice::from_raw_parts_mut(core::ptr::NonNull::<Symbolic>::dangling().as_ptr(), n)
2840        }
2841    }
2842}
2843
2844impl num_traits::Num for Symbolic {
2845    type FromStrRadixErr = ();
2846    fn from_str_radix(_: &str, _: u32) -> Result<Self, Self::FromStrRadixErr> {
2847        Ok(Self)
2848    }
2849}
2850
2851impl num_traits::Zero for Symbolic {
2852    fn zero() -> Self {
2853        Self
2854    }
2855    fn is_zero(&self) -> bool {
2856        true
2857    }
2858}
2859impl num_traits::One for Symbolic {
2860    fn one() -> Self {
2861        Self
2862    }
2863}
2864
2865impl core::ops::Neg for Symbolic {
2866    type Output = Self;
2867    fn neg(self) -> Self {
2868        Self
2869    }
2870}
2871impl core::ops::Add<Symbolic> for Symbolic {
2872    type Output = Self;
2873    fn add(self, _: Self) -> Self {
2874        Self
2875    }
2876}
2877impl core::ops::Sub<Symbolic> for Symbolic {
2878    type Output = Self;
2879    fn sub(self, _: Self) -> Self {
2880        Self
2881    }
2882}
2883impl core::ops::Mul<Symbolic> for Symbolic {
2884    type Output = Self;
2885    fn mul(self, _: Self) -> Self {
2886        Self
2887    }
2888}
2889impl core::ops::Div<Symbolic> for Symbolic {
2890    type Output = Self;
2891    fn div(self, _: Self) -> Self {
2892        Self
2893    }
2894}
2895impl core::ops::Rem<Symbolic> for Symbolic {
2896    type Output = Self;
2897    fn rem(self, _: Self) -> Self {
2898        Self
2899    }
2900}
2901
2902impl core::ops::AddAssign<Symbolic> for Symbolic {
2903    fn add_assign(&mut self, _: Self) {}
2904}
2905impl core::ops::SubAssign<Symbolic> for Symbolic {
2906    fn sub_assign(&mut self, _: Self) {}
2907}
2908impl core::ops::MulAssign<Symbolic> for Symbolic {
2909    fn mul_assign(&mut self, _: Self) {}
2910}
2911impl core::ops::DivAssign<Symbolic> for Symbolic {
2912    fn div_assign(&mut self, _: Self) {}
2913}
2914impl core::ops::RemAssign<Symbolic> for Symbolic {
2915    fn rem_assign(&mut self, _: Self) {}
2916}
2917
2918unsafe impl bytemuck::Zeroable for Symbolic {}
2919unsafe impl Pod for Symbolic {}
2920unsafe impl Entity for Symbolic {
2921    type Unit = Symbolic;
2922    type Index = usize;
2923    type SimdUnit<S: pulp::Simd> = Symbolic;
2924    type SimdMask<S: pulp::Simd> = bool;
2925    type SimdIndex<S: pulp::Simd> = usize;
2926    type Group = IdentityGroup;
2927    type Iter<I: Iterator> = I;
2928    const N_COMPONENTS: usize = 1;
2929    const UNIT: GroupCopyFor<Self, ()> = ();
2930
2931    type PrefixUnit<'a, S: Simd> = &'a [Self];
2932    type SuffixUnit<'a, S: Simd> = &'a [Self];
2933    type PrefixMutUnit<'a, S: Simd> = &'a mut [Self];
2934    type SuffixMutUnit<'a, S: Simd> = &'a mut [Self];
2935
2936    #[inline(always)]
2937    fn faer_first<T>(group: GroupFor<Self, T>) -> T {
2938        group
2939    }
2940
2941    #[inline(always)]
2942    fn faer_from_units(group: GroupFor<Self, Self::Unit>) -> Self {
2943        group
2944    }
2945
2946    #[inline(always)]
2947    fn faer_into_units(self) -> GroupFor<Self, Self::Unit> {
2948        self
2949    }
2950
2951    #[inline(always)]
2952    fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
2953        group
2954    }
2955
2956    #[inline(always)]
2957    fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
2958        group
2959    }
2960
2961    #[inline(always)]
2962    fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
2963        group
2964    }
2965
2966    #[inline(always)]
2967    fn faer_map_impl<T, U>(
2968        group: GroupFor<Self, T>,
2969        f: &mut impl FnMut(T) -> U,
2970    ) -> GroupFor<Self, U> {
2971        (*f)(group)
2972    }
2973
2974    #[inline(always)]
2975    fn faer_zip<T, U>(
2976        first: GroupFor<Self, T>,
2977        second: GroupFor<Self, U>,
2978    ) -> GroupFor<Self, (T, U)> {
2979        (first, second)
2980    }
2981
2982    #[inline(always)]
2983    fn faer_unzip<T, U>(zipped: GroupFor<Self, (T, U)>) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
2984        zipped
2985    }
2986
2987    #[inline(always)]
2988    fn faer_map_with_context<Ctx, T, U>(
2989        ctx: Ctx,
2990        group: GroupFor<Self, T>,
2991        f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
2992    ) -> (Ctx, GroupFor<Self, U>) {
2993        (*f)(ctx, group)
2994    }
2995
2996    #[inline(always)]
2997    fn faer_into_iter<I: IntoIterator>(iter: GroupFor<Self, I>) -> Self::Iter<I::IntoIter> {
2998        iter.into_iter()
2999    }
3000}
3001
3002unsafe impl Conjugate for Symbolic {
3003    type Conj = Symbolic;
3004    type Canonical = Symbolic;
3005    #[inline(always)]
3006    fn canonicalize(self) -> Self::Canonical {
3007        self
3008    }
3009}
3010
3011impl RealField for Symbolic {
3012    #[inline(always)]
3013    fn faer_epsilon() -> Self {
3014        Self
3015    }
3016
3017    #[inline(always)]
3018    fn faer_zero_threshold() -> Self {
3019        Self
3020    }
3021
3022    #[inline(always)]
3023    fn faer_div(self, _rhs: Self) -> Self {
3024        Self
3025    }
3026
3027    #[inline(always)]
3028    fn faer_usize_to_index(a: usize) -> Self::Index {
3029        a
3030    }
3031
3032    #[inline(always)]
3033    fn faer_index_to_usize(a: Self::Index) -> usize {
3034        a
3035    }
3036
3037    #[inline(always)]
3038    fn faer_max_index() -> Self::Index {
3039        usize::MAX
3040    }
3041
3042    #[inline(always)]
3043    fn faer_simd_less_than<S: pulp::Simd>(
3044        _simd: S,
3045        _a: SimdGroupFor<Self, S>,
3046        _b: SimdGroupFor<Self, S>,
3047    ) -> Self::SimdMask<S> {
3048        false
3049    }
3050
3051    #[inline(always)]
3052    fn faer_simd_less_than_or_equal<S: pulp::Simd>(
3053        _simd: S,
3054        _a: SimdGroupFor<Self, S>,
3055        _b: SimdGroupFor<Self, S>,
3056    ) -> Self::SimdMask<S> {
3057        true
3058    }
3059
3060    #[inline(always)]
3061    fn faer_simd_greater_than<S: pulp::Simd>(
3062        _simd: S,
3063        _a: SimdGroupFor<Self, S>,
3064        _b: SimdGroupFor<Self, S>,
3065    ) -> Self::SimdMask<S> {
3066        false
3067    }
3068
3069    #[inline(always)]
3070    fn faer_simd_greater_than_or_equal<S: pulp::Simd>(
3071        _simd: S,
3072        _a: SimdGroupFor<Self, S>,
3073        _b: SimdGroupFor<Self, S>,
3074    ) -> Self::SimdMask<S> {
3075        true
3076    }
3077
3078    #[inline(always)]
3079    fn faer_simd_select<S: pulp::Simd>(
3080        _simd: S,
3081        _mask: Self::SimdMask<S>,
3082        _if_true: SimdGroupFor<Self, S>,
3083        _if_false: SimdGroupFor<Self, S>,
3084    ) -> SimdGroupFor<Self, S> {
3085        Self
3086    }
3087
3088    #[inline(always)]
3089    fn faer_simd_index_select<S: pulp::Simd>(
3090        _simd: S,
3091        mask: Self::SimdMask<S>,
3092        if_true: Self::SimdIndex<S>,
3093        if_false: Self::SimdIndex<S>,
3094    ) -> Self::SimdIndex<S> {
3095        if mask {
3096            if_true
3097        } else {
3098            if_false
3099        }
3100    }
3101
3102    #[inline(always)]
3103    fn faer_simd_index_seq<S: pulp::Simd>(_simd: S) -> Self::SimdIndex<S> {
3104        0
3105    }
3106
3107    #[inline(always)]
3108    fn faer_simd_index_splat<S: pulp::Simd>(_simd: S, value: Self::Index) -> Self::SimdIndex<S> {
3109        value
3110    }
3111
3112    #[inline(always)]
3113    fn faer_simd_index_add<S: pulp::Simd>(
3114        _simd: S,
3115        a: Self::SimdIndex<S>,
3116        b: Self::SimdIndex<S>,
3117    ) -> Self::SimdIndex<S> {
3118        a.wrapping_add(b)
3119    }
3120
3121    #[inline(always)]
3122    fn faer_simd_index_rotate_left<S: Simd>(
3123        _simd: S,
3124        values: SimdIndexFor<Self, S>,
3125        _amount: usize,
3126    ) -> SimdIndexFor<Self, S> {
3127        values
3128    }
3129
3130    #[inline(always)]
3131    fn faer_min_positive() -> Self {
3132        Self
3133    }
3134    #[inline(always)]
3135    fn faer_min_positive_inv() -> Self {
3136        Self
3137    }
3138    #[inline(always)]
3139    fn faer_min_positive_sqrt() -> Self {
3140        Self
3141    }
3142    #[inline(always)]
3143    fn faer_min_positive_sqrt_inv() -> Self {
3144        Self
3145    }
3146
3147    #[inline(always)]
3148    fn faer_simd_abs<S: Simd>(_simd: S, _values: SimdGroupFor<Self, S>) -> SimdGroupFor<Self, S> {
3149        Self
3150    }
3151}
3152
3153impl ComplexField for Symbolic {
3154    type Real = Symbolic;
3155    type Simd = NoSimd;
3156    type ScalarSimd = NoSimd;
3157    type PortableSimd = NoSimd;
3158
3159    #[inline(always)]
3160    fn faer_from_f64(_value: f64) -> Self {
3161        Self
3162    }
3163
3164    #[inline(always)]
3165    fn faer_add(self, _rhs: Self) -> Self {
3166        Self
3167    }
3168
3169    #[inline(always)]
3170    fn faer_sub(self, _rhs: Self) -> Self {
3171        Self
3172    }
3173
3174    #[inline(always)]
3175    fn faer_mul(self, _rhs: Self) -> Self {
3176        Self
3177    }
3178
3179    #[inline(always)]
3180    fn faer_neg(self) -> Self {
3181        Self
3182    }
3183
3184    #[inline(always)]
3185    fn faer_inv(self) -> Self {
3186        Self
3187    }
3188
3189    #[inline(always)]
3190    fn faer_conj(self) -> Self {
3191        Self
3192    }
3193
3194    #[inline(always)]
3195    fn faer_sqrt(self) -> Self {
3196        Self
3197    }
3198
3199    #[inline(always)]
3200    fn faer_scale_real(self, _rhs: Self::Real) -> Self {
3201        Self
3202    }
3203
3204    #[inline(always)]
3205    fn faer_scale_power_of_two(self, _rhs: Self::Real) -> Self {
3206        Self
3207    }
3208
3209    #[inline(always)]
3210    fn faer_score(self) -> Self::Real {
3211        Self
3212    }
3213
3214    #[inline(always)]
3215    fn faer_abs(self) -> Self::Real {
3216        Self
3217    }
3218
3219    #[inline(always)]
3220    fn faer_abs2(self) -> Self::Real {
3221        Self
3222    }
3223
3224    #[inline(always)]
3225    fn faer_nan() -> Self {
3226        Self
3227    }
3228
3229    #[inline(always)]
3230    fn faer_from_real(_real: Self::Real) -> Self {
3231        Self
3232    }
3233
3234    #[inline(always)]
3235    fn faer_real(self) -> Self::Real {
3236        Self
3237    }
3238
3239    #[inline(always)]
3240    fn faer_imag(self) -> Self::Real {
3241        Self
3242    }
3243
3244    #[inline(always)]
3245    fn faer_zero() -> Self {
3246        Self
3247    }
3248
3249    #[inline(always)]
3250    fn faer_one() -> Self {
3251        Self
3252    }
3253
3254    #[inline(always)]
3255    fn faer_align_offset<S: Simd>(
3256        _simd: S,
3257        _ptr: *const UnitFor<Self>,
3258        len: usize,
3259    ) -> pulp::Offset<SimdMaskFor<Self, S>> {
3260        pulp::Scalar::new().i32s_align_offset(core::ptr::null(), len)
3261    }
3262
3263    #[inline(always)]
3264    fn faer_slice_as_aligned_simd<S: Simd>(
3265        _simd: S,
3266        slice: &[UnitFor<Self>],
3267        _offset: pulp::Offset<SimdMaskFor<Self, S>>,
3268    ) -> (
3269        Self::PrefixUnit<'_, S>,
3270        &[SimdUnitFor<Self, S>],
3271        Self::SuffixUnit<'_, S>,
3272    ) {
3273        (&[], slice, &[])
3274    }
3275    #[inline(always)]
3276    fn faer_slice_as_aligned_simd_mut<S: Simd>(
3277        _simd: S,
3278        slice: &mut [UnitFor<Self>],
3279        _offset: pulp::Offset<SimdMaskFor<Self, S>>,
3280    ) -> (
3281        Self::PrefixMutUnit<'_, S>,
3282        &mut [SimdUnitFor<Self, S>],
3283        Self::SuffixMutUnit<'_, S>,
3284    ) {
3285        (&mut [], slice, &mut [])
3286    }
3287
3288    #[inline(always)]
3289    fn faer_slice_as_simd<S: pulp::Simd>(
3290        slice: &[Self::Unit],
3291    ) -> (&[Self::SimdUnit<S>], &[Self::Unit]) {
3292        (slice, &[])
3293    }
3294
3295    #[inline(always)]
3296    fn faer_slice_as_simd_mut<S: pulp::Simd>(
3297        slice: &mut [Self::Unit],
3298    ) -> (&mut [Self::SimdUnit<S>], &mut [Self::Unit]) {
3299        (slice, &mut [])
3300    }
3301
3302    #[inline(always)]
3303    fn faer_partial_load_unit<S: pulp::Simd>(_simd: S, _slice: &[Self::Unit]) -> Self::SimdUnit<S> {
3304        Self
3305    }
3306
3307    #[inline(always)]
3308    fn faer_partial_store_unit<S: pulp::Simd>(
3309        _simd: S,
3310        _slice: &mut [Self::Unit],
3311        _values: Self::SimdUnit<S>,
3312    ) {
3313    }
3314
3315    #[inline(always)]
3316    fn faer_partial_load_last_unit<S: pulp::Simd>(
3317        _simd: S,
3318        _slice: &[Self::Unit],
3319    ) -> Self::SimdUnit<S> {
3320        Self
3321    }
3322
3323    #[inline(always)]
3324    fn faer_partial_store_last_unit<S: pulp::Simd>(
3325        _simd: S,
3326        _slice: &mut [Self::Unit],
3327        _values: Self::SimdUnit<S>,
3328    ) {
3329    }
3330
3331    #[inline(always)]
3332    fn faer_simd_splat_unit<S: pulp::Simd>(_simd: S, _unit: Self::Unit) -> Self::SimdUnit<S> {
3333        Self
3334    }
3335
3336    #[inline(always)]
3337    fn faer_simd_scalar_mul<S: pulp::Simd>(_simd: S, _lhs: Self, _rhs: Self) -> Self {
3338        Self
3339    }
3340
3341    #[inline(always)]
3342    fn faer_simd_scalar_conj_mul<S: pulp::Simd>(_simd: S, _lhs: Self, _rhs: Self) -> Self {
3343        Self
3344    }
3345
3346    #[inline(always)]
3347    fn faer_simd_scalar_mul_adde<S: pulp::Simd>(
3348        _simd: S,
3349        _lhs: Self,
3350        _rhs: Self,
3351        _acc: Self,
3352    ) -> Self {
3353        Self
3354    }
3355
3356    #[inline(always)]
3357    fn faer_simd_scalar_conj_mul_adde<S: pulp::Simd>(
3358        _simd: S,
3359        _lhs: Self,
3360        _rhs: Self,
3361        _acc: Self,
3362    ) -> Self {
3363        Self
3364    }
3365
3366    #[inline(always)]
3367    fn faer_simd_neg<S: pulp::Simd>(
3368        _simd: S,
3369        _values: SimdGroupFor<Self, S>,
3370    ) -> SimdGroupFor<Self, S> {
3371        Self
3372    }
3373
3374    #[inline(always)]
3375    fn faer_simd_conj<S: pulp::Simd>(
3376        _simd: S,
3377        _values: SimdGroupFor<Self, S>,
3378    ) -> SimdGroupFor<Self, S> {
3379        Self
3380    }
3381
3382    #[inline(always)]
3383    fn faer_simd_rotate_left<S: Simd>(
3384        _simd: S,
3385        values: SimdGroupFor<Self, S>,
3386        _amount: usize,
3387    ) -> SimdGroupFor<Self, S> {
3388        values
3389    }
3390
3391    #[inline(always)]
3392    fn faer_simd_add<S: pulp::Simd>(
3393        _simd: S,
3394        _lhs: SimdGroupFor<Self, S>,
3395        _rhs: SimdGroupFor<Self, S>,
3396    ) -> SimdGroupFor<Self, S> {
3397        Self
3398    }
3399
3400    #[inline(always)]
3401    fn faer_simd_sub<S: pulp::Simd>(
3402        _simd: S,
3403        _lhs: SimdGroupFor<Self, S>,
3404        _rhs: SimdGroupFor<Self, S>,
3405    ) -> SimdGroupFor<Self, S> {
3406        Self
3407    }
3408
3409    #[inline(always)]
3410    fn faer_simd_mul<S: pulp::Simd>(
3411        _simd: S,
3412        _lhs: SimdGroupFor<Self, S>,
3413        _rhs: SimdGroupFor<Self, S>,
3414    ) -> SimdGroupFor<Self, S> {
3415        Self
3416    }
3417
3418    #[inline(always)]
3419    fn faer_simd_scale_real<S: pulp::Simd>(
3420        _simd: S,
3421        _lhs: SimdGroupFor<Self::Real, S>,
3422        _rhs: SimdGroupFor<Self, S>,
3423    ) -> SimdGroupFor<Self, S> {
3424        Self
3425    }
3426
3427    #[inline(always)]
3428    fn faer_simd_conj_mul<S: pulp::Simd>(
3429        _simd: S,
3430        _lhs: SimdGroupFor<Self, S>,
3431        _rhs: SimdGroupFor<Self, S>,
3432    ) -> SimdGroupFor<Self, S> {
3433        Self
3434    }
3435
3436    #[inline(always)]
3437    fn faer_simd_mul_adde<S: pulp::Simd>(
3438        _simd: S,
3439        _lhs: SimdGroupFor<Self, S>,
3440        _rhs: SimdGroupFor<Self, S>,
3441        _acc: SimdGroupFor<Self, S>,
3442    ) -> SimdGroupFor<Self, S> {
3443        Self
3444    }
3445
3446    #[inline(always)]
3447    fn faer_simd_conj_mul_adde<S: pulp::Simd>(
3448        _simd: S,
3449        _lhs: SimdGroupFor<Self, S>,
3450        _rhs: SimdGroupFor<Self, S>,
3451        _acc: SimdGroupFor<Self, S>,
3452    ) -> SimdGroupFor<Self, S> {
3453        Self
3454    }
3455
3456    #[inline(always)]
3457    fn faer_simd_abs2_adde<S: pulp::Simd>(
3458        _simd: S,
3459        _values: SimdGroupFor<Self, S>,
3460        _acc: SimdGroupFor<Self::Real, S>,
3461    ) -> SimdGroupFor<Self::Real, S> {
3462        Self
3463    }
3464
3465    #[inline(always)]
3466    fn faer_simd_abs2<S: pulp::Simd>(
3467        _simd: S,
3468        _values: SimdGroupFor<Self, S>,
3469    ) -> SimdGroupFor<Self::Real, S> {
3470        Self
3471    }
3472
3473    #[inline(always)]
3474    fn faer_simd_score<S: pulp::Simd>(
3475        _simd: S,
3476        _values: SimdGroupFor<Self, S>,
3477    ) -> SimdGroupFor<Self::Real, S> {
3478        Self
3479    }
3480}
3481
3482#[cfg(test)]
3483mod tests {
3484    use super::*;
3485
3486    #[test]
3487    fn test_sqrt() {
3488        for _ in 0..100 {
3489            let a = num_complex::Complex64::new(rand::random(), rand::random());
3490            let num_complex::Complex {
3491                re: target_re,
3492                im: target_im,
3493            } = a.faer_sqrt();
3494            let (sqrt_re, sqrt_im) = sqrt_impl(a.re, a.im);
3495            assert!((target_re - sqrt_re).abs() < 1e-12);
3496            assert!((target_im - sqrt_im).abs() < 1e-12);
3497        }
3498    }
3499}