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