1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_GENERIC_PACKET_MATH_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_GENERIC_PACKET_MATH_H
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \file GenericPacketMath.h
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Default implementation for types not supported by the vectorization.
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * In practice these functions are provided to make easier the writing
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * of generic vectorized code.
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_DEBUG_ALIGNED_LOAD
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_DEBUG_ALIGNED_LOAD
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_DEBUG_UNALIGNED_LOAD
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_DEBUG_UNALIGNED_LOAD
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_DEBUG_ALIGNED_STORE
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_DEBUG_ALIGNED_STORE
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_DEBUG_UNALIGNED_STORE
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_DEBUG_UNALIGNED_STORE
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct default_packet_traits
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasHalfPacket = 0,
462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAdd    = 1,
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSub    = 1,
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMul    = 1,
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasNegate = 1,
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs    = 1,
522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasArg    = 0,
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs2   = 1,
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMin    = 1,
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMax    = 1,
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasConj   = 1,
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSetLinear = 1,
582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasBlend  = 0,
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasDiv    = 0,
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSqrt   = 0,
622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasRsqrt  = 0,
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasExp    = 0,
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasLog    = 0,
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasLog1p  = 0,
662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasLog10  = 0,
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasPow    = 0,
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSin    = 0,
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasCos    = 0,
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasTan    = 0,
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasASin   = 0,
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasACos   = 0,
742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasATan   = 0,
752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasSinh   = 0,
762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasCosh   = 0,
772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasTanh   = 0,
782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasLGamma = 0,
792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasDiGamma = 0,
802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasZeta = 0,
812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasPolygamma = 0,
822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasErf = 0,
832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasErfc = 0,
842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasIGamma = 0,
852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasIGammac = 0,
862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasBetaInc = 0,
872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasRound  = 0,
892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasFloor  = 0,
902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasCeil   = 0,
912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasSign   = 0
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct packet_traits : default_packet_traits
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef T type;
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T half;
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Vectorizable = 0,
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    size = 1,
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    AlignedOnScalar = 0,
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    HasHalfPacket = 0
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAdd    = 0,
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSub    = 0,
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMul    = 0,
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasNegate = 0,
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs    = 0,
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs2   = 0,
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMin    = 0,
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMax    = 0,
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasConj   = 0,
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSetLinear = 0
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct packet_traits<const T> : packet_traits<T> { };
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Src, typename Tgt> struct type_casting_traits {
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum {
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VectorizedCast = 0,
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    SrcCoeffRatio = 1,
1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    TgtCoeffRatio = 1
1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename SrcPacket, typename TgtPacket>
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC inline TgtPacket
1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpcast(const SrcPacket& a) {
1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return static_cast<TgtPacket>(a);
1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename SrcPacket, typename TgtPacket>
1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC inline TgtPacket
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpcast(const SrcPacket& a, const SrcPacket& /*b*/) {
1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return static_cast<TgtPacket>(a);
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename SrcPacket, typename TgtPacket>
1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC inline TgtPacket
1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return static_cast<TgtPacket>(a);
1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a + b (coeff-wise) */
1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpadd(const Packet& a,
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Packet& b) { return a+b; }
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a - b (coeff-wise) */
1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpsub(const Packet& a,
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Packet& b) { return a-b; }
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns -a (coeff-wise) */
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpnegate(const Packet& a) { return -a; }
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns conj(a) (coeff-wise) */
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
1667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezpconj(const Packet& a) { return numext::conj(a); }
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a * b (coeff-wise) */
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpmul(const Packet& a,
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Packet& b) { return a*b; }
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a / b (coeff-wise) */
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpdiv(const Packet& a,
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Packet& b) { return a/b; }
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the min of \a a and \a b  (coeff-wise) */
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpmin(const Packet& a,
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        const Packet& b) { return numext::mini(a, b); }
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the max of \a a and \a b  (coeff-wise) */
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpmax(const Packet& a,
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        const Packet& b) { return numext::maxi(a, b); }
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the absolute value of \a a */
1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
1907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezpabs(const Packet& a) { using std::abs; return abs(a); }
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the phase angle of \a a */
1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangparg(const Packet& a) { using numext::arg; return arg(a); }
1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the bitwise and of \a a and \a b */
1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpand(const Packet& a, const Packet& b) { return a & b; }
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the bitwise or of \a a and \a b */
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpor(const Packet& a, const Packet& b) { return a | b; }
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the bitwise xor of \a a and \a b */
2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpxor(const Packet& a, const Packet& b) { return a ^ b; }
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the bitwise andnot of \a a and \a b */
2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpandnot(const Packet& a, const Packet& b) { return a & (!b); }
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpload(const typename unpacket_traits<Packet>::type* from) { return *from; }
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a packet version of \a *from, (un-aligned load) */
2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpset1(const typename unpacket_traits<Packet>::type& a) { return a; }
2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpload1(const typename unpacket_traits<Packet>::type  *a) { return pset1<Packet>(*a); }
2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/** \internal \returns a packet with elements of \a *from duplicated.
2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For instance, for a packet of 8 elements, 4 scalars will be read from \a *from and
2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
2317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * Currently, this function is only used for scalar * complex products.
2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
233eda03298de395cf6217486971e6529f92da8da79Miao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns a packet with elements of \a *from quadrupled.
2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For instance, for a packet of 8 elements, 2 scalars will be read from \a *from and
2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * replicated to form: {from[0],from[0],from[0],from[0],from[1],from[1],from[1],from[1]}
2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Currently, this function is only used in matrix products.
2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For packet-size smaller or equal to 4, this function is equivalent to pload1
2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangploadquad(const typename unpacket_traits<Packet>::type* from)
2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ return pload1<Packet>(from); }
2452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal equivalent to
2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \code
2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a0 = pload1(a+0);
2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a1 = pload1(a+1);
2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a2 = pload1(a+2);
2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a3 = pload1(a+3);
2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \endcode
2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \sa pset1, pload1, ploaddup, pbroadcast2
2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC
2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline void pbroadcast4(const typename unpacket_traits<Packet>::type *a,
2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                        Packet& a0, Packet& a1, Packet& a2, Packet& a3)
2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a0 = pload1<Packet>(a+0);
2602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a1 = pload1<Packet>(a+1);
2612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a2 = pload1<Packet>(a+2);
2622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a3 = pload1<Packet>(a+3);
2632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
2642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal equivalent to
2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \code
2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a0 = pload1(a+0);
2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * a1 = pload1(a+1);
2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \endcode
2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \sa pset1, pload1, ploaddup, pbroadcast4
2712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
2722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC
2732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
2742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                        Packet& a0, Packet& a1)
2752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a0 = pload1<Packet>(a+0);
2772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  a1 = pload1<Packet>(a+1);
2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
281eda03298de395cf6217486971e6529f92da8da79Miao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangplset(const typename unpacket_traits<Packet>::type& a) { return a; }
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ (*to) = from; }
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal copy the packet \a from to \a *to, (un-aligned store) */
2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{  (*to) = from; }
2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { return ploadu<Packet>(from); }
2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pscatter(Scalar* to, const Packet& from, Index /*stride*/)
2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { pstore(to, from); }
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal tries to do cache prefetching of \a addr */
2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
3012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifdef __CUDA_ARCH__
3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if defined(__LP64__)
3032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // 64-bit pointer operand constraint for inlined asm
3042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#else
3062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // 32-bit pointer operand constraint for inlined asm
3072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  asm(" prefetch.L1 [ %1 ];" : "=r"(addr) : "r"(addr));
3082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
3092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
3102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  __builtin_prefetch(addr);
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the first element of a packet */
3152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
3192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpreduxp(const Packet* vecs) { return vecs[0]; }
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the sum of the elements of \a a*/
3232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux(const Packet& a)
3242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ return a; }
3252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the sum of the elements of \a a by block of 4 elements.
3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For packet-size smaller or equal to 4, this boils down to a noop.
3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline
3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtypename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
3322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpredux_downto4(const Packet& a)
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the product of the elements of \a a*/
3362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the min of the elements of \a a*/
3402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the max of the elements of \a a*/
3442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the reversed elements of \a a*/
3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return a; }
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
3537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
3547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // FIXME: uncomment the following in case we drop the internal imag and real functions.
3557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//   using std::imag;
3567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//   using std::real;
3577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return Packet(imag(a),real(a));
3587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Special math functions
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************/
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the sine of \a a (coeff-wise) */
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket psin(const Packet& a) { using std::sin; return sin(a); }
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the cosine of \a a (coeff-wise) */
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket pcos(const Packet& a) { using std::cos; return cos(a); }
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the tan of \a a (coeff-wise) */
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket ptan(const Packet& a) { using std::tan; return tan(a); }
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the arc sine of \a a (coeff-wise) */
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket pasin(const Packet& a) { using std::asin; return asin(a); }
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the arc cosine of \a a (coeff-wise) */
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket pacos(const Packet& a) { using std::acos; return acos(a); }
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
3842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the arc tangent of \a a (coeff-wise) */
3852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket patan(const Packet& a) { using std::atan; return atan(a); }
3872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
3892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket psinh(const Packet& a) { using std::sinh; return sinh(a); }
3912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
3932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket pcosh(const Packet& a) { using std::cosh; return cosh(a); }
3952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
3972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
3982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket ptanh(const Packet& a) { using std::tanh; return tanh(a); }
3992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the exp of \a a (coeff-wise) */
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket pexp(const Packet& a) { using std::exp; return exp(a); }
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the log of \a a (coeff-wise) */
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket plog(const Packet& a) { using std::log; return log(a); }
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the log1p of \a a (coeff-wise) */
4092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket plog1p(const Packet& a) { return numext::log1p(a); }
4112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the log10 of \a a (coeff-wise) */
4132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket plog10(const Packet& a) { using std::log10; return log10(a); }
4152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns the square-root of \a a (coeff-wise) */
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezPacket psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
4212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket prsqrt(const Packet& a) {
4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return pdiv(pset1<Packet>(1), psqrt(a));
4242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
4252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the rounded value of \a a (coeff-wise) */
4272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket pround(const Packet& a) { using numext::round; return round(a); }
4292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the floor of \a a (coeff-wise) */
4312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket pfloor(const Packet& a) { using numext::floor; return floor(a); }
4332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns the ceil of \a a (coeff-wise) */
4352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
4362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket pceil(const Packet& a) { using numext::ceil; return ceil(a); }
4372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* The following functions might not have to be overwritten for vectorized types
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet>
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  pstore(to, pset1<Packet>(a));
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a * b + c (coeff-wise) */
4512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpmadd(const Packet&  a,
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         const Packet&  b,
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         const Packet&  c)
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return padd(pmul(a, b),c); }
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \returns a packet version of \a *from.
4582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
4592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet, int Alignment>
4602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(const typename unpacket_traits<Packet>::type* from)
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
4622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(Alignment >= unpacket_traits<Packet>::alignment)
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return pload<Packet>(from);
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return ploadu<Packet>(from);
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal copy the packet \a from to \a *to.
4692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
4702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar, typename Packet, int Alignment>
4712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& from)
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
4732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(Alignment >= unpacket_traits<Packet>::alignment)
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    pstore(to, from);
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    pstoreu(to, from);
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns a packet version of \a *from.
4802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Unlike ploadt, ploadt_ro takes advantage of the read-only memory path on the
4812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * hardware if available to speedup the loading of data that won't be modified
4822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * by the current computation.
4832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
4842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet, int LoadMode>
485eda03298de395cf6217486971e6529f92da8da79Miao WangEIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
4872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return ploadt<Packet, LoadMode>(from);
4882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
4892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal default implementation of palign() allowing partial specialization */
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Offset,typename PacketType>
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct palign_impl
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // by default data are aligned, so there is nothing to be done :)
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(PacketType&, const PacketType&) {}
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
4997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * of \a first and \a Offset first elements of \a second.
5007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *
5017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * This function is currently only used to optimize matrix-vector products on unligned matrices.
5027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * It takes 2 packets that represent a contiguous memory array, and returns a packet starting
5037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * at the position \a Offset. For instance, for packets of 4 elements, we have:
5047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *  Input:
5057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *  - first = {f0,f1,f2,f3}
5067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *  - second = {s0,s1,s2,s3}
5077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * Output:
5087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *   - if Offset==0 then {f0,f1,f2,f3}
5097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *   - if Offset==1 then {f1,f2,f3,s0}
5107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *   - if Offset==2 then {f2,f3,s0,s1}
5117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  *   - if Offset==3 then {f3,s0,s1,s3}
5127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  */
513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Offset,typename PacketType>
514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void palign(PacketType& first, const PacketType& second)
515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  palign_impl<Offset,PacketType>::run(first,second);
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Fast complex products (GCC generates a function call which is very slow)
521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Eigen+CUDA does not support complexes.
5242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef __CUDACC__
5252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
5332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/***************************************************************************
5362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * PacketBlock, that is a collection of N packets where the number of words
5372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * in the packet is a multiple of N.
5382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang***************************************************************************/
5392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Packet,int N=unpacket_traits<Packet>::size> struct PacketBlock {
5402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Packet packet[N];
5412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
5422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline void
5442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangptranspose(PacketBlock<Packet,1>& /*kernel*/) {
5452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Nothing to do in the scalar case, i.e. a 1x1 matrix.
5462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
5472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/***************************************************************************
5492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Selector, i.e. vector of N boolean values used to select (i.e. blend)
5502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * words from 2 packets.
5512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang***************************************************************************/
5522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <size_t N> struct Selector {
5532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  bool select[N];
5542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
5552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
5572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& thenPacket, const Packet& elsePacket) {
5582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return ifPacket.select[0] ? thenPacket : elsePacket;
5592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
5602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns \a a with the first coefficient replaced by the scalar b */
5622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
5632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpinsertfirst(const Packet& a, typename unpacket_traits<Packet>::type b)
5642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
5652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Default implementation based on pblend.
5662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // It must be specialized for higher performance.
5672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Selector<unpacket_traits<Packet>::size> mask;
5682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  mask.select[0] = true;
5692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // This for loop should be optimized away by the compiler.
5702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i=1; i<unpacket_traits<Packet>::size; ++i)
5712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    mask.select[i] = false;
5722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return pblend(mask, pset1<Packet>(b), a);
5732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
5742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal \returns \a a with the last coefficient replaced by the scalar b */
5762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Packet> EIGEN_DEVICE_FUNC inline Packet
5772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b)
5782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
5792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Default implementation based on pblend.
5802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // It must be specialized for higher performance.
5812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Selector<unpacket_traits<Packet>::size> mask;
5822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // This for loop should be optimized away by the compiler.
5832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i=0; i<unpacket_traits<Packet>::size-1; ++i)
5842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    mask.select[i] = false;
5852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  mask.select[unpacket_traits<Packet>::size-1] = true;
5862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return pblend(mask, pset1<Packet>(b), a);
5872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
5882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_GENERIC_PACKET_MATH_H
594