WPILibC++ 2023.4.3
Complex.h
Go to the documentation of this file.
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2010 Konstantinos Margaritis <markos@freevec.org>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_COMPLEX_NEON_H
12#define EIGEN_COMPLEX_NEON_H
13
14namespace Eigen {
15
16namespace internal {
17
18inline uint32x4_t p4ui_CONJ_XOR()
19{
20// See bug 1325, clang fails to call vld1q_u64.
21#if EIGEN_COMP_CLANG || EIGEN_COMP_CASTXML
22 uint32x4_t ret = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
23 return ret;
24#else
25 static const uint32_t conj_XOR_DATA[] = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
26 return vld1q_u32( conj_XOR_DATA );
27#endif
28}
29
30inline uint32x2_t p2ui_CONJ_XOR()
31{
32 static const uint32_t conj_XOR_DATA[] = { 0x00000000, 0x80000000 };
33 return vld1_u32( conj_XOR_DATA );
34}
35
36//---------- float ----------
37
39{
41 EIGEN_STRONG_INLINE explicit Packet1cf(const Packet2f& a) : v(a) {}
43};
44struct Packet2cf
45{
47 EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
48 Packet4f v;
49};
50
51template<> struct packet_traits<std::complex<float> > : default_packet_traits
52{
53 typedef Packet2cf type;
54 typedef Packet1cf half;
55 enum
56 {
57 Vectorizable = 1,
59 size = 2,
60 HasHalfPacket = 1,
61
62 HasAdd = 1,
63 HasSub = 1,
64 HasMul = 1,
65 HasDiv = 1,
66 HasNegate = 1,
67 HasAbs = 0,
68 HasAbs2 = 0,
69 HasMin = 0,
70 HasMax = 0,
71 HasSetLinear = 0
72 };
73};
74
75template<> struct unpacket_traits<Packet1cf>
76{
77 typedef std::complex<float> type;
78 typedef Packet1cf half;
80 enum
81 {
82 size = 1,
87 };
88};
89template<> struct unpacket_traits<Packet2cf>
90{
91 typedef std::complex<float> type;
92 typedef Packet1cf half;
94 enum
95 {
96 size = 2,
98 vectorizable = true,
101 };
102};
103
105{ return Packet1cf(vset_lane_f32(a, vdup_n_f32(0.f), 0)); }
107{ return Packet2cf(vreinterpretq_f32_u64(vmovl_u32(vreinterpret_u32_f32(a)))); }
108
109template<> EIGEN_STRONG_INLINE Packet1cf pset1<Packet1cf>(const std::complex<float>& from)
110{ return Packet1cf(vld1_f32(reinterpret_cast<const float*>(&from))); }
111template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
112{
113 const float32x2_t r64 = vld1_f32(reinterpret_cast<const float*>(&from));
114 return Packet2cf(vcombine_f32(r64, r64));
115}
116
118{ return Packet1cf(padd<Packet2f>(a.v, b.v)); }
120{ return Packet2cf(padd<Packet4f>(a.v, b.v)); }
121
123{ return Packet1cf(psub<Packet2f>(a.v, b.v)); }
125{ return Packet2cf(psub<Packet4f>(a.v, b.v)); }
126
127template<> EIGEN_STRONG_INLINE Packet1cf pnegate(const Packet1cf& a) { return Packet1cf(pnegate<Packet2f>(a.v)); }
128template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate<Packet4f>(a.v)); }
129
131{
132 const Packet2ui b = vreinterpret_u32_f32(a.v);
133 return Packet1cf(vreinterpret_f32_u32(veor_u32(b, p2ui_CONJ_XOR())));
134}
136{
137 const Packet4ui b = vreinterpretq_u32_f32(a.v);
138 return Packet2cf(vreinterpretq_f32_u32(veorq_u32(b, p4ui_CONJ_XOR())));
139}
140
142{
143 Packet2f v1, v2;
144
145 // Get the real values of a | a1_re | a1_re |
146 v1 = vdup_lane_f32(a.v, 0);
147 // Get the imag values of a | a1_im | a1_im |
148 v2 = vdup_lane_f32(a.v, 1);
149 // Multiply the real a with b
150 v1 = vmul_f32(v1, b.v);
151 // Multiply the imag a with b
152 v2 = vmul_f32(v2, b.v);
153 // Conjugate v2
154 v2 = vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(v2), p2ui_CONJ_XOR()));
155 // Swap real/imag elements in v2.
156 v2 = vrev64_f32(v2);
157 // Add and return the result
158 return Packet1cf(vadd_f32(v1, v2));
159}
161{
162 Packet4f v1, v2;
163
164 // Get the real values of a | a1_re | a1_re | a2_re | a2_re |
165 v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0));
166 // Get the imag values of a | a1_im | a1_im | a2_im | a2_im |
167 v2 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 1), vdup_lane_f32(vget_high_f32(a.v), 1));
168 // Multiply the real a with b
169 v1 = vmulq_f32(v1, b.v);
170 // Multiply the imag a with b
171 v2 = vmulq_f32(v2, b.v);
172 // Conjugate v2
173 v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR()));
174 // Swap real/imag elements in v2.
175 v2 = vrev64q_f32(v2);
176 // Add and return the result
177 return Packet2cf(vaddq_f32(v1, v2));
178}
179
181{
182 // Compare real and imaginary parts of a and b to get the mask vector:
183 // [re(a[0])==re(b[0]), im(a[0])==im(b[0])]
184 Packet2f eq = pcmp_eq<Packet2f>(a.v, b.v);
185 // Swap real/imag elements in the mask in to get:
186 // [im(a[0])==im(b[0]), re(a[0])==re(b[0])]
187 Packet2f eq_swapped = vrev64_f32(eq);
188 // Return re(a)==re(b) && im(a)==im(b) by computing bitwise AND of eq and eq_swapped
189 return Packet1cf(pand<Packet2f>(eq, eq_swapped));
190}
192{
193 // Compare real and imaginary parts of a and b to get the mask vector:
194 // [re(a[0])==re(b[0]), im(a[0])==im(b[0]), re(a[1])==re(b[1]), im(a[1])==im(b[1])]
195 Packet4f eq = pcmp_eq<Packet4f>(a.v, b.v);
196 // Swap real/imag elements in the mask in to get:
197 // [im(a[0])==im(b[0]), re(a[0])==re(b[0]), im(a[1])==im(b[1]), re(a[1])==re(b[1])]
198 Packet4f eq_swapped = vrev64q_f32(eq);
199 // Return re(a)==re(b) && im(a)==im(b) by computing bitwise AND of eq and eq_swapped
200 return Packet2cf(pand<Packet4f>(eq, eq_swapped));
201}
202
204{ return Packet1cf(vreinterpret_f32_u32(vand_u32(vreinterpret_u32_f32(a.v), vreinterpret_u32_f32(b.v)))); }
206{ return Packet2cf(vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.v), vreinterpretq_u32_f32(b.v)))); }
207
209{ return Packet1cf(vreinterpret_f32_u32(vorr_u32(vreinterpret_u32_f32(a.v), vreinterpret_u32_f32(b.v)))); }
211{ return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v), vreinterpretq_u32_f32(b.v)))); }
212
214{ return Packet1cf(vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(a.v), vreinterpret_u32_f32(b.v)))); }
216{ return Packet2cf(vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a.v), vreinterpretq_u32_f32(b.v)))); }
217
219{ return Packet1cf(vreinterpret_f32_u32(vbic_u32(vreinterpret_u32_f32(a.v), vreinterpret_u32_f32(b.v)))); }
221{ return Packet2cf(vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.v), vreinterpretq_u32_f32(b.v)))); }
222
223template<> EIGEN_STRONG_INLINE Packet1cf pload<Packet1cf>(const std::complex<float>* from)
224{ EIGEN_DEBUG_ALIGNED_LOAD return Packet1cf(pload<Packet2f>((const float*)from)); }
225template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from)
226{ EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(reinterpret_cast<const float*>(from))); }
227
228template<> EIGEN_STRONG_INLINE Packet1cf ploadu<Packet1cf>(const std::complex<float>* from)
230template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from)
231{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(reinterpret_cast<const float*>(from))); }
232
233template<> EIGEN_STRONG_INLINE Packet1cf ploaddup<Packet1cf>(const std::complex<float>* from)
234{ return pset1<Packet1cf>(*from); }
235template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from)
236{ return pset1<Packet2cf>(*from); }
237
238template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *to, const Packet1cf& from)
239{ EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
240template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *to, const Packet2cf& from)
241{ EIGEN_DEBUG_ALIGNED_STORE pstore(reinterpret_cast<float*>(to), from.v); }
242
243template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *to, const Packet1cf& from)
244{ EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
245template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *to, const Packet2cf& from)
246{ EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<float*>(to), from.v); }
247
248template<> EIGEN_DEVICE_FUNC inline Packet1cf pgather<std::complex<float>, Packet1cf>(
249 const std::complex<float>* from, Index stride)
250{
251 const Packet2f tmp = vdup_n_f32(std::real(from[0*stride]));
252 return Packet1cf(vset_lane_f32(std::imag(from[0*stride]), tmp, 1));
253}
254template<> EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(
255 const std::complex<float>* from, Index stride)
256{
257 Packet4f res = vdupq_n_f32(std::real(from[0*stride]));
258 res = vsetq_lane_f32(std::imag(from[0*stride]), res, 1);
259 res = vsetq_lane_f32(std::real(from[1*stride]), res, 2);
260 res = vsetq_lane_f32(std::imag(from[1*stride]), res, 3);
261 return Packet2cf(res);
262}
263
264template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet1cf>(
265 std::complex<float>* to, const Packet1cf& from, Index stride)
266{ to[stride*0] = std::complex<float>(vget_lane_f32(from.v, 0), vget_lane_f32(from.v, 1)); }
267template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf>(
268 std::complex<float>* to, const Packet2cf& from, Index stride)
269{
270 to[stride*0] = std::complex<float>(vgetq_lane_f32(from.v, 0), vgetq_lane_f32(from.v, 1));
271 to[stride*1] = std::complex<float>(vgetq_lane_f32(from.v, 2), vgetq_lane_f32(from.v, 3));
272}
273
274template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *addr)
275{ EIGEN_ARM_PREFETCH(reinterpret_cast<const float*>(addr)); }
276
277template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet1cf>(const Packet1cf& a)
278{
279 EIGEN_ALIGN16 std::complex<float> x;
280 vst1_f32(reinterpret_cast<float*>(&x), a.v);
281 return x;
282}
283template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
284{
285 EIGEN_ALIGN16 std::complex<float> x[2];
286 vst1q_f32(reinterpret_cast<float*>(x), a.v);
287 return x[0];
288}
289
290template<> EIGEN_STRONG_INLINE Packet1cf preverse(const Packet1cf& a) { return a; }
292{ return Packet2cf(vcombine_f32(vget_high_f32(a.v), vget_low_f32(a.v))); }
293
295{ return Packet1cf(vrev64_f32(a.v)); }
297{ return Packet2cf(vrev64q_f32(a.v)); }
298
299template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet1cf>(const Packet1cf& a)
300{
301 std::complex<float> s;
302 vst1_f32((float *)&s, a.v);
303 return s;
304}
305template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a)
306{
307 std::complex<float> s;
308 vst1_f32(reinterpret_cast<float*>(&s), vadd_f32(vget_low_f32(a.v), vget_high_f32(a.v)));
309 return s;
310}
311
312template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet1cf>(const Packet1cf& a)
313{
314 std::complex<float> s;
315 vst1_f32((float *)&s, a.v);
316 return s;
317}
318template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a)
319{
320 float32x2_t a1, a2, v1, v2, prod;
321 std::complex<float> s;
322
323 a1 = vget_low_f32(a.v);
324 a2 = vget_high_f32(a.v);
325 // Get the real values of a | a1_re | a1_re | a2_re | a2_re |
326 v1 = vdup_lane_f32(a1, 0);
327 // Get the real values of a | a1_im | a1_im | a2_im | a2_im |
328 v2 = vdup_lane_f32(a1, 1);
329 // Multiply the real a with b
330 v1 = vmul_f32(v1, a2);
331 // Multiply the imag a with b
332 v2 = vmul_f32(v2, a2);
333 // Conjugate v2
334 v2 = vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(v2), p2ui_CONJ_XOR()));
335 // Swap real/imag elements in v2.
336 v2 = vrev64_f32(v2);
337 // Add v1, v2
338 prod = vadd_f32(v1, v2);
339
340 vst1_f32(reinterpret_cast<float*>(&s), prod);
341
342 return s;
343}
344
347
349{
350 // TODO optimize it for NEON
351 Packet1cf res = pmul(a, pconj(b));
352 Packet2f s, rev_s;
353
354 // this computes the norm
355 s = vmul_f32(b.v, b.v);
356 rev_s = vrev64_f32(s);
357
358 return Packet1cf(pdiv<Packet2f>(res.v, vadd_f32(s, rev_s)));
359}
361{
362 // TODO optimize it for NEON
363 Packet2cf res = pmul(a,pconj(b));
364 Packet4f s, rev_s;
365
366 // this computes the norm
367 s = vmulq_f32(b.v, b.v);
368 rev_s = vrev64q_f32(s);
369
370 return Packet2cf(pdiv<Packet4f>(res.v, vaddq_f32(s, rev_s)));
371}
372
374EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2cf, 2>& kernel)
375{
376 Packet4f tmp = vcombine_f32(vget_high_f32(kernel.packet[0].v), vget_high_f32(kernel.packet[1].v));
377 kernel.packet[0].v = vcombine_f32(vget_low_f32(kernel.packet[0].v), vget_low_f32(kernel.packet[1].v));
378 kernel.packet[1].v = tmp;
379}
380
382 return psqrt_complex<Packet1cf>(a);
383}
384
386 return psqrt_complex<Packet2cf>(a);
387}
388
389//---------- double ----------
390#if EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG
391
392// See bug 1325, clang fails to call vld1q_u64.
393#if EIGEN_COMP_CLANG || EIGEN_COMP_CASTXML
394 static uint64x2_t p2ul_CONJ_XOR = {0x0, 0x8000000000000000};
395#else
396 const uint64_t p2ul_conj_XOR_DATA[] = { 0x0, 0x8000000000000000 };
397 static uint64x2_t p2ul_CONJ_XOR = vld1q_u64( p2ul_conj_XOR_DATA );
398#endif
399
400struct Packet1cd
401{
403 EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {}
404 Packet2d v;
405};
406
407template<> struct packet_traits<std::complex<double> > : default_packet_traits
408{
409 typedef Packet1cd type;
410 typedef Packet1cd half;
411 enum
412 {
413 Vectorizable = 1,
414 AlignedOnScalar = 0,
415 size = 1,
416 HasHalfPacket = 0,
417
418 HasAdd = 1,
419 HasSub = 1,
420 HasMul = 1,
421 HasDiv = 1,
422 HasNegate = 1,
423 HasAbs = 0,
424 HasAbs2 = 0,
425 HasMin = 0,
426 HasMax = 0,
427 HasSetLinear = 0
428 };
429};
430
431template<> struct unpacket_traits<Packet1cd>
432{
433 typedef std::complex<double> type;
434 typedef Packet1cd half;
435 typedef Packet2d as_real;
436 enum
437 {
438 size=1,
440 vectorizable=true,
443 };
444};
445
446template<> EIGEN_STRONG_INLINE Packet1cd pload<Packet1cd>(const std::complex<double>* from)
447{ EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>(reinterpret_cast<const double*>(from))); }
448
449template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from)
450{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>(reinterpret_cast<const double*>(from))); }
451
452template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>& from)
453{
454 /* here we really have to use unaligned loads :( */
455 return ploadu<Packet1cd>(&from);
456}
457
458template<> EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
459{ return Packet1cd(padd<Packet2d>(a.v, b.v)); }
460
461template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
462{ return Packet1cd(psub<Packet2d>(a.v, b.v)); }
463
464template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a)
465{ return Packet1cd(pnegate<Packet2d>(a.v)); }
466
467template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a)
468{ return Packet1cd(vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(a.v), p2ul_CONJ_XOR))); }
469
470template<> EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
471{
472 Packet2d v1, v2;
473
474 // Get the real values of a
475 v1 = vdupq_lane_f64(vget_low_f64(a.v), 0);
476 // Get the imag values of a
477 v2 = vdupq_lane_f64(vget_high_f64(a.v), 0);
478 // Multiply the real a with b
479 v1 = vmulq_f64(v1, b.v);
480 // Multiply the imag a with b
481 v2 = vmulq_f64(v2, b.v);
482 // Conjugate v2
483 v2 = vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(v2), p2ul_CONJ_XOR));
484 // Swap real/imag elements in v2.
485 v2 = preverse<Packet2d>(v2);
486 // Add and return the result
487 return Packet1cd(vaddq_f64(v1, v2));
488}
489
490template<> EIGEN_STRONG_INLINE Packet1cd pcmp_eq(const Packet1cd& a, const Packet1cd& b)
491{
492 // Compare real and imaginary parts of a and b to get the mask vector:
493 // [re(a)==re(b), im(a)==im(b)]
494 Packet2d eq = pcmp_eq<Packet2d>(a.v, b.v);
495 // Swap real/imag elements in the mask in to get:
496 // [im(a)==im(b), re(a)==re(b)]
497 Packet2d eq_swapped = vreinterpretq_f64_u32(vrev64q_u32(vreinterpretq_u32_f64(eq)));
498 // Return re(a)==re(b) & im(a)==im(b) by computing bitwise AND of eq and eq_swapped
499 return Packet1cd(pand<Packet2d>(eq, eq_swapped));
500}
501
502template<> EIGEN_STRONG_INLINE Packet1cd pand<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
503{ return Packet1cd(vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v)))); }
504
505template<> EIGEN_STRONG_INLINE Packet1cd por<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
506{ return Packet1cd(vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v)))); }
507
508template<> EIGEN_STRONG_INLINE Packet1cd pxor<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
509{ return Packet1cd(vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v)))); }
510
511template<> EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
512{ return Packet1cd(vreinterpretq_f64_u64(vbicq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v)))); }
513
514template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from)
515{ return pset1<Packet1cd>(*from); }
516
517template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> *to, const Packet1cd& from)
518{ EIGEN_DEBUG_ALIGNED_STORE pstore(reinterpret_cast<double*>(to), from.v); }
519
520template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> *to, const Packet1cd& from)
521{ EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<double*>(to), from.v); }
522
523template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> *addr)
524{ EIGEN_ARM_PREFETCH(reinterpret_cast<const double*>(addr)); }
525
526template<> EIGEN_DEVICE_FUNC inline Packet1cd pgather<std::complex<double>, Packet1cd>(
527 const std::complex<double>* from, Index stride)
528{
529 Packet2d res = pset1<Packet2d>(0.0);
530 res = vsetq_lane_f64(std::real(from[0*stride]), res, 0);
531 res = vsetq_lane_f64(std::imag(from[0*stride]), res, 1);
532 return Packet1cd(res);
533}
534
535template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet1cd>(
536 std::complex<double>* to, const Packet1cd& from, Index stride)
537{ to[stride*0] = std::complex<double>(vgetq_lane_f64(from.v, 0), vgetq_lane_f64(from.v, 1)); }
538
539template<> EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet1cd>(const Packet1cd& a)
540{
541 EIGEN_ALIGN16 std::complex<double> res;
542 pstore<std::complex<double> >(&res, a);
543 return res;
544}
545
546template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; }
547
548template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
549
550template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
551
553
554template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
555{
556 // TODO optimize it for NEON
557 Packet1cd res = pmul(a,pconj(b));
558 Packet2d s = pmul<Packet2d>(b.v, b.v);
559 Packet2d rev_s = preverse<Packet2d>(s);
560
561 return Packet1cd(pdiv(res.v, padd<Packet2d>(s,rev_s)));
562}
563
564EIGEN_STRONG_INLINE Packet1cd pcplxflip/*<Packet1cd>*/(const Packet1cd& x)
565{ return Packet1cd(preverse(Packet2d(x.v))); }
566
567EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet1cd,2>& kernel)
568{
569 Packet2d tmp = vcombine_f64(vget_high_f64(kernel.packet[0].v), vget_high_f64(kernel.packet[1].v));
570 kernel.packet[0].v = vcombine_f64(vget_low_f64(kernel.packet[0].v), vget_low_f64(kernel.packet[1].v));
571 kernel.packet[1].v = tmp;
572}
573
574template<> EIGEN_STRONG_INLINE Packet1cd psqrt<Packet1cd>(const Packet1cd& a) {
575 return psqrt_complex<Packet1cd>(a);
576}
577
578#endif // EIGEN_ARCH_ARM64
579
580} // end namespace internal
581
582} // end namespace Eigen
583
584#endif // EIGEN_COMPLEX_NEON_H
EIGEN_DEVICE_FUNC RealReturnType real() const
Definition: CommonCwiseUnaryOps.h:100
EIGEN_DEVICE_FUNC const ImagReturnType imag() const
Definition: CommonCwiseUnaryOps.h:109
#define EIGEN_ALIGN16
Definition: ConfigureVectorization.h:153
#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL)
Definition: ConjHelper.h:14
#define EIGEN_DEBUG_ALIGNED_STORE
Definition: GenericPacketMath.h:35
#define EIGEN_DEBUG_ALIGNED_LOAD
Definition: GenericPacketMath.h:27
#define EIGEN_DEBUG_UNALIGNED_STORE
Definition: GenericPacketMath.h:39
#define EIGEN_DEBUG_UNALIGNED_LOAD
Definition: GenericPacketMath.h:31
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:986
#define EIGEN_STRONG_INLINE
Definition: Macros.h:927
#define EIGEN_ARM_PREFETCH(ADDR)
Definition: PacketMath.h:162
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable from
Definition: ThirdPartyNotices.txt:131
@ Aligned16
Data pointer is aligned on a 16 bytes boundary.
Definition: Constants.h:235
EIGEN_STRONG_INLINE std::complex< float > predux< Packet1cf >(const Packet1cf &a)
Definition: Complex.h:299
uint32x2_t p2ui_CONJ_XOR()
Definition: Complex.h:30
EIGEN_STRONG_INLINE std::complex< float > predux_mul< Packet2cf >(const Packet2cf &a)
Definition: Complex.h:163
EIGEN_STRONG_INLINE std::complex< float > predux< Packet2cf >(const Packet2cf &a)
Definition: Complex.h:158
__m128d Packet2d
Definition: PacketMath.h:43
EIGEN_STRONG_INLINE Packet2d padd< Packet2d >(const Packet2d &a, const Packet2d &b)
Definition: PacketMath.h:290
uint32x2_t Packet2ui
Definition: PacketMath.h:76
EIGEN_STRONG_INLINE Packet2f pand< Packet2f >(const Packet2f &a, const Packet2f &b)
Definition: PacketMath.h:1465
EIGEN_STRONG_INLINE Packet2cf psqrt< Packet2cf >(const Packet2cf &a)
Definition: Complex.h:344
EIGEN_STRONG_INLINE Packet4f pcmp_eq< Packet4f >(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:1400
EIGEN_STRONG_INLINE Packet4f padd< Packet4f >(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:289
__m128 Packet4f
Definition: PacketMath.h:42
EIGEN_STRONG_INLINE std::complex< double > predux_mul< Packet1cd >(const Packet1cd &a)
Definition: Complex.h:293
EIGEN_STRONG_INLINE Packet2cf pandnot< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:102
EIGEN_STRONG_INLINE Packet1cf psqrt< Packet1cf >(const Packet1cf &a)
Definition: Complex.h:381
EIGEN_STRONG_INLINE Packet1cf padd< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:117
EIGEN_STRONG_INLINE std::complex< float > pfirst< Packet1cf >(const Packet1cf &a)
Definition: Complex.h:277
EIGEN_STRONG_INLINE Packet2d pand< Packet2d >(const Packet2d &a, const Packet2d &b)
Definition: PacketMath.h:413
EIGEN_STRONG_INLINE Packet2f pcmp_eq< Packet2f >(const Packet2f &a, const Packet2f &b)
Definition: PacketMath.h:1398
EIGEN_STRONG_INLINE Packet1cd psqrt< Packet1cd >(const Packet1cd &a)
Definition: Complex.h:340
EIGEN_STRONG_INLINE Packet1cf por< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:208
EIGEN_STRONG_INLINE Packet2cf ploaddup< Packet2cf >(const std::complex< float > *from)
Definition: Complex.h:119
EIGEN_STRONG_INLINE std::complex< float > predux_mul< Packet1cf >(const Packet1cf &a)
Definition: Complex.h:312
EIGEN_DEVICE_FUNC Packet pdiv(const Packet &a, const Packet &b)
Definition: GenericPacketMath.h:244
EIGEN_DEVICE_FUNC void ptranspose(PacketBlock< Packet4f, 4 > &kernel)
Definition: PacketMath.h:1124
EIGEN_STRONG_INLINE Packet1cf pand< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:203
EIGEN_STRONG_INLINE Packet2cf pmul< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:81
uint32x4_t p4ui_CONJ_XOR()
Definition: Complex.h:18
EIGEN_STRONG_INLINE Packet1cd pmul< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:243
EIGEN_STRONG_INLINE Packet2d pset1< Packet2d >(const double &from)
Definition: PacketMath.h:258
EIGEN_STRONG_INLINE std::complex< float > pfirst< Packet2cf >(const Packet2cf &a)
Definition: Complex.h:141
EIGEN_STRONG_INLINE Packet4f pload< Packet4f >(const float *from)
Definition: PacketMath.h:715
EIGEN_STRONG_INLINE Packet1cd ploadu< Packet1cd >(const std::complex< double > *from)
Definition: Complex.h:266
EIGEN_STRONG_INLINE Packet2cf por< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:100
EIGEN_STRONG_INLINE Packet2cf pset1< Packet2cf >(const std::complex< float > &from)
Definition: Complex.h:107
EIGEN_STRONG_INLINE Packet1cf pcast< float, Packet1cf >(const float &a)
Definition: Complex.h:104
uint32x4_t Packet4ui
Definition: PacketMath.h:77
EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf &x)
Definition: Complex.h:168
EIGEN_STRONG_INLINE Packet2cf pcplxflip< Packet2cf >(const Packet2cf &a)
Definition: Complex.h:296
EIGEN_DEVICE_FUNC Packet pmul(const Packet &a, const Packet &b)
Definition: GenericPacketMath.h:237
EIGEN_STRONG_INLINE Packet4f pdiv< Packet4f >(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:366
EIGEN_STRONG_INLINE Packet2d pload< Packet2d >(const double *from)
Definition: PacketMath.h:716
EIGEN_STRONG_INLINE Packet1cf pload< Packet1cf >(const std::complex< float > *from)
Definition: Complex.h:223
EIGEN_STRONG_INLINE Packet2d pmul< Packet2d >(const Packet2d &a, const Packet2d &b)
Definition: PacketMath.h:347
EIGEN_STRONG_INLINE Packet1cd pxor< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:260
EIGEN_STRONG_INLINE Packet2cf pdiv< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:175
EIGEN_STRONG_INLINE Packet1cf ploaddup< Packet1cf >(const std::complex< float > *from)
Definition: Complex.h:233
EIGEN_STRONG_INLINE Packet1cf ploadu< Packet1cf >(const std::complex< float > *from)
Definition: Complex.h:228
EIGEN_STRONG_INLINE Packet4f pcmp_eq(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:434
EIGEN_STRONG_INLINE Packet1cd padd< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:234
EIGEN_STRONG_INLINE Packet2cf ploadu< Packet2cf >(const std::complex< float > *from)
Definition: Complex.h:105
EIGEN_STRONG_INLINE Packet1cf pset1< Packet1cf >(const std::complex< float > &from)
Definition: Complex.h:109
EIGEN_STRONG_INLINE Packet1cf pcplxflip< Packet1cf >(const Packet1cf &a)
Definition: Complex.h:294
EIGEN_STRONG_INLINE Packet1cf pmul< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:141
EIGEN_STRONG_INLINE Packet1cd ploaddup< Packet1cd >(const std::complex< double > *from)
Definition: Complex.h:271
EIGEN_STRONG_INLINE Packet2cf pload< Packet2cf >(const std::complex< float > *from)
Definition: Complex.h:104
EIGEN_STRONG_INLINE Packet1cf pandnot< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:218
EIGEN_STRONG_INLINE std::complex< double > predux< Packet1cd >(const Packet1cd &a)
Definition: Complex.h:288
float32x2_t Packet2f
Definition: PacketMath.h:62
EIGEN_DEVICE_FUNC void pstore(Scalar *to, const Packet &from)
Definition: GenericPacketMath.h:696
EIGEN_STRONG_INLINE Packet2d ploadu< Packet2d >(const double *from)
Definition: PacketMath.h:743
EIGEN_STRONG_INLINE Packet2cf pcast< Packet2f, Packet2cf >(const Packet2f &a)
Definition: Complex.h:106
EIGEN_STRONG_INLINE Packet1cd pload< Packet1cd >(const std::complex< double > *from)
Definition: Complex.h:264
EIGEN_STRONG_INLINE Packet1cd pand< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:258
EIGEN_STRONG_INLINE Packet2f ploadu< Packet2f >(const float *from)
Definition: PacketMath.h:1709
EIGEN_STRONG_INLINE Packet2cf pand< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:99
EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f &a)
Definition: PacketMath.h:891
EIGEN_STRONG_INLINE Packet1cd pandnot< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:261
EIGEN_DEVICE_FUNC void pstoreu(Scalar *to, const Packet &from)
Definition: GenericPacketMath.h:700
EIGEN_STRONG_INLINE Packet2cf pxor< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:101
EIGEN_STRONG_INLINE Packet2f padd< Packet2f >(const Packet2f &a, const Packet2f &b)
Definition: PacketMath.h:805
EIGEN_STRONG_INLINE Packet4f ploadu< Packet4f >(const float *from)
Definition: PacketMath.h:736
EIGEN_STRONG_INLINE Packet2cf psub< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:68
EIGEN_DEVICE_FUNC unpacket_traits< Packet >::type pfirst(const Packet &a)
Definition: GenericPacketMath.h:844
EIGEN_STRONG_INLINE Packet2f pdiv< Packet2f >(const Packet2f &a, const Packet2f &b)
Definition: PacketMath.h:950
EIGEN_STRONG_INLINE Packet4f pand< Packet4f >(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:412
EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f &a)
Definition: PacketMath.h:342
EIGEN_STRONG_INLINE Packet1cf pxor< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:213
EIGEN_STRONG_INLINE Packet2cf padd< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: Complex.h:67
EIGEN_STRONG_INLINE Packet1cd por< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:259
EIGEN_STRONG_INLINE Packet2d psub< Packet2d >(const Packet2d &a, const Packet2d &b)
Definition: PacketMath.h:296
EIGEN_STRONG_INLINE Packet4f psub< Packet4f >(const Packet4f &a, const Packet4f &b)
Definition: PacketMath.h:295
EIGEN_STRONG_INLINE Packet1cd pset1< Packet1cd >(const std::complex< double > &from)
Definition: Complex.h:268
EIGEN_STRONG_INLINE std::complex< double > pfirst< Packet1cd >(const Packet1cd &a)
Definition: Complex.h:279
EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f &a)
Definition: PacketMath.h:322
EIGEN_STRONG_INLINE Packet1cd pdiv< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:300
EIGEN_STRONG_INLINE Packet1cf psub< Packet1cf >(const Packet1cf &a, const Packet1cf &b)
Definition: Complex.h:122
EIGEN_STRONG_INLINE Packet2f pload< Packet2f >(const float *from)
Definition: PacketMath.h:1664
EIGEN_STRONG_INLINE Packet2f psub< Packet2f >(const Packet2f &a, const Packet2f &b)
Definition: PacketMath.h:834
EIGEN_STRONG_INLINE Packet1cd psub< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: Complex.h:235
::uint64_t uint64_t
Definition: Meta.h:58
::uint32_t uint32_t
Definition: Meta.h:56
Namespace containing all symbols from the Eigen library.
Definition: MatrixExponential.h:16
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Definition: Eigen_Colamd.h:50
Definition: StdDeque.h:50
b
Definition: data.h:44
EIGEN_STRONG_INLINE Packet1cd()
Definition: Complex.h:188
Packet2d v
Definition: Complex.h:190
Definition: Complex.h:39
EIGEN_STRONG_INLINE Packet1cf()
Definition: Complex.h:40
Packet2f v
Definition: Complex.h:42
EIGEN_STRONG_INLINE Packet1cf(const Packet2f &a)
Definition: Complex.h:41
Definition: Complex.h:19
Packet4f v
Definition: Complex.h:22
EIGEN_STRONG_INLINE Packet2cf()
Definition: Complex.h:46
EIGEN_STRONG_INLINE Packet2cf(const Packet4f &a)
Definition: Complex.h:47
Definition: GenericPacketMath.h:1014
@ HasDiv
Definition: GenericPacketMath.h:65
@ HasHalfPacket
Definition: GenericPacketMath.h:114
@ size
Definition: GenericPacketMath.h:112
@ AlignedOnScalar
Definition: GenericPacketMath.h:113
@ Vectorizable
Definition: GenericPacketMath.h:111
@ HasSub
Definition: GenericPacketMath.h:118
@ HasMax
Definition: GenericPacketMath.h:124
@ HasNegate
Definition: GenericPacketMath.h:120
@ HasMul
Definition: GenericPacketMath.h:119
@ HasAdd
Definition: GenericPacketMath.h:117
@ HasSetLinear
Definition: GenericPacketMath.h:126
@ HasMin
Definition: GenericPacketMath.h:123
@ HasAbs2
Definition: GenericPacketMath.h:122
@ HasAbs
Definition: GenericPacketMath.h:121
T type
Definition: GenericPacketMath.h:108
T half
Definition: GenericPacketMath.h:109
Packet2f as_real
Definition: Complex.h:79
Packet1cf half
Definition: Complex.h:78
std::complex< float > type
Definition: Complex.h:77
std::complex< float > type
Definition: Complex.h:91
Packet4f as_real
Definition: Complex.h:93
Packet1cf half
Definition: Complex.h:92
Definition: GenericPacketMath.h:133
T type
Definition: GenericPacketMath.h:134
T half
Definition: GenericPacketMath.h:135
@ masked_load_available
Definition: GenericPacketMath.h:141
@ size
Definition: GenericPacketMath.h:138
@ masked_store_available
Definition: GenericPacketMath.h:142
@ vectorizable
Definition: GenericPacketMath.h:140
@ alignment
Definition: GenericPacketMath.h:139