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 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
208pub 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
386pub unsafe trait Conjugate: Entity {
391 const IS_CANONICAL: bool = true;
392
393 type Conj: Entity + Conjugate<Conj = Self, Canonical = Self::Canonical>;
395 type Canonical: Entity + Conjugate<Canonical = Self::Canonical>;
398
399 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
432pub 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 fn faer_from_f64(value: f64) -> Self;
452
453 fn faer_add(self, rhs: Self) -> Self;
455 fn faer_sub(self, rhs: Self) -> Self;
457 fn faer_mul(self, rhs: Self) -> Self;
459
460 fn faer_neg(self) -> Self;
462 fn faer_inv(self) -> Self;
464 fn faer_conj(self) -> Self;
466 fn faer_sqrt(self) -> Self;
468
469 fn faer_scale_real(self, rhs: Self::Real) -> Self;
471
472 fn faer_scale_power_of_two(self, rhs: Self::Real) -> Self;
474
475 fn faer_score(self) -> Self::Real;
479 fn faer_abs(self) -> Self::Real;
481 fn faer_abs2(self) -> Self::Real;
483
484 fn faer_nan() -> Self;
486
487 #[inline(always)]
489 fn faer_is_nan(&self) -> bool {
490 #[allow(clippy::eq_op)]
491 {
492 self != self
493 }
494 }
495
496 #[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 fn faer_from_real(real: Self::Real) -> Self;
509
510 fn faer_real(self) -> Self::Real;
512 fn faer_imag(self) -> Self::Real;
514
515 fn faer_zero() -> Self;
517 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
712pub 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 Self::faer_nan()
2281 } else if self == Self::faer_zero() {
2282 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
2775pub mod complex_split {
2777
2778 #[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 #[derive(Clone, Debug)]
2792 pub struct ComplexIter<I> {
2793 pub(crate) re: I,
2794 pub(crate) im: I,
2795 }
2796
2797 #[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}