Skip to main content

faer_traits/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(non_camel_case_types)]
3use bytemuck::Pod;
4use core::fmt::Debug;
5use num_complex::Complex;
6use pulp::Simd;
7use qd::Quad;
8// taken from imply-hack (MIT license)
9pub mod imply {
10	pub trait Imply<T: ?Sized>: sealed::ImplyInner<T, Is = T> {}
11	impl<T: ?Sized, U: ?Sized> Imply<T> for U {}
12	mod sealed {
13		pub trait ImplyInner<T: ?Sized> {
14			type Is: ?Sized;
15		}
16		impl<T: ?Sized, U: ?Sized> ImplyInner<T> for U {
17			type Is = T;
18		}
19	}
20}
21use core::ops::*;
22use imply::Imply;
23use math_utils::*;
24pub mod math_utils {
25	use crate::{ByRef, ComplexField, RealField, abs_impl};
26	#[inline(always)]
27	#[must_use]
28	pub fn eps<T: RealField>() -> T {
29		T::Real::epsilon_impl()
30	}
31	#[inline(always)]
32	#[must_use]
33	pub fn nbits<T: ComplexField>() -> usize {
34		T::Real::nbits_impl()
35	}
36	#[inline(always)]
37	#[must_use]
38	pub fn min_positive<T: RealField>() -> T {
39		T::min_positive_impl()
40	}
41	#[inline(always)]
42	#[must_use]
43	pub fn max_positive<T: RealField>() -> T {
44		T::max_positive_impl()
45	}
46	#[inline(always)]
47	#[must_use]
48	pub fn sqrt_min_positive<T: RealField>() -> T {
49		T::sqrt_min_positive_impl()
50	}
51	#[inline(always)]
52	#[must_use]
53	pub fn sqrt_max_positive<T: RealField>() -> T {
54		T::sqrt_max_positive_impl()
55	}
56	#[inline(always)]
57	#[must_use]
58	pub fn zero<T: ComplexField>() -> T {
59		T::zero_impl()
60	}
61	#[inline(always)]
62	#[must_use]
63	pub fn one<T: ComplexField>() -> T {
64		T::one_impl()
65	}
66	#[inline(always)]
67	#[must_use]
68	pub fn nan<T: ComplexField>() -> T {
69		T::nan_impl()
70	}
71	#[inline(always)]
72	#[must_use]
73	pub fn infinity<T: ComplexField>() -> T {
74		T::infinity_impl()
75	}
76	#[inline(always)]
77	#[must_use]
78	pub fn as_real<T: ComplexField>(value: &T) -> T {
79		T::from_real_impl(&T::real_part_impl((value).by_ref()))
80	}
81	#[inline(always)]
82	#[must_use]
83	pub fn real<T: ComplexField>(value: &T) -> T::Real {
84		T::real_part_impl((value).by_ref())
85	}
86	#[inline(always)]
87	#[must_use]
88	pub fn imag<T: ComplexField>(value: &T) -> T::Real {
89		T::imag_part_impl((value).by_ref())
90	}
91	#[inline(always)]
92	#[track_caller]
93	#[must_use]
94	pub fn neg<T: NegByRef>(value: &T) -> T::Output {
95		value.neg_by_ref()
96	}
97	#[inline(always)]
98	#[must_use]
99	pub fn copy<T: ComplexField>(value: &T) -> T {
100		T::copy_impl((value).by_ref())
101	}
102	#[inline(always)]
103	#[must_use]
104	pub fn conj<T: ComplexField>(value: &T) -> T {
105		T::conj_impl((value).by_ref())
106	}
107	#[inline(always)]
108	#[track_caller]
109	#[must_use]
110	pub fn add<T: AddByRef<U>, U>(lhs: &T, rhs: &U) -> T::Output {
111		lhs.add_by_ref(rhs)
112	}
113	#[inline(always)]
114	#[track_caller]
115	#[must_use]
116	pub fn sub<T: SubByRef<U>, U>(lhs: &T, rhs: &U) -> T::Output {
117		lhs.sub_by_ref(rhs)
118	}
119	#[inline(always)]
120	#[track_caller]
121	#[must_use]
122	pub fn mul<T: MulByRef<U>, U>(lhs: &T, rhs: &U) -> T::Output {
123		lhs.mul_by_ref(rhs)
124	}
125	#[inline(always)]
126	#[track_caller]
127	#[must_use]
128	pub fn div<T: DivByRef<U>, U>(lhs: &T, rhs: &U) -> T::Output {
129		lhs.div_by_ref(rhs)
130	}
131	#[inline(always)]
132	#[must_use]
133	pub fn mul_real<T: ComplexField>(lhs: &T, rhs: &T::Real) -> T {
134		T::mul_real_impl((lhs).by_ref(), (rhs).by_ref())
135	}
136	#[inline(always)]
137	#[must_use]
138	pub fn mul_pow2<T: ComplexField>(lhs: &T, rhs: &T::Real) -> T {
139		T::mul_real_impl((lhs).by_ref(), (rhs).by_ref())
140	}
141	#[inline(always)]
142	#[must_use]
143	pub fn abs1<T: ComplexField>(value: &T) -> T::Real {
144		T::abs1_impl((value).by_ref())
145	}
146	#[inline(always)]
147	#[must_use]
148	pub fn absmax<T: ComplexField>(value: &T) -> T::Real {
149		if const { T::IS_REAL } {
150			T::abs1_impl(value)
151		} else {
152			&T::Real::abs1_impl(&real(value))
153				+ &T::Real::abs1_impl(&imag(value))
154		}
155	}
156	#[inline(always)]
157	#[must_use]
158	pub fn abs<T: ComplexField>(value: &T) -> T::Real {
159		T::abs_impl((value).by_ref())
160	}
161	#[inline(always)]
162	#[must_use]
163	pub fn hypot<T: RealField>(lhs: &T, rhs: &T) -> T {
164		abs_impl::<T::Real>(lhs.clone(), rhs.clone())
165	}
166	#[inline(always)]
167	#[must_use]
168	pub fn abs2<T: ComplexField>(value: &T) -> T::Real {
169		T::abs2_impl((value).by_ref())
170	}
171	#[inline(always)]
172	#[must_use]
173	pub fn max<T: RealField>(lhs: &T, rhs: &T) -> T {
174		if lhs > rhs { copy(lhs) } else { copy(rhs) }
175	}
176	#[inline(always)]
177	#[must_use]
178	pub fn min<T: RealField>(lhs: &T, rhs: &T) -> T {
179		if lhs < rhs { copy(lhs) } else { copy(rhs) }
180	}
181	#[inline(always)]
182	#[must_use]
183	pub fn is_nan<T: ComplexField>(value: &T) -> bool {
184		T::is_nan_impl((value).by_ref())
185	}
186	#[inline(always)]
187	#[must_use]
188	pub fn is_finite<T: ComplexField>(value: &T) -> bool {
189		T::is_finite_impl((value).by_ref())
190	}
191	#[inline(always)]
192	#[must_use]
193	pub fn sqrt<T: ComplexField>(value: &T) -> T {
194		T::sqrt_impl((value).by_ref())
195	}
196	#[inline(always)]
197	#[must_use]
198	pub fn recip<T: ComplexField>(value: &T) -> T {
199		T::recip_impl((value).by_ref())
200	}
201	#[inline(always)]
202	#[must_use]
203	pub fn from_real<T: ComplexField>(value: &T::Real) -> T {
204		T::from_real_impl((value).by_ref())
205	}
206	#[inline(always)]
207	#[must_use]
208	pub fn from_f64<T: ComplexField>(value: f64) -> T {
209		T::from_f64_impl(value)
210	}
211	pub use crate::{AddByRef, DivByRef, MulByRef, NegByRef, SubByRef};
212}
213macro_rules! impl_op {
214	({$(
215		impl$(<$T:ident: $bound:ident>)? $op:ident for $ty:ty {
216			fn $op_fn:ident($self:ident, $rhs:ident: Self) -> Self::Output $body:block
217		}
218	)*}) => {$(
219		impl$(<$T: $bound>)? $op for $ty {
220			type Output = $ty;
221			#[inline(always)]
222			fn $op_fn($self, $rhs: $ty) -> Self::Output $body
223		}
224		impl$(<$T: $bound>)? $op<&$ty> for $ty {
225			type Output = $ty;
226			#[inline(always)]
227			fn $op_fn($self, $rhs: &$ty) -> Self::Output $body
228		}
229		impl$(<$T: $bound>)? $op<$ty> for &$ty {
230			type Output = $ty;
231			#[inline(always)]
232			fn $op_fn($self, $rhs: $ty) -> Self::Output $body
233		}
234		impl$(<$T: $bound>)? $op<&$ty> for &$ty {
235			type Output = $ty;
236			#[inline(always)]
237			fn $op_fn($self, $rhs: &$ty) -> Self::Output $body
238		}
239	)*};
240}
241macro_rules! impl_assign_op {
242	({$(
243		impl$(<$T:ident: $bound:ident>)? $op:ident for $ty:ty {
244			fn $op_fn:ident(&mut $self:ident, $rhs:ident: Self) $body:block
245		}
246	)*}) => {$(
247		impl$(<$T: $bound>)? $op for $ty {
248			#[inline(always)]
249			fn $op_fn(&mut $self, $rhs: Self) $body
250		}
251		impl$(<$T: $bound>)? $op<&$ty> for $ty {
252			#[inline(always)]
253			fn $op_fn(&mut $self, $rhs: &$ty) $body
254		}
255	)*};
256}
257pub trait AddByRef<Rhs = Self> {
258	type Output;
259	fn add_by_ref(&self, rhs: &Rhs) -> Self::Output;
260}
261pub trait SubByRef<Rhs = Self> {
262	type Output;
263	fn sub_by_ref(&self, rhs: &Rhs) -> Self::Output;
264}
265pub trait NegByRef {
266	type Output;
267	fn neg_by_ref(&self) -> Self::Output;
268}
269pub trait MulByRef<Rhs = Self> {
270	type Output;
271	fn mul_by_ref(&self, rhs: &Rhs) -> Self::Output;
272}
273pub trait DivByRef<Rhs = Self> {
274	type Output;
275	fn div_by_ref(&self, rhs: &Rhs) -> Self::Output;
276}
277impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
278where
279	for<'a> &'a Lhs: core::ops::Add<&'a Rhs, Output = Output>,
280{
281	type Output = Output;
282
283	#[inline]
284	#[track_caller]
285	fn add_by_ref(&self, rhs: &Rhs) -> Self::Output {
286		self + rhs
287	}
288}
289impl<Rhs, Lhs, Output> SubByRef<Rhs> for Lhs
290where
291	for<'a> &'a Lhs: core::ops::Sub<&'a Rhs, Output = Output>,
292{
293	type Output = Output;
294
295	#[inline]
296	#[track_caller]
297	fn sub_by_ref(&self, rhs: &Rhs) -> Self::Output {
298		self - rhs
299	}
300}
301impl<Rhs, Lhs, Output> MulByRef<Rhs> for Lhs
302where
303	for<'a> &'a Lhs: core::ops::Mul<&'a Rhs, Output = Output>,
304{
305	type Output = Output;
306
307	#[inline]
308	#[track_caller]
309	fn mul_by_ref(&self, rhs: &Rhs) -> Self::Output {
310		self * rhs
311	}
312}
313impl<Rhs, Lhs, Output> DivByRef<Rhs> for Lhs
314where
315	for<'a> &'a Lhs: core::ops::Div<&'a Rhs, Output = Output>,
316{
317	type Output = Output;
318
319	#[inline]
320	#[track_caller]
321	fn div_by_ref(&self, rhs: &Rhs) -> Self::Output {
322		self / rhs
323	}
324}
325impl<T, Output> NegByRef for T
326where
327	for<'a> &'a T: core::ops::Neg<Output = Output>,
328{
329	type Output = Output;
330
331	#[inline]
332	#[track_caller]
333	fn neg_by_ref(&self) -> Self::Output {
334		-self
335	}
336}
337fn abs_impl<T: RealField>(re: T, im: T) -> T {
338	use ext::*;
339	let (re, im) = &(re, im);
340	let small = &sqrt_min_positive();
341	let big = &sqrt_max_positive();
342	let one = &one();
343	let re_abs = &re.abs();
344	let im_abs = &im.abs();
345	if re_abs > big || im_abs > big {
346		((re * small).abs2() + (im * small).abs2()).sqrt() * big
347	} else if re_abs > one || im_abs > one {
348		(re.abs2() + im.abs2()).sqrt()
349	} else {
350		((re * big).abs2() + (im * big).abs2()).sqrt() * small
351	}
352}
353fn recip_impl<T: RealField>(re: T, im: T) -> (T, T) {
354	use ext::*;
355	let (re, im) = &(re, im);
356	if is_nan(re) || is_nan(im) {
357		return (nan(), nan());
358	}
359	if *re == zero() && *im == zero() {
360		return (infinity(), infinity());
361	}
362	if !is_finite(re) || !is_finite(im) {
363		return (zero(), zero());
364	}
365	let small = &sqrt_min_positive();
366	let big = &sqrt_max_positive();
367	let one = &one();
368	let re_abs = &abs(re);
369	let im_abs = &abs(im);
370	if re_abs > big || im_abs > big {
371		let re = re * small;
372		let im = im * small;
373		let inv = &(re.abs2() + im.abs2()).recip();
374		(((re * inv) * small), ((-im * inv) * small))
375	} else if re_abs > one || im_abs > one {
376		let inv = &(re.abs2() + im.abs2()).recip();
377		((re * inv), (-im * inv))
378	} else {
379		let re = re * big;
380		let im = im * big;
381		if &abs(&re) < small && &abs(&im) < small {
382			// a subnormal input is still below `small` after one scaling,
383			// where the squared magnitude's reciprocal would overflow
384			let re = re * big;
385			let im = im * big;
386			let inv = &(re.abs2() + im.abs2()).recip();
387			(((re * inv) * big) * big, ((-im * inv) * big) * big)
388		} else {
389			let inv = &(re.abs2() + im.abs2()).recip();
390			(((re * inv) * big), ((-im * inv) * big))
391		}
392	}
393}
394fn sqrt_impl<T: RealField>(re: T, im: T) -> (T, T) {
395	use ext::*;
396	let im_negative = im < zero();
397	let half = &from_f64(0.5);
398	let abs = &abs_impl(re.clone(), im);
399	let zero = &zero::<T>();
400	let re = &re;
401	let mut sum = re + abs;
402	if &sum < zero {
403		sum = zero.copy();
404	}
405	let out_re = sum.mul_pow2(half).sqrt();
406	let mut out_im = (abs - re).mul_pow2(half).fmax(zero).sqrt();
407	if im_negative {
408		out_im = -out_im;
409	}
410	(out_re, out_im)
411}
412pub trait ByRef<T> {
413	fn by_ref(&self) -> &T;
414}
415impl<T> ByRef<T> for T {
416	#[inline]
417	fn by_ref(&self) -> &T {
418		self
419	}
420}
421impl<T> ByRef<T> for &T {
422	#[inline]
423	fn by_ref(&self) -> &T {
424		*self
425	}
426}
427#[repr(transparent)]
428pub struct SimdCtx<T: ComplexField, S: Simd>(pub T::SimdCtx<S>);
429impl<T: ComplexField, S: Simd> Copy for SimdCtx<T, S> {}
430impl<T: ComplexField, S: Simd> Clone for SimdCtx<T, S> {
431	#[inline]
432	fn clone(&self) -> Self {
433		*self
434	}
435}
436#[derive(Copy, Clone, Debug)]
437#[repr(transparent)]
438pub struct RealReg<T>(pub T);
439impl<T: ComplexField, S: Simd> SimdCtx<T, S> {
440	#[inline(always)]
441	pub fn new(ctx: &T::SimdCtx<S>) -> &Self {
442		unsafe { &*(ctx as *const T::SimdCtx<S> as *const Self) }
443	}
444
445	#[inline(always)]
446	pub fn zero(&self) -> T::SimdVec<S> {
447		unsafe { core::mem::zeroed() }
448	}
449
450	#[inline(always)]
451	pub fn splat(&self, value: impl ByRef<T>) -> T::SimdVec<S> {
452		unsafe {
453			core::mem::transmute_copy(&T::simd_splat(&self.0, value.by_ref()))
454		}
455	}
456
457	#[inline(always)]
458	pub fn splat_real(
459		&self,
460		value: impl ByRef<T::Real>,
461	) -> RealReg<T::SimdVec<S>> {
462		RealReg(unsafe {
463			core::mem::transmute_copy(&T::simd_splat_real(
464				&self.0,
465				value.by_ref(),
466			))
467		})
468	}
469
470	#[inline(always)]
471	pub fn add(&self, lhs: T::SimdVec<S>, rhs: T::SimdVec<S>) -> T::SimdVec<S> {
472		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
473		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
474		unsafe { core::mem::transmute_copy(&T::simd_add(&self.0, lhs, rhs)) }
475	}
476
477	#[inline(always)]
478	pub fn sub(&self, lhs: T::SimdVec<S>, rhs: T::SimdVec<S>) -> T::SimdVec<S> {
479		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
480		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
481		unsafe { core::mem::transmute_copy(&T::simd_sub(&self.0, lhs, rhs)) }
482	}
483
484	#[inline(always)]
485	pub fn neg(&self, value: T::SimdVec<S>) -> T::SimdVec<S> {
486		let value = unsafe { core::mem::transmute_copy(&value) };
487		unsafe { core::mem::transmute_copy(&T::simd_neg(&self.0, value)) }
488	}
489
490	#[inline(always)]
491	pub fn conj(&self, value: T::SimdVec<S>) -> T::SimdVec<S> {
492		let value = unsafe { core::mem::transmute_copy(&value) };
493		unsafe { core::mem::transmute_copy(&T::simd_conj(&self.0, value)) }
494	}
495
496	#[inline(always)]
497	pub fn abs1(&self, value: T::SimdVec<S>) -> RealReg<T::SimdVec<S>> {
498		let value = unsafe { core::mem::transmute_copy(&value) };
499		RealReg(unsafe {
500			core::mem::transmute_copy(&T::simd_abs1(&self.0, value))
501		})
502	}
503
504	#[inline(always)]
505	pub fn abs_max(&self, value: T::SimdVec<S>) -> RealReg<T::SimdVec<S>> {
506		let value = unsafe { core::mem::transmute_copy(&value) };
507		RealReg(unsafe {
508			core::mem::transmute_copy(&T::simd_abs_max(&self.0, value))
509		})
510	}
511
512	#[inline(always)]
513	pub fn mul_real(
514		&self,
515		lhs: T::SimdVec<S>,
516		rhs: RealReg<T::SimdVec<S>>,
517	) -> T::SimdVec<S> {
518		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
519		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
520		unsafe {
521			core::mem::transmute_copy(&T::simd_mul_real(&self.0, lhs, rhs))
522		}
523	}
524
525	#[inline(always)]
526	pub fn mul_pow2(
527		&self,
528		lhs: T::SimdVec<S>,
529		rhs: RealReg<T::SimdVec<S>>,
530	) -> T::SimdVec<S> {
531		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
532		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
533		unsafe {
534			core::mem::transmute_copy(&T::simd_mul_pow2(&self.0, lhs, rhs))
535		}
536	}
537
538	#[inline(always)]
539	pub fn mul(&self, lhs: T::SimdVec<S>, rhs: T::SimdVec<S>) -> T::SimdVec<S> {
540		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
541		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
542		unsafe { core::mem::transmute_copy(&T::simd_mul(&self.0, lhs, rhs)) }
543	}
544
545	#[inline(always)]
546	pub fn conj_mul(
547		&self,
548		lhs: T::SimdVec<S>,
549		rhs: T::SimdVec<S>,
550	) -> T::SimdVec<S> {
551		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
552		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
553		unsafe {
554			core::mem::transmute_copy(&T::simd_conj_mul(&self.0, lhs, rhs))
555		}
556	}
557
558	#[inline(always)]
559	pub fn mul_add(
560		&self,
561		lhs: T::SimdVec<S>,
562		rhs: T::SimdVec<S>,
563		acc: T::SimdVec<S>,
564	) -> T::SimdVec<S> {
565		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
566		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
567		let acc = unsafe { core::mem::transmute_copy(&acc) };
568		unsafe {
569			core::mem::transmute_copy(&T::simd_mul_add(&self.0, lhs, rhs, acc))
570		}
571	}
572
573	#[inline(always)]
574	pub fn conj_mul_add(
575		&self,
576		lhs: T::SimdVec<S>,
577		rhs: T::SimdVec<S>,
578		acc: T::SimdVec<S>,
579	) -> T::SimdVec<S> {
580		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
581		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
582		let acc = unsafe { core::mem::transmute_copy(&acc) };
583		unsafe {
584			core::mem::transmute_copy(&T::simd_conj_mul_add(
585				&self.0, lhs, rhs, acc,
586			))
587		}
588	}
589
590	#[inline(always)]
591	pub fn maybe_conj_mul_add<const CONJ: bool>(
592		&self,
593		lhs: T::SimdVec<S>,
594		rhs: T::SimdVec<S>,
595		acc: T::SimdVec<S>,
596	) -> T::SimdVec<S> {
597		if const { CONJ } {
598			self.conj_mul_add(lhs, rhs, acc)
599		} else {
600			self.mul_add(lhs, rhs, acc)
601		}
602	}
603
604	#[inline(always)]
605	pub fn abs2(&self, value: T::SimdVec<S>) -> RealReg<T::SimdVec<S>> {
606		let value = unsafe { core::mem::transmute_copy(&value) };
607		RealReg(unsafe {
608			core::mem::transmute_copy(&T::simd_abs2(&self.0, value))
609		})
610	}
611
612	#[inline(always)]
613	pub fn abs2_add(
614		&self,
615		value: T::SimdVec<S>,
616		acc: RealReg<T::SimdVec<S>>,
617	) -> RealReg<T::SimdVec<S>> {
618		let value = unsafe { core::mem::transmute_copy(&value) };
619		let acc = unsafe { core::mem::transmute_copy(&acc) };
620		RealReg(unsafe {
621			core::mem::transmute_copy(&T::simd_abs2_add(&self.0, value, acc))
622		})
623	}
624
625	#[inline(always)]
626	pub fn reduce_sum(&self, value: T::SimdVec<S>) -> T {
627		let value = unsafe { core::mem::transmute_copy(&value) };
628		unsafe {
629			core::mem::transmute_copy(&T::simd_reduce_sum(&self.0, value))
630		}
631	}
632
633	#[inline(always)]
634	pub fn reduce_max(&self, value: RealReg<T::SimdVec<S>>) -> T {
635		let value = unsafe { core::mem::transmute_copy(&value) };
636		unsafe {
637			core::mem::transmute_copy(&T::simd_reduce_max(&self.0, value))
638		}
639	}
640
641	#[inline(always)]
642	pub fn reduce_sum_real(&self, value: RealReg<T::SimdVec<S>>) -> Real<T> {
643		let value = T::simd_reduce_sum(&self.0, value.0);
644		if const { T::SIMD_ABS_SPLIT_REAL_IMAG && !S::IS_SCALAR } {
645			let r = real(&value);
646			let i = imag(&value);
647			&r + &i
648		} else {
649			real(&value)
650		}
651	}
652
653	#[inline(always)]
654	pub fn reduce_max_real(&self, value: RealReg<T::SimdVec<S>>) -> Real<T> {
655		use crate::ext::*;
656		let value = T::simd_reduce_max(&self.0, value.0);
657		if const { T::SIMD_ABS_SPLIT_REAL_IMAG && !S::IS_SCALAR } {
658			value.real().fmax(value.imag())
659		} else {
660			value.real()
661		}
662	}
663
664	#[inline(always)]
665	pub fn max(
666		&self,
667		lhs: RealReg<T::SimdVec<S>>,
668		rhs: RealReg<T::SimdVec<S>>,
669	) -> RealReg<T::SimdVec<S>> {
670		let cmp = self.gt(lhs, rhs);
671		RealReg(self.select(cmp, lhs.0, rhs.0))
672	}
673
674	#[inline(always)]
675	pub fn eq(&self, lhs: T::SimdVec<S>, rhs: T::SimdVec<S>) -> T::SimdMask<S> {
676		T::simd_equal(&self.0, lhs, rhs)
677	}
678
679	#[inline(always)]
680	pub fn lt(
681		&self,
682		lhs: RealReg<T::SimdVec<S>>,
683		rhs: RealReg<T::SimdVec<S>>,
684	) -> T::SimdMask<S> {
685		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
686		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
687		unsafe {
688			core::mem::transmute_copy(&T::simd_less_than(&self.0, lhs, rhs))
689		}
690	}
691
692	#[inline(always)]
693	pub fn gt(
694		&self,
695		lhs: RealReg<T::SimdVec<S>>,
696		rhs: RealReg<T::SimdVec<S>>,
697	) -> T::SimdMask<S> {
698		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
699		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
700		unsafe {
701			core::mem::transmute_copy(&T::simd_greater_than(&self.0, lhs, rhs))
702		}
703	}
704
705	#[inline(always)]
706	pub fn le(
707		&self,
708		lhs: RealReg<T::SimdVec<S>>,
709		rhs: RealReg<T::SimdVec<S>>,
710	) -> T::SimdMask<S> {
711		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
712		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
713		unsafe {
714			core::mem::transmute_copy(&T::simd_less_than_or_equal(
715				&self.0, lhs, rhs,
716			))
717		}
718	}
719
720	#[inline(always)]
721	pub fn ge(
722		&self,
723		lhs: RealReg<T::SimdVec<S>>,
724		rhs: RealReg<T::SimdVec<S>>,
725	) -> T::SimdMask<S> {
726		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
727		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
728		unsafe {
729			core::mem::transmute_copy(&T::simd_greater_than_or_equal(
730				&self.0, lhs, rhs,
731			))
732		}
733	}
734
735	#[inline(always)]
736	pub fn select(
737		&self,
738		mask: T::SimdMask<S>,
739		lhs: T::SimdVec<S>,
740		rhs: T::SimdVec<S>,
741	) -> T::SimdVec<S> {
742		let lhs = unsafe { core::mem::transmute_copy(&lhs) };
743		let rhs = unsafe { core::mem::transmute_copy(&rhs) };
744		unsafe {
745			core::mem::transmute_copy(&T::simd_select(&self.0, mask, lhs, rhs))
746		}
747	}
748
749	#[inline(always)]
750	pub fn iselect(
751		&self,
752		mask: T::SimdMask<S>,
753		lhs: T::SimdIndex<S>,
754		rhs: T::SimdIndex<S>,
755	) -> T::SimdIndex<S> {
756		unsafe {
757			core::mem::transmute_copy(&T::simd_index_select(
758				&self.0, mask, lhs, rhs,
759			))
760		}
761	}
762
763	#[inline(always)]
764	pub fn isplat(&self, value: T::Index) -> T::SimdIndex<S> {
765		unsafe {
766			core::mem::transmute_copy(&T::simd_index_splat(&self.0, value))
767		}
768	}
769
770	#[inline(always)]
771	pub fn izero(&self) -> T::SimdIndex<S> {
772		unsafe { core::mem::zeroed() }
773	}
774
775	#[inline(always)]
776	pub fn iadd(
777		&self,
778		lhs: T::SimdIndex<S>,
779		rhs: T::SimdIndex<S>,
780	) -> T::SimdIndex<S> {
781		unsafe {
782			core::mem::transmute_copy(&T::simd_index_add(&self.0, lhs, rhs))
783		}
784	}
785
786	#[inline(always)]
787	pub fn or_mask(
788		&self,
789		lhs: T::SimdMask<S>,
790		rhs: T::SimdMask<S>,
791	) -> T::SimdMask<S> {
792		T::simd_or_mask(&self.0, lhs, rhs)
793	}
794
795	#[inline(always)]
796	pub fn and_mask(
797		&self,
798		lhs: T::SimdMask<S>,
799		rhs: T::SimdMask<S>,
800	) -> T::SimdMask<S> {
801		T::simd_and_mask(&self.0, lhs, rhs)
802	}
803
804	#[inline(always)]
805	pub fn not_mask(&self, mask: T::SimdMask<S>) -> T::SimdMask<S> {
806		T::simd_not_mask(&self.0, mask)
807	}
808
809	#[inline(always)]
810	pub fn first_true_mask(&self, value: T::SimdMask<S>) -> usize {
811		T::simd_first_true_mask(&self.0, value)
812	}
813
814	#[inline(always)]
815	pub unsafe fn mask_load(
816		&self,
817		mask: T::SimdMemMask<S>,
818		ptr: *const T::SimdVec<S>,
819	) -> T::SimdVec<S> {
820		unsafe { T::simd_mask_load(&self.0, mask, ptr) }
821	}
822
823	#[inline(always)]
824	pub unsafe fn mask_store(
825		&self,
826		mask: T::SimdMemMask<S>,
827		ptr: *mut T::SimdVec<S>,
828		value: T::SimdVec<S>,
829	) {
830		let value = unsafe { core::mem::transmute_copy(&value) };
831		unsafe { T::simd_mask_store(&self.0, mask, ptr, value) }
832	}
833
834	#[inline(always)]
835	pub fn load(&self, ptr: &T::SimdVec<S>) -> T::SimdVec<S> {
836		unsafe { core::mem::transmute_copy(&T::simd_load(&self.0, ptr)) }
837	}
838
839	#[inline(always)]
840	pub fn store(&self, ptr: &mut T::SimdVec<S>, value: T::SimdVec<S>) {
841		let value = unsafe { core::mem::transmute_copy(&value) };
842		unsafe {
843			core::mem::transmute_copy(&T::simd_store(&self.0, ptr, value))
844		}
845	}
846}
847pub unsafe trait Conjugate:
848	Send + Sync + core::fmt::Debug + Imply<Self::Canonical, Is: RefOps>
849{
850	const IS_CANONICAL: bool;
851	type Conj: Conjugate<Conj = Self, Canonical = Self::Canonical>;
852	type Canonical: Conjugate<Canonical = Self::Canonical> + ComplexField;
853}
854pub type Real<T> = <<T as Conjugate>::Canonical as ComplexField>::Real;
855#[derive(Copy, Clone, Debug, PartialEq, Eq)]
856pub struct ComplexConj<T> {
857	pub re: T,
858	pub im_neg: T,
859}
860#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
861pub enum SimdCapabilities {
862	None,
863	Copy,
864	Simd,
865}
866impl SimdCapabilities {
867	#[inline]
868	pub const fn is_copy(self) -> bool {
869		matches!(self, Self::Copy | Self::Simd)
870	}
871
872	#[inline]
873	pub const fn is_simd(self) -> bool {
874		matches!(self, Self::Simd)
875	}
876}
877mod seal {
878	pub trait Seal {}
879	impl Seal for u8 {}
880	impl Seal for u16 {}
881	impl Seal for u32 {}
882	impl Seal for u64 {}
883	impl Seal for u128 {}
884	impl Seal for usize {}
885	impl Seal for i32 {}
886	impl Seal for i64 {}
887	impl Seal for isize {}
888}
889pub trait Seal: seal::Seal {}
890impl<T: seal::Seal> Seal for T {}
891/// Trait for signed integers corresponding to the ones satisfying [`Index`].
892///
893/// Always smaller than or equal to `isize`.
894pub trait SignedIndex:
895	Seal
896	+ core::fmt::Debug
897	+ core::ops::Neg<Output = Self>
898	+ core::ops::Add<Output = Self>
899	+ core::ops::Sub<Output = Self>
900	+ core::ops::AddAssign
901	+ core::ops::SubAssign
902	+ bytemuck::Pod
903	+ Eq
904	+ Ord
905	+ Send
906	+ Sync
907{
908	/// Maximum representable value.
909	const MAX: Self;
910	/// Truncate `value` to type [`Self`].
911	#[must_use]
912	fn truncate(value: usize) -> Self;
913	/// Zero extend `self`.
914	#[must_use]
915	fn zx(self) -> usize;
916	/// Sign extend `self`.
917	#[must_use]
918	fn sx(self) -> usize;
919	/// Sum nonnegative values while checking for overflow.
920	fn sum_nonnegative(slice: &[Self]) -> Option<Self> {
921		let mut acc = Self::zeroed();
922		for &i in slice {
923			if Self::MAX - i < acc {
924				return None;
925			}
926			acc += i;
927		}
928		Some(acc)
929	}
930}
931impl SignedIndex for i32 {
932	const MAX: Self = Self::MAX;
933
934	#[inline(always)]
935	fn truncate(value: usize) -> Self {
936		value as isize as Self
937	}
938
939	#[inline(always)]
940	fn zx(self) -> usize {
941		self as u32 as usize
942	}
943
944	#[inline(always)]
945	fn sx(self) -> usize {
946		self as isize as usize
947	}
948}
949impl SignedIndex for i64 {
950	const MAX: Self = Self::MAX;
951
952	#[inline(always)]
953	fn truncate(value: usize) -> Self {
954		value as isize as Self
955	}
956
957	#[inline(always)]
958	fn zx(self) -> usize {
959		self as u64 as usize
960	}
961
962	#[inline(always)]
963	fn sx(self) -> usize {
964		self as isize as usize
965	}
966}
967impl SignedIndex for isize {
968	const MAX: Self = Self::MAX;
969
970	#[inline(always)]
971	fn truncate(value: usize) -> Self {
972		value as isize
973	}
974
975	#[inline(always)]
976	fn zx(self) -> usize {
977		self as usize
978	}
979
980	#[inline(always)]
981	fn sx(self) -> usize {
982		self as usize
983	}
984}
985pub trait IndexCore:
986	Seal
987	+ core::fmt::Debug
988	+ core::ops::Not<Output = Self>
989	+ core::ops::BitAnd<Output = Self>
990	+ core::ops::BitOr<Output = Self>
991	+ core::ops::BitXor<Output = Self>
992	+ core::ops::Add<Output = Self>
993	+ core::ops::Sub<Output = Self>
994	+ core::ops::AddAssign
995	+ core::ops::SubAssign
996	+ bytemuck::Pod
997	+ Eq
998	+ Ord
999	+ Send
1000	+ Sync
1001	+ Ord
1002{
1003	const MAX: Self;
1004	/// Truncate `value` to type [`Self`].
1005	#[must_use]
1006	fn truncate(value: usize) -> Self;
1007	/// Zero extend `self`.
1008	#[must_use]
1009	fn zx(self) -> usize;
1010}
1011pub trait Index: IndexCore {
1012	/// Equally-sized index type with a fixed size (no `usize`).
1013	type FixedWidth: Index;
1014	/// Equally-sized signed index type.
1015	type Signed: SignedIndex;
1016	const BITS: u32 = core::mem::size_of::<Self>() as u32 * 8;
1017	/// Convert a reference to a slice of [`Self`] to fixed width types.
1018	#[inline(always)]
1019	fn canonicalize(slice: &[Self]) -> &[Self::FixedWidth] {
1020		bytemuck::cast_slice(slice)
1021	}
1022	/// Convert a mutable reference to a slice of [`Self`] to fixed width types.
1023	#[inline(always)]
1024	fn canonicalize_mut(slice: &mut [Self]) -> &mut [Self::FixedWidth] {
1025		bytemuck::cast_slice_mut(slice)
1026	}
1027	/// Convert a signed value to an unsigned one.
1028	#[inline(always)]
1029	fn from_signed(value: Self::Signed) -> Self {
1030		bytemuck::cast(value)
1031	}
1032	/// Convert an unsigned value to a signed one.
1033	#[inline(always)]
1034	fn to_signed(self) -> Self::Signed {
1035		bytemuck::cast(self)
1036	}
1037	/// Sum values while checking for overflow.
1038	#[inline]
1039	fn sum_nonnegative(slice: &[Self]) -> Option<Self> {
1040		Self::Signed::sum_nonnegative(bytemuck::cast_slice(slice))
1041			.map(Self::from_signed)
1042	}
1043}
1044impl IndexCore for u8 {
1045	const MAX: Self = Self::MAX;
1046
1047	#[inline(always)]
1048	fn truncate(value: usize) -> Self {
1049		value as _
1050	}
1051
1052	#[inline(always)]
1053	fn zx(self) -> usize {
1054		self as _
1055	}
1056}
1057impl IndexCore for u16 {
1058	const MAX: Self = Self::MAX;
1059
1060	#[inline(always)]
1061	fn truncate(value: usize) -> Self {
1062		value as _
1063	}
1064
1065	#[inline(always)]
1066	fn zx(self) -> usize {
1067		self as _
1068	}
1069}
1070impl IndexCore for u32 {
1071	const MAX: Self = Self::MAX;
1072
1073	#[inline(always)]
1074	fn truncate(value: usize) -> Self {
1075		value as _
1076	}
1077
1078	#[inline(always)]
1079	fn zx(self) -> usize {
1080		self as _
1081	}
1082}
1083impl IndexCore for u64 {
1084	const MAX: Self = Self::MAX;
1085
1086	#[inline(always)]
1087	fn truncate(value: usize) -> Self {
1088		value as _
1089	}
1090
1091	#[inline(always)]
1092	fn zx(self) -> usize {
1093		self as _
1094	}
1095}
1096impl IndexCore for u128 {
1097	const MAX: Self = Self::MAX;
1098
1099	#[inline(always)]
1100	fn truncate(value: usize) -> Self {
1101		value as _
1102	}
1103
1104	#[inline(always)]
1105	fn zx(self) -> usize {
1106		self as _
1107	}
1108}
1109impl IndexCore for usize {
1110	const MAX: Self = Self::MAX;
1111
1112	#[inline(always)]
1113	fn truncate(value: usize) -> Self {
1114		value
1115	}
1116
1117	#[inline(always)]
1118	fn zx(self) -> usize {
1119		self
1120	}
1121}
1122impl Index for u32 {
1123	type FixedWidth = u32;
1124	type Signed = i32;
1125}
1126impl Index for u64 {
1127	type FixedWidth = u64;
1128	type Signed = i64;
1129}
1130impl Index for usize {
1131	#[cfg(target_pointer_width = "32")]
1132	type FixedWidth = u32;
1133	#[cfg(target_pointer_width = "64")]
1134	type FixedWidth = u64;
1135	type Signed = isize;
1136}
1137unsafe impl<T: RealField> Conjugate for T {
1138	type Canonical = T;
1139	type Conj = T;
1140
1141	const IS_CANONICAL: bool = true;
1142}
1143unsafe impl<T: RealField> Conjugate for Complex<T> {
1144	type Canonical = Complex<T>;
1145	type Conj = ComplexConj<T>;
1146
1147	const IS_CANONICAL: bool = true;
1148}
1149unsafe impl<T: RealField> Conjugate for ComplexConj<T> {
1150	type Canonical = Complex<T>;
1151	type Conj = Complex<T>;
1152
1153	const IS_CANONICAL: bool = false;
1154}
1155pub trait SimdArch: Copy + Default + Send + Sync {
1156	fn dispatch<R>(self, f: impl pulp::WithSimd<Output = R>) -> R;
1157}
1158impl SimdArch for pulp::Arch {
1159	#[inline]
1160	fn dispatch<R>(self, f: impl pulp::WithSimd<Output = R>) -> R {
1161		self.dispatch(f)
1162	}
1163}
1164impl SimdArch for pulp::Scalar {
1165	#[inline]
1166	fn dispatch<R>(self, f: impl pulp::WithSimd<Output = R>) -> R {
1167		f.with_simd(self)
1168	}
1169}
1170pub trait RefOps:
1171	Sized
1172	+ core::ops::Neg<Output = Self>
1173	+ core::ops::Add<Output = Self>
1174	+ core::ops::Sub<Output = Self>
1175	+ core::ops::Mul<Output = Self>
1176	+ core::ops::Div<Output = Self>
1177	+ core::ops::AddAssign
1178	+ core::ops::SubAssign
1179	+ core::ops::MulAssign
1180	+ core::ops::DivAssign
1181	+ for<'a> core::ops::Add<&'a Self, Output = Self>
1182	+ for<'a> core::ops::Sub<&'a Self, Output = Self>
1183	+ for<'a> core::ops::Mul<&'a Self, Output = Self>
1184	+ for<'a> core::ops::Div<&'a Self, Output = Self>
1185	+ for<'a> core::ops::AddAssign<&'a Self>
1186	+ for<'a> core::ops::SubAssign<&'a Self>
1187	+ for<'a> core::ops::MulAssign<&'a Self>
1188	+ for<'a> core::ops::DivAssign<&'a Self>
1189	+ for<'a> Imply<
1190		&'a Self,
1191		Is: core::ops::Neg<Output = Self>
1192		        + core::ops::Add<Output = Self>
1193		        + core::ops::Sub<Output = Self>
1194		        + core::ops::Mul<Output = Self>
1195		        + core::ops::Div<Output = Self>
1196		        + core::ops::Add<Self, Output = Self>
1197		        + core::ops::Sub<Self, Output = Self>
1198		        + core::ops::Mul<Self, Output = Self>
1199		        + core::ops::Div<Self, Output = Self>,
1200	>
1201{
1202}
1203impl<T> RefOps for T
1204where
1205	T: core::ops::Neg<Output = Self>
1206		+ core::ops::Add<Output = Self>
1207		+ core::ops::Sub<Output = Self>
1208		+ core::ops::Mul<Output = Self>
1209		+ core::ops::Div<Output = Self>
1210		+ core::ops::AddAssign
1211		+ core::ops::SubAssign
1212		+ core::ops::MulAssign
1213		+ core::ops::DivAssign
1214		+ for<'a> core::ops::Add<&'a T, Output = Self>
1215		+ for<'a> core::ops::Sub<&'a T, Output = Self>
1216		+ for<'a> core::ops::Mul<&'a T, Output = Self>
1217		+ for<'a> core::ops::Div<&'a T, Output = Self>
1218		+ for<'a> core::ops::AddAssign<&'a T>
1219		+ for<'a> core::ops::SubAssign<&'a T>
1220		+ for<'a> core::ops::MulAssign<&'a T>
1221		+ for<'a> core::ops::DivAssign<&'a T>,
1222	for<'a> &'a T: core::ops::Neg<Output = T>
1223		+ core::ops::Add<Output = T>
1224		+ core::ops::Sub<Output = T>
1225		+ core::ops::Mul<Output = T>
1226		+ core::ops::Div<Output = T>
1227		+ core::ops::Add<T, Output = T>
1228		+ core::ops::Sub<T, Output = T>
1229		+ core::ops::Mul<T, Output = T>
1230		+ core::ops::Div<T, Output = T>,
1231{
1232}
1233pub trait ComplexField:
1234	Debug
1235	+ Clone
1236	+ Conjugate<Canonical = Self>
1237	+ PartialEq
1238	+ RefOps
1239	+ Imply<Self::Real, Is: RefOps>
1240{
1241	const IS_REAL: bool;
1242	const SIMD_ABS_SPLIT_REAL_IMAG: bool = false;
1243	type Arch: SimdArch;
1244	type Unit: ComplexField;
1245	type SimdCtx<S: Simd>: Copy;
1246	type Index: IndexCore;
1247	type Real: RealField;
1248	#[doc(hidden)]
1249	const IS_NATIVE_F32: bool = false;
1250	#[doc(hidden)]
1251	const IS_NATIVE_C32: bool = false;
1252	#[doc(hidden)]
1253	const IS_NATIVE_F64: bool = false;
1254	#[doc(hidden)]
1255	const IS_NATIVE_C64: bool = false;
1256	const SIMD_CAPABILITIES: SimdCapabilities;
1257	type SimdMask<S: Simd>: Copy + Debug;
1258	type SimdMemMask<S: Simd>: Copy + Debug;
1259	type SimdVec<S: Simd>: Pod + Debug;
1260	type SimdIndex<S: Simd>: Pod + Debug;
1261	fn zero_impl() -> Self;
1262	fn one_impl() -> Self;
1263	fn nan_impl() -> Self;
1264	fn infinity_impl() -> Self;
1265	fn from_real_impl(real: &Self::Real) -> Self;
1266	fn from_f64_impl(real: f64) -> Self;
1267	fn real_part_impl(value: &Self) -> Self::Real;
1268	fn imag_part_impl(value: &Self) -> Self::Real;
1269	fn copy_impl(value: &Self) -> Self;
1270	fn conj_impl(value: &Self) -> Self;
1271	fn recip_impl(value: &Self) -> Self;
1272	fn sqrt_impl(value: &Self) -> Self;
1273	fn abs_impl(value: &Self) -> Self::Real;
1274	fn abs1_impl(value: &Self) -> Self::Real;
1275	fn abs2_impl(value: &Self) -> Self::Real;
1276	fn mul_real_impl(lhs: &Self, rhs: &Self::Real) -> Self;
1277	fn mul_pow2_impl(lhs: &Self, rhs: &Self::Real) -> Self;
1278	fn is_finite_impl(value: &Self) -> bool;
1279	fn is_nan_impl(value: &Self) -> bool {
1280		value != value
1281	}
1282	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S>;
1283	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S;
1284	fn simd_mask_between<S: Simd>(
1285		ctx: &Self::SimdCtx<S>,
1286		start: Self::Index,
1287		end: Self::Index,
1288	) -> Self::SimdMask<S>;
1289	fn simd_mem_mask_between<S: Simd>(
1290		ctx: &Self::SimdCtx<S>,
1291		start: Self::Index,
1292		end: Self::Index,
1293	) -> Self::SimdMemMask<S>;
1294	unsafe fn simd_mask_load_raw<S: Simd>(
1295		ctx: &Self::SimdCtx<S>,
1296		mask: Self::SimdMemMask<S>,
1297		ptr: *const Self::SimdVec<S>,
1298	) -> Self::SimdVec<S>;
1299	unsafe fn simd_mask_store_raw<S: Simd>(
1300		ctx: &Self::SimdCtx<S>,
1301		mask: Self::SimdMemMask<S>,
1302		ptr: *mut Self::SimdVec<S>,
1303		values: Self::SimdVec<S>,
1304	);
1305	fn simd_splat<S: Simd>(
1306		ctx: &Self::SimdCtx<S>,
1307		value: &Self,
1308	) -> Self::SimdVec<S>;
1309	fn simd_splat_real<S: Simd>(
1310		ctx: &Self::SimdCtx<S>,
1311		value: &Self::Real,
1312	) -> Self::SimdVec<S>;
1313	fn simd_add<S: Simd>(
1314		ctx: &Self::SimdCtx<S>,
1315		lhs: Self::SimdVec<S>,
1316		rhs: Self::SimdVec<S>,
1317	) -> Self::SimdVec<S>;
1318	fn simd_sub<S: Simd>(
1319		ctx: &Self::SimdCtx<S>,
1320		lhs: Self::SimdVec<S>,
1321		rhs: Self::SimdVec<S>,
1322	) -> Self::SimdVec<S>;
1323	fn simd_neg<S: Simd>(
1324		ctx: &Self::SimdCtx<S>,
1325		value: Self::SimdVec<S>,
1326	) -> Self::SimdVec<S>;
1327	fn simd_conj<S: Simd>(
1328		ctx: &Self::SimdCtx<S>,
1329		value: Self::SimdVec<S>,
1330	) -> Self::SimdVec<S>;
1331	fn simd_abs1<S: Simd>(
1332		ctx: &Self::SimdCtx<S>,
1333		value: Self::SimdVec<S>,
1334	) -> Self::SimdVec<S>;
1335	fn simd_abs_max<S: Simd>(
1336		ctx: &Self::SimdCtx<S>,
1337		value: Self::SimdVec<S>,
1338	) -> Self::SimdVec<S>;
1339	fn simd_mul_real<S: Simd>(
1340		ctx: &Self::SimdCtx<S>,
1341		lhs: Self::SimdVec<S>,
1342		real_rhs: Self::SimdVec<S>,
1343	) -> Self::SimdVec<S>;
1344	fn simd_mul_pow2<S: Simd>(
1345		ctx: &Self::SimdCtx<S>,
1346		lhs: Self::SimdVec<S>,
1347		real_rhs: Self::SimdVec<S>,
1348	) -> Self::SimdVec<S>;
1349	fn simd_mul<S: Simd>(
1350		ctx: &Self::SimdCtx<S>,
1351		lhs: Self::SimdVec<S>,
1352		rhs: Self::SimdVec<S>,
1353	) -> Self::SimdVec<S>;
1354	fn simd_conj_mul<S: Simd>(
1355		ctx: &Self::SimdCtx<S>,
1356		lhs: Self::SimdVec<S>,
1357		rhs: Self::SimdVec<S>,
1358	) -> Self::SimdVec<S>;
1359	fn simd_mul_add<S: Simd>(
1360		ctx: &Self::SimdCtx<S>,
1361		lhs: Self::SimdVec<S>,
1362		rhs: Self::SimdVec<S>,
1363		acc: Self::SimdVec<S>,
1364	) -> Self::SimdVec<S>;
1365	fn simd_conj_mul_add<S: Simd>(
1366		ctx: &Self::SimdCtx<S>,
1367		lhs: Self::SimdVec<S>,
1368		rhs: Self::SimdVec<S>,
1369		acc: Self::SimdVec<S>,
1370	) -> Self::SimdVec<S>;
1371	fn simd_abs2<S: Simd>(
1372		ctx: &Self::SimdCtx<S>,
1373		value: Self::SimdVec<S>,
1374	) -> Self::SimdVec<S>;
1375	fn simd_abs2_add<S: Simd>(
1376		ctx: &Self::SimdCtx<S>,
1377		value: Self::SimdVec<S>,
1378		acc: Self::SimdVec<S>,
1379	) -> Self::SimdVec<S>;
1380	fn simd_reduce_sum<S: Simd>(
1381		ctx: &Self::SimdCtx<S>,
1382		value: Self::SimdVec<S>,
1383	) -> Self;
1384	fn simd_reduce_max<S: Simd>(
1385		ctx: &Self::SimdCtx<S>,
1386		value: Self::SimdVec<S>,
1387	) -> Self;
1388	fn simd_equal<S: Simd>(
1389		ctx: &Self::SimdCtx<S>,
1390		real_lhs: Self::SimdVec<S>,
1391		real_rhs: Self::SimdVec<S>,
1392	) -> Self::SimdMask<S>;
1393	fn simd_less_than<S: Simd>(
1394		ctx: &Self::SimdCtx<S>,
1395		real_lhs: Self::SimdVec<S>,
1396		real_rhs: Self::SimdVec<S>,
1397	) -> Self::SimdMask<S>;
1398	fn simd_less_than_or_equal<S: Simd>(
1399		ctx: &Self::SimdCtx<S>,
1400		real_lhs: Self::SimdVec<S>,
1401		real_rhs: Self::SimdVec<S>,
1402	) -> Self::SimdMask<S>;
1403	fn simd_greater_than<S: Simd>(
1404		ctx: &Self::SimdCtx<S>,
1405		real_lhs: Self::SimdVec<S>,
1406		real_rhs: Self::SimdVec<S>,
1407	) -> Self::SimdMask<S>;
1408	fn simd_greater_than_or_equal<S: Simd>(
1409		ctx: &Self::SimdCtx<S>,
1410		real_lhs: Self::SimdVec<S>,
1411		real_rhs: Self::SimdVec<S>,
1412	) -> Self::SimdMask<S>;
1413	fn simd_select<S: Simd>(
1414		ctx: &Self::SimdCtx<S>,
1415		mask: Self::SimdMask<S>,
1416		lhs: Self::SimdVec<S>,
1417		rhs: Self::SimdVec<S>,
1418	) -> Self::SimdVec<S>;
1419	fn simd_index_select<S: Simd>(
1420		ctx: &Self::SimdCtx<S>,
1421		mask: Self::SimdMask<S>,
1422		lhs: Self::SimdIndex<S>,
1423		rhs: Self::SimdIndex<S>,
1424	) -> Self::SimdIndex<S>;
1425	fn simd_index_splat<S: Simd>(
1426		ctx: &Self::SimdCtx<S>,
1427		value: Self::Index,
1428	) -> Self::SimdIndex<S>;
1429	fn simd_index_add<S: Simd>(
1430		ctx: &Self::SimdCtx<S>,
1431		lhs: Self::SimdIndex<S>,
1432		rhs: Self::SimdIndex<S>,
1433	) -> Self::SimdIndex<S>;
1434	fn simd_index_less_than<S: Simd>(
1435		ctx: &Self::SimdCtx<S>,
1436		lhs: Self::SimdIndex<S>,
1437		rhs: Self::SimdIndex<S>,
1438	) -> Self::SimdMask<S>;
1439	#[inline(always)]
1440	fn simd_index_greater_than<S: Simd>(
1441		ctx: &Self::SimdCtx<S>,
1442		lhs: Self::SimdIndex<S>,
1443		rhs: Self::SimdIndex<S>,
1444	) -> Self::SimdMask<S> {
1445		Self::simd_index_less_than(ctx, rhs, lhs)
1446	}
1447	#[inline(always)]
1448	fn simd_index_less_than_or_equal<S: Simd>(
1449		ctx: &Self::SimdCtx<S>,
1450		lhs: Self::SimdIndex<S>,
1451		rhs: Self::SimdIndex<S>,
1452	) -> Self::SimdMask<S> {
1453		Self::simd_not_mask(ctx, Self::simd_index_less_than(ctx, rhs, lhs))
1454	}
1455	#[inline(always)]
1456	fn simd_index_greater_than_or_equal<S: Simd>(
1457		ctx: &Self::SimdCtx<S>,
1458		lhs: Self::SimdIndex<S>,
1459		rhs: Self::SimdIndex<S>,
1460	) -> Self::SimdMask<S> {
1461		Self::simd_not_mask(ctx, Self::simd_index_greater_than(ctx, rhs, lhs))
1462	}
1463	fn simd_and_mask<S: Simd>(
1464		ctx: &Self::SimdCtx<S>,
1465		lhs: Self::SimdMask<S>,
1466		rhs: Self::SimdMask<S>,
1467	) -> Self::SimdMask<S>;
1468	fn simd_or_mask<S: Simd>(
1469		ctx: &Self::SimdCtx<S>,
1470		lhs: Self::SimdMask<S>,
1471		rhs: Self::SimdMask<S>,
1472	) -> Self::SimdMask<S>;
1473	fn simd_not_mask<S: Simd>(
1474		ctx: &Self::SimdCtx<S>,
1475		mask: Self::SimdMask<S>,
1476	) -> Self::SimdMask<S>;
1477	fn simd_first_true_mask<S: Simd>(
1478		ctx: &Self::SimdCtx<S>,
1479		value: Self::SimdMask<S>,
1480	) -> usize;
1481	#[inline(always)]
1482	fn simd_load<S: Simd>(
1483		ctx: &Self::SimdCtx<S>,
1484		ptr: &Self::SimdVec<S>,
1485	) -> Self::SimdVec<S> {
1486		let simd = Self::ctx_from_simd(ctx);
1487		if const { Self::Unit::IS_NATIVE_F32 } {
1488			simd.deinterleave_shfl_f32s(*ptr)
1489		} else if const { Self::Unit::IS_NATIVE_F64 } {
1490			simd.deinterleave_shfl_f64s(*ptr)
1491		} else {
1492			panic!();
1493		}
1494	}
1495	#[inline(always)]
1496	fn simd_store<S: Simd>(
1497		ctx: &Self::SimdCtx<S>,
1498		ptr: &mut Self::SimdVec<S>,
1499		value: Self::SimdVec<S>,
1500	) {
1501		let simd = Self::ctx_from_simd(ctx);
1502		if const { Self::Unit::IS_NATIVE_F32 } {
1503			*ptr = simd.interleave_shfl_f32s(value)
1504		} else if const { Self::Unit::IS_NATIVE_F64 } {
1505			*ptr = simd.interleave_shfl_f64s(value)
1506		} else {
1507			panic!();
1508		}
1509	}
1510	#[inline(always)]
1511	unsafe fn simd_mask_load<S: Simd>(
1512		ctx: &Self::SimdCtx<S>,
1513		mask: Self::SimdMemMask<S>,
1514		ptr: *const Self::SimdVec<S>,
1515	) -> Self::SimdVec<S> {
1516		let simd = Self::ctx_from_simd(ctx);
1517		let value = Self::simd_mask_load_raw(ctx, mask, ptr);
1518		if const { Self::Unit::IS_NATIVE_F32 } {
1519			simd.deinterleave_shfl_f32s(value)
1520		} else if const { Self::Unit::IS_NATIVE_F64 } {
1521			simd.deinterleave_shfl_f64s(value)
1522		} else {
1523			panic!();
1524		}
1525	}
1526	#[inline(always)]
1527	unsafe fn simd_mask_store<S: Simd>(
1528		ctx: &Self::SimdCtx<S>,
1529		mask: Self::SimdMemMask<S>,
1530		ptr: *mut Self::SimdVec<S>,
1531		value: Self::SimdVec<S>,
1532	) {
1533		let simd = Self::ctx_from_simd(ctx);
1534		if const { Self::Unit::IS_NATIVE_F32 } {
1535			Self::simd_mask_store_raw(
1536				ctx,
1537				mask,
1538				ptr,
1539				simd.interleave_shfl_f32s(value),
1540			)
1541		} else if const { Self::Unit::IS_NATIVE_F64 } {
1542			Self::simd_mask_store_raw(
1543				ctx,
1544				mask,
1545				ptr,
1546				simd.interleave_shfl_f64s(value),
1547			)
1548		} else {
1549			panic!();
1550		}
1551	}
1552	#[inline(always)]
1553	fn simd_iota<S: Simd>(ctx: &Self::SimdCtx<S>) -> Self::SimdIndex<S> {
1554		let simd = Self::ctx_from_simd(ctx);
1555		#[repr(transparent)]
1556		struct Interleave<T>(T);
1557		unsafe impl<T> pulp::Interleave for Interleave<T> {}
1558		unsafe {
1559			if const { Self::Unit::IS_NATIVE_F32 } {
1560				core::mem::transmute_copy::<_, Self::SimdIndex<S>>(
1561					&simd.deinterleave_shfl_f32s(Interleave(
1562						core::mem::transmute_copy::<_, Self::SimdVec<S>>(
1563							&pulp::iota_32::<Interleave<Self>, 64>(),
1564						),
1565					)),
1566				)
1567			} else if const { Self::Unit::IS_NATIVE_F64 } {
1568				core::mem::transmute_copy::<_, Self::SimdIndex<S>>(
1569					&simd.deinterleave_shfl_f64s(core::mem::transmute_copy::<
1570						_,
1571						Self::SimdVec<S>,
1572					>(&pulp::iota_64::<
1573						Interleave<Self>,
1574						64,
1575					>())),
1576				)
1577			} else {
1578				panic!();
1579			}
1580		}
1581	}
1582}
1583pub trait RealField:
1584	ComplexField<Real = Self, Conj = Self>
1585	+ PartialOrd
1586	+ num_traits::NumAssign
1587	+ num_traits::Num
1588	+ RefOps
1589{
1590	fn epsilon_impl() -> Self;
1591	fn nbits_impl() -> usize;
1592	fn min_positive_impl() -> Self;
1593	fn max_positive_impl() -> Self;
1594	fn sqrt_min_positive_impl() -> Self;
1595	fn sqrt_max_positive_impl() -> Self;
1596}
1597impl ComplexField for f32 {
1598	type Arch = pulp::Arch;
1599	type Index = u32;
1600	type Real = Self;
1601	type SimdCtx<S: Simd> = S;
1602	type SimdIndex<S: Simd> = S::u32s;
1603	type SimdMask<S: Simd> = S::m32s;
1604	type SimdMemMask<S: Simd> = pulp::MemMask<S::m32s>;
1605	type SimdVec<S: Simd> = S::f32s;
1606	type Unit = Self;
1607
1608	const IS_NATIVE_F32: bool = true;
1609	const IS_REAL: bool = true;
1610	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Simd;
1611
1612	#[inline(always)]
1613	fn zero_impl() -> Self {
1614		0.0
1615	}
1616
1617	#[inline(always)]
1618	fn one_impl() -> Self {
1619		1.0
1620	}
1621
1622	#[inline(always)]
1623	fn nan_impl() -> Self {
1624		Self::NAN
1625	}
1626
1627	#[inline(always)]
1628	fn infinity_impl() -> Self {
1629		Self::INFINITY
1630	}
1631
1632	#[inline(always)]
1633	fn from_real_impl(value: &Self) -> Self {
1634		*value
1635	}
1636
1637	#[inline(always)]
1638	fn from_f64_impl(value: f64) -> Self {
1639		value as _
1640	}
1641
1642	#[inline(always)]
1643	fn real_part_impl(value: &Self) -> Self {
1644		*value
1645	}
1646
1647	#[inline(always)]
1648	fn imag_part_impl(_: &Self) -> Self {
1649		0.0
1650	}
1651
1652	#[inline(always)]
1653	fn copy_impl(value: &Self) -> Self {
1654		*value
1655	}
1656
1657	#[inline(always)]
1658	fn conj_impl(value: &Self) -> Self {
1659		*value
1660	}
1661
1662	#[inline(always)]
1663	fn recip_impl(value: &Self) -> Self {
1664		1.0 / *value
1665	}
1666
1667	#[inline(always)]
1668	fn sqrt_impl(value: &Self) -> Self {
1669		#[cfg(feature = "std")]
1670		{
1671			Self::sqrt(*value)
1672		}
1673		#[cfg(not(feature = "std"))]
1674		{
1675			libm::sqrtf(*value)
1676		}
1677	}
1678
1679	#[inline(always)]
1680	fn abs_impl(value: &Self) -> Self {
1681		(*value).abs()
1682	}
1683
1684	#[inline(always)]
1685	fn abs1_impl(value: &Self) -> Self {
1686		(*value).abs()
1687	}
1688
1689	#[inline(always)]
1690	fn abs2_impl(value: &Self) -> Self {
1691		(*value) * (*value)
1692	}
1693
1694	#[inline(always)]
1695	fn mul_real_impl(lhs: &Self, rhs: &Self) -> Self {
1696		(*lhs) * (*rhs)
1697	}
1698
1699	#[inline(always)]
1700	fn mul_pow2_impl(lhs: &Self, rhs: &Self) -> Self {
1701		(*lhs) * (*rhs)
1702	}
1703
1704	#[inline(always)]
1705	fn is_finite_impl(value: &Self) -> bool {
1706		(*value).is_finite()
1707	}
1708
1709	#[inline(always)]
1710	fn is_nan_impl(value: &Self) -> bool {
1711		(*value).is_nan()
1712	}
1713
1714	#[inline(always)]
1715	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
1716		simd
1717	}
1718
1719	#[inline(always)]
1720	fn simd_splat<S: Simd>(
1721		ctx: &Self::SimdCtx<S>,
1722		value: &Self,
1723	) -> Self::SimdVec<S> {
1724		ctx.splat_f32s(*value)
1725	}
1726
1727	#[inline(always)]
1728	fn simd_splat_real<S: Simd>(
1729		ctx: &Self::SimdCtx<S>,
1730		value: &Self::Real,
1731	) -> Self::SimdVec<S> {
1732		ctx.splat_f32s(*value)
1733	}
1734
1735	#[inline(always)]
1736	fn simd_add<S: Simd>(
1737		ctx: &Self::SimdCtx<S>,
1738		lhs: Self::SimdVec<S>,
1739		rhs: Self::SimdVec<S>,
1740	) -> Self::SimdVec<S> {
1741		ctx.add_f32s(lhs, rhs)
1742	}
1743
1744	#[inline(always)]
1745	fn simd_sub<S: Simd>(
1746		ctx: &Self::SimdCtx<S>,
1747		lhs: Self::SimdVec<S>,
1748		rhs: Self::SimdVec<S>,
1749	) -> Self::SimdVec<S> {
1750		ctx.sub_f32s(lhs, rhs)
1751	}
1752
1753	#[inline(always)]
1754	fn simd_neg<S: Simd>(
1755		ctx: &Self::SimdCtx<S>,
1756		value: Self::SimdVec<S>,
1757	) -> Self::SimdVec<S> {
1758		ctx.neg_f32s(value)
1759	}
1760
1761	#[inline(always)]
1762	fn simd_conj<S: Simd>(
1763		_: &Self::SimdCtx<S>,
1764		value: Self::SimdVec<S>,
1765	) -> Self::SimdVec<S> {
1766		value
1767	}
1768
1769	#[inline(always)]
1770	fn simd_abs1<S: Simd>(
1771		ctx: &Self::SimdCtx<S>,
1772		value: Self::SimdVec<S>,
1773	) -> Self::SimdVec<S> {
1774		ctx.abs_f32s(value)
1775	}
1776
1777	#[inline(always)]
1778	fn simd_mul<S: Simd>(
1779		ctx: &Self::SimdCtx<S>,
1780		lhs: Self::SimdVec<S>,
1781		rhs: Self::SimdVec<S>,
1782	) -> Self::SimdVec<S> {
1783		ctx.mul_f32s(lhs, rhs)
1784	}
1785
1786	#[inline(always)]
1787	fn simd_mul_real<S: Simd>(
1788		ctx: &Self::SimdCtx<S>,
1789		lhs: Self::SimdVec<S>,
1790		real_rhs: Self::SimdVec<S>,
1791	) -> Self::SimdVec<S> {
1792		ctx.mul_f32s(lhs, real_rhs)
1793	}
1794
1795	#[inline(always)]
1796	fn simd_mul_pow2<S: Simd>(
1797		ctx: &Self::SimdCtx<S>,
1798		lhs: Self::SimdVec<S>,
1799		real_rhs: Self::SimdVec<S>,
1800	) -> Self::SimdVec<S> {
1801		ctx.mul_f32s(lhs, real_rhs)
1802	}
1803
1804	#[inline(always)]
1805	fn simd_conj_mul<S: Simd>(
1806		ctx: &Self::SimdCtx<S>,
1807		lhs: Self::SimdVec<S>,
1808		rhs: Self::SimdVec<S>,
1809	) -> Self::SimdVec<S> {
1810		ctx.mul_f32s(lhs, rhs)
1811	}
1812
1813	#[inline(always)]
1814	fn simd_mul_add<S: Simd>(
1815		ctx: &Self::SimdCtx<S>,
1816		lhs: Self::SimdVec<S>,
1817		rhs: Self::SimdVec<S>,
1818		acc: Self::SimdVec<S>,
1819	) -> Self::SimdVec<S> {
1820		ctx.mul_add_e_f32s(lhs, rhs, acc)
1821	}
1822
1823	#[inline(always)]
1824	fn simd_conj_mul_add<S: Simd>(
1825		ctx: &Self::SimdCtx<S>,
1826		lhs: Self::SimdVec<S>,
1827		rhs: Self::SimdVec<S>,
1828		acc: Self::SimdVec<S>,
1829	) -> Self::SimdVec<S> {
1830		ctx.mul_add_e_f32s(lhs, rhs, acc)
1831	}
1832
1833	#[inline(always)]
1834	fn simd_abs2<S: Simd>(
1835		ctx: &Self::SimdCtx<S>,
1836		value: Self::SimdVec<S>,
1837	) -> Self::SimdVec<S> {
1838		ctx.mul_f32s(value, value)
1839	}
1840
1841	#[inline(always)]
1842	fn simd_abs2_add<S: Simd>(
1843		ctx: &Self::SimdCtx<S>,
1844		value: Self::SimdVec<S>,
1845		acc: Self::SimdVec<S>,
1846	) -> Self::SimdVec<S> {
1847		ctx.mul_add_e_f32s(value, value, acc)
1848	}
1849
1850	#[inline(always)]
1851	fn simd_reduce_sum<S: Simd>(
1852		ctx: &Self::SimdCtx<S>,
1853		value: Self::SimdVec<S>,
1854	) -> Self {
1855		ctx.reduce_sum_f32s(value)
1856	}
1857
1858	#[inline(always)]
1859	fn simd_reduce_max<S: Simd>(
1860		ctx: &Self::SimdCtx<S>,
1861		value: Self::SimdVec<S>,
1862	) -> Self {
1863		ctx.reduce_max_f32s(value)
1864	}
1865
1866	#[inline(always)]
1867	fn simd_equal<S: Simd>(
1868		ctx: &Self::SimdCtx<S>,
1869		real_lhs: Self::SimdVec<S>,
1870		real_rhs: Self::SimdVec<S>,
1871	) -> Self::SimdMask<S> {
1872		ctx.equal_f32s(real_lhs, real_rhs)
1873	}
1874
1875	#[inline(always)]
1876	fn simd_less_than<S: Simd>(
1877		ctx: &Self::SimdCtx<S>,
1878		real_lhs: Self::SimdVec<S>,
1879		real_rhs: Self::SimdVec<S>,
1880	) -> Self::SimdMask<S> {
1881		ctx.less_than_f32s(real_lhs, real_rhs)
1882	}
1883
1884	#[inline(always)]
1885	fn simd_greater_than<S: Simd>(
1886		ctx: &Self::SimdCtx<S>,
1887		real_lhs: Self::SimdVec<S>,
1888		real_rhs: Self::SimdVec<S>,
1889	) -> Self::SimdMask<S> {
1890		ctx.greater_than_f32s(real_lhs, real_rhs)
1891	}
1892
1893	#[inline(always)]
1894	fn simd_less_than_or_equal<S: Simd>(
1895		ctx: &Self::SimdCtx<S>,
1896		real_lhs: Self::SimdVec<S>,
1897		real_rhs: Self::SimdVec<S>,
1898	) -> Self::SimdMask<S> {
1899		ctx.less_than_or_equal_f32s(real_lhs, real_rhs)
1900	}
1901
1902	#[inline(always)]
1903	fn simd_greater_than_or_equal<S: Simd>(
1904		ctx: &Self::SimdCtx<S>,
1905		real_lhs: Self::SimdVec<S>,
1906		real_rhs: Self::SimdVec<S>,
1907	) -> Self::SimdMask<S> {
1908		ctx.greater_than_or_equal_f32s(real_lhs, real_rhs)
1909	}
1910
1911	#[inline(always)]
1912	fn simd_select<S: Simd>(
1913		ctx: &Self::SimdCtx<S>,
1914		mask: Self::SimdMask<S>,
1915		lhs: Self::SimdVec<S>,
1916		rhs: Self::SimdVec<S>,
1917	) -> Self::SimdVec<S> {
1918		ctx.select_f32s(mask, lhs, rhs)
1919	}
1920
1921	#[inline(always)]
1922	fn simd_index_select<S: Simd>(
1923		ctx: &Self::SimdCtx<S>,
1924		mask: Self::SimdMask<S>,
1925		lhs: Self::SimdIndex<S>,
1926		rhs: Self::SimdIndex<S>,
1927	) -> Self::SimdIndex<S> {
1928		ctx.select_u32s(mask, lhs, rhs)
1929	}
1930
1931	#[inline(always)]
1932	fn simd_index_splat<S: Simd>(
1933		ctx: &Self::SimdCtx<S>,
1934		value: Self::Index,
1935	) -> Self::SimdIndex<S> {
1936		ctx.splat_u32s(value as _)
1937	}
1938
1939	#[inline(always)]
1940	fn simd_index_add<S: Simd>(
1941		ctx: &Self::SimdCtx<S>,
1942		lhs: Self::SimdIndex<S>,
1943		rhs: Self::SimdIndex<S>,
1944	) -> Self::SimdIndex<S> {
1945		ctx.add_u32s(lhs, rhs)
1946	}
1947
1948	#[inline(always)]
1949	fn simd_index_less_than<S: Simd>(
1950		ctx: &Self::SimdCtx<S>,
1951		lhs: Self::SimdIndex<S>,
1952		rhs: Self::SimdIndex<S>,
1953	) -> Self::SimdMask<S> {
1954		ctx.less_than_u32s(lhs, rhs)
1955	}
1956
1957	#[inline(always)]
1958	fn simd_abs_max<S: Simd>(
1959		ctx: &Self::SimdCtx<S>,
1960		value: Self::SimdVec<S>,
1961	) -> Self::SimdVec<S> {
1962		ctx.abs_f32s(value)
1963	}
1964
1965	#[inline(always)]
1966	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
1967		*ctx
1968	}
1969
1970	#[inline(always)]
1971	fn simd_and_mask<S: Simd>(
1972		simd: &Self::SimdCtx<S>,
1973		lhs: Self::SimdMask<S>,
1974		rhs: Self::SimdMask<S>,
1975	) -> Self::SimdMask<S> {
1976		simd.and_m32s(lhs, rhs)
1977	}
1978
1979	#[inline(always)]
1980	fn simd_or_mask<S: Simd>(
1981		simd: &Self::SimdCtx<S>,
1982		lhs: Self::SimdMask<S>,
1983		rhs: Self::SimdMask<S>,
1984	) -> Self::SimdMask<S> {
1985		simd.or_m32s(lhs, rhs)
1986	}
1987
1988	#[inline(always)]
1989	fn simd_not_mask<S: Simd>(
1990		ctx: &Self::SimdCtx<S>,
1991		mask: Self::SimdMask<S>,
1992	) -> Self::SimdMask<S> {
1993		ctx.not_m32s(mask)
1994	}
1995
1996	#[inline(always)]
1997	fn simd_first_true_mask<S: Simd>(
1998		ctx: &Self::SimdCtx<S>,
1999		value: Self::SimdMask<S>,
2000	) -> usize {
2001		ctx.first_true_m32s(value)
2002	}
2003
2004	#[inline(always)]
2005	fn simd_mem_mask_between<S: Simd>(
2006		ctx: &Self::SimdCtx<S>,
2007		start: Self::Index,
2008		end: Self::Index,
2009	) -> Self::SimdMemMask<S> {
2010		ctx.mask_between_m32s(start as _, end as _)
2011	}
2012
2013	#[inline(always)]
2014	fn simd_mask_between<S: Simd>(
2015		ctx: &Self::SimdCtx<S>,
2016		start: Self::Index,
2017		end: Self::Index,
2018	) -> Self::SimdMask<S> {
2019		ctx.mask_between_m32s(start as _, end as _).mask()
2020	}
2021
2022	#[inline(always)]
2023	unsafe fn simd_mask_load_raw<S: Simd>(
2024		ctx: &Self::SimdCtx<S>,
2025		mask: Self::SimdMemMask<S>,
2026		ptr: *const Self::SimdVec<S>,
2027	) -> Self::SimdVec<S> {
2028		ctx.mask_load_ptr_f32s(mask, ptr as _)
2029	}
2030
2031	#[inline(always)]
2032	unsafe fn simd_mask_store_raw<S: Simd>(
2033		ctx: &Self::SimdCtx<S>,
2034		mask: Self::SimdMemMask<S>,
2035		ptr: *mut Self::SimdVec<S>,
2036		values: Self::SimdVec<S>,
2037	) {
2038		ctx.mask_store_ptr_f32s(mask, ptr as _, values);
2039	}
2040}
2041impl RealField for f32 {
2042	#[inline(always)]
2043	fn epsilon_impl() -> Self {
2044		Self::EPSILON
2045	}
2046
2047	#[inline(always)]
2048	fn min_positive_impl() -> Self {
2049		Self::MIN_POSITIVE
2050	}
2051
2052	#[inline(always)]
2053	fn max_positive_impl() -> Self {
2054		Self::MIN_POSITIVE.recip()
2055	}
2056
2057	#[inline(always)]
2058	fn sqrt_min_positive_impl() -> Self {
2059		Self::sqrt_impl(&Self::MIN_POSITIVE)
2060	}
2061
2062	#[inline(always)]
2063	fn sqrt_max_positive_impl() -> Self {
2064		Self::sqrt_impl(&Self::MIN_POSITIVE.recip())
2065	}
2066
2067	#[inline(always)]
2068	fn nbits_impl() -> usize {
2069		Self::MANTISSA_DIGITS as usize
2070	}
2071}
2072impl ComplexField for f64 {
2073	type Arch = pulp::Arch;
2074	type Index = u64;
2075	type Real = Self;
2076	type SimdCtx<S: Simd> = S;
2077	type SimdIndex<S: Simd> = S::u64s;
2078	type SimdMask<S: Simd> = S::m64s;
2079	type SimdMemMask<S: Simd> = pulp::MemMask<S::m64s>;
2080	type SimdVec<S: Simd> = S::f64s;
2081	type Unit = Self;
2082
2083	const IS_NATIVE_F64: bool = true;
2084	const IS_REAL: bool = true;
2085	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Simd;
2086
2087	#[inline(always)]
2088	fn zero_impl() -> Self {
2089		0.0
2090	}
2091
2092	#[inline(always)]
2093	fn one_impl() -> Self {
2094		1.0
2095	}
2096
2097	#[inline(always)]
2098	fn nan_impl() -> Self {
2099		Self::NAN
2100	}
2101
2102	#[inline(always)]
2103	fn infinity_impl() -> Self {
2104		Self::INFINITY
2105	}
2106
2107	#[inline(always)]
2108	fn from_real_impl(value: &Self) -> Self {
2109		*value
2110	}
2111
2112	#[inline(always)]
2113	fn from_f64_impl(value: f64) -> Self {
2114		value as _
2115	}
2116
2117	#[inline(always)]
2118	fn real_part_impl(value: &Self) -> Self {
2119		*value
2120	}
2121
2122	#[inline(always)]
2123	fn imag_part_impl(_: &Self) -> Self {
2124		0.0
2125	}
2126
2127	#[inline(always)]
2128	fn copy_impl(value: &Self) -> Self {
2129		*value
2130	}
2131
2132	#[inline(always)]
2133	fn conj_impl(value: &Self) -> Self {
2134		*value
2135	}
2136
2137	#[inline(always)]
2138	fn recip_impl(value: &Self) -> Self {
2139		1.0 / *value
2140	}
2141
2142	#[inline(always)]
2143	fn sqrt_impl(value: &Self) -> Self {
2144		#[cfg(feature = "std")]
2145		{
2146			Self::sqrt(*value)
2147		}
2148		#[cfg(not(feature = "std"))]
2149		{
2150			libm::sqrt(*value)
2151		}
2152	}
2153
2154	#[inline(always)]
2155	fn abs_impl(value: &Self) -> Self {
2156		(*value).abs()
2157	}
2158
2159	#[inline(always)]
2160	fn abs1_impl(value: &Self) -> Self {
2161		(*value).abs()
2162	}
2163
2164	#[inline(always)]
2165	fn abs2_impl(value: &Self) -> Self {
2166		(*value) * (*value)
2167	}
2168
2169	#[inline(always)]
2170	fn mul_real_impl(lhs: &Self, rhs: &Self) -> Self {
2171		(*lhs) * (*rhs)
2172	}
2173
2174	#[inline(always)]
2175	fn mul_pow2_impl(lhs: &Self, rhs: &Self) -> Self {
2176		(*lhs) * (*rhs)
2177	}
2178
2179	#[inline(always)]
2180	fn is_nan_impl(value: &Self) -> bool {
2181		(*value).is_nan()
2182	}
2183
2184	#[inline(always)]
2185	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
2186		simd
2187	}
2188
2189	#[inline(always)]
2190	fn simd_splat<S: Simd>(
2191		ctx: &Self::SimdCtx<S>,
2192		value: &Self,
2193	) -> Self::SimdVec<S> {
2194		ctx.splat_f64s(*value)
2195	}
2196
2197	#[inline(always)]
2198	fn simd_splat_real<S: Simd>(
2199		ctx: &Self::SimdCtx<S>,
2200		value: &Self::Real,
2201	) -> Self::SimdVec<S> {
2202		ctx.splat_f64s(*value)
2203	}
2204
2205	#[inline(always)]
2206	fn simd_add<S: Simd>(
2207		ctx: &Self::SimdCtx<S>,
2208		lhs: Self::SimdVec<S>,
2209		rhs: Self::SimdVec<S>,
2210	) -> Self::SimdVec<S> {
2211		ctx.add_f64s(lhs, rhs)
2212	}
2213
2214	#[inline(always)]
2215	fn simd_sub<S: Simd>(
2216		ctx: &Self::SimdCtx<S>,
2217		lhs: Self::SimdVec<S>,
2218		rhs: Self::SimdVec<S>,
2219	) -> Self::SimdVec<S> {
2220		ctx.sub_f64s(lhs, rhs)
2221	}
2222
2223	#[inline(always)]
2224	fn simd_neg<S: Simd>(
2225		ctx: &Self::SimdCtx<S>,
2226		value: Self::SimdVec<S>,
2227	) -> Self::SimdVec<S> {
2228		ctx.neg_f64s(value)
2229	}
2230
2231	#[inline(always)]
2232	fn simd_conj<S: Simd>(
2233		_: &Self::SimdCtx<S>,
2234		value: Self::SimdVec<S>,
2235	) -> Self::SimdVec<S> {
2236		value
2237	}
2238
2239	#[inline(always)]
2240	fn simd_abs1<S: Simd>(
2241		ctx: &Self::SimdCtx<S>,
2242		value: Self::SimdVec<S>,
2243	) -> Self::SimdVec<S> {
2244		ctx.abs_f64s(value)
2245	}
2246
2247	#[inline(always)]
2248	fn simd_mul<S: Simd>(
2249		ctx: &Self::SimdCtx<S>,
2250		lhs: Self::SimdVec<S>,
2251		rhs: Self::SimdVec<S>,
2252	) -> Self::SimdVec<S> {
2253		ctx.mul_f64s(lhs, rhs)
2254	}
2255
2256	#[inline(always)]
2257	fn simd_mul_real<S: Simd>(
2258		ctx: &Self::SimdCtx<S>,
2259		lhs: Self::SimdVec<S>,
2260		real_rhs: Self::SimdVec<S>,
2261	) -> Self::SimdVec<S> {
2262		ctx.mul_f64s(lhs, real_rhs)
2263	}
2264
2265	#[inline(always)]
2266	fn simd_mul_pow2<S: Simd>(
2267		ctx: &Self::SimdCtx<S>,
2268		lhs: Self::SimdVec<S>,
2269		real_rhs: Self::SimdVec<S>,
2270	) -> Self::SimdVec<S> {
2271		ctx.mul_f64s(lhs, real_rhs)
2272	}
2273
2274	#[inline(always)]
2275	fn simd_conj_mul<S: Simd>(
2276		ctx: &Self::SimdCtx<S>,
2277		lhs: Self::SimdVec<S>,
2278		rhs: Self::SimdVec<S>,
2279	) -> Self::SimdVec<S> {
2280		ctx.mul_f64s(lhs, rhs)
2281	}
2282
2283	#[inline(always)]
2284	fn simd_mul_add<S: Simd>(
2285		ctx: &Self::SimdCtx<S>,
2286		lhs: Self::SimdVec<S>,
2287		rhs: Self::SimdVec<S>,
2288		acc: Self::SimdVec<S>,
2289	) -> Self::SimdVec<S> {
2290		ctx.mul_add_e_f64s(lhs, rhs, acc)
2291	}
2292
2293	#[inline(always)]
2294	fn simd_conj_mul_add<S: Simd>(
2295		ctx: &Self::SimdCtx<S>,
2296		lhs: Self::SimdVec<S>,
2297		rhs: Self::SimdVec<S>,
2298		acc: Self::SimdVec<S>,
2299	) -> Self::SimdVec<S> {
2300		ctx.mul_add_e_f64s(lhs, rhs, acc)
2301	}
2302
2303	#[inline(always)]
2304	fn simd_abs2<S: Simd>(
2305		ctx: &Self::SimdCtx<S>,
2306		value: Self::SimdVec<S>,
2307	) -> Self::SimdVec<S> {
2308		ctx.mul_f64s(value, value)
2309	}
2310
2311	#[inline(always)]
2312	fn simd_abs2_add<S: Simd>(
2313		ctx: &Self::SimdCtx<S>,
2314		value: Self::SimdVec<S>,
2315		acc: Self::SimdVec<S>,
2316	) -> Self::SimdVec<S> {
2317		ctx.mul_add_e_f64s(value, value, acc)
2318	}
2319
2320	#[inline(always)]
2321	fn simd_reduce_sum<S: Simd>(
2322		ctx: &Self::SimdCtx<S>,
2323		value: Self::SimdVec<S>,
2324	) -> Self {
2325		ctx.reduce_sum_f64s(value)
2326	}
2327
2328	#[inline(always)]
2329	fn simd_reduce_max<S: Simd>(
2330		ctx: &Self::SimdCtx<S>,
2331		value: Self::SimdVec<S>,
2332	) -> Self {
2333		ctx.reduce_max_f64s(value)
2334	}
2335
2336	#[inline(always)]
2337	fn simd_equal<S: Simd>(
2338		ctx: &Self::SimdCtx<S>,
2339		real_lhs: Self::SimdVec<S>,
2340		real_rhs: Self::SimdVec<S>,
2341	) -> Self::SimdMask<S> {
2342		ctx.equal_f64s(real_lhs, real_rhs)
2343	}
2344
2345	#[inline(always)]
2346	fn simd_less_than<S: Simd>(
2347		ctx: &Self::SimdCtx<S>,
2348		real_lhs: Self::SimdVec<S>,
2349		real_rhs: Self::SimdVec<S>,
2350	) -> Self::SimdMask<S> {
2351		ctx.less_than_f64s(real_lhs, real_rhs)
2352	}
2353
2354	#[inline(always)]
2355	fn simd_greater_than<S: Simd>(
2356		ctx: &Self::SimdCtx<S>,
2357		real_lhs: Self::SimdVec<S>,
2358		real_rhs: Self::SimdVec<S>,
2359	) -> Self::SimdMask<S> {
2360		ctx.greater_than_f64s(real_lhs, real_rhs)
2361	}
2362
2363	#[inline(always)]
2364	fn simd_less_than_or_equal<S: Simd>(
2365		ctx: &Self::SimdCtx<S>,
2366		real_lhs: Self::SimdVec<S>,
2367		real_rhs: Self::SimdVec<S>,
2368	) -> Self::SimdMask<S> {
2369		ctx.less_than_or_equal_f64s(real_lhs, real_rhs)
2370	}
2371
2372	#[inline(always)]
2373	fn simd_greater_than_or_equal<S: Simd>(
2374		ctx: &Self::SimdCtx<S>,
2375		real_lhs: Self::SimdVec<S>,
2376		real_rhs: Self::SimdVec<S>,
2377	) -> Self::SimdMask<S> {
2378		ctx.greater_than_or_equal_f64s(real_lhs, real_rhs)
2379	}
2380
2381	#[inline(always)]
2382	fn simd_select<S: Simd>(
2383		ctx: &Self::SimdCtx<S>,
2384		mask: Self::SimdMask<S>,
2385		lhs: Self::SimdVec<S>,
2386		rhs: Self::SimdVec<S>,
2387	) -> Self::SimdVec<S> {
2388		ctx.select_f64s(mask, lhs, rhs)
2389	}
2390
2391	#[inline(always)]
2392	fn simd_index_select<S: Simd>(
2393		ctx: &Self::SimdCtx<S>,
2394		mask: Self::SimdMask<S>,
2395		lhs: Self::SimdIndex<S>,
2396		rhs: Self::SimdIndex<S>,
2397	) -> Self::SimdIndex<S> {
2398		ctx.select_u64s(mask, lhs, rhs)
2399	}
2400
2401	#[inline(always)]
2402	fn simd_index_splat<S: Simd>(
2403		ctx: &Self::SimdCtx<S>,
2404		value: Self::Index,
2405	) -> Self::SimdIndex<S> {
2406		ctx.splat_u64s(value as _)
2407	}
2408
2409	#[inline(always)]
2410	fn simd_index_add<S: Simd>(
2411		ctx: &Self::SimdCtx<S>,
2412		lhs: Self::SimdIndex<S>,
2413		rhs: Self::SimdIndex<S>,
2414	) -> Self::SimdIndex<S> {
2415		ctx.add_u64s(lhs, rhs)
2416	}
2417
2418	#[inline(always)]
2419	fn simd_index_less_than<S: Simd>(
2420		ctx: &Self::SimdCtx<S>,
2421		lhs: Self::SimdIndex<S>,
2422		rhs: Self::SimdIndex<S>,
2423	) -> Self::SimdMask<S> {
2424		ctx.less_than_u64s(lhs, rhs)
2425	}
2426
2427	#[inline(always)]
2428	fn simd_abs_max<S: Simd>(
2429		ctx: &Self::SimdCtx<S>,
2430		value: Self::SimdVec<S>,
2431	) -> Self::SimdVec<S> {
2432		ctx.abs_f64s(value)
2433	}
2434
2435	#[inline(always)]
2436	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
2437		*ctx
2438	}
2439
2440	#[inline(always)]
2441	fn simd_and_mask<S: Simd>(
2442		simd: &Self::SimdCtx<S>,
2443		lhs: Self::SimdMask<S>,
2444		rhs: Self::SimdMask<S>,
2445	) -> Self::SimdMask<S> {
2446		simd.and_m64s(lhs, rhs)
2447	}
2448
2449	#[inline(always)]
2450	fn simd_or_mask<S: Simd>(
2451		simd: &Self::SimdCtx<S>,
2452		lhs: Self::SimdMask<S>,
2453		rhs: Self::SimdMask<S>,
2454	) -> Self::SimdMask<S> {
2455		simd.or_m64s(lhs, rhs)
2456	}
2457
2458	#[inline(always)]
2459	fn simd_not_mask<S: Simd>(
2460		ctx: &Self::SimdCtx<S>,
2461		mask: Self::SimdMask<S>,
2462	) -> Self::SimdMask<S> {
2463		ctx.not_m64s(mask)
2464	}
2465
2466	#[inline(always)]
2467	fn simd_first_true_mask<S: Simd>(
2468		ctx: &Self::SimdCtx<S>,
2469		value: Self::SimdMask<S>,
2470	) -> usize {
2471		ctx.first_true_m64s(value)
2472	}
2473
2474	#[inline(always)]
2475	fn is_finite_impl(value: &Self) -> bool {
2476		(*value).is_finite()
2477	}
2478
2479	#[inline(always)]
2480	fn simd_mem_mask_between<S: Simd>(
2481		ctx: &Self::SimdCtx<S>,
2482		start: Self::Index,
2483		end: Self::Index,
2484	) -> Self::SimdMemMask<S> {
2485		ctx.mask_between_m64s(start as _, end as _)
2486	}
2487
2488	#[inline(always)]
2489	fn simd_mask_between<S: Simd>(
2490		ctx: &Self::SimdCtx<S>,
2491		start: Self::Index,
2492		end: Self::Index,
2493	) -> Self::SimdMask<S> {
2494		ctx.mask_between_m64s(start as _, end as _).mask()
2495	}
2496
2497	#[inline(always)]
2498	unsafe fn simd_mask_load_raw<S: Simd>(
2499		ctx: &Self::SimdCtx<S>,
2500		mask: Self::SimdMemMask<S>,
2501		ptr: *const Self::SimdVec<S>,
2502	) -> Self::SimdVec<S> {
2503		ctx.mask_load_ptr_f64s(mask, ptr as _)
2504	}
2505
2506	#[inline(always)]
2507	unsafe fn simd_mask_store_raw<S: Simd>(
2508		ctx: &Self::SimdCtx<S>,
2509		mask: Self::SimdMemMask<S>,
2510		ptr: *mut Self::SimdVec<S>,
2511		values: Self::SimdVec<S>,
2512	) {
2513		ctx.mask_store_ptr_f64s(mask, ptr as _, values);
2514	}
2515}
2516impl RealField for f64 {
2517	#[inline(always)]
2518	fn epsilon_impl() -> Self {
2519		Self::EPSILON
2520	}
2521
2522	#[inline(always)]
2523	fn min_positive_impl() -> Self {
2524		Self::MIN_POSITIVE
2525	}
2526
2527	#[inline(always)]
2528	fn max_positive_impl() -> Self {
2529		Self::MIN_POSITIVE.recip()
2530	}
2531
2532	#[inline(always)]
2533	fn sqrt_min_positive_impl() -> Self {
2534		Self::sqrt_impl(&Self::MIN_POSITIVE)
2535	}
2536
2537	#[inline(always)]
2538	fn sqrt_max_positive_impl() -> Self {
2539		Self::sqrt_impl(&Self::MIN_POSITIVE.recip())
2540	}
2541
2542	#[inline(always)]
2543	fn nbits_impl() -> usize {
2544		Self::MANTISSA_DIGITS as usize
2545	}
2546}
2547impl<T: RealField<Unit: ComplexField>> ComplexField for Complex<T> {
2548	type Arch = T::Arch;
2549	type Index = T::Index;
2550	type Real = T;
2551	type SimdCtx<S: Simd> = T::SimdCtx<S>;
2552	type SimdIndex<S: Simd> = T::SimdIndex<S>;
2553	type SimdMask<S: Simd> = T::SimdMask<S>;
2554	type SimdMemMask<S: Simd> = Complex<T::SimdMemMask<S>>;
2555	type SimdVec<S: Simd> = Complex<T::SimdVec<S>>;
2556	type Unit = T::Unit;
2557
2558	const IS_NATIVE_C32: bool = T::IS_NATIVE_F32;
2559	const IS_NATIVE_C64: bool = T::IS_NATIVE_F64;
2560	const IS_REAL: bool = false;
2561	const SIMD_CAPABILITIES: SimdCapabilities = T::SIMD_CAPABILITIES;
2562
2563	#[inline]
2564	fn zero_impl() -> Self {
2565		Complex {
2566			re: T::zero_impl(),
2567			im: T::zero_impl(),
2568		}
2569	}
2570
2571	#[inline]
2572	fn one_impl() -> Self {
2573		Complex {
2574			re: T::one_impl(),
2575			im: T::zero_impl(),
2576		}
2577	}
2578
2579	#[inline]
2580	fn nan_impl() -> Self {
2581		Complex {
2582			re: T::nan_impl(),
2583			im: T::nan_impl(),
2584		}
2585	}
2586
2587	#[inline]
2588	fn infinity_impl() -> Self {
2589		Complex {
2590			re: T::infinity_impl(),
2591			im: T::infinity_impl(),
2592		}
2593	}
2594
2595	#[inline]
2596	fn from_real_impl(real: &Self::Real) -> Self {
2597		Complex {
2598			re: real.clone(),
2599			im: T::zero_impl(),
2600		}
2601	}
2602
2603	#[inline]
2604	fn from_f64_impl(real: f64) -> Self {
2605		Complex {
2606			re: T::from_f64_impl(real),
2607			im: T::zero_impl(),
2608		}
2609	}
2610
2611	#[inline]
2612	fn real_part_impl(value: &Self) -> Self::Real {
2613		value.re.clone()
2614	}
2615
2616	#[inline]
2617	fn imag_part_impl(value: &Self) -> Self::Real {
2618		value.im.clone()
2619	}
2620
2621	#[inline]
2622	fn copy_impl(value: &Self) -> Self {
2623		value.clone()
2624	}
2625
2626	#[inline]
2627	fn conj_impl(value: &Self) -> Self {
2628		Self {
2629			re: value.re.clone(),
2630			im: value.im.neg_by_ref(),
2631		}
2632	}
2633
2634	#[inline]
2635	fn recip_impl(value: &Self) -> Self {
2636		let (re, im) = recip_impl(value.re.clone(), value.im.clone());
2637		Complex { re, im }
2638	}
2639
2640	#[inline]
2641	fn sqrt_impl(value: &Self) -> Self {
2642		let (re, im) = sqrt_impl(value.re.clone(), value.im.clone());
2643		Complex { re, im }
2644	}
2645
2646	#[inline]
2647	fn abs_impl(value: &Self) -> Self::Real {
2648		abs_impl(value.re.clone(), value.im.clone())
2649	}
2650
2651	#[inline]
2652	fn abs1_impl(value: &Self) -> Self::Real {
2653		use crate::ext::*;
2654		value.re.abs1() + value.im.abs1()
2655	}
2656
2657	#[inline]
2658	fn abs2_impl(value: &Self) -> Self::Real {
2659		use crate::ext::*;
2660		value.re.abs2() + value.im.abs2()
2661	}
2662
2663	#[inline]
2664	fn mul_real_impl(lhs: &Self, rhs: &Self::Real) -> Self {
2665		Complex {
2666			re: &lhs.re * rhs,
2667			im: &lhs.im * rhs,
2668		}
2669	}
2670
2671	#[inline]
2672	fn mul_pow2_impl(lhs: &Self, rhs: &Self::Real) -> Self {
2673		use crate::ext::*;
2674		Complex {
2675			re: lhs.re.mul_pow2(rhs),
2676			im: lhs.im.mul_pow2(rhs),
2677		}
2678	}
2679
2680	#[inline]
2681	fn is_finite_impl(value: &Self) -> bool {
2682		use crate::ext::*;
2683		value.re.is_finite() && value.im.is_finite()
2684	}
2685
2686	#[inline(always)]
2687	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
2688		T::simd_ctx(simd)
2689	}
2690
2691	#[inline(always)]
2692	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
2693		T::ctx_from_simd(ctx)
2694	}
2695
2696	#[inline(always)]
2697	fn simd_splat<S: Simd>(
2698		ctx: &Self::SimdCtx<S>,
2699		value: &Self,
2700	) -> Self::SimdVec<S> {
2701		Complex {
2702			re: T::simd_splat(ctx, &value.re),
2703			im: T::simd_splat(ctx, &value.im),
2704		}
2705	}
2706
2707	#[inline(always)]
2708	fn simd_splat_real<S: Simd>(
2709		ctx: &Self::SimdCtx<S>,
2710		value: &Self::Real,
2711	) -> Self::SimdVec<S> {
2712		Complex {
2713			re: T::simd_splat_real(ctx, value),
2714			im: T::simd_splat_real(ctx, value),
2715		}
2716	}
2717
2718	#[inline(always)]
2719	fn simd_add<S: Simd>(
2720		ctx: &Self::SimdCtx<S>,
2721		lhs: Self::SimdVec<S>,
2722		rhs: Self::SimdVec<S>,
2723	) -> Self::SimdVec<S> {
2724		Complex {
2725			re: T::simd_add(ctx, lhs.re, rhs.re),
2726			im: T::simd_add(ctx, lhs.im, rhs.im),
2727		}
2728	}
2729
2730	#[inline(always)]
2731	fn simd_sub<S: Simd>(
2732		ctx: &Self::SimdCtx<S>,
2733		lhs: Self::SimdVec<S>,
2734		rhs: Self::SimdVec<S>,
2735	) -> Self::SimdVec<S> {
2736		Complex {
2737			re: T::simd_sub(ctx, lhs.re, rhs.re),
2738			im: T::simd_sub(ctx, lhs.im, rhs.im),
2739		}
2740	}
2741
2742	#[inline(always)]
2743	fn simd_neg<S: Simd>(
2744		ctx: &Self::SimdCtx<S>,
2745		value: Self::SimdVec<S>,
2746	) -> Self::SimdVec<S> {
2747		Complex {
2748			re: T::simd_neg(ctx, value.re),
2749			im: T::simd_neg(ctx, value.im),
2750		}
2751	}
2752
2753	#[inline(always)]
2754	fn simd_conj<S: Simd>(
2755		ctx: &Self::SimdCtx<S>,
2756		value: Self::SimdVec<S>,
2757	) -> Self::SimdVec<S> {
2758		Complex {
2759			re: value.re,
2760			im: T::simd_neg(ctx, value.im),
2761		}
2762	}
2763
2764	#[inline(always)]
2765	fn simd_abs1<S: Simd>(
2766		ctx: &Self::SimdCtx<S>,
2767		value: Self::SimdVec<S>,
2768	) -> Self::SimdVec<S> {
2769		let v = T::simd_add(
2770			ctx,
2771			T::simd_abs1(ctx, value.re),
2772			T::simd_abs1(ctx, value.im),
2773		);
2774		Complex { re: v, im: v }
2775	}
2776
2777	#[inline(always)]
2778	fn simd_abs_max<S: Simd>(
2779		ctx: &Self::SimdCtx<S>,
2780		value: Self::SimdVec<S>,
2781	) -> Self::SimdVec<S> {
2782		let re = T::simd_abs_max(ctx, value.re);
2783		let im = T::simd_abs_max(ctx, value.im);
2784		let v = T::simd_select(ctx, T::simd_greater_than(ctx, re, im), re, im);
2785		Complex { re: v, im: v }
2786	}
2787
2788	#[inline(always)]
2789	fn simd_mul_real<S: Simd>(
2790		ctx: &Self::SimdCtx<S>,
2791		lhs: Self::SimdVec<S>,
2792		real_rhs: Self::SimdVec<S>,
2793	) -> Self::SimdVec<S> {
2794		Complex {
2795			re: T::simd_mul_real(ctx, lhs.re, real_rhs.re),
2796			im: T::simd_mul_real(ctx, lhs.im, real_rhs.re),
2797		}
2798	}
2799
2800	#[inline(always)]
2801	fn simd_mul_pow2<S: Simd>(
2802		ctx: &Self::SimdCtx<S>,
2803		lhs: Self::SimdVec<S>,
2804		real_rhs: Self::SimdVec<S>,
2805	) -> Self::SimdVec<S> {
2806		Complex {
2807			re: T::simd_mul_pow2(ctx, lhs.re, real_rhs.re),
2808			im: T::simd_mul_pow2(ctx, lhs.im, real_rhs.re),
2809		}
2810	}
2811
2812	#[inline(always)]
2813	fn simd_mul<S: Simd>(
2814		ctx: &Self::SimdCtx<S>,
2815		lhs: Self::SimdVec<S>,
2816		rhs: Self::SimdVec<S>,
2817	) -> Self::SimdVec<S> {
2818		Complex {
2819			re: T::simd_mul_add(
2820				ctx,
2821				lhs.re,
2822				rhs.re,
2823				T::simd_neg(ctx, T::simd_mul(ctx, lhs.im, rhs.im)),
2824			),
2825			im: T::simd_mul_add(
2826				ctx,
2827				lhs.re,
2828				rhs.im,
2829				T::simd_mul(ctx, lhs.im, rhs.re),
2830			),
2831		}
2832	}
2833
2834	#[inline(always)]
2835	fn simd_conj_mul<S: Simd>(
2836		ctx: &Self::SimdCtx<S>,
2837		lhs: Self::SimdVec<S>,
2838		rhs: Self::SimdVec<S>,
2839	) -> Self::SimdVec<S> {
2840		Complex {
2841			re: T::simd_mul_add(
2842				ctx,
2843				lhs.re,
2844				rhs.re,
2845				T::simd_mul(ctx, lhs.im, rhs.im),
2846			),
2847			im: T::simd_mul_add(
2848				ctx,
2849				lhs.re,
2850				rhs.im,
2851				T::simd_neg(ctx, T::simd_mul(ctx, lhs.im, rhs.re)),
2852			),
2853		}
2854	}
2855
2856	#[inline(always)]
2857	fn simd_mul_add<S: Simd>(
2858		ctx: &Self::SimdCtx<S>,
2859		lhs: Self::SimdVec<S>,
2860		rhs: Self::SimdVec<S>,
2861		acc: Self::SimdVec<S>,
2862	) -> Self::SimdVec<S> {
2863		Complex {
2864			re: T::simd_mul_add(
2865				ctx,
2866				T::simd_neg(ctx, lhs.im),
2867				rhs.im,
2868				T::simd_mul_add(ctx, lhs.re, rhs.re, acc.re),
2869			),
2870			im: T::simd_mul_add(
2871				ctx,
2872				lhs.re,
2873				rhs.im,
2874				T::simd_mul_add(ctx, lhs.im, rhs.re, acc.im),
2875			),
2876		}
2877	}
2878
2879	#[inline(always)]
2880	fn simd_conj_mul_add<S: Simd>(
2881		ctx: &Self::SimdCtx<S>,
2882		lhs: Self::SimdVec<S>,
2883		rhs: Self::SimdVec<S>,
2884		acc: Self::SimdVec<S>,
2885	) -> Self::SimdVec<S> {
2886		Complex {
2887			re: T::simd_mul_add(
2888				ctx,
2889				lhs.im,
2890				rhs.im,
2891				T::simd_mul_add(ctx, lhs.re, rhs.re, acc.re),
2892			),
2893			im: T::simd_mul_add(
2894				ctx,
2895				lhs.re,
2896				rhs.im,
2897				T::simd_mul_add(ctx, T::simd_neg(ctx, lhs.im), rhs.re, acc.im),
2898			),
2899		}
2900	}
2901
2902	#[inline(always)]
2903	fn simd_abs2<S: Simd>(
2904		ctx: &Self::SimdCtx<S>,
2905		value: Self::SimdVec<S>,
2906	) -> Self::SimdVec<S> {
2907		let v = T::simd_abs2_add(ctx, value.re, T::simd_abs2(ctx, value.im));
2908		Complex { re: v, im: v }
2909	}
2910
2911	#[inline(always)]
2912	fn simd_abs2_add<S: Simd>(
2913		ctx: &Self::SimdCtx<S>,
2914		value: Self::SimdVec<S>,
2915		acc: Self::SimdVec<S>,
2916	) -> Self::SimdVec<S> {
2917		let v = T::simd_abs2_add(
2918			ctx,
2919			value.re,
2920			T::simd_abs2_add(ctx, value.im, acc.re),
2921		);
2922		Complex { re: v, im: v }
2923	}
2924
2925	#[inline(always)]
2926	fn simd_reduce_sum<S: Simd>(
2927		ctx: &Self::SimdCtx<S>,
2928		value: Self::SimdVec<S>,
2929	) -> Self {
2930		Complex {
2931			re: T::simd_reduce_sum(ctx, value.re),
2932			im: T::simd_reduce_sum(ctx, value.im),
2933		}
2934	}
2935
2936	#[inline(always)]
2937	fn simd_reduce_max<S: Simd>(
2938		ctx: &Self::SimdCtx<S>,
2939		value: Self::SimdVec<S>,
2940	) -> Self {
2941		Complex {
2942			re: T::simd_reduce_max(ctx, value.re),
2943			im: T::simd_reduce_max(ctx, value.im),
2944		}
2945	}
2946
2947	#[inline(always)]
2948	fn simd_equal<S: Simd>(
2949		ctx: &Self::SimdCtx<S>,
2950		real_lhs: Self::SimdVec<S>,
2951		real_rhs: Self::SimdVec<S>,
2952	) -> Self::SimdMask<S> {
2953		T::simd_and_mask(
2954			ctx,
2955			T::simd_equal(ctx, real_lhs.re, real_rhs.re),
2956			T::simd_equal(ctx, real_lhs.im, real_rhs.im),
2957		)
2958	}
2959
2960	#[inline(always)]
2961	fn simd_less_than<S: Simd>(
2962		ctx: &Self::SimdCtx<S>,
2963		real_lhs: Self::SimdVec<S>,
2964		real_rhs: Self::SimdVec<S>,
2965	) -> Self::SimdMask<S> {
2966		T::simd_less_than(ctx, real_lhs.re, real_rhs.re)
2967	}
2968
2969	#[inline(always)]
2970	fn simd_less_than_or_equal<S: Simd>(
2971		ctx: &Self::SimdCtx<S>,
2972		real_lhs: Self::SimdVec<S>,
2973		real_rhs: Self::SimdVec<S>,
2974	) -> Self::SimdMask<S> {
2975		T::simd_less_than_or_equal(ctx, real_lhs.re, real_rhs.re)
2976	}
2977
2978	#[inline(always)]
2979	fn simd_greater_than<S: Simd>(
2980		ctx: &Self::SimdCtx<S>,
2981		real_lhs: Self::SimdVec<S>,
2982		real_rhs: Self::SimdVec<S>,
2983	) -> Self::SimdMask<S> {
2984		T::simd_greater_than(ctx, real_lhs.re, real_rhs.re)
2985	}
2986
2987	#[inline(always)]
2988	fn simd_greater_than_or_equal<S: Simd>(
2989		ctx: &Self::SimdCtx<S>,
2990		real_lhs: Self::SimdVec<S>,
2991		real_rhs: Self::SimdVec<S>,
2992	) -> Self::SimdMask<S> {
2993		T::simd_greater_than_or_equal(ctx, real_lhs.re, real_rhs.re)
2994	}
2995
2996	#[inline(always)]
2997	fn simd_select<S: Simd>(
2998		ctx: &Self::SimdCtx<S>,
2999		mask: Self::SimdMask<S>,
3000		lhs: Self::SimdVec<S>,
3001		rhs: Self::SimdVec<S>,
3002	) -> Self::SimdVec<S> {
3003		Complex {
3004			re: T::simd_select(ctx, mask, lhs.re, rhs.re),
3005			im: T::simd_select(ctx, mask, lhs.im, rhs.im),
3006		}
3007	}
3008
3009	#[inline(always)]
3010	fn simd_index_select<S: Simd>(
3011		ctx: &Self::SimdCtx<S>,
3012		mask: Self::SimdMask<S>,
3013		lhs: Self::SimdIndex<S>,
3014		rhs: Self::SimdIndex<S>,
3015	) -> Self::SimdIndex<S> {
3016		T::simd_index_select(ctx, mask, lhs, rhs)
3017	}
3018
3019	#[inline(always)]
3020	fn simd_index_splat<S: Simd>(
3021		ctx: &Self::SimdCtx<S>,
3022		value: Self::Index,
3023	) -> Self::SimdIndex<S> {
3024		T::simd_index_splat(ctx, value)
3025	}
3026
3027	#[inline(always)]
3028	fn simd_index_add<S: Simd>(
3029		ctx: &Self::SimdCtx<S>,
3030		lhs: Self::SimdIndex<S>,
3031		rhs: Self::SimdIndex<S>,
3032	) -> Self::SimdIndex<S> {
3033		T::simd_index_add(ctx, lhs, rhs)
3034	}
3035
3036	#[inline(always)]
3037	fn simd_index_less_than<S: Simd>(
3038		ctx: &Self::SimdCtx<S>,
3039		lhs: Self::SimdIndex<S>,
3040		rhs: Self::SimdIndex<S>,
3041	) -> Self::SimdMask<S> {
3042		T::simd_index_less_than(ctx, lhs, rhs)
3043	}
3044
3045	#[inline(always)]
3046	fn simd_and_mask<S: Simd>(
3047		ctx: &Self::SimdCtx<S>,
3048		lhs: Self::SimdMask<S>,
3049		rhs: Self::SimdMask<S>,
3050	) -> Self::SimdMask<S> {
3051		T::simd_and_mask(ctx, lhs, rhs)
3052	}
3053
3054	#[inline(always)]
3055	fn simd_or_mask<S: Simd>(
3056		ctx: &Self::SimdCtx<S>,
3057		lhs: Self::SimdMask<S>,
3058		rhs: Self::SimdMask<S>,
3059	) -> Self::SimdMask<S> {
3060		T::simd_or_mask(ctx, lhs, rhs)
3061	}
3062
3063	#[inline(always)]
3064	fn simd_not_mask<S: Simd>(
3065		ctx: &Self::SimdCtx<S>,
3066		mask: Self::SimdMask<S>,
3067	) -> Self::SimdMask<S> {
3068		T::simd_not_mask(ctx, mask)
3069	}
3070
3071	#[inline(always)]
3072	fn simd_first_true_mask<S: Simd>(
3073		ctx: &Self::SimdCtx<S>,
3074		value: Self::SimdMask<S>,
3075	) -> usize {
3076		T::simd_first_true_mask(ctx, value)
3077	}
3078
3079	#[inline(always)]
3080	fn simd_mem_mask_between<S: Simd>(
3081		ctx: &Self::SimdCtx<S>,
3082		start: Self::Index,
3083		end: Self::Index,
3084	) -> Self::SimdMemMask<S> {
3085		let n = core::mem::size_of::<Self::SimdVec<S>>()
3086			/ core::mem::size_of::<Self>();
3087		let start = start.zx() * 2;
3088		let end = end.zx() * 2;
3089		let mut sa = start.min(n);
3090		let mut ea = end.min(n);
3091		let mut sb = start.max(n) - n;
3092		let mut eb = end.max(n) - n;
3093		if sa == ea {
3094			sa = 0;
3095			ea = 0;
3096		}
3097		if sb == eb {
3098			sb = 0;
3099			eb = 0;
3100		}
3101		let re = T::simd_mem_mask_between(
3102			ctx,
3103			T::Index::truncate(sa),
3104			T::Index::truncate(ea),
3105		);
3106		let im = T::simd_mem_mask_between(
3107			ctx,
3108			T::Index::truncate(sb),
3109			T::Index::truncate(eb),
3110		);
3111		Complex { re, im }
3112	}
3113
3114	#[inline(always)]
3115	fn simd_mask_between<S: Simd>(
3116		ctx: &Self::SimdCtx<S>,
3117		start: Self::Index,
3118		end: Self::Index,
3119	) -> Self::SimdMask<S> {
3120		T::simd_mask_between(ctx, start, end)
3121	}
3122
3123	#[inline(always)]
3124	unsafe fn simd_mask_load_raw<S: Simd>(
3125		ctx: &Self::SimdCtx<S>,
3126		mask: Self::SimdMemMask<S>,
3127		ptr: *const Self::SimdVec<S>,
3128	) -> Self::SimdVec<S> {
3129		Complex {
3130			re: T::simd_mask_load_raw(
3131				ctx,
3132				mask.re,
3133				core::ptr::addr_of!((*ptr).re),
3134			),
3135			im: T::simd_mask_load_raw(
3136				ctx,
3137				mask.im,
3138				core::ptr::addr_of!((*ptr).im),
3139			),
3140		}
3141	}
3142
3143	#[inline(always)]
3144	unsafe fn simd_mask_store_raw<S: Simd>(
3145		ctx: &Self::SimdCtx<S>,
3146		mask: Self::SimdMemMask<S>,
3147		ptr: *mut Self::SimdVec<S>,
3148		values: Self::SimdVec<S>,
3149	) {
3150		T::simd_mask_store_raw(
3151			ctx,
3152			mask.re,
3153			core::ptr::addr_of_mut!((*ptr).re),
3154			values.re,
3155		);
3156		T::simd_mask_store_raw(
3157			ctx,
3158			mask.im,
3159			core::ptr::addr_of_mut!((*ptr).im),
3160			values.im,
3161		);
3162	}
3163}
3164#[repr(transparent)]
3165#[doc(hidden)]
3166#[derive(Copy, Clone, Debug, PartialEq)]
3167pub struct ComplexImpl<T>(Complex<T>);
3168#[repr(transparent)]
3169#[doc(hidden)]
3170#[derive(Copy, Clone, Debug, PartialEq)]
3171pub struct ComplexImplConj<T>(Complex<T>);
3172unsafe impl Conjugate for ComplexImpl<f32> {
3173	type Canonical = ComplexImpl<f32>;
3174	type Conj = ComplexImplConj<f32>;
3175
3176	const IS_CANONICAL: bool = true;
3177}
3178unsafe impl Conjugate for ComplexImplConj<f32> {
3179	type Canonical = ComplexImpl<f32>;
3180	type Conj = ComplexImpl<f32>;
3181
3182	const IS_CANONICAL: bool = false;
3183}
3184unsafe impl Conjugate for ComplexImpl<f64> {
3185	type Canonical = ComplexImpl<f64>;
3186	type Conj = ComplexImplConj<f64>;
3187
3188	const IS_CANONICAL: bool = true;
3189}
3190unsafe impl Conjugate for ComplexImplConj<f64> {
3191	type Canonical = ComplexImpl<f64>;
3192	type Conj = ComplexImpl<f64>;
3193
3194	const IS_CANONICAL: bool = false;
3195}
3196impl<T: RealField> core::ops::Neg for ComplexImpl<T> {
3197	type Output = ComplexImpl<T>;
3198
3199	#[inline]
3200	fn neg(self) -> Self::Output {
3201		use math_utils::*;
3202		ComplexImpl(neg(&self.0))
3203	}
3204}
3205impl<T: RealField> core::ops::Neg for &ComplexImpl<T> {
3206	type Output = ComplexImpl<T>;
3207
3208	#[inline]
3209	fn neg(self) -> Self::Output {
3210		use math_utils::*;
3211		ComplexImpl(neg(&self.0))
3212	}
3213}
3214impl_op!({
3215	impl<T: RealField> Add for ComplexImpl<T> {
3216		fn add(self, rhs: Self) -> Self::Output {
3217			use math_utils::*;
3218			ComplexImpl(add(&self.0, &rhs.0))
3219		}
3220	}
3221	impl<T: RealField> Sub for ComplexImpl<T> {
3222		fn sub(self, rhs: Self) -> Self::Output {
3223			use math_utils::*;
3224			ComplexImpl(sub(&self.0, &rhs.0))
3225		}
3226	}
3227	impl<T: RealField> Mul for ComplexImpl<T> {
3228		fn mul(self, rhs: Self) -> Self::Output {
3229			use math_utils::*;
3230			ComplexImpl(mul(&self.0, &rhs.0))
3231		}
3232	}
3233	impl<T: RealField> Div for ComplexImpl<T> {
3234		fn div(self, rhs: Self) -> Self::Output {
3235			use math_utils::*;
3236			ComplexImpl(div(&self.0, &rhs.0))
3237		}
3238	}
3239});
3240impl_assign_op!({
3241	impl<T: RealField> AddAssign for ComplexImpl<T> {
3242		fn add_assign(&mut self, rhs: Self) {
3243			use math_utils::*;
3244			*self = ComplexImpl(add(&self.0, &rhs.0));
3245		}
3246	}
3247	impl<T: RealField> SubAssign for ComplexImpl<T> {
3248		fn sub_assign(&mut self, rhs: Self) {
3249			use math_utils::*;
3250			*self = ComplexImpl(sub(&self.0, &rhs.0));
3251		}
3252	}
3253	impl<T: RealField> MulAssign for ComplexImpl<T> {
3254		fn mul_assign(&mut self, rhs: Self) {
3255			use math_utils::*;
3256			*self = ComplexImpl(mul(&self.0, &rhs.0));
3257		}
3258	}
3259	impl<T: RealField> DivAssign for ComplexImpl<T> {
3260		fn div_assign(&mut self, rhs: Self) {
3261			use math_utils::*;
3262			*self = ComplexImpl(div(&self.0, &rhs.0));
3263		}
3264	}
3265});
3266impl<T> From<Complex<T>> for ComplexImpl<T> {
3267	#[inline]
3268	fn from(value: Complex<T>) -> Self {
3269		Self(value)
3270	}
3271}
3272impl ComplexField for ComplexImpl<f32> {
3273	type Arch = pulp::Arch;
3274	type Index = u32;
3275	type Real = f32;
3276	type SimdCtx<S: Simd> = S;
3277	type SimdIndex<S: Simd> = S::u32s;
3278	type SimdMask<S: Simd> = S::m32s;
3279	type SimdMemMask<S: Simd> = pulp::MemMask<S::m32s>;
3280	type SimdVec<S: Simd> = S::c32s;
3281	type Unit = f32;
3282
3283	const IS_NATIVE_C32: bool = true;
3284	const IS_REAL: bool = false;
3285	const SIMD_ABS_SPLIT_REAL_IMAG: bool = true;
3286	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Simd;
3287
3288	#[inline]
3289	fn zero_impl() -> Self {
3290		Complex {
3291			re: f32::zero_impl(),
3292			im: f32::zero_impl(),
3293		}
3294		.into()
3295	}
3296
3297	#[inline]
3298	fn one_impl() -> Self {
3299		Complex {
3300			re: f32::one_impl(),
3301			im: f32::zero_impl(),
3302		}
3303		.into()
3304	}
3305
3306	#[inline]
3307	fn nan_impl() -> Self {
3308		Complex {
3309			re: f32::nan_impl(),
3310			im: f32::nan_impl(),
3311		}
3312		.into()
3313	}
3314
3315	#[inline]
3316	fn infinity_impl() -> Self {
3317		Complex {
3318			re: f32::infinity_impl(),
3319			im: f32::infinity_impl(),
3320		}
3321		.into()
3322	}
3323
3324	#[inline]
3325	fn from_real_impl(real: &Self::Real) -> Self {
3326		Complex {
3327			re: real.clone(),
3328			im: f32::zero_impl(),
3329		}
3330		.into()
3331	}
3332
3333	#[inline]
3334	fn from_f64_impl(real: f64) -> Self {
3335		Complex {
3336			re: f32::from_f64_impl(real),
3337			im: f32::zero_impl(),
3338		}
3339		.into()
3340	}
3341
3342	#[inline]
3343	fn real_part_impl(value: &Self) -> Self::Real {
3344		value.0.re.clone()
3345	}
3346
3347	#[inline]
3348	fn imag_part_impl(value: &Self) -> Self::Real {
3349		value.0.im.clone()
3350	}
3351
3352	#[inline]
3353	fn copy_impl(value: &Self) -> Self {
3354		value.clone()
3355	}
3356
3357	#[inline]
3358	fn conj_impl(value: &Self) -> Self {
3359		Complex {
3360			re: value.0.re.clone(),
3361			im: value.0.im.neg_by_ref(),
3362		}
3363		.into()
3364	}
3365
3366	#[inline]
3367	fn recip_impl(value: &Self) -> Self {
3368		let (re, im) = recip_impl(value.0.re.clone(), value.0.im.clone());
3369		Complex { re, im }.into()
3370	}
3371
3372	#[inline]
3373	fn sqrt_impl(value: &Self) -> Self {
3374		let (re, im) = sqrt_impl(value.0.re.clone(), value.0.im.clone());
3375		Complex { re, im }.into()
3376	}
3377
3378	#[inline]
3379	fn abs_impl(value: &Self) -> Self::Real {
3380		abs_impl(value.0.re.clone(), value.0.im.clone())
3381	}
3382
3383	#[inline]
3384	fn abs1_impl(value: &Self) -> Self::Real {
3385		use crate::ext::*;
3386		value.0.re.abs1() + value.0.im.abs1()
3387	}
3388
3389	#[inline]
3390	fn abs2_impl(value: &Self) -> Self::Real {
3391		use crate::ext::*;
3392		value.0.re.abs2() + value.0.im.abs2()
3393	}
3394
3395	#[inline]
3396	fn mul_real_impl(lhs: &Self, rhs: &Self::Real) -> Self {
3397		Complex {
3398			re: lhs.0.re * rhs,
3399			im: lhs.0.im * rhs,
3400		}
3401		.into()
3402	}
3403
3404	#[inline]
3405	fn mul_pow2_impl(lhs: &Self, rhs: &Self::Real) -> Self {
3406		use crate::ext::*;
3407		Complex {
3408			re: lhs.0.re.mul_pow2(rhs),
3409			im: lhs.0.im.mul_pow2(rhs),
3410		}
3411		.into()
3412	}
3413
3414	#[inline]
3415	fn is_finite_impl(value: &Self) -> bool {
3416		value.0.re.is_finite() && value.0.im.is_finite()
3417	}
3418
3419	#[inline(always)]
3420	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
3421		f32::simd_ctx(simd)
3422	}
3423
3424	#[inline(always)]
3425	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
3426		f32::ctx_from_simd(ctx)
3427	}
3428
3429	#[inline(always)]
3430	fn simd_splat<S: Simd>(
3431		ctx: &Self::SimdCtx<S>,
3432		value: &Self,
3433	) -> Self::SimdVec<S> {
3434		ctx.splat_c32s(value.0)
3435	}
3436
3437	#[inline(always)]
3438	fn simd_splat_real<S: Simd>(
3439		ctx: &Self::SimdCtx<S>,
3440		value: &Self::Real,
3441	) -> Self::SimdVec<S> {
3442		ctx.splat_c32s(Complex {
3443			re: *value,
3444			im: *value,
3445		})
3446	}
3447
3448	#[inline(always)]
3449	fn simd_add<S: Simd>(
3450		ctx: &Self::SimdCtx<S>,
3451		lhs: Self::SimdVec<S>,
3452		rhs: Self::SimdVec<S>,
3453	) -> Self::SimdVec<S> {
3454		ctx.add_c32s(lhs, rhs)
3455	}
3456
3457	#[inline(always)]
3458	fn simd_sub<S: Simd>(
3459		ctx: &Self::SimdCtx<S>,
3460		lhs: Self::SimdVec<S>,
3461		rhs: Self::SimdVec<S>,
3462	) -> Self::SimdVec<S> {
3463		ctx.sub_c32s(lhs, rhs)
3464	}
3465
3466	#[inline(always)]
3467	fn simd_neg<S: Simd>(
3468		ctx: &Self::SimdCtx<S>,
3469		value: Self::SimdVec<S>,
3470	) -> Self::SimdVec<S> {
3471		ctx.neg_c32s(value)
3472	}
3473
3474	#[inline(always)]
3475	fn simd_conj<S: Simd>(
3476		ctx: &Self::SimdCtx<S>,
3477		value: Self::SimdVec<S>,
3478	) -> Self::SimdVec<S> {
3479		ctx.conj_c32s(value)
3480	}
3481
3482	#[inline(always)]
3483	fn simd_abs1<S: Simd>(
3484		ctx: &Self::SimdCtx<S>,
3485		value: Self::SimdVec<S>,
3486	) -> Self::SimdVec<S> {
3487		if const {
3488			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3489		} {
3490			bytemuck::cast(ctx.abs_f32s(bytemuck::cast(value)))
3491		} else if const {
3492			core::mem::size_of::<S::c32s>()
3493				== core::mem::size_of::<Complex<f32>>()
3494		} {
3495			let value: Complex<f32> = bytemuck::cast(value);
3496			let v = value.re.abs() + value.im.abs();
3497			bytemuck::cast(Complex { re: v, im: v })
3498		} else {
3499			panic!();
3500		}
3501	}
3502
3503	#[inline(always)]
3504	fn simd_abs_max<S: Simd>(
3505		ctx: &Self::SimdCtx<S>,
3506		value: Self::SimdVec<S>,
3507	) -> Self::SimdVec<S> {
3508		if const {
3509			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3510		} {
3511			bytemuck::cast(ctx.abs_f32s(bytemuck::cast(value)))
3512		} else if const {
3513			core::mem::size_of::<S::c32s>()
3514				== core::mem::size_of::<Complex<f32>>()
3515		} {
3516			let value: Complex<f32> = bytemuck::cast(value);
3517			let re = value.re.abs();
3518			let im = value.im.abs();
3519			let v = if re > im { re } else { im };
3520			bytemuck::cast(Complex { re: v, im: v })
3521		} else {
3522			panic!();
3523		}
3524	}
3525
3526	#[inline(always)]
3527	fn simd_mul_real<S: Simd>(
3528		ctx: &Self::SimdCtx<S>,
3529		lhs: Self::SimdVec<S>,
3530		real_rhs: Self::SimdVec<S>,
3531	) -> Self::SimdVec<S> {
3532		if const {
3533			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3534		} {
3535			bytemuck::cast(
3536				ctx.mul_f32s(bytemuck::cast(lhs), bytemuck::cast(real_rhs)),
3537			)
3538		} else if const {
3539			core::mem::size_of::<S::c32s>()
3540				== core::mem::size_of::<Complex<f32>>()
3541		} {
3542			let mut lhs: Complex<f32> = bytemuck::cast(lhs);
3543			let rhs: Complex<f32> = bytemuck::cast(real_rhs);
3544			lhs *= rhs.re;
3545			bytemuck::cast(lhs)
3546		} else {
3547			panic!();
3548		}
3549	}
3550
3551	#[inline(always)]
3552	fn simd_mul_pow2<S: Simd>(
3553		ctx: &Self::SimdCtx<S>,
3554		lhs: Self::SimdVec<S>,
3555		real_rhs: Self::SimdVec<S>,
3556	) -> Self::SimdVec<S> {
3557		Self::simd_mul_real(ctx, lhs, real_rhs)
3558	}
3559
3560	#[inline(always)]
3561	fn simd_mul<S: Simd>(
3562		ctx: &Self::SimdCtx<S>,
3563		lhs: Self::SimdVec<S>,
3564		rhs: Self::SimdVec<S>,
3565	) -> Self::SimdVec<S> {
3566		ctx.mul_e_c32s(lhs, rhs)
3567	}
3568
3569	#[inline(always)]
3570	fn simd_conj_mul<S: Simd>(
3571		ctx: &Self::SimdCtx<S>,
3572		lhs: Self::SimdVec<S>,
3573		rhs: Self::SimdVec<S>,
3574	) -> Self::SimdVec<S> {
3575		ctx.conj_mul_e_c32s(lhs, rhs)
3576	}
3577
3578	#[inline(always)]
3579	fn simd_mul_add<S: Simd>(
3580		ctx: &Self::SimdCtx<S>,
3581		lhs: Self::SimdVec<S>,
3582		rhs: Self::SimdVec<S>,
3583		acc: Self::SimdVec<S>,
3584	) -> Self::SimdVec<S> {
3585		ctx.mul_add_e_c32s(lhs, rhs, acc)
3586	}
3587
3588	#[inline(always)]
3589	fn simd_conj_mul_add<S: Simd>(
3590		ctx: &Self::SimdCtx<S>,
3591		lhs: Self::SimdVec<S>,
3592		rhs: Self::SimdVec<S>,
3593		acc: Self::SimdVec<S>,
3594	) -> Self::SimdVec<S> {
3595		ctx.conj_mul_add_e_c32s(lhs, rhs, acc)
3596	}
3597
3598	#[inline(always)]
3599	fn simd_abs2<S: Simd>(
3600		ctx: &Self::SimdCtx<S>,
3601		value: Self::SimdVec<S>,
3602	) -> Self::SimdVec<S> {
3603		if const {
3604			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3605		} {
3606			bytemuck::cast(
3607				ctx.mul_f32s(bytemuck::cast(value), bytemuck::cast(value)),
3608			)
3609		} else if const {
3610			core::mem::size_of::<S::c32s>()
3611				== core::mem::size_of::<Complex<f32>>()
3612		} {
3613			let value: Complex<f32> = bytemuck::cast(value);
3614			let v = value.re * value.re + value.im * value.im;
3615			bytemuck::cast(Complex { re: v, im: v })
3616		} else {
3617			panic!();
3618		}
3619	}
3620
3621	#[inline(always)]
3622	fn simd_abs2_add<S: Simd>(
3623		ctx: &Self::SimdCtx<S>,
3624		value: Self::SimdVec<S>,
3625		acc: Self::SimdVec<S>,
3626	) -> Self::SimdVec<S> {
3627		if const {
3628			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3629		} {
3630			bytemuck::cast(ctx.mul_add_f32s(
3631				bytemuck::cast(value),
3632				bytemuck::cast(value),
3633				bytemuck::cast(acc),
3634			))
3635		} else if const {
3636			core::mem::size_of::<S::c32s>()
3637				== core::mem::size_of::<Complex<f32>>()
3638		} {
3639			let value: Complex<f32> = bytemuck::cast(value);
3640			let acc: Complex<f32> = bytemuck::cast(acc);
3641			let v = value.re * value.re + value.im * value.im + acc.re;
3642			bytemuck::cast(Complex { re: v, im: v })
3643		} else {
3644			panic!();
3645		}
3646	}
3647
3648	#[inline(always)]
3649	fn simd_reduce_sum<S: Simd>(
3650		ctx: &Self::SimdCtx<S>,
3651		value: Self::SimdVec<S>,
3652	) -> Self {
3653		ctx.reduce_sum_c32s(value).into()
3654	}
3655
3656	#[inline(always)]
3657	fn simd_reduce_max<S: Simd>(
3658		ctx: &Self::SimdCtx<S>,
3659		value: Self::SimdVec<S>,
3660	) -> Self {
3661		ctx.reduce_max_c32s(value).into()
3662	}
3663
3664	#[inline(always)]
3665	fn simd_equal<S: Simd>(
3666		_: &Self::SimdCtx<S>,
3667		_: Self::SimdVec<S>,
3668		_: Self::SimdVec<S>,
3669	) -> Self::SimdMask<S> {
3670		panic!()
3671	}
3672
3673	#[inline(always)]
3674	fn simd_less_than<S: Simd>(
3675		ctx: &Self::SimdCtx<S>,
3676		real_lhs: Self::SimdVec<S>,
3677		real_rhs: Self::SimdVec<S>,
3678	) -> Self::SimdMask<S> {
3679		if const {
3680			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3681		} {
3682			ctx.less_than_f32s(
3683				bytemuck::cast(real_lhs),
3684				bytemuck::cast(real_rhs),
3685			)
3686		} else if const {
3687			core::mem::size_of::<S::c32s>()
3688				== core::mem::size_of::<Complex<f32>>()
3689		} {
3690			assert!(
3691				const {
3692					core::mem::size_of::<S::m32s>()
3693						== core::mem::size_of::<bool>()
3694				}
3695			);
3696			let lhs: Complex<f32> = bytemuck::cast(real_lhs);
3697			let rhs: Complex<f32> = bytemuck::cast(real_rhs);
3698			unsafe { core::mem::transmute_copy(&(lhs.re < rhs.re)) }
3699		} else {
3700			panic!();
3701		}
3702	}
3703
3704	#[inline(always)]
3705	fn simd_less_than_or_equal<S: Simd>(
3706		ctx: &Self::SimdCtx<S>,
3707		real_lhs: Self::SimdVec<S>,
3708		real_rhs: Self::SimdVec<S>,
3709	) -> Self::SimdMask<S> {
3710		if const {
3711			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3712		} {
3713			ctx.less_than_or_equal_f32s(
3714				bytemuck::cast(real_lhs),
3715				bytemuck::cast(real_rhs),
3716			)
3717		} else if const {
3718			core::mem::size_of::<S::c32s>()
3719				== core::mem::size_of::<Complex<f32>>()
3720		} {
3721			assert!(
3722				const {
3723					core::mem::size_of::<S::m32s>()
3724						== core::mem::size_of::<bool>()
3725				}
3726			);
3727			let lhs: Complex<f32> = bytemuck::cast(real_lhs);
3728			let rhs: Complex<f32> = bytemuck::cast(real_rhs);
3729			unsafe { core::mem::transmute_copy(&(lhs.re <= rhs.re)) }
3730		} else {
3731			panic!();
3732		}
3733	}
3734
3735	#[inline(always)]
3736	fn simd_greater_than<S: Simd>(
3737		ctx: &Self::SimdCtx<S>,
3738		real_lhs: Self::SimdVec<S>,
3739		real_rhs: Self::SimdVec<S>,
3740	) -> Self::SimdMask<S> {
3741		if const {
3742			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3743		} {
3744			ctx.greater_than_f32s(
3745				bytemuck::cast(real_lhs),
3746				bytemuck::cast(real_rhs),
3747			)
3748		} else if const {
3749			core::mem::size_of::<S::c32s>()
3750				== core::mem::size_of::<Complex<f32>>()
3751		} {
3752			assert!(
3753				const {
3754					core::mem::size_of::<S::m32s>()
3755						== core::mem::size_of::<bool>()
3756				}
3757			);
3758			let lhs: Complex<f32> = bytemuck::cast(real_lhs);
3759			let rhs: Complex<f32> = bytemuck::cast(real_rhs);
3760			unsafe { core::mem::transmute_copy(&(lhs.re > rhs.re)) }
3761		} else {
3762			panic!();
3763		}
3764	}
3765
3766	#[inline(always)]
3767	fn simd_greater_than_or_equal<S: Simd>(
3768		ctx: &Self::SimdCtx<S>,
3769		real_lhs: Self::SimdVec<S>,
3770		real_rhs: Self::SimdVec<S>,
3771	) -> Self::SimdMask<S> {
3772		if const {
3773			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3774		} {
3775			ctx.greater_than_or_equal_f32s(
3776				bytemuck::cast(real_lhs),
3777				bytemuck::cast(real_rhs),
3778			)
3779		} else if const {
3780			core::mem::size_of::<S::c32s>()
3781				== core::mem::size_of::<Complex<f32>>()
3782		} {
3783			assert!(
3784				const {
3785					core::mem::size_of::<S::m32s>()
3786						== core::mem::size_of::<bool>()
3787				}
3788			);
3789			let lhs: Complex<f32> = bytemuck::cast(real_lhs);
3790			let rhs: Complex<f32> = bytemuck::cast(real_rhs);
3791			unsafe { core::mem::transmute_copy(&(lhs.re >= rhs.re)) }
3792		} else {
3793			panic!();
3794		}
3795	}
3796
3797	#[inline(always)]
3798	fn simd_select<S: Simd>(
3799		ctx: &Self::SimdCtx<S>,
3800		mask: Self::SimdMask<S>,
3801		lhs: Self::SimdVec<S>,
3802		rhs: Self::SimdVec<S>,
3803	) -> Self::SimdVec<S> {
3804		if const {
3805			core::mem::size_of::<S::c32s>() == core::mem::size_of::<S::f32s>()
3806		} {
3807			bytemuck::cast(ctx.select_f32s(
3808				mask,
3809				bytemuck::cast(lhs),
3810				bytemuck::cast(rhs),
3811			))
3812		} else if const {
3813			core::mem::size_of::<S::c32s>()
3814				== core::mem::size_of::<Complex<f32>>()
3815		} {
3816			assert!(
3817				const {
3818					core::mem::size_of::<S::m32s>()
3819						== core::mem::size_of::<bool>()
3820				}
3821			);
3822			let mask: bool = unsafe { core::mem::transmute_copy(&mask) };
3823			let lhs: Complex<f32> = bytemuck::cast(lhs);
3824			let rhs: Complex<f32> = bytemuck::cast(rhs);
3825			bytemuck::cast(if mask { lhs } else { rhs })
3826		} else {
3827			panic!();
3828		}
3829	}
3830
3831	#[inline(always)]
3832	fn simd_index_select<S: Simd>(
3833		ctx: &Self::SimdCtx<S>,
3834		mask: Self::SimdMask<S>,
3835		lhs: Self::SimdIndex<S>,
3836		rhs: Self::SimdIndex<S>,
3837	) -> Self::SimdIndex<S> {
3838		f32::simd_index_select(ctx, mask, lhs, rhs)
3839	}
3840
3841	#[inline(always)]
3842	fn simd_index_splat<S: Simd>(
3843		ctx: &Self::SimdCtx<S>,
3844		value: Self::Index,
3845	) -> Self::SimdIndex<S> {
3846		f32::simd_index_splat(ctx, value)
3847	}
3848
3849	#[inline(always)]
3850	fn simd_index_add<S: Simd>(
3851		ctx: &Self::SimdCtx<S>,
3852		lhs: Self::SimdIndex<S>,
3853		rhs: Self::SimdIndex<S>,
3854	) -> Self::SimdIndex<S> {
3855		f32::simd_index_add(ctx, lhs, rhs)
3856	}
3857
3858	#[inline(always)]
3859	fn simd_index_less_than<S: Simd>(
3860		ctx: &Self::SimdCtx<S>,
3861		lhs: Self::SimdIndex<S>,
3862		rhs: Self::SimdIndex<S>,
3863	) -> Self::SimdMask<S> {
3864		f32::simd_index_less_than(ctx, lhs, rhs)
3865	}
3866
3867	#[inline(always)]
3868	fn simd_and_mask<S: Simd>(
3869		ctx: &Self::SimdCtx<S>,
3870		lhs: Self::SimdMask<S>,
3871		rhs: Self::SimdMask<S>,
3872	) -> Self::SimdMask<S> {
3873		f32::simd_and_mask(ctx, lhs, rhs)
3874	}
3875
3876	#[inline(always)]
3877	fn simd_or_mask<S: Simd>(
3878		ctx: &Self::SimdCtx<S>,
3879		lhs: Self::SimdMask<S>,
3880		rhs: Self::SimdMask<S>,
3881	) -> Self::SimdMask<S> {
3882		f32::simd_or_mask(ctx, lhs, rhs)
3883	}
3884
3885	#[inline(always)]
3886	fn simd_not_mask<S: Simd>(
3887		ctx: &Self::SimdCtx<S>,
3888		mask: Self::SimdMask<S>,
3889	) -> Self::SimdMask<S> {
3890		f32::simd_not_mask(ctx, mask)
3891	}
3892
3893	#[inline(always)]
3894	fn simd_first_true_mask<S: Simd>(
3895		ctx: &Self::SimdCtx<S>,
3896		value: Self::SimdMask<S>,
3897	) -> usize {
3898		f32::simd_first_true_mask(ctx, value)
3899	}
3900
3901	#[inline(always)]
3902	fn simd_mem_mask_between<S: Simd>(
3903		ctx: &Self::SimdCtx<S>,
3904		start: Self::Index,
3905		end: Self::Index,
3906	) -> Self::SimdMemMask<S> {
3907		ctx.mask_between_m32s((2 * start) as _, (2 * end) as _)
3908	}
3909
3910	#[inline(always)]
3911	fn simd_mask_between<S: Simd>(
3912		ctx: &Self::SimdCtx<S>,
3913		start: Self::Index,
3914		end: Self::Index,
3915	) -> Self::SimdMask<S> {
3916		ctx.mask_between_m32s((2 * start) as _, (2 * end) as _)
3917			.mask()
3918	}
3919
3920	#[inline(always)]
3921	unsafe fn simd_mask_load_raw<S: Simd>(
3922		ctx: &Self::SimdCtx<S>,
3923		mask: Self::SimdMemMask<S>,
3924		ptr: *const Self::SimdVec<S>,
3925	) -> Self::SimdVec<S> {
3926		ctx.mask_load_ptr_c32s(mask, ptr as _)
3927	}
3928
3929	#[inline(always)]
3930	unsafe fn simd_mask_store_raw<S: Simd>(
3931		ctx: &Self::SimdCtx<S>,
3932		mask: Self::SimdMemMask<S>,
3933		ptr: *mut Self::SimdVec<S>,
3934		values: Self::SimdVec<S>,
3935	) {
3936		ctx.mask_store_ptr_c32s(mask, ptr as _, values);
3937	}
3938}
3939impl ComplexField for ComplexImpl<f64> {
3940	type Arch = pulp::Arch;
3941	type Index = u64;
3942	type Real = f64;
3943	type SimdCtx<S: Simd> = S;
3944	type SimdIndex<S: Simd> = S::u64s;
3945	type SimdMask<S: Simd> = S::m64s;
3946	type SimdMemMask<S: Simd> = pulp::MemMask<S::m64s>;
3947	type SimdVec<S: Simd> = S::c64s;
3948	type Unit = f64;
3949
3950	const IS_NATIVE_C64: bool = true;
3951	const IS_REAL: bool = false;
3952	const SIMD_ABS_SPLIT_REAL_IMAG: bool = true;
3953	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Simd;
3954
3955	#[inline]
3956	fn zero_impl() -> Self {
3957		Complex {
3958			re: f64::zero_impl(),
3959			im: f64::zero_impl(),
3960		}
3961		.into()
3962	}
3963
3964	#[inline]
3965	fn one_impl() -> Self {
3966		Complex {
3967			re: f64::one_impl(),
3968			im: f64::zero_impl(),
3969		}
3970		.into()
3971	}
3972
3973	#[inline]
3974	fn nan_impl() -> Self {
3975		Complex {
3976			re: f64::nan_impl(),
3977			im: f64::nan_impl(),
3978		}
3979		.into()
3980	}
3981
3982	#[inline]
3983	fn infinity_impl() -> Self {
3984		Complex {
3985			re: f64::infinity_impl(),
3986			im: f64::infinity_impl(),
3987		}
3988		.into()
3989	}
3990
3991	#[inline]
3992	fn from_real_impl(real: &Self::Real) -> Self {
3993		Complex {
3994			re: real.clone(),
3995			im: f64::zero_impl(),
3996		}
3997		.into()
3998	}
3999
4000	#[inline]
4001	fn from_f64_impl(real: f64) -> Self {
4002		Complex {
4003			re: f64::from_f64_impl(real),
4004			im: f64::zero_impl(),
4005		}
4006		.into()
4007	}
4008
4009	#[inline]
4010	fn real_part_impl(value: &Self) -> Self::Real {
4011		value.0.re.clone()
4012	}
4013
4014	#[inline]
4015	fn imag_part_impl(value: &Self) -> Self::Real {
4016		value.0.im.clone()
4017	}
4018
4019	#[inline]
4020	fn copy_impl(value: &Self) -> Self {
4021		value.clone()
4022	}
4023
4024	#[inline]
4025	fn conj_impl(value: &Self) -> Self {
4026		Complex {
4027			re: value.0.re.clone(),
4028			im: value.0.im.neg_by_ref(),
4029		}
4030		.into()
4031	}
4032
4033	#[inline]
4034	fn recip_impl(value: &Self) -> Self {
4035		let (re, im) = recip_impl(value.0.re.clone(), value.0.im.clone());
4036		Complex { re, im }.into()
4037	}
4038
4039	#[inline]
4040	fn sqrt_impl(value: &Self) -> Self {
4041		let (re, im) = sqrt_impl(value.0.re.clone(), value.0.im.clone());
4042		Complex { re, im }.into()
4043	}
4044
4045	#[inline]
4046	fn abs_impl(value: &Self) -> Self::Real {
4047		abs_impl(value.0.re.clone(), value.0.im.clone())
4048	}
4049
4050	#[inline]
4051	fn abs1_impl(value: &Self) -> Self::Real {
4052		use crate::ext::*;
4053		value.0.re.abs1() + value.0.im.abs1()
4054	}
4055
4056	#[inline]
4057	fn abs2_impl(value: &Self) -> Self::Real {
4058		use crate::ext::*;
4059		value.0.re.abs2() + value.0.im.abs2()
4060	}
4061
4062	#[inline]
4063	fn mul_real_impl(lhs: &Self, rhs: &Self::Real) -> Self {
4064		Complex {
4065			re: lhs.0.re * rhs,
4066			im: lhs.0.im * rhs,
4067		}
4068		.into()
4069	}
4070
4071	#[inline]
4072	fn mul_pow2_impl(lhs: &Self, rhs: &Self::Real) -> Self {
4073		use crate::ext::*;
4074		Complex {
4075			re: lhs.0.re.mul_pow2(rhs),
4076			im: lhs.0.im.mul_pow2(rhs),
4077		}
4078		.into()
4079	}
4080
4081	#[inline]
4082	fn is_finite_impl(value: &Self) -> bool {
4083		value.0.re.is_finite() && value.0.im.is_finite()
4084	}
4085
4086	#[inline(always)]
4087	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
4088		f64::simd_ctx(simd)
4089	}
4090
4091	#[inline(always)]
4092	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
4093		f64::ctx_from_simd(ctx)
4094	}
4095
4096	#[inline(always)]
4097	fn simd_splat<S: Simd>(
4098		ctx: &Self::SimdCtx<S>,
4099		value: &Self,
4100	) -> Self::SimdVec<S> {
4101		ctx.splat_c64s(value.0)
4102	}
4103
4104	#[inline(always)]
4105	fn simd_splat_real<S: Simd>(
4106		ctx: &Self::SimdCtx<S>,
4107		value: &Self::Real,
4108	) -> Self::SimdVec<S> {
4109		ctx.splat_c64s(Complex {
4110			re: *value,
4111			im: *value,
4112		})
4113	}
4114
4115	#[inline(always)]
4116	fn simd_add<S: Simd>(
4117		ctx: &Self::SimdCtx<S>,
4118		lhs: Self::SimdVec<S>,
4119		rhs: Self::SimdVec<S>,
4120	) -> Self::SimdVec<S> {
4121		ctx.add_c64s(lhs, rhs)
4122	}
4123
4124	#[inline(always)]
4125	fn simd_sub<S: Simd>(
4126		ctx: &Self::SimdCtx<S>,
4127		lhs: Self::SimdVec<S>,
4128		rhs: Self::SimdVec<S>,
4129	) -> Self::SimdVec<S> {
4130		ctx.sub_c64s(lhs, rhs)
4131	}
4132
4133	#[inline(always)]
4134	fn simd_neg<S: Simd>(
4135		ctx: &Self::SimdCtx<S>,
4136		value: Self::SimdVec<S>,
4137	) -> Self::SimdVec<S> {
4138		ctx.neg_c64s(value)
4139	}
4140
4141	#[inline(always)]
4142	fn simd_conj<S: Simd>(
4143		ctx: &Self::SimdCtx<S>,
4144		value: Self::SimdVec<S>,
4145	) -> Self::SimdVec<S> {
4146		ctx.conj_c64s(value)
4147	}
4148
4149	#[inline(always)]
4150	fn simd_abs1<S: Simd>(
4151		ctx: &Self::SimdCtx<S>,
4152		value: Self::SimdVec<S>,
4153	) -> Self::SimdVec<S> {
4154		if const {
4155			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4156		} {
4157			bytemuck::cast(ctx.abs_f64s(bytemuck::cast(value)))
4158		} else if const {
4159			core::mem::size_of::<S::c64s>()
4160				== core::mem::size_of::<Complex<f64>>()
4161		} {
4162			let value: Complex<f64> = bytemuck::cast(value);
4163			let v = value.re.abs() + value.im.abs();
4164			bytemuck::cast(Complex { re: v, im: v })
4165		} else {
4166			panic!();
4167		}
4168	}
4169
4170	#[inline(always)]
4171	fn simd_abs_max<S: Simd>(
4172		ctx: &Self::SimdCtx<S>,
4173		value: Self::SimdVec<S>,
4174	) -> Self::SimdVec<S> {
4175		if const {
4176			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4177		} {
4178			bytemuck::cast(ctx.abs_f64s(bytemuck::cast(value)))
4179		} else if const {
4180			core::mem::size_of::<S::c64s>()
4181				== core::mem::size_of::<Complex<f64>>()
4182		} {
4183			let value: Complex<f64> = bytemuck::cast(value);
4184			let re = value.re.abs();
4185			let im = value.im.abs();
4186			let v = if re > im { re } else { im };
4187			bytemuck::cast(Complex { re: v, im: v })
4188		} else {
4189			panic!();
4190		}
4191	}
4192
4193	#[inline(always)]
4194	fn simd_mul_real<S: Simd>(
4195		ctx: &Self::SimdCtx<S>,
4196		lhs: Self::SimdVec<S>,
4197		real_rhs: Self::SimdVec<S>,
4198	) -> Self::SimdVec<S> {
4199		if const {
4200			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4201		} {
4202			bytemuck::cast(
4203				ctx.mul_f64s(bytemuck::cast(lhs), bytemuck::cast(real_rhs)),
4204			)
4205		} else if const {
4206			core::mem::size_of::<S::c64s>()
4207				== core::mem::size_of::<Complex<f64>>()
4208		} {
4209			let mut lhs: Complex<f64> = bytemuck::cast(lhs);
4210			let rhs: Complex<f64> = bytemuck::cast(real_rhs);
4211			lhs *= rhs.re;
4212			bytemuck::cast(lhs)
4213		} else {
4214			panic!();
4215		}
4216	}
4217
4218	#[inline(always)]
4219	fn simd_mul_pow2<S: Simd>(
4220		ctx: &Self::SimdCtx<S>,
4221		lhs: Self::SimdVec<S>,
4222		real_rhs: Self::SimdVec<S>,
4223	) -> Self::SimdVec<S> {
4224		Self::simd_mul_real(ctx, lhs, real_rhs)
4225	}
4226
4227	#[inline(always)]
4228	fn simd_mul<S: Simd>(
4229		ctx: &Self::SimdCtx<S>,
4230		lhs: Self::SimdVec<S>,
4231		rhs: Self::SimdVec<S>,
4232	) -> Self::SimdVec<S> {
4233		ctx.mul_e_c64s(lhs, rhs)
4234	}
4235
4236	#[inline(always)]
4237	fn simd_conj_mul<S: Simd>(
4238		ctx: &Self::SimdCtx<S>,
4239		lhs: Self::SimdVec<S>,
4240		rhs: Self::SimdVec<S>,
4241	) -> Self::SimdVec<S> {
4242		ctx.conj_mul_e_c64s(lhs, rhs)
4243	}
4244
4245	#[inline(always)]
4246	fn simd_mul_add<S: Simd>(
4247		ctx: &Self::SimdCtx<S>,
4248		lhs: Self::SimdVec<S>,
4249		rhs: Self::SimdVec<S>,
4250		acc: Self::SimdVec<S>,
4251	) -> Self::SimdVec<S> {
4252		ctx.mul_add_e_c64s(lhs, rhs, acc)
4253	}
4254
4255	#[inline(always)]
4256	fn simd_conj_mul_add<S: Simd>(
4257		ctx: &Self::SimdCtx<S>,
4258		lhs: Self::SimdVec<S>,
4259		rhs: Self::SimdVec<S>,
4260		acc: Self::SimdVec<S>,
4261	) -> Self::SimdVec<S> {
4262		ctx.conj_mul_add_e_c64s(lhs, rhs, acc)
4263	}
4264
4265	#[inline(always)]
4266	fn simd_abs2<S: Simd>(
4267		ctx: &Self::SimdCtx<S>,
4268		value: Self::SimdVec<S>,
4269	) -> Self::SimdVec<S> {
4270		if const {
4271			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4272		} {
4273			bytemuck::cast(
4274				ctx.mul_f64s(bytemuck::cast(value), bytemuck::cast(value)),
4275			)
4276		} else if const {
4277			core::mem::size_of::<S::c64s>()
4278				== core::mem::size_of::<Complex<f64>>()
4279		} {
4280			let value: Complex<f64> = bytemuck::cast(value);
4281			let v = value.re * value.re + value.im * value.im;
4282			bytemuck::cast(Complex { re: v, im: v })
4283		} else {
4284			panic!();
4285		}
4286	}
4287
4288	#[inline(always)]
4289	fn simd_abs2_add<S: Simd>(
4290		ctx: &Self::SimdCtx<S>,
4291		value: Self::SimdVec<S>,
4292		acc: Self::SimdVec<S>,
4293	) -> Self::SimdVec<S> {
4294		if const {
4295			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4296		} {
4297			bytemuck::cast(ctx.mul_add_f64s(
4298				bytemuck::cast(value),
4299				bytemuck::cast(value),
4300				bytemuck::cast(acc),
4301			))
4302		} else if const {
4303			core::mem::size_of::<S::c64s>()
4304				== core::mem::size_of::<Complex<f64>>()
4305		} {
4306			let value: Complex<f64> = bytemuck::cast(value);
4307			let acc: Complex<f64> = bytemuck::cast(acc);
4308			let v = value.re * value.re + value.im * value.im + acc.re;
4309			bytemuck::cast(Complex { re: v, im: v })
4310		} else {
4311			panic!();
4312		}
4313	}
4314
4315	#[inline(always)]
4316	fn simd_reduce_sum<S: Simd>(
4317		ctx: &Self::SimdCtx<S>,
4318		value: Self::SimdVec<S>,
4319	) -> Self {
4320		ctx.reduce_sum_c64s(value).into()
4321	}
4322
4323	#[inline(always)]
4324	fn simd_reduce_max<S: Simd>(
4325		ctx: &Self::SimdCtx<S>,
4326		value: Self::SimdVec<S>,
4327	) -> Self {
4328		ctx.reduce_max_c64s(value).into()
4329	}
4330
4331	#[inline(always)]
4332	fn simd_equal<S: Simd>(
4333		_: &Self::SimdCtx<S>,
4334		_: Self::SimdVec<S>,
4335		_: Self::SimdVec<S>,
4336	) -> Self::SimdMask<S> {
4337		panic!()
4338	}
4339
4340	#[inline(always)]
4341	fn simd_less_than<S: Simd>(
4342		ctx: &Self::SimdCtx<S>,
4343		real_lhs: Self::SimdVec<S>,
4344		real_rhs: Self::SimdVec<S>,
4345	) -> Self::SimdMask<S> {
4346		if const {
4347			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4348		} {
4349			ctx.less_than_f64s(
4350				bytemuck::cast(real_lhs),
4351				bytemuck::cast(real_rhs),
4352			)
4353		} else if const {
4354			core::mem::size_of::<S::c64s>()
4355				== core::mem::size_of::<Complex<f64>>()
4356		} {
4357			assert!(
4358				const {
4359					core::mem::size_of::<S::m64s>()
4360						== core::mem::size_of::<bool>()
4361				}
4362			);
4363			let lhs: Complex<f64> = bytemuck::cast(real_lhs);
4364			let rhs: Complex<f64> = bytemuck::cast(real_rhs);
4365			unsafe { core::mem::transmute_copy(&(lhs.re < rhs.re)) }
4366		} else {
4367			panic!();
4368		}
4369	}
4370
4371	#[inline(always)]
4372	fn simd_less_than_or_equal<S: Simd>(
4373		ctx: &Self::SimdCtx<S>,
4374		real_lhs: Self::SimdVec<S>,
4375		real_rhs: Self::SimdVec<S>,
4376	) -> Self::SimdMask<S> {
4377		if const {
4378			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4379		} {
4380			ctx.less_than_or_equal_f64s(
4381				bytemuck::cast(real_lhs),
4382				bytemuck::cast(real_rhs),
4383			)
4384		} else if const {
4385			core::mem::size_of::<S::c64s>()
4386				== core::mem::size_of::<Complex<f64>>()
4387		} {
4388			assert!(
4389				const {
4390					core::mem::size_of::<S::m64s>()
4391						== core::mem::size_of::<bool>()
4392				}
4393			);
4394			let lhs: Complex<f64> = bytemuck::cast(real_lhs);
4395			let rhs: Complex<f64> = bytemuck::cast(real_rhs);
4396			unsafe { core::mem::transmute_copy(&(lhs.re <= rhs.re)) }
4397		} else {
4398			panic!();
4399		}
4400	}
4401
4402	#[inline(always)]
4403	fn simd_greater_than<S: Simd>(
4404		ctx: &Self::SimdCtx<S>,
4405		real_lhs: Self::SimdVec<S>,
4406		real_rhs: Self::SimdVec<S>,
4407	) -> Self::SimdMask<S> {
4408		if const {
4409			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4410		} {
4411			ctx.greater_than_f64s(
4412				bytemuck::cast(real_lhs),
4413				bytemuck::cast(real_rhs),
4414			)
4415		} else if const {
4416			core::mem::size_of::<S::c64s>()
4417				== core::mem::size_of::<Complex<f64>>()
4418		} {
4419			assert!(
4420				const {
4421					core::mem::size_of::<S::m64s>()
4422						== core::mem::size_of::<bool>()
4423				}
4424			);
4425			let lhs: Complex<f64> = bytemuck::cast(real_lhs);
4426			let rhs: Complex<f64> = bytemuck::cast(real_rhs);
4427			unsafe { core::mem::transmute_copy(&(lhs.re > rhs.re)) }
4428		} else {
4429			panic!();
4430		}
4431	}
4432
4433	#[inline(always)]
4434	fn simd_greater_than_or_equal<S: Simd>(
4435		ctx: &Self::SimdCtx<S>,
4436		real_lhs: Self::SimdVec<S>,
4437		real_rhs: Self::SimdVec<S>,
4438	) -> Self::SimdMask<S> {
4439		if const {
4440			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4441		} {
4442			ctx.greater_than_or_equal_f64s(
4443				bytemuck::cast(real_lhs),
4444				bytemuck::cast(real_rhs),
4445			)
4446		} else if const {
4447			core::mem::size_of::<S::c64s>()
4448				== core::mem::size_of::<Complex<f64>>()
4449		} {
4450			assert!(
4451				const {
4452					core::mem::size_of::<S::m64s>()
4453						== core::mem::size_of::<bool>()
4454				}
4455			);
4456			let lhs: Complex<f64> = bytemuck::cast(real_lhs);
4457			let rhs: Complex<f64> = bytemuck::cast(real_rhs);
4458			unsafe { core::mem::transmute_copy(&(lhs.re >= rhs.re)) }
4459		} else {
4460			panic!();
4461		}
4462	}
4463
4464	#[inline(always)]
4465	fn simd_select<S: Simd>(
4466		ctx: &Self::SimdCtx<S>,
4467		mask: Self::SimdMask<S>,
4468		lhs: Self::SimdVec<S>,
4469		rhs: Self::SimdVec<S>,
4470	) -> Self::SimdVec<S> {
4471		if const {
4472			core::mem::size_of::<S::c64s>() == core::mem::size_of::<S::f64s>()
4473		} {
4474			bytemuck::cast(ctx.select_f64s(
4475				mask,
4476				bytemuck::cast(lhs),
4477				bytemuck::cast(rhs),
4478			))
4479		} else if const {
4480			core::mem::size_of::<S::c64s>()
4481				== core::mem::size_of::<Complex<f64>>()
4482		} {
4483			assert!(
4484				const {
4485					core::mem::size_of::<S::m64s>()
4486						== core::mem::size_of::<bool>()
4487				}
4488			);
4489			let mask: bool = unsafe { core::mem::transmute_copy(&mask) };
4490			let lhs: Complex<f64> = bytemuck::cast(lhs);
4491			let rhs: Complex<f64> = bytemuck::cast(rhs);
4492			bytemuck::cast(if mask { lhs } else { rhs })
4493		} else {
4494			panic!();
4495		}
4496	}
4497
4498	#[inline(always)]
4499	fn simd_index_select<S: Simd>(
4500		ctx: &Self::SimdCtx<S>,
4501		mask: Self::SimdMask<S>,
4502		lhs: Self::SimdIndex<S>,
4503		rhs: Self::SimdIndex<S>,
4504	) -> Self::SimdIndex<S> {
4505		f64::simd_index_select(ctx, mask, lhs, rhs)
4506	}
4507
4508	#[inline(always)]
4509	fn simd_index_splat<S: Simd>(
4510		ctx: &Self::SimdCtx<S>,
4511		value: Self::Index,
4512	) -> Self::SimdIndex<S> {
4513		f64::simd_index_splat(ctx, value)
4514	}
4515
4516	#[inline(always)]
4517	fn simd_index_add<S: Simd>(
4518		ctx: &Self::SimdCtx<S>,
4519		lhs: Self::SimdIndex<S>,
4520		rhs: Self::SimdIndex<S>,
4521	) -> Self::SimdIndex<S> {
4522		f64::simd_index_add(ctx, lhs, rhs)
4523	}
4524
4525	#[inline(always)]
4526	fn simd_index_less_than<S: Simd>(
4527		ctx: &Self::SimdCtx<S>,
4528		lhs: Self::SimdIndex<S>,
4529		rhs: Self::SimdIndex<S>,
4530	) -> Self::SimdMask<S> {
4531		f64::simd_index_less_than(ctx, lhs, rhs)
4532	}
4533
4534	#[inline(always)]
4535	fn simd_and_mask<S: Simd>(
4536		ctx: &Self::SimdCtx<S>,
4537		lhs: Self::SimdMask<S>,
4538		rhs: Self::SimdMask<S>,
4539	) -> Self::SimdMask<S> {
4540		f64::simd_and_mask(ctx, lhs, rhs)
4541	}
4542
4543	#[inline(always)]
4544	fn simd_or_mask<S: Simd>(
4545		ctx: &Self::SimdCtx<S>,
4546		lhs: Self::SimdMask<S>,
4547		rhs: Self::SimdMask<S>,
4548	) -> Self::SimdMask<S> {
4549		f64::simd_or_mask(ctx, lhs, rhs)
4550	}
4551
4552	#[inline(always)]
4553	fn simd_not_mask<S: Simd>(
4554		ctx: &Self::SimdCtx<S>,
4555		mask: Self::SimdMask<S>,
4556	) -> Self::SimdMask<S> {
4557		f64::simd_not_mask(ctx, mask)
4558	}
4559
4560	#[inline(always)]
4561	fn simd_first_true_mask<S: Simd>(
4562		ctx: &Self::SimdCtx<S>,
4563		value: Self::SimdMask<S>,
4564	) -> usize {
4565		f64::simd_first_true_mask(ctx, value)
4566	}
4567
4568	#[inline(always)]
4569	fn simd_mem_mask_between<S: Simd>(
4570		ctx: &Self::SimdCtx<S>,
4571		start: Self::Index,
4572		end: Self::Index,
4573	) -> Self::SimdMemMask<S> {
4574		ctx.mask_between_m64s((2 * start) as _, (2 * end) as _)
4575	}
4576
4577	#[inline(always)]
4578	fn simd_mask_between<S: Simd>(
4579		ctx: &Self::SimdCtx<S>,
4580		start: Self::Index,
4581		end: Self::Index,
4582	) -> Self::SimdMask<S> {
4583		ctx.mask_between_m64s((2 * start) as _, (2 * end) as _)
4584			.mask()
4585	}
4586
4587	#[inline(always)]
4588	unsafe fn simd_mask_load_raw<S: Simd>(
4589		ctx: &Self::SimdCtx<S>,
4590		mask: Self::SimdMemMask<S>,
4591		ptr: *const Self::SimdVec<S>,
4592	) -> Self::SimdVec<S> {
4593		ctx.mask_load_ptr_c64s(mask, ptr as _)
4594	}
4595
4596	#[inline(always)]
4597	unsafe fn simd_mask_store_raw<S: Simd>(
4598		ctx: &Self::SimdCtx<S>,
4599		mask: Self::SimdMemMask<S>,
4600		ptr: *mut Self::SimdVec<S>,
4601		values: Self::SimdVec<S>,
4602	) {
4603		ctx.mask_store_ptr_c64s(mask, ptr as _, values);
4604	}
4605}
4606#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
4607pub struct Symbolic;
4608impl_op!({
4609	impl Add for Symbolic {
4610		fn add(self, rhs: Self) -> Self::Output {
4611			_ = rhs;
4612			Symbolic
4613		}
4614	}
4615	impl Sub for Symbolic {
4616		fn sub(self, rhs: Self) -> Self::Output {
4617			_ = rhs;
4618			Symbolic
4619		}
4620	}
4621	impl Mul for Symbolic {
4622		fn mul(self, rhs: Self) -> Self::Output {
4623			_ = rhs;
4624			Symbolic
4625		}
4626	}
4627	impl Div for Symbolic {
4628		fn div(self, rhs: Self) -> Self::Output {
4629			_ = rhs;
4630			Symbolic
4631		}
4632	}
4633	impl Rem for Symbolic {
4634		fn rem(self, rhs: Self) -> Self::Output {
4635			_ = rhs;
4636			Symbolic
4637		}
4638	}
4639});
4640impl_assign_op!({
4641	impl AddAssign for Symbolic {
4642		fn add_assign(&mut self, rhs: Self) {
4643			_ = rhs;
4644		}
4645	}
4646	impl SubAssign for Symbolic {
4647		fn sub_assign(&mut self, rhs: Self) {
4648			_ = rhs;
4649		}
4650	}
4651	impl MulAssign for Symbolic {
4652		fn mul_assign(&mut self, rhs: Self) {
4653			_ = rhs;
4654		}
4655	}
4656	impl DivAssign for Symbolic {
4657		fn div_assign(&mut self, rhs: Self) {
4658			_ = rhs;
4659		}
4660	}
4661	impl RemAssign for Symbolic {
4662		fn rem_assign(&mut self, rhs: Self) {
4663			_ = rhs;
4664		}
4665	}
4666});
4667impl core::ops::Neg for Symbolic {
4668	type Output = Self;
4669
4670	fn neg(self) -> Self {
4671		Self
4672	}
4673}
4674impl core::ops::Neg for &Symbolic {
4675	type Output = Symbolic;
4676
4677	fn neg(self) -> Symbolic {
4678		Symbolic
4679	}
4680}
4681impl num_traits::Zero for Symbolic {
4682	fn zero() -> Self {
4683		Self
4684	}
4685
4686	fn is_zero(&self) -> bool {
4687		true
4688	}
4689}
4690impl num_traits::One for Symbolic {
4691	fn one() -> Self {
4692		Self
4693	}
4694
4695	fn is_one(&self) -> bool {
4696		true
4697	}
4698}
4699impl num_traits::Num for Symbolic {
4700	type FromStrRadixErr = core::convert::Infallible;
4701
4702	fn from_str_radix(_: &str, _: u32) -> Result<Self, Self::FromStrRadixErr> {
4703		Ok(Self)
4704	}
4705}
4706impl Symbolic {
4707	#[inline]
4708	pub fn materialize(len: usize) -> &'static mut [Self] {
4709		unsafe {
4710			core::slice::from_raw_parts_mut(
4711				core::ptr::NonNull::dangling().as_ptr(),
4712				len,
4713			)
4714		}
4715	}
4716}
4717impl RealField for Symbolic {
4718	fn epsilon_impl() -> Self {
4719		Self
4720	}
4721
4722	fn nbits_impl() -> usize {
4723		0
4724	}
4725
4726	fn min_positive_impl() -> Self {
4727		Self
4728	}
4729
4730	fn max_positive_impl() -> Self {
4731		Self
4732	}
4733
4734	fn sqrt_min_positive_impl() -> Self {
4735		Self
4736	}
4737
4738	fn sqrt_max_positive_impl() -> Self {
4739		Self
4740	}
4741}
4742impl ComplexField for Symbolic {
4743	type Arch = pulp::Scalar;
4744	type Index = usize;
4745	type Real = Self;
4746	type SimdCtx<S: pulp::Simd> = S;
4747	type SimdIndex<S: pulp::Simd> = ();
4748	type SimdMask<S: pulp::Simd> = ();
4749	type SimdMemMask<S: pulp::Simd> = ();
4750	type SimdVec<S: pulp::Simd> = ();
4751	type Unit = Self;
4752
4753	const IS_REAL: bool = true;
4754	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Copy;
4755
4756	fn zero_impl() -> Self {
4757		Self
4758	}
4759
4760	fn one_impl() -> Self {
4761		Self
4762	}
4763
4764	fn nan_impl() -> Self {
4765		Self
4766	}
4767
4768	fn infinity_impl() -> Self {
4769		Self
4770	}
4771
4772	fn from_real_impl(_: &Self::Real) -> Self {
4773		Self
4774	}
4775
4776	fn from_f64_impl(_: f64) -> Self {
4777		Self
4778	}
4779
4780	fn real_part_impl(_: &Self) -> Self::Real {
4781		Self
4782	}
4783
4784	fn imag_part_impl(_: &Self) -> Self::Real {
4785		Self
4786	}
4787
4788	fn copy_impl(_: &Self) -> Self {
4789		Self
4790	}
4791
4792	fn conj_impl(_: &Self) -> Self {
4793		Self
4794	}
4795
4796	fn recip_impl(_: &Self) -> Self {
4797		Self
4798	}
4799
4800	fn sqrt_impl(_: &Self) -> Self {
4801		Self
4802	}
4803
4804	fn abs_impl(_: &Self) -> Self::Real {
4805		Self
4806	}
4807
4808	fn abs1_impl(_: &Self) -> Self::Real {
4809		Self
4810	}
4811
4812	fn abs2_impl(_: &Self) -> Self::Real {
4813		Self
4814	}
4815
4816	fn mul_real_impl(_: &Self, _: &Self::Real) -> Self {
4817		Self
4818	}
4819
4820	fn mul_pow2_impl(_: &Self, _: &Self::Real) -> Self {
4821		Self
4822	}
4823
4824	fn is_finite_impl(_: &Self) -> bool {
4825		true
4826	}
4827
4828	fn simd_ctx<S: pulp::Simd>(simd: S) -> Self::SimdCtx<S> {
4829		simd
4830	}
4831
4832	fn ctx_from_simd<S: pulp::Simd>(simd: &Self::SimdCtx<S>) -> S {
4833		*simd
4834	}
4835
4836	fn simd_mem_mask_between<S: pulp::Simd>(
4837		_: &Self::SimdCtx<S>,
4838		_: Self::Index,
4839		_: Self::Index,
4840	) -> Self::SimdMemMask<S> {
4841		()
4842	}
4843
4844	unsafe fn simd_mask_load_raw<S: pulp::Simd>(
4845		_: &Self::SimdCtx<S>,
4846		_: Self::SimdMemMask<S>,
4847		_: *const Self::SimdVec<S>,
4848	) -> Self::SimdVec<S> {
4849		()
4850	}
4851
4852	unsafe fn simd_mask_store_raw<S: pulp::Simd>(
4853		_: &Self::SimdCtx<S>,
4854		_: Self::SimdMemMask<S>,
4855		_: *mut Self::SimdVec<S>,
4856		_: Self::SimdVec<S>,
4857	) {
4858		()
4859	}
4860
4861	fn simd_splat<S: pulp::Simd>(
4862		_: &Self::SimdCtx<S>,
4863		_: &Self,
4864	) -> Self::SimdVec<S> {
4865		()
4866	}
4867
4868	fn simd_splat_real<S: pulp::Simd>(
4869		_: &Self::SimdCtx<S>,
4870		_: &Self::Real,
4871	) -> Self::SimdVec<S> {
4872		()
4873	}
4874
4875	fn simd_add<S: pulp::Simd>(
4876		_: &Self::SimdCtx<S>,
4877		_: Self::SimdVec<S>,
4878		_: Self::SimdVec<S>,
4879	) -> Self::SimdVec<S> {
4880		()
4881	}
4882
4883	fn simd_sub<S: pulp::Simd>(
4884		_: &Self::SimdCtx<S>,
4885		_: Self::SimdVec<S>,
4886		_: Self::SimdVec<S>,
4887	) -> Self::SimdVec<S> {
4888		()
4889	}
4890
4891	fn simd_neg<S: pulp::Simd>(
4892		_: &Self::SimdCtx<S>,
4893		_: Self::SimdVec<S>,
4894	) -> Self::SimdVec<S> {
4895		()
4896	}
4897
4898	fn simd_conj<S: pulp::Simd>(
4899		_: &Self::SimdCtx<S>,
4900		_: Self::SimdVec<S>,
4901	) -> Self::SimdVec<S> {
4902		()
4903	}
4904
4905	fn simd_abs1<S: pulp::Simd>(
4906		_: &Self::SimdCtx<S>,
4907		_: Self::SimdVec<S>,
4908	) -> Self::SimdVec<S> {
4909		()
4910	}
4911
4912	fn simd_abs_max<S: pulp::Simd>(
4913		_: &Self::SimdCtx<S>,
4914		_: Self::SimdVec<S>,
4915	) -> Self::SimdVec<S> {
4916		()
4917	}
4918
4919	fn simd_mul_real<S: pulp::Simd>(
4920		_: &Self::SimdCtx<S>,
4921		_: Self::SimdVec<S>,
4922		_: Self::SimdVec<S>,
4923	) -> Self::SimdVec<S> {
4924		()
4925	}
4926
4927	fn simd_mul_pow2<S: pulp::Simd>(
4928		_: &Self::SimdCtx<S>,
4929		_: Self::SimdVec<S>,
4930		_: Self::SimdVec<S>,
4931	) -> Self::SimdVec<S> {
4932		()
4933	}
4934
4935	fn simd_mul<S: pulp::Simd>(
4936		_: &Self::SimdCtx<S>,
4937		_: Self::SimdVec<S>,
4938		_: Self::SimdVec<S>,
4939	) -> Self::SimdVec<S> {
4940		()
4941	}
4942
4943	fn simd_conj_mul<S: pulp::Simd>(
4944		_: &Self::SimdCtx<S>,
4945		_: Self::SimdVec<S>,
4946		_: Self::SimdVec<S>,
4947	) -> Self::SimdVec<S> {
4948		()
4949	}
4950
4951	fn simd_mul_add<S: pulp::Simd>(
4952		_: &Self::SimdCtx<S>,
4953		_: Self::SimdVec<S>,
4954		_: Self::SimdVec<S>,
4955		_: Self::SimdVec<S>,
4956	) -> Self::SimdVec<S> {
4957		()
4958	}
4959
4960	fn simd_conj_mul_add<S: pulp::Simd>(
4961		_: &Self::SimdCtx<S>,
4962		_: Self::SimdVec<S>,
4963		_: Self::SimdVec<S>,
4964		_: Self::SimdVec<S>,
4965	) -> Self::SimdVec<S> {
4966		()
4967	}
4968
4969	fn simd_abs2<S: pulp::Simd>(
4970		_: &Self::SimdCtx<S>,
4971		_: Self::SimdVec<S>,
4972	) -> Self::SimdVec<S> {
4973		()
4974	}
4975
4976	fn simd_abs2_add<S: pulp::Simd>(
4977		_: &Self::SimdCtx<S>,
4978		_: Self::SimdVec<S>,
4979		_: Self::SimdVec<S>,
4980	) -> Self::SimdVec<S> {
4981		()
4982	}
4983
4984	fn simd_reduce_sum<S: pulp::Simd>(
4985		_: &Self::SimdCtx<S>,
4986		_: Self::SimdVec<S>,
4987	) -> Self {
4988		Self
4989	}
4990
4991	fn simd_reduce_max<S: pulp::Simd>(
4992		_: &Self::SimdCtx<S>,
4993		_: Self::SimdVec<S>,
4994	) -> Self {
4995		Self
4996	}
4997
4998	fn simd_equal<S: pulp::Simd>(
4999		_: &Self::SimdCtx<S>,
5000		_: Self::SimdVec<S>,
5001		_: Self::SimdVec<S>,
5002	) -> Self::SimdMask<S> {
5003		()
5004	}
5005
5006	fn simd_less_than<S: pulp::Simd>(
5007		_: &Self::SimdCtx<S>,
5008		_: Self::SimdVec<S>,
5009		_: Self::SimdVec<S>,
5010	) -> Self::SimdMask<S> {
5011		()
5012	}
5013
5014	fn simd_less_than_or_equal<S: pulp::Simd>(
5015		_: &Self::SimdCtx<S>,
5016		_: Self::SimdVec<S>,
5017		_: Self::SimdVec<S>,
5018	) -> Self::SimdMask<S> {
5019		()
5020	}
5021
5022	fn simd_greater_than<S: pulp::Simd>(
5023		_: &Self::SimdCtx<S>,
5024		_: Self::SimdVec<S>,
5025		_: Self::SimdVec<S>,
5026	) -> Self::SimdMask<S> {
5027		()
5028	}
5029
5030	fn simd_greater_than_or_equal<S: pulp::Simd>(
5031		_: &Self::SimdCtx<S>,
5032		_: Self::SimdVec<S>,
5033		_: Self::SimdVec<S>,
5034	) -> Self::SimdMask<S> {
5035		()
5036	}
5037
5038	fn simd_select<S: pulp::Simd>(
5039		_: &Self::SimdCtx<S>,
5040		_: Self::SimdMask<S>,
5041		_: Self::SimdVec<S>,
5042		_: Self::SimdVec<S>,
5043	) -> Self::SimdVec<S> {
5044		()
5045	}
5046
5047	fn simd_index_select<S: pulp::Simd>(
5048		_: &Self::SimdCtx<S>,
5049		_: Self::SimdMask<S>,
5050		_: Self::SimdIndex<S>,
5051		_: Self::SimdIndex<S>,
5052	) -> Self::SimdIndex<S> {
5053		()
5054	}
5055
5056	fn simd_index_splat<S: pulp::Simd>(
5057		_: &Self::SimdCtx<S>,
5058		_: Self::Index,
5059	) -> Self::SimdIndex<S> {
5060		()
5061	}
5062
5063	fn simd_index_add<S: pulp::Simd>(
5064		_: &Self::SimdCtx<S>,
5065		_: Self::SimdIndex<S>,
5066		_: Self::SimdIndex<S>,
5067	) -> Self::SimdIndex<S> {
5068		()
5069	}
5070
5071	fn simd_and_mask<S: pulp::Simd>(
5072		_: &Self::SimdCtx<S>,
5073		_: Self::SimdMask<S>,
5074		_: Self::SimdMask<S>,
5075	) -> Self::SimdMask<S> {
5076		()
5077	}
5078
5079	fn simd_or_mask<S: pulp::Simd>(
5080		_: &Self::SimdCtx<S>,
5081		_: Self::SimdMask<S>,
5082		_: Self::SimdMask<S>,
5083	) -> Self::SimdMask<S> {
5084		()
5085	}
5086
5087	fn simd_not_mask<S: Simd>(
5088		_: &Self::SimdCtx<S>,
5089		_: Self::SimdMask<S>,
5090	) -> Self::SimdMask<S> {
5091		()
5092	}
5093
5094	fn simd_first_true_mask<S: pulp::Simd>(
5095		_: &Self::SimdCtx<S>,
5096		_: Self::SimdMask<S>,
5097	) -> usize {
5098		0
5099	}
5100
5101	fn simd_mask_between<S: Simd>(
5102		_: &Self::SimdCtx<S>,
5103		_: Self::Index,
5104		_: Self::Index,
5105	) -> Self::SimdMask<S> {
5106		()
5107	}
5108
5109	fn simd_index_less_than<S: Simd>(
5110		_: &Self::SimdCtx<S>,
5111		_: Self::SimdIndex<S>,
5112		_: Self::SimdIndex<S>,
5113	) -> Self::SimdMask<S> {
5114		()
5115	}
5116}
5117pub type c64 = Complex<f64>;
5118pub type c32 = Complex<f32>;
5119pub type fx128 = qd::Quad;
5120pub type cx128 = Complex<fx128>;
5121pub extern crate num_traits;
5122pub extern crate pulp;
5123impl ComplexField for fx128 {
5124	type Arch = pulp::Arch;
5125	type Index = u64;
5126	type Real = Self;
5127	type SimdCtx<S: Simd> = S;
5128	type SimdIndex<S: Simd> = S::u64s;
5129	type SimdMask<S: Simd> = S::m64s;
5130	type SimdMemMask<S: Simd> = Quad<pulp::MemMask<S::m64s>>;
5131	type SimdVec<S: Simd> = Quad<S::f64s>;
5132	type Unit = f64;
5133
5134	const IS_REAL: bool = true;
5135	const SIMD_CAPABILITIES: SimdCapabilities = SimdCapabilities::Simd;
5136
5137	#[inline(always)]
5138	fn zero_impl() -> Self {
5139		Self::ZERO
5140	}
5141
5142	#[inline(always)]
5143	fn one_impl() -> Self {
5144		Quad(1.0, 0.0)
5145	}
5146
5147	#[inline(always)]
5148	fn nan_impl() -> Self {
5149		Self::NAN
5150	}
5151
5152	#[inline(always)]
5153	fn infinity_impl() -> Self {
5154		Self::INFINITY
5155	}
5156
5157	#[inline(always)]
5158	fn from_real_impl(real: &Self::Real) -> Self {
5159		*real
5160	}
5161
5162	#[inline(always)]
5163	fn from_f64_impl(real: f64) -> Self {
5164		real.into()
5165	}
5166
5167	#[inline(always)]
5168	fn real_part_impl(value: &Self) -> Self::Real {
5169		*value
5170	}
5171
5172	#[inline(always)]
5173	fn imag_part_impl(_: &Self) -> Self::Real {
5174		Self::ZERO
5175	}
5176
5177	#[inline(always)]
5178	fn copy_impl(value: &Self) -> Self {
5179		*value
5180	}
5181
5182	#[inline(always)]
5183	fn conj_impl(value: &Self) -> Self {
5184		*value
5185	}
5186
5187	#[inline(always)]
5188	fn recip_impl(value: &Self) -> Self {
5189		if value.0.abs() == f64::INFINITY {
5190			Quad::ZERO
5191		} else {
5192			Quad::from(1.0) / *value
5193		}
5194	}
5195
5196	#[inline(always)]
5197	fn sqrt_impl(value: &Self) -> Self {
5198		value.sqrt()
5199	}
5200
5201	#[inline(always)]
5202	fn abs_impl(value: &Self) -> Self::Real {
5203		value.abs()
5204	}
5205
5206	#[inline(always)]
5207	fn abs1_impl(value: &Self) -> Self::Real {
5208		value.abs()
5209	}
5210
5211	#[inline(always)]
5212	fn abs2_impl(value: &Self) -> Self::Real {
5213		value * value
5214	}
5215
5216	#[inline(always)]
5217	fn mul_real_impl(lhs: &Self, rhs: &Self::Real) -> Self {
5218		lhs * rhs
5219	}
5220
5221	#[inline(always)]
5222	fn mul_pow2_impl(lhs: &Self, rhs: &Self::Real) -> Self {
5223		lhs * rhs
5224	}
5225
5226	#[inline(always)]
5227	fn is_finite_impl(value: &Self) -> bool {
5228		value.0.is_finite() && value.1.is_finite()
5229	}
5230
5231	#[inline(always)]
5232	fn simd_ctx<S: Simd>(simd: S) -> Self::SimdCtx<S> {
5233		simd
5234	}
5235
5236	#[inline(always)]
5237	fn ctx_from_simd<S: Simd>(ctx: &Self::SimdCtx<S>) -> S {
5238		*ctx
5239	}
5240
5241	#[inline(always)]
5242	fn simd_mask_between<S: Simd>(
5243		ctx: &Self::SimdCtx<S>,
5244		start: Self::Index,
5245		end: Self::Index,
5246	) -> Self::SimdMask<S> {
5247		ctx.mask_between_m64s(start as _, end as _).mask()
5248	}
5249
5250	#[inline(always)]
5251	fn simd_mem_mask_between<S: Simd>(
5252		ctx: &Self::SimdCtx<S>,
5253		start: Self::Index,
5254		end: Self::Index,
5255	) -> Self::SimdMemMask<S> {
5256		let n = (core::mem::size_of::<Self::SimdVec<S>>()
5257			/ core::mem::size_of::<Self>()) as u64;
5258		let start = start * 2;
5259		let end = end * 2;
5260		let mut sa = start.min(n);
5261		let mut ea = end.min(n);
5262		let mut sb = start.max(n) - n;
5263		let mut eb = end.max(n) - n;
5264		if sa == ea {
5265			sa = 0;
5266			ea = 0;
5267		}
5268		if sb == eb {
5269			sb = 0;
5270			eb = 0;
5271		}
5272		let a = f64::simd_mem_mask_between(ctx, sa, ea);
5273		let b = f64::simd_mem_mask_between(ctx, sb, eb);
5274		Quad(a, b)
5275	}
5276
5277	#[inline(always)]
5278	unsafe fn simd_mask_load_raw<S: Simd>(
5279		ctx: &Self::SimdCtx<S>,
5280		mask: Self::SimdMemMask<S>,
5281		ptr: *const Self::SimdVec<S>,
5282	) -> Self::SimdVec<S> {
5283		unsafe {
5284			Quad(
5285				f64::simd_mask_load_raw(ctx, mask.0, &raw const (*ptr).0),
5286				f64::simd_mask_load_raw(ctx, mask.1, &raw const (*ptr).1),
5287			)
5288		}
5289	}
5290
5291	#[inline(always)]
5292	unsafe fn simd_mask_store_raw<S: Simd>(
5293		ctx: &Self::SimdCtx<S>,
5294		mask: Self::SimdMemMask<S>,
5295		ptr: *mut Self::SimdVec<S>,
5296		values: Self::SimdVec<S>,
5297	) {
5298		unsafe {
5299			Quad(
5300				f64::simd_mask_store_raw(
5301					ctx,
5302					mask.0,
5303					&raw mut (*ptr).0,
5304					values.0,
5305				),
5306				f64::simd_mask_store_raw(
5307					ctx,
5308					mask.1,
5309					&raw mut (*ptr).1,
5310					values.1,
5311				),
5312			);
5313		}
5314	}
5315
5316	#[inline(always)]
5317	fn simd_splat<S: Simd>(
5318		ctx: &Self::SimdCtx<S>,
5319		value: &Self,
5320	) -> Self::SimdVec<S> {
5321		Quad(ctx.splat_f64s(value.0), ctx.splat_f64s(value.1))
5322	}
5323
5324	#[inline(always)]
5325	fn simd_splat_real<S: Simd>(
5326		ctx: &Self::SimdCtx<S>,
5327		value: &Self::Real,
5328	) -> Self::SimdVec<S> {
5329		Quad(ctx.splat_f64s(value.0), ctx.splat_f64s(value.1))
5330	}
5331
5332	#[inline(always)]
5333	fn simd_add<S: Simd>(
5334		ctx: &Self::SimdCtx<S>,
5335		lhs: Self::SimdVec<S>,
5336		rhs: Self::SimdVec<S>,
5337	) -> Self::SimdVec<S> {
5338		qd::simd::add_estimate(*ctx, lhs, rhs)
5339	}
5340
5341	#[inline(always)]
5342	fn simd_sub<S: Simd>(
5343		ctx: &Self::SimdCtx<S>,
5344		lhs: Self::SimdVec<S>,
5345		rhs: Self::SimdVec<S>,
5346	) -> Self::SimdVec<S> {
5347		qd::simd::sub_estimate(*ctx, lhs, rhs)
5348	}
5349
5350	#[inline(always)]
5351	fn simd_neg<S: Simd>(
5352		ctx: &Self::SimdCtx<S>,
5353		value: Self::SimdVec<S>,
5354	) -> Self::SimdVec<S> {
5355		qd::simd::neg(*ctx, value)
5356	}
5357
5358	#[inline(always)]
5359	fn simd_conj<S: Simd>(
5360		_: &Self::SimdCtx<S>,
5361		value: Self::SimdVec<S>,
5362	) -> Self::SimdVec<S> {
5363		value
5364	}
5365
5366	#[inline(always)]
5367	fn simd_abs1<S: Simd>(
5368		ctx: &Self::SimdCtx<S>,
5369		value: Self::SimdVec<S>,
5370	) -> Self::SimdVec<S> {
5371		qd::simd::abs(*ctx, value)
5372	}
5373
5374	#[inline(always)]
5375	fn simd_abs_max<S: Simd>(
5376		ctx: &Self::SimdCtx<S>,
5377		value: Self::SimdVec<S>,
5378	) -> Self::SimdVec<S> {
5379		qd::simd::abs(*ctx, value)
5380	}
5381
5382	#[inline(always)]
5383	fn simd_mul_real<S: Simd>(
5384		ctx: &Self::SimdCtx<S>,
5385		lhs: Self::SimdVec<S>,
5386		real_rhs: Self::SimdVec<S>,
5387	) -> Self::SimdVec<S> {
5388		qd::simd::mul(*ctx, lhs, real_rhs)
5389	}
5390
5391	#[inline(always)]
5392	fn simd_mul_pow2<S: Simd>(
5393		ctx: &Self::SimdCtx<S>,
5394		lhs: Self::SimdVec<S>,
5395		real_rhs: Self::SimdVec<S>,
5396	) -> Self::SimdVec<S> {
5397		qd::simd::mul(*ctx, lhs, real_rhs)
5398	}
5399
5400	#[inline(always)]
5401	fn simd_mul<S: Simd>(
5402		ctx: &Self::SimdCtx<S>,
5403		lhs: Self::SimdVec<S>,
5404		rhs: Self::SimdVec<S>,
5405	) -> Self::SimdVec<S> {
5406		qd::simd::mul(*ctx, lhs, rhs)
5407	}
5408
5409	#[inline(always)]
5410	fn simd_conj_mul<S: Simd>(
5411		ctx: &Self::SimdCtx<S>,
5412		lhs: Self::SimdVec<S>,
5413		rhs: Self::SimdVec<S>,
5414	) -> Self::SimdVec<S> {
5415		qd::simd::mul(*ctx, lhs, rhs)
5416	}
5417
5418	#[inline(always)]
5419	fn simd_mul_add<S: Simd>(
5420		ctx: &Self::SimdCtx<S>,
5421		lhs: Self::SimdVec<S>,
5422		rhs: Self::SimdVec<S>,
5423		acc: Self::SimdVec<S>,
5424	) -> Self::SimdVec<S> {
5425		qd::simd::add_estimate(*ctx, qd::simd::mul(*ctx, lhs, rhs), acc)
5426	}
5427
5428	#[inline(always)]
5429	fn simd_conj_mul_add<S: Simd>(
5430		ctx: &Self::SimdCtx<S>,
5431		lhs: Self::SimdVec<S>,
5432		rhs: Self::SimdVec<S>,
5433		acc: Self::SimdVec<S>,
5434	) -> Self::SimdVec<S> {
5435		qd::simd::add_estimate(*ctx, qd::simd::mul(*ctx, lhs, rhs), acc)
5436	}
5437
5438	#[inline(always)]
5439	fn simd_abs2<S: Simd>(
5440		ctx: &Self::SimdCtx<S>,
5441		value: Self::SimdVec<S>,
5442	) -> Self::SimdVec<S> {
5443		qd::simd::mul(*ctx, value, value)
5444	}
5445
5446	#[inline(always)]
5447	fn simd_abs2_add<S: Simd>(
5448		ctx: &Self::SimdCtx<S>,
5449		value: Self::SimdVec<S>,
5450		acc: Self::SimdVec<S>,
5451	) -> Self::SimdVec<S> {
5452		qd::simd::add_estimate(*ctx, qd::simd::mul(*ctx, value, value), acc)
5453	}
5454
5455	#[inline(always)]
5456	fn simd_reduce_sum<S: Simd>(
5457		_: &Self::SimdCtx<S>,
5458		value: Self::SimdVec<S>,
5459	) -> Self {
5460		let a = value.0;
5461		let b = value.1;
5462		let a: &[f64] = bytemuck::cast_slice(core::slice::from_ref(&a));
5463		let b: &[f64] = bytemuck::cast_slice(core::slice::from_ref(&b));
5464		let mut acc = Quad::ZERO;
5465		for (&a, &b) in core::iter::zip(a, b) {
5466			acc += Quad(a, b);
5467		}
5468		acc
5469	}
5470
5471	#[inline(always)]
5472	fn simd_reduce_max<S: Simd>(
5473		_: &Self::SimdCtx<S>,
5474		value: Self::SimdVec<S>,
5475	) -> Self {
5476		let a = value.0;
5477		let b = value.1;
5478		let a: &[f64] = bytemuck::cast_slice(core::slice::from_ref(&a));
5479		let b: &[f64] = bytemuck::cast_slice(core::slice::from_ref(&b));
5480		let mut acc = Quad::NEG_INFINITY;
5481		for (&a, &b) in core::iter::zip(a, b) {
5482			let val = Quad(a, b);
5483			if val > acc {
5484				acc = val
5485			}
5486		}
5487		acc
5488	}
5489
5490	#[inline(always)]
5491	fn simd_equal<S: Simd>(
5492		ctx: &Self::SimdCtx<S>,
5493		real_lhs: Self::SimdVec<S>,
5494		real_rhs: Self::SimdVec<S>,
5495	) -> Self::SimdMask<S> {
5496		qd::simd::eq(*ctx, real_lhs, real_rhs)
5497	}
5498
5499	#[inline(always)]
5500	fn simd_less_than<S: Simd>(
5501		ctx: &Self::SimdCtx<S>,
5502		real_lhs: Self::SimdVec<S>,
5503		real_rhs: Self::SimdVec<S>,
5504	) -> Self::SimdMask<S> {
5505		qd::simd::less_than(*ctx, real_lhs, real_rhs)
5506	}
5507
5508	#[inline(always)]
5509	fn simd_less_than_or_equal<S: Simd>(
5510		ctx: &Self::SimdCtx<S>,
5511		real_lhs: Self::SimdVec<S>,
5512		real_rhs: Self::SimdVec<S>,
5513	) -> Self::SimdMask<S> {
5514		qd::simd::less_than_or_equal(*ctx, real_lhs, real_rhs)
5515	}
5516
5517	#[inline(always)]
5518	fn simd_greater_than<S: Simd>(
5519		ctx: &Self::SimdCtx<S>,
5520		real_lhs: Self::SimdVec<S>,
5521		real_rhs: Self::SimdVec<S>,
5522	) -> Self::SimdMask<S> {
5523		qd::simd::greater_than(*ctx, real_lhs, real_rhs)
5524	}
5525
5526	#[inline(always)]
5527	fn simd_greater_than_or_equal<S: Simd>(
5528		ctx: &Self::SimdCtx<S>,
5529		real_lhs: Self::SimdVec<S>,
5530		real_rhs: Self::SimdVec<S>,
5531	) -> Self::SimdMask<S> {
5532		qd::simd::greater_than_or_equal(*ctx, real_lhs, real_rhs)
5533	}
5534
5535	#[inline(always)]
5536	fn simd_select<S: Simd>(
5537		ctx: &Self::SimdCtx<S>,
5538		mask: Self::SimdMask<S>,
5539		lhs: Self::SimdVec<S>,
5540		rhs: Self::SimdVec<S>,
5541	) -> Self::SimdVec<S> {
5542		Quad(
5543			ctx.select_f64s(mask, lhs.0, rhs.0),
5544			ctx.select_f64s(mask, lhs.1, rhs.1),
5545		)
5546	}
5547
5548	#[inline(always)]
5549	fn simd_index_select<S: Simd>(
5550		ctx: &Self::SimdCtx<S>,
5551		mask: Self::SimdMask<S>,
5552		lhs: Self::SimdIndex<S>,
5553		rhs: Self::SimdIndex<S>,
5554	) -> Self::SimdIndex<S> {
5555		ctx.select_u64s(mask, lhs, rhs)
5556	}
5557
5558	#[inline(always)]
5559	fn simd_index_splat<S: Simd>(
5560		ctx: &Self::SimdCtx<S>,
5561		value: Self::Index,
5562	) -> Self::SimdIndex<S> {
5563		ctx.splat_u64s(value as u64)
5564	}
5565
5566	#[inline(always)]
5567	fn simd_index_add<S: Simd>(
5568		ctx: &Self::SimdCtx<S>,
5569		lhs: Self::SimdIndex<S>,
5570		rhs: Self::SimdIndex<S>,
5571	) -> Self::SimdIndex<S> {
5572		ctx.add_u64s(lhs, rhs)
5573	}
5574
5575	#[inline(always)]
5576	fn simd_index_less_than<S: Simd>(
5577		ctx: &Self::SimdCtx<S>,
5578		lhs: Self::SimdIndex<S>,
5579		rhs: Self::SimdIndex<S>,
5580	) -> Self::SimdMask<S> {
5581		ctx.less_than_u64s(lhs, rhs)
5582	}
5583
5584	#[inline(always)]
5585	fn simd_and_mask<S: Simd>(
5586		ctx: &Self::SimdCtx<S>,
5587		lhs: Self::SimdMask<S>,
5588		rhs: Self::SimdMask<S>,
5589	) -> Self::SimdMask<S> {
5590		ctx.and_m64s(lhs, rhs)
5591	}
5592
5593	#[inline(always)]
5594	fn simd_or_mask<S: Simd>(
5595		ctx: &Self::SimdCtx<S>,
5596		lhs: Self::SimdMask<S>,
5597		rhs: Self::SimdMask<S>,
5598	) -> Self::SimdMask<S> {
5599		ctx.or_m64s(lhs, rhs)
5600	}
5601
5602	#[inline(always)]
5603	fn simd_not_mask<S: Simd>(
5604		ctx: &Self::SimdCtx<S>,
5605		mask: Self::SimdMask<S>,
5606	) -> Self::SimdMask<S> {
5607		ctx.not_m64s(mask)
5608	}
5609
5610	#[inline(always)]
5611	fn simd_first_true_mask<S: Simd>(
5612		ctx: &Self::SimdCtx<S>,
5613		value: Self::SimdMask<S>,
5614	) -> usize {
5615		ctx.first_true_m64s(value)
5616	}
5617}
5618impl RealField for fx128 {
5619	#[inline(always)]
5620	fn epsilon_impl() -> Self {
5621		let mut x = Quad::EPSILON;
5622		x.0 *= 8.0;
5623		x.1 *= 8.0;
5624		x
5625	}
5626
5627	#[inline(always)]
5628	fn nbits_impl() -> usize {
5629		100
5630	}
5631
5632	#[inline(always)]
5633	fn min_positive_impl() -> Self {
5634		Quad::MIN_POSITIVE
5635	}
5636
5637	#[inline(always)]
5638	fn max_positive_impl() -> Self {
5639		Quad::MIN_POSITIVE.recip()
5640	}
5641
5642	#[inline(always)]
5643	fn sqrt_min_positive_impl() -> Self {
5644		Quad::MIN_POSITIVE.sqrt()
5645	}
5646
5647	#[inline(always)]
5648	fn sqrt_max_positive_impl() -> Self {
5649		Quad::MIN_POSITIVE.recip().sqrt()
5650	}
5651}
5652pub mod ext {
5653	use super::*;
5654	pub use super::{ComplexField, RealField};
5655	pub trait ComplexFieldExt: ComplexField {
5656		#[inline(always)]
5657		#[must_use]
5658		fn nbits() -> usize {
5659			Self::Real::nbits_impl()
5660		}
5661		#[inline(always)]
5662		#[must_use]
5663		fn zero() -> Self {
5664			Self::zero_impl()
5665		}
5666		#[inline(always)]
5667		#[must_use]
5668		fn one() -> Self {
5669			Self::one_impl()
5670		}
5671		#[inline(always)]
5672		#[must_use]
5673		fn nan() -> Self {
5674			Self::nan_impl()
5675		}
5676		#[inline(always)]
5677		#[must_use]
5678		fn infinity() -> Self {
5679			Self::infinity_impl()
5680		}
5681		#[inline(always)]
5682		#[must_use]
5683		fn as_real(&self) -> Self {
5684			Self::from_real_impl(&Self::real_part_impl(self))
5685		}
5686		#[inline(always)]
5687		#[must_use]
5688		fn real(&self) -> Self::Real {
5689			Self::real_part_impl(self)
5690		}
5691		#[inline(always)]
5692		#[must_use]
5693		fn imag(&self) -> Self::Real {
5694			Self::imag_part_impl(self)
5695		}
5696		#[inline(always)]
5697		#[must_use]
5698		fn copy(&self) -> Self {
5699			Self::copy_impl(self)
5700		}
5701		#[inline(always)]
5702		#[must_use]
5703		fn conj(&self) -> Self {
5704			Self::conj_impl(self)
5705		}
5706		#[inline(always)]
5707		#[must_use]
5708		fn mul_real(&self, rhs: impl ByRef<Self::Real>) -> Self {
5709			Self::mul_real_impl(self, rhs.by_ref())
5710		}
5711		#[inline(always)]
5712		#[must_use]
5713		fn mul_pow2(&self, rhs: impl ByRef<Self::Real>) -> Self {
5714			Self::mul_real_impl(self, rhs.by_ref())
5715		}
5716		#[inline(always)]
5717		#[must_use]
5718		fn abs1(&self) -> Self::Real {
5719			Self::abs1_impl(self)
5720		}
5721		#[inline(always)]
5722		#[must_use]
5723		fn absmax(&self) -> Self::Real {
5724			if const { Self::IS_REAL } {
5725				Self::abs1_impl(self)
5726			} else {
5727				&Self::Real::abs1_impl(&real(self))
5728					+ &Self::Real::abs1_impl(&imag(self))
5729			}
5730		}
5731		#[inline(always)]
5732		#[must_use]
5733		fn abs(&self) -> Self::Real {
5734			Self::abs_impl(self)
5735		}
5736		#[inline(always)]
5737		#[must_use]
5738		fn abs2(&self) -> Self::Real {
5739			Self::abs2_impl(self)
5740		}
5741		#[inline(always)]
5742		#[must_use]
5743		fn is_nan(&self) -> bool {
5744			Self::is_nan_impl(self)
5745		}
5746		#[inline(always)]
5747		#[must_use]
5748		fn is_finite(&self) -> bool {
5749			Self::is_finite_impl(self)
5750		}
5751		#[inline(always)]
5752		#[must_use]
5753		fn sqrt(&self) -> Self {
5754			Self::sqrt_impl(self)
5755		}
5756		#[inline(always)]
5757		#[must_use]
5758		fn recip(&self) -> Self {
5759			Self::recip_impl(self)
5760		}
5761		#[inline(always)]
5762		#[must_use]
5763		fn from_f64(value: f64) -> Self {
5764			Self::from_f64_impl(value)
5765		}
5766	}
5767	pub trait RealFieldExt: RealField {
5768		#[inline(always)]
5769		#[must_use]
5770		fn eps<T: RealField>() -> T {
5771			T::Real::epsilon_impl()
5772		}
5773		#[inline(always)]
5774		#[must_use]
5775		fn nbits<T: ComplexField>() -> usize {
5776			T::Real::nbits_impl()
5777		}
5778		#[inline(always)]
5779		#[must_use]
5780		fn min_positive<T: RealField>() -> T {
5781			T::min_positive_impl()
5782		}
5783		#[inline(always)]
5784		#[must_use]
5785		fn max_positive<T: RealField>() -> T {
5786			T::max_positive_impl()
5787		}
5788		#[inline(always)]
5789		#[must_use]
5790		fn sqrt_min_positive<T: RealField>() -> T {
5791			T::sqrt_min_positive_impl()
5792		}
5793		#[inline(always)]
5794		#[must_use]
5795		fn sqrt_max_positive<T: RealField>() -> T {
5796			T::sqrt_max_positive_impl()
5797		}
5798		#[inline(always)]
5799		#[must_use]
5800		fn to_cplx<T: ComplexField<Real = Self>>(&self) -> T {
5801			T::from_real_impl(self)
5802		}
5803		#[inline(always)]
5804		#[must_use]
5805		fn fmax(&self, rhs: impl ByRef<Self>) -> Self {
5806			math_utils::max(self, rhs.by_ref())
5807		}
5808		#[inline(always)]
5809		#[must_use]
5810		fn fmin(&self, rhs: impl ByRef<Self>) -> Self {
5811			math_utils::min(self, rhs.by_ref())
5812		}
5813		#[inline(always)]
5814		#[must_use]
5815		fn hypot(&self, rhs: impl ByRef<Self>) -> Self {
5816			math_utils::hypot(self, rhs.by_ref())
5817		}
5818	}
5819	impl<T: ComplexField> ComplexFieldExt for T {}
5820	impl<T: RealField> RealFieldExt for T {}
5821}
5822#[cfg(test)]
5823mod tests {
5824	use super::*;
5825	/// the reciprocal of a subnormal complex value is finite whenever the
5826	/// exact result is (`tensor4all/faer#31`)
5827	#[test]
5828	fn recip_of_subnormal() {
5829		let (re, im) = recip_impl(0.0f64, f64::MIN_POSITIVE / 2.0);
5830		assert_eq!((re, im), (0.0, -2.0 / f64::MIN_POSITIVE));
5831		let (re, im) = recip_impl(f64::MIN_POSITIVE / 4.0, 0.0);
5832		assert_eq!((re, im), (4.0 / f64::MIN_POSITIVE, 0.0));
5833		let (re, im) = recip_impl(0.0f32, f32::MIN_POSITIVE / 2.0);
5834		assert_eq!((re, im), (0.0, -2.0 / f32::MIN_POSITIVE));
5835		// 1 / 2^-1074 exceeds the largest finite value
5836		let (re, _) = recip_impl(f64::from_bits(1), 0.0);
5837		assert_eq!(re, f64::INFINITY);
5838	}
5839}