$darkmode
Eigen  5.0.1-dev
Complex.h
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) 2016 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_COMPLEX32_ZVECTOR_H
12 #define EIGEN_COMPLEX32_ZVECTOR_H
13 
14 // IWYU pragma: private
15 #include "../../InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
19 namespace internal {
20 
21 #if !defined(__ARCH__) || (defined(__ARCH__) && __ARCH__ >= 12)
22 inline Packet4ui p4ui_CONJ_XOR() {
23  return Packet4ui {0x00000000, 0x80000000, 0x00000000, 0x80000000}; // vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_MZERO);
24 }
25 #endif
26 
27 inline Packet2ul p2ul_CONJ_XOR1() {
28  return (Packet2ul)vec_sld((Packet4ui)p2d_ZERO_, (Packet4ui)p2l_ZERO,
29  8); //{ 0x8000000000000000, 0x0000000000000000 };
30 }
31 inline Packet2ul p2ul_CONJ_XOR2() {
32  return (Packet2ul)vec_sld((Packet4ui)p2l_ZERO, (Packet4ui)p2d_ZERO_,
33  8); //{ 0x8000000000000000, 0x0000000000000000 };
34 }
35 
36 struct Packet1cd {
37  EIGEN_STRONG_INLINE Packet1cd() {}
38  EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {}
39  Packet2d v;
40 };
41 
42 struct Packet2cf {
43  EIGEN_STRONG_INLINE Packet2cf() {}
44  EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
45 #if !defined(__ARCH__) || (defined(__ARCH__) && __ARCH__ < 12)
46  union {
47  Packet4f v;
48  Packet1cd cd[2];
49  };
50 #else
51  Packet4f v;
52 #endif
53 };
54 
55 template <>
56 struct packet_traits<std::complex<float> > : default_packet_traits {
57  typedef Packet2cf type;
58  typedef Packet2cf half;
59  enum {
60  Vectorizable = 1,
61  AlignedOnScalar = 1,
62  size = 2,
63 
64  HasAdd = 1,
65  HasSub = 1,
66  HasMul = 1,
67  HasDiv = 1,
68  HasLog = 1,
69  HasExp = 1,
70  HasNegate = 1,
71  HasAbs = 0,
72  HasAbs2 = 0,
73  HasMin = 0,
74  HasMax = 0,
75  HasBlend = 1,
76  HasSetLinear = 0
77  };
78 };
79 
80 template <>
81 struct packet_traits<std::complex<double> > : default_packet_traits {
82  typedef Packet1cd type;
83  typedef Packet1cd half;
84  enum {
85  Vectorizable = 1,
86  AlignedOnScalar = 1,
87  size = 1,
88 
89  HasAdd = 1,
90  HasSub = 1,
91  HasMul = 1,
92  HasDiv = 1,
93  HasLog = 1,
94  HasNegate = 1,
95  HasAbs = 0,
96  HasAbs2 = 0,
97  HasMin = 0,
98  HasMax = 0,
99  HasSetLinear = 0
100  };
101 };
102 
103 template <>
104 struct unpacket_traits<Packet2cf> {
105  typedef std::complex<float> type;
106  enum {
107  size = 2,
108  alignment = Aligned16,
109  vectorizable = true,
110  masked_load_available = false,
111  masked_store_available = false
112  };
113  typedef Packet2cf half;
114  typedef Packet4f as_real;
115 };
116 template <>
117 struct unpacket_traits<Packet1cd> {
118  typedef std::complex<double> type;
119  enum {
120  size = 1,
121  alignment = Aligned16,
122  vectorizable = true,
123  masked_load_available = false,
124  masked_store_available = false
125  };
126  typedef Packet1cd half;
127  typedef Packet2d as_real;
128 };
129 
130 /* Forward declaration */
131 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet2cf, 2>& kernel);
132 
133 /* complex<double> first */
134 template <>
135 EIGEN_STRONG_INLINE Packet1cd pload<Packet1cd>(const std::complex<double>* from) {
136  EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>((const double*)from));
137 }
138 template <>
139 EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from) {
140  EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>((const double*)from));
141 }
142 template <>
143 EIGEN_STRONG_INLINE void pstore<std::complex<double> >(std::complex<double>* to, const Packet1cd& from) {
144  EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v);
145 }
146 template <>
147 EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double>* to, const Packet1cd& from) {
148  EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v);
149 }
150 
151 template <>
152 EIGEN_STRONG_INLINE Packet1cd
153 pset1<Packet1cd>(const std::complex<double>& from) { /* here we really have to use unaligned loads :( */
154  return ploadu<Packet1cd>(&from);
155 }
156 
157 template <>
158 EIGEN_DEVICE_FUNC inline Packet1cd pgather<std::complex<double>, Packet1cd>(const std::complex<double>* from,
159  Index stride EIGEN_UNUSED) {
160  return pload<Packet1cd>(from);
161 }
162 template <>
163 EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet1cd>(std::complex<double>* to, const Packet1cd& from,
164  Index stride EIGEN_UNUSED) {
165  pstore<std::complex<double> >(to, from);
166 }
167 template <>
168 EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
169  return Packet1cd(a.v + b.v);
170 }
171 template <>
172 EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
173  return Packet1cd(a.v - b.v);
174 }
175 template <>
176 EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) {
177  return Packet1cd(pnegate(Packet2d(a.v)));
178 }
179 template <>
180 EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) {
181  return Packet1cd((Packet2d)vec_xor((Packet2d)a.v, (Packet2d)p2ul_CONJ_XOR2()));
182 }
183 template <>
184 EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
185  Packet2d a_re, a_im, v1, v2;
186 
187  // Permute and multiply the real parts of a and b
188  a_re = vec_perm(a.v, a.v, p16uc_PSET64_HI);
189  // Get the imaginary parts of a
190  a_im = vec_perm(a.v, a.v, p16uc_PSET64_LO);
191  // multiply a_re * b
192  v1 = vec_madd(a_re, b.v, p2d_ZERO);
193  // multiply a_im * b and get the conjugate result
194  v2 = vec_madd(a_im, b.v, p2d_ZERO);
195  v2 = (Packet2d)vec_sld((Packet4ui)v2, (Packet4ui)v2, 8);
196  v2 = (Packet2d)vec_xor((Packet2d)v2, (Packet2d)p2ul_CONJ_XOR1());
197 
198  return Packet1cd(v1 + v2);
199 }
200 template <>
201 EIGEN_STRONG_INLINE Packet1cd pand<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
202  return Packet1cd(vec_and(a.v, b.v));
203 }
204 template <>
205 EIGEN_STRONG_INLINE Packet1cd por<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
206  return Packet1cd(vec_or(a.v, b.v));
207 }
208 template <>
209 EIGEN_STRONG_INLINE Packet1cd pxor<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
210  return Packet1cd(vec_xor(a.v, b.v));
211 }
212 template <>
213 EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
214  return Packet1cd(vec_and(a.v, vec_nor(b.v, b.v)));
215 }
216 template <>
217 EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) {
218  return pset1<Packet1cd>(*from);
219 }
220 template <>
221 EIGEN_STRONG_INLINE Packet1cd pcmp_eq(const Packet1cd& a, const Packet1cd& b) {
222  Packet2d eq = vec_cmpeq(a.v, b.v);
223  Packet2d tmp = {eq[1], eq[0]};
224  return (Packet1cd)pand<Packet2d>(eq, tmp);
225 }
226 
227 template <>
228 EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double>* addr) {
229  EIGEN_ZVECTOR_PREFETCH(addr);
230 }
231 
232 template <>
233 EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet1cd>(const Packet1cd& a) {
234  EIGEN_ALIGN16 std::complex<double> res;
235  pstore<std::complex<double> >(&res, a);
236 
237  return res;
238 }
239 
240 template <>
241 EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) {
242  return a;
243 }
244 template <>
245 EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) {
246  return pfirst(a);
247 }
248 template <>
249 EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) {
250  return pfirst(a);
251 }
252 EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd, Packet2d)
253 
254 template <>
255 EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b) {
256  return pdiv_complex(a, b);
257 }
258 
259 template <>
260 EIGEN_STRONG_INLINE Packet1cd psqrt<Packet1cd>(const Packet1cd& a) {
261  return psqrt_complex<Packet1cd>(a);
262 }
263 
264 template <>
265 EIGEN_STRONG_INLINE Packet2cf psqrt<Packet2cf>(const Packet2cf& a) {
266  return psqrt_complex<Packet2cf>(a);
267 }
268 
269 template <>
270 EIGEN_STRONG_INLINE Packet1cd plog<Packet1cd>(const Packet1cd& a) {
271  return plog_complex<Packet1cd>(a);
272 }
273 template <>
274 EIGEN_STRONG_INLINE Packet2cf plog<Packet2cf>(const Packet2cf& a) {
275  return plog_complex<Packet2cf>(a);
276 }
277 
278 template <>
279 EIGEN_STRONG_INLINE Packet2cf pexp<Packet2cf>(const Packet2cf& a) {
280  return pexp_complex(a);
281 }
282 
283 EIGEN_STRONG_INLINE Packet1cd pcplxflip /*<Packet1cd>*/ (const Packet1cd& x) {
284  return Packet1cd(preverse(Packet2d(x.v)));
285 }
286 
287 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet1cd, 2>& kernel) {
288  Packet2d tmp = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_HI);
289  kernel.packet[1].v = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_LO);
290  kernel.packet[0].v = tmp;
291 }
292 
293 /* complex<float> follows */
294 template <>
295 EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) {
296  EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from));
297 }
298 template <>
299 EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) {
300  EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from));
301 }
302 template <>
303 EIGEN_STRONG_INLINE void pstore<std::complex<float> >(std::complex<float>* to, const Packet2cf& from) {
304  EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v);
305 }
306 template <>
307 EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float>* to, const Packet2cf& from) {
308  EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v);
309 }
310 
311 template <>
312 EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a) {
313  EIGEN_ALIGN16 std::complex<float> res[2];
314  pstore<std::complex<float> >(res, a);
315 
316  return res[0];
317 }
318 
319 #if !defined(__ARCH__) || (defined(__ARCH__) && __ARCH__ < 12)
320 template <>
321 EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from) {
322  Packet2cf res;
323  res.cd[0] = Packet1cd(vec_ld2f((const float*)&from));
324  res.cd[1] = res.cd[0];
325  return res;
326 }
327 #else
328 template <>
329 EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from) {
330  Packet2cf res;
331  if ((std::ptrdiff_t(&from) % 16) == 0)
332  res.v = pload<Packet4f>((const float*)&from);
333  else
334  res.v = ploadu<Packet4f>((const float*)&from);
335  res.v = vec_perm(res.v, res.v, p16uc_PSET64_HI);
336  return res;
337 }
338 #endif
339 
340 template <>
341 EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(const std::complex<float>* from,
342  Index stride) {
343  EIGEN_ALIGN16 std::complex<float> af[2];
344  af[0] = from[0 * stride];
345  af[1] = from[1 * stride];
346  return pload<Packet2cf>(af);
347 }
348 template <>
349 EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf>(std::complex<float>* to, const Packet2cf& from,
350  Index stride) {
351  EIGEN_ALIGN16 std::complex<float> af[2];
352  pstore<std::complex<float> >((std::complex<float>*)af, from);
353  to[0 * stride] = af[0];
354  to[1 * stride] = af[1];
355 }
356 
357 template <>
358 EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
359  return Packet2cf(padd<Packet4f>(a.v, b.v));
360 }
361 template <>
362 EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
363  return Packet2cf(psub<Packet4f>(a.v, b.v));
364 }
365 template <>
366 EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) {
367  return Packet2cf(pnegate(Packet4f(a.v)));
368 }
369 
370 template <>
371 EIGEN_STRONG_INLINE Packet2cf pand<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
372  return Packet2cf(pand<Packet4f>(a.v, b.v));
373 }
374 template <>
375 EIGEN_STRONG_INLINE Packet2cf por<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
376  return Packet2cf(por<Packet4f>(a.v, b.v));
377 }
378 template <>
379 EIGEN_STRONG_INLINE Packet2cf pxor<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
380  return Packet2cf(pxor<Packet4f>(a.v, b.v));
381 }
382 template <>
383 EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
384  return Packet2cf(pandnot<Packet4f>(a.v, b.v));
385 }
386 
387 template <>
388 EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) {
389  return pset1<Packet2cf>(*from);
390 }
391 
392 template <>
393 EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float>* addr) {
394  EIGEN_ZVECTOR_PREFETCH(addr);
395 }
396 
397 #if !defined(__ARCH__) || (defined(__ARCH__) && __ARCH__ < 12)
398 
399 template <>
400 EIGEN_STRONG_INLINE Packet2cf pcmp_eq(const Packet2cf& a, const Packet2cf& b) {
401  Packet4f eq = pcmp_eq<Packet4f>(a.v, b.v);
402  Packet2cf res;
403  Packet2d tmp1 = {eq.v4f[0][1], eq.v4f[0][0]};
404  Packet2d tmp2 = {eq.v4f[1][1], eq.v4f[1][0]};
405  res.v.v4f[0] = pand<Packet2d>(eq.v4f[0], tmp1);
406  res.v.v4f[1] = pand<Packet2d>(eq.v4f[1], tmp2);
407  return res;
408 }
409 
410 template <>
411 EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) {
412  Packet2cf res;
413  res.v.v4f[0] = pconj(Packet1cd(reinterpret_cast<Packet2d>(a.v.v4f[0]))).v;
414  res.v.v4f[1] = pconj(Packet1cd(reinterpret_cast<Packet2d>(a.v.v4f[1]))).v;
415  return res;
416 }
417 
418 template <>
419 EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
420  Packet2cf res;
421  res.v.v4f[0] =
422  pmul(Packet1cd(reinterpret_cast<Packet2d>(a.v.v4f[0])), Packet1cd(reinterpret_cast<Packet2d>(b.v.v4f[0]))).v;
423  res.v.v4f[1] =
424  pmul(Packet1cd(reinterpret_cast<Packet2d>(a.v.v4f[1])), Packet1cd(reinterpret_cast<Packet2d>(b.v.v4f[1]))).v;
425  return res;
426 }
427 
428 template <>
429 EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) {
430  Packet2cf res;
431  res.cd[0] = a.cd[1];
432  res.cd[1] = a.cd[0];
433  return res;
434 }
435 
436 template <>
437 EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) {
438  std::complex<float> res;
439  Packet1cd b = padd<Packet1cd>(a.cd[0], a.cd[1]);
440  vec_st2f(b.v, (float*)&res);
441  return res;
442 }
443 
444 template <>
445 EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) {
446  std::complex<float> res;
447  Packet1cd b = pmul<Packet1cd>(a.cd[0], a.cd[1]);
448  vec_st2f(b.v, (float*)&res);
449  return res;
450 }
451 
452 EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf, Packet4f)
453 
454 template <>
455 EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
456  return pdiv_complex(a, b);
457 }
458 
459 EIGEN_STRONG_INLINE Packet2cf pcplxflip /*<Packet2cf>*/ (const Packet2cf& x) {
460  Packet2cf res;
461  res.cd[0] = pcplxflip(x.cd[0]);
462  res.cd[1] = pcplxflip(x.cd[1]);
463  return res;
464 }
465 
466 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet2cf, 2>& kernel) {
467  Packet1cd tmp = kernel.packet[0].cd[1];
468  kernel.packet[0].cd[1] = kernel.packet[1].cd[0];
469  kernel.packet[1].cd[0] = tmp;
470 }
471 
472 template <>
473 EIGEN_STRONG_INLINE Packet2cf pblend(const Selector<2>& ifPacket, const Packet2cf& thenPacket,
474  const Packet2cf& elsePacket) {
475  Packet2cf result;
476  const Selector<4> ifPacket4 = {ifPacket.select[0], ifPacket.select[0], ifPacket.select[1], ifPacket.select[1]};
477  result.v = pblend<Packet4f>(ifPacket4, thenPacket.v, elsePacket.v);
478  return result;
479 }
480 #else
481 template <>
482 EIGEN_STRONG_INLINE Packet2cf pcmp_eq(const Packet2cf& a, const Packet2cf& b) {
483  Packet4f eq = vec_cmpeq(a.v, b.v);
484  Packet4f tmp = {eq[1], eq[0], eq[3], eq[2]};
485  return (Packet2cf)pand<Packet4f>(eq, tmp);
486 }
487 template <>
488 EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) {
489  return Packet2cf(pxor<Packet4f>(a.v, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR())));
490 }
491 template <>
492 EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
493  Packet4f a_re, a_im, prod, prod_im;
494 
495  // Permute and multiply the real parts of a and b
496  a_re = vec_perm(a.v, a.v, p16uc_PSET32_WODD);
497 
498  // Get the imaginary parts of a
499  a_im = vec_perm(a.v, a.v, p16uc_PSET32_WEVEN);
500 
501  // multiply a_im * b and get the conjugate result
502  prod_im = a_im * b.v;
503  prod_im = pxor<Packet4f>(prod_im, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR()));
504  // permute back to a proper order
505  prod_im = vec_perm(prod_im, prod_im, p16uc_COMPLEX32_REV);
506 
507  // multiply a_re * b, add prod_im
508  prod = pmadd<Packet4f>(a_re, b.v, prod_im);
509 
510  return Packet2cf(prod);
511 }
512 
513 template <>
514 EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) {
515  Packet4f rev_a;
516  rev_a = vec_perm(a.v, a.v, p16uc_COMPLEX32_REV2);
517  return Packet2cf(rev_a);
518 }
519 
520 template <>
521 EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) {
522  Packet4f b;
523  b = vec_sld(a.v, a.v, 8);
524  b = padd<Packet4f>(a.v, b);
525  return pfirst<Packet2cf>(Packet2cf(b));
526 }
527 
528 template <>
529 EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) {
530  Packet4f b;
531  Packet2cf prod;
532  b = vec_sld(a.v, a.v, 8);
533  prod = pmul<Packet2cf>(a, Packet2cf(b));
534 
535  return pfirst<Packet2cf>(prod);
536 }
537 
538 EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf, Packet4f)
539 
540 template <>
541 EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) {
542  return pdiv_complex(a, b);
543 }
544 
545 template <>
546 EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x) {
547  return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX32_REV));
548 }
549 
550 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet2cf, 2>& kernel) {
551  Packet4f tmp = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_HI);
552  kernel.packet[1].v = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_LO);
553  kernel.packet[0].v = tmp;
554 }
555 
556 template <>
557 EIGEN_STRONG_INLINE Packet2cf pblend(const Selector<2>& ifPacket, const Packet2cf& thenPacket,
558  const Packet2cf& elsePacket) {
559  Packet2cf result;
560  result.v = reinterpret_cast<Packet4f>(
561  pblend<Packet2d>(ifPacket, reinterpret_cast<Packet2d>(thenPacket.v), reinterpret_cast<Packet2d>(elsePacket.v)));
562  return result;
563 }
564 #endif
565 
566 } // end namespace internal
567 
568 } // end namespace Eigen
569 
570 #endif // EIGEN_COMPLEX32_ZVECTOR_H
Definition: Constants.h:237
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Definition: BFloat16.h:231
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82