Eigen  3.3.90 (mercurial changeset 94875feeeeb9)
GenericPacketMath.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
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_GENERIC_PACKET_MATH_H
12 #define EIGEN_GENERIC_PACKET_MATH_H
13 
14 namespace Eigen {
15 
16 namespace internal {
17 
26 #ifndef EIGEN_DEBUG_ALIGNED_LOAD
27 #define EIGEN_DEBUG_ALIGNED_LOAD
28 #endif
29 
30 #ifndef EIGEN_DEBUG_UNALIGNED_LOAD
31 #define EIGEN_DEBUG_UNALIGNED_LOAD
32 #endif
33 
34 #ifndef EIGEN_DEBUG_ALIGNED_STORE
35 #define EIGEN_DEBUG_ALIGNED_STORE
36 #endif
37 
38 #ifndef EIGEN_DEBUG_UNALIGNED_STORE
39 #define EIGEN_DEBUG_UNALIGNED_STORE
40 #endif
41 
42 struct default_packet_traits
43 {
44  enum {
45  HasHalfPacket = 0,
46 
47  HasAdd = 1,
48  HasSub = 1,
49  HasMul = 1,
50  HasNegate = 1,
51  HasAbs = 1,
52  HasArg = 0,
53  HasAbs2 = 1,
54  HasMin = 1,
55  HasMax = 1,
56  HasConj = 1,
57  HasSetLinear = 1,
58  HasBlend = 0,
59  HasReduxp = 1,
60 
61  HasDiv = 0,
62  HasSqrt = 0,
63  HasRsqrt = 0,
64  HasExp = 0,
65  HasExpm1 = 0,
66  HasLog = 0,
67  HasLog1p = 0,
68  HasLog10 = 0,
69  HasPow = 0,
70 
71  HasSin = 0,
72  HasCos = 0,
73  HasTan = 0,
74  HasASin = 0,
75  HasACos = 0,
76  HasATan = 0,
77  HasSinh = 0,
78  HasCosh = 0,
79  HasTanh = 0,
80  HasLGamma = 0,
81  HasDiGamma = 0,
82  HasZeta = 0,
83  HasPolygamma = 0,
84  HasErf = 0,
85  HasErfc = 0,
86  HasNdtri = 0,
87  HasBessel = 0,
88  HasIGamma = 0,
89  HasIGammaDerA = 0,
90  HasGammaSampleDerAlpha = 0,
91  HasIGammac = 0,
92  HasBetaInc = 0,
93 
94  HasRound = 0,
95  HasFloor = 0,
96  HasCeil = 0,
97 
98  HasSign = 0
99  };
100 };
101 
102 template<typename T> struct packet_traits : default_packet_traits
103 {
104  typedef T type;
105  typedef T half;
106  enum {
107  Vectorizable = 0,
108  size = 1,
109  AlignedOnScalar = 0,
110  HasHalfPacket = 0
111  };
112  enum {
113  HasAdd = 0,
114  HasSub = 0,
115  HasMul = 0,
116  HasNegate = 0,
117  HasAbs = 0,
118  HasAbs2 = 0,
119  HasMin = 0,
120  HasMax = 0,
121  HasConj = 0,
122  HasSetLinear = 0
123  };
124 };
125 
126 template<typename T> struct packet_traits<const T> : packet_traits<T> { };
127 
128 template <typename Src, typename Tgt> struct type_casting_traits {
129  enum {
130  VectorizedCast = 0,
131  SrcCoeffRatio = 1,
132  TgtCoeffRatio = 1
133  };
134 };
135 
136 
138 template <typename SrcPacket, typename TgtPacket>
139 EIGEN_DEVICE_FUNC inline TgtPacket
140 pcast(const SrcPacket& a) {
141  return static_cast<TgtPacket>(a);
142 }
143 template <typename SrcPacket, typename TgtPacket>
144 EIGEN_DEVICE_FUNC inline TgtPacket
145 pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
146  return static_cast<TgtPacket>(a);
147 }
148 
149 template <typename SrcPacket, typename TgtPacket>
150 EIGEN_DEVICE_FUNC inline TgtPacket
151 pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
152  return static_cast<TgtPacket>(a);
153 }
154 
156 template <typename Target, typename Packet>
157 EIGEN_DEVICE_FUNC inline Target
158 preinterpret(const Packet& a); /* { return reinterpret_cast<const Target&>(a); } */
159 
161 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
162 padd(const Packet& a, const Packet& b) { return a+b; }
163 
165 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
166 psub(const Packet& a, const Packet& b) { return a-b; }
167 
169 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
170 pnegate(const Packet& a) { return -a; }
171 
174 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
175 pconj(const Packet& a) { return numext::conj(a); }
176 
178 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
179 pmul(const Packet& a, const Packet& b) { return a*b; }
180 
182 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
183 pdiv(const Packet& a, const Packet& b) { return a/b; }
184 
186 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
187 pmin(const Packet& a, const Packet& b) { return numext::mini(a, b); }
188 
190 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
191 pmax(const Packet& a, const Packet& b) { return numext::maxi(a, b); }
192 
194 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
195 pabs(const Packet& a) { using std::abs; return abs(a); }
196 
198 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
199 parg(const Packet& a) { using numext::arg; return arg(a); }
200 
202 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
203 pand(const Packet& a, const Packet& b) { return a & b; }
204 
206 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
207 por(const Packet& a, const Packet& b) { return a | b; }
208 
210 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
211 pxor(const Packet& a, const Packet& b) { return a ^ b; }
212 
214 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
215 pandnot(const Packet& a, const Packet& b) { return a & (~b); }
216 
218 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
219 ptrue(const Packet& /*a*/) { Packet b; memset((void*)&b, 0xff, sizeof(b)); return b;}
220 
221 template <typename RealScalar>
222 EIGEN_DEVICE_FUNC inline std::complex<RealScalar> ptrue(const std::complex<RealScalar>& /*a*/) {
223  RealScalar b;
224  b = ptrue(b);
225  return std::complex<RealScalar>(b, b);
226 }
227 
229 template <typename Packet> EIGEN_DEVICE_FUNC inline Packet
230 pnot(const Packet& a) { return pxor(ptrue(a), a);}
231 
233 template<int N> EIGEN_DEVICE_FUNC inline int
234 pshiftright(const int& a) { return a >> N; }
235 template<int N> EIGEN_DEVICE_FUNC inline long int
236 pshiftright(const long int& a) { return a >> N; }
237 
239 template<int N> EIGEN_DEVICE_FUNC inline int
240 pshiftleft(const int& a) { return a << N; }
241 template<int N> EIGEN_DEVICE_FUNC inline long int
242 pshiftleft(const long int& a) { return a << N; }
243 
247 template <typename Packet>
248 EIGEN_DEVICE_FUNC inline Packet pfrexp(const Packet& a, Packet& exponent) {
249  int exp;
250  EIGEN_USING_STD_MATH(frexp);
251  Packet result = frexp(a, &exp);
252  exponent = static_cast<Packet>(exp);
253  return result;
254 }
255 
259 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
260 pldexp(const Packet &a, const Packet &exponent) {
261  EIGEN_USING_STD_MATH(ldexp);
262  return ldexp(a, static_cast<int>(exponent));
263 }
264 
266 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
267 pzero(const Packet& a) { return pxor(a,a); }
268 
269 template<> EIGEN_DEVICE_FUNC inline float pzero<float>(const float& a) {
270  EIGEN_UNUSED_VARIABLE(a);
271  return 0.f;
272 }
273 
274 template<> EIGEN_DEVICE_FUNC inline double pzero<double>(const double& a) {
275  EIGEN_UNUSED_VARIABLE(a);
276  return 0.;
277 }
278 
280 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
281 pselect(const Packet& mask, const Packet& a, const Packet& b) {
282  return por(pand(a,mask),pandnot(b,mask));
283 }
284 
285 template<> EIGEN_DEVICE_FUNC inline float pselect<float>(
286  const float& mask, const float& a, const float&b) {
287  return numext::equal_strict(mask,0.f) ? b : a;
288 }
289 
290 template<> EIGEN_DEVICE_FUNC inline double pselect<double>(
291  const double& mask, const double& a, const double& b) {
292  return numext::equal_strict(mask,0.) ? b : a;
293 }
294 
296 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
297 pcmp_le(const Packet& a, const Packet& b) { return a<=b ? ptrue(a) : pzero(a); }
298 
300 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
301 pcmp_lt(const Packet& a, const Packet& b) { return a<b ? ptrue(a) : pzero(a); }
302 
304 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
305 pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(a); }
306 
308 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
309 pcmp_lt_or_nan(const Packet& a, const Packet& b) { return pnot(pcmp_le(b,a)); }
310 
312 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
313 pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
314 
316 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
317 ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
318 
323 template<typename Packet> EIGEN_DEVICE_FUNC inline
324 typename enable_if<unpacket_traits<Packet>::masked_load_available, Packet>::type
325 ploadu(const typename unpacket_traits<Packet>::type* from, typename unpacket_traits<Packet>::mask_t umask);
326 
328 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
329 pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
330 
332 template<typename Packet,typename BitsType> EIGEN_DEVICE_FUNC inline Packet
333 pset1frombits(BitsType a);
334 
336 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
337 pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
338 
344 template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
345 ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
346 
353 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
354 ploadquad(const typename unpacket_traits<Packet>::type* from)
355 { return pload1<Packet>(from); }
356 
366 template<typename Packet> EIGEN_DEVICE_FUNC
367 inline void pbroadcast4(const typename unpacket_traits<Packet>::type *a,
368  Packet& a0, Packet& a1, Packet& a2, Packet& a3)
369 {
370  a0 = pload1<Packet>(a+0);
371  a1 = pload1<Packet>(a+1);
372  a2 = pload1<Packet>(a+2);
373  a3 = pload1<Packet>(a+3);
374 }
375 
383 template<typename Packet> EIGEN_DEVICE_FUNC
384 inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
385  Packet& a0, Packet& a1)
386 {
387  a0 = pload1<Packet>(a+0);
388  a1 = pload1<Packet>(a+1);
389 }
390 
392 template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
393 plset(const typename unpacket_traits<Packet>::type& a) { return a; }
394 
396 template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
397 { (*to) = from; }
398 
400 template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
401 { (*to) = from; }
402 
407 template<typename Scalar, typename Packet>
408 EIGEN_DEVICE_FUNC inline
409 typename enable_if<unpacket_traits<Packet>::masked_store_available, void>::type
410 pstoreu(Scalar* to, const Packet& from, typename unpacket_traits<Packet>::mask_t umask);
411 
412  template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
413  { return ploadu<Packet>(from); }
414 
415  template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pscatter(Scalar* to, const Packet& from, Index /*stride*/)
416  { pstore(to, from); }
417 
419 template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
420 {
421 #if defined(EIGEN_HIP_DEVICE_COMPILE)
422  // do nothing
423 #elif defined(EIGEN_CUDA_ARCH)
424 #if defined(__LP64__)
425  // 64-bit pointer operand constraint for inlined asm
426  asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
427 #else
428  // 32-bit pointer operand constraint for inlined asm
429  asm(" prefetch.L1 [ %1 ];" : "=r"(addr) : "r"(addr));
430 #endif
431 #elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
432  __builtin_prefetch(addr);
433 #endif
434 }
435 
437 template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
438 { return a; }
439 
441 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
442 preduxp(const Packet* vecs) { return vecs[0]; }
443 
445 template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux(const Packet& a)
446 { return a; }
447 
452 template<typename Packet> EIGEN_DEVICE_FUNC inline
453 typename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
454 predux_half_dowto4(const Packet& a)
455 { return a; }
456 
458 template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
459 { return a; }
460 
462 template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
463 { return a; }
464 
466 template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
467 { return a; }
468 
472 // not needed yet
473 // template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_all(const Packet& a)
474 // { return bool(a); }
475 
479 template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_any(const Packet& a)
480 {
481  // Dirty but generic implementation where "true" is assumed to be non 0 and all the sames.
482  // It is expected that "true" is either:
483  // - Scalar(1)
484  // - bits full of ones (NaN for floats),
485  // - or first bit equals to 1 (1 for ints, smallest denormal for floats).
486  // For all these cases, taking the sum is just fine, and this boils down to a no-op for scalars.
487  return bool(predux(a));
488 }
489 
491 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
492 { return a; }
493 
495 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
496 {
497  return Packet(numext::imag(a),numext::real(a));
498 }
499 
500 /**************************
501 * Special math functions
502 ***************************/
503 
505 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
506 Packet psin(const Packet& a) { EIGEN_USING_STD_MATH(sin); return sin(a); }
507 
509 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
510 Packet pcos(const Packet& a) { EIGEN_USING_STD_MATH(cos); return cos(a); }
511 
513 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
514 Packet ptan(const Packet& a) { EIGEN_USING_STD_MATH(tan); return tan(a); }
515 
517 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
518 Packet pasin(const Packet& a) { EIGEN_USING_STD_MATH(asin); return asin(a); }
519 
521 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
522 Packet pacos(const Packet& a) { EIGEN_USING_STD_MATH(acos); return acos(a); }
523 
525 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
526 Packet patan(const Packet& a) { EIGEN_USING_STD_MATH(atan); return atan(a); }
527 
529 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
530 Packet psinh(const Packet& a) { EIGEN_USING_STD_MATH(sinh); return sinh(a); }
531 
533 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
534 Packet pcosh(const Packet& a) { EIGEN_USING_STD_MATH(cosh); return cosh(a); }
535 
537 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
538 Packet ptanh(const Packet& a) { EIGEN_USING_STD_MATH(tanh); return tanh(a); }
539 
541 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
542 Packet pexp(const Packet& a) { EIGEN_USING_STD_MATH(exp); return exp(a); }
543 
545 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
546 Packet pexpm1(const Packet& a) { return numext::expm1(a); }
547 
549 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
550 Packet plog(const Packet& a) { EIGEN_USING_STD_MATH(log); return log(a); }
551 
553 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
554 Packet plog1p(const Packet& a) { return numext::log1p(a); }
555 
557 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
558 Packet plog10(const Packet& a) { EIGEN_USING_STD_MATH(log10); return log10(a); }
559 
561 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
562 Packet psqrt(const Packet& a) { EIGEN_USING_STD_MATH(sqrt); return sqrt(a); }
563 
565 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
566 Packet prsqrt(const Packet& a) {
567  return pdiv(pset1<Packet>(1), psqrt(a));
568 }
569 
571 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
572 Packet pround(const Packet& a) { using numext::round; return round(a); }
573 
575 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
576 Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
577 
579 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
580 Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
581 
582 /***************************************************************************
583 * The following functions might not have to be overwritten for vectorized types
584 ***************************************************************************/
585 
587 // NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
588 template<typename Packet>
589 inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
590 {
591  pstore(to, pset1<Packet>(a));
592 }
593 
595 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
596 pmadd(const Packet& a,
597  const Packet& b,
598  const Packet& c)
599 { return padd(pmul(a, b),c); }
600 
603 template<typename Packet, int Alignment>
604 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(const typename unpacket_traits<Packet>::type* from)
605 {
606  if(Alignment >= unpacket_traits<Packet>::alignment)
607  return pload<Packet>(from);
608  else
609  return ploadu<Packet>(from);
610 }
611 
614 template<typename Scalar, typename Packet, int Alignment>
615 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& from)
616 {
617  if(Alignment >= unpacket_traits<Packet>::alignment)
618  pstore(to, from);
619  else
620  pstoreu(to, from);
621 }
622 
628 template<typename Packet, int LoadMode>
629 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
630 {
631  return ploadt<Packet, LoadMode>(from);
632 }
633 
635 template<int Offset,typename PacketType>
636 struct palign_impl
637 {
638  // by default data are aligned, so there is nothing to be done :)
639  static inline void run(PacketType&, const PacketType&) {}
640 };
641 
657 template<int Offset,typename PacketType>
658 inline void palign(PacketType& first, const PacketType& second)
659 {
660  palign_impl<Offset,PacketType>::run(first,second);
661 }
662 
663 /***************************************************************************
664 * Fast complex products (GCC generates a function call which is very slow)
665 ***************************************************************************/
666 
667 // Eigen+CUDA does not support complexes.
668 #if !defined(EIGEN_GPUCC)
669 
670 template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
671 { return std::complex<float>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
672 
673 template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
674 { return std::complex<double>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
675 
676 #endif
677 
678 
679 /***************************************************************************
680  * PacketBlock, that is a collection of N packets where the number of words
681  * in the packet is a multiple of N.
682 ***************************************************************************/
683 template <typename Packet,int N=unpacket_traits<Packet>::size> struct PacketBlock {
684  Packet packet[N];
685 };
686 
687 template<typename Packet> EIGEN_DEVICE_FUNC inline void
688 ptranspose(PacketBlock<Packet,1>& /*kernel*/) {
689  // Nothing to do in the scalar case, i.e. a 1x1 matrix.
690 }
691 
692 /***************************************************************************
693  * Selector, i.e. vector of N boolean values used to select (i.e. blend)
694  * words from 2 packets.
695 ***************************************************************************/
696 template <size_t N> struct Selector {
697  bool select[N];
698 };
699 
700 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
701 pblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& thenPacket, const Packet& elsePacket) {
702  return ifPacket.select[0] ? thenPacket : elsePacket;
703 }
704 
706 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
707 pinsertfirst(const Packet& a, typename unpacket_traits<Packet>::type b)
708 {
709  // Default implementation based on pblend.
710  // It must be specialized for higher performance.
711  Selector<unpacket_traits<Packet>::size> mask;
712  mask.select[0] = true;
713  // This for loop should be optimized away by the compiler.
714  for(Index i=1; i<unpacket_traits<Packet>::size; ++i)
715  mask.select[i] = false;
716  return pblend(mask, pset1<Packet>(b), a);
717 }
718 
720 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
721 pinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b)
722 {
723  // Default implementation based on pblend.
724  // It must be specialized for higher performance.
725  Selector<unpacket_traits<Packet>::size> mask;
726  // This for loop should be optimized away by the compiler.
727  for(Index i=0; i<unpacket_traits<Packet>::size-1; ++i)
728  mask.select[i] = false;
729  mask.select[unpacket_traits<Packet>::size-1] = true;
730  return pblend(mask, pset1<Packet>(b), a);
731 }
732 
733 /***************************************************************************
734  * Some generic implementations to be used by implementors
735 ***************************************************************************/
736 
740 template<typename Packet> EIGEN_STRONG_INLINE Packet
741 pfrexp_float(const Packet& a, Packet& exponent);
742 
746 template<typename Packet> EIGEN_STRONG_INLINE Packet
747 pldexp_float(Packet a, Packet exponent);
748 
749 } // end namespace internal
750 
751 } // end namespace Eigen
752 
753 #endif // EIGEN_GENERIC_PACKET_MATH_H
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tanh_op< typename Derived::Scalar >, const Derived > tanh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_arg_op< typename Derived::Scalar >, const Derived > arg(const Eigen::ArrayBase< Derived > &x)
Namespace containing all symbols from the Eigen library.
Definition: Core:129
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_asin_op< typename Derived::Scalar >, const Derived > asin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_acos_op< typename Derived::Scalar >, const Derived > acos(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:42
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_round_op< typename Derived::Scalar >, const Derived > round(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_floor_op< typename Derived::Scalar >, const Derived > floor(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cosh_op< typename Derived::Scalar >, const Derived > cosh(const Eigen::ArrayBase< Derived > &x)
Definition: Eigen_Colamd.h:50
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tan_op< typename Derived::Scalar >, const Derived > tan(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_atan_op< typename Derived::Scalar >, const Derived > atan(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sin_op< typename Derived::Scalar >, const Derived > sin(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log10_op< typename Derived::Scalar >, const Derived > log10(const Eigen::ArrayBase< Derived > &x)