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-2009 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#include "main.h"
122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#include "unsupported/Eigen/SpecialFunctions"
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if defined __GNUC__ && __GNUC__>=6
152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  #pragma GCC diagnostic ignored "-Wignored-attributes"
162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// using namespace Eigen;
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifdef EIGEN_VECTORIZE_SSE
202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangconst bool g_vectorize_sse = true;
212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#else
222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangconst bool g_vectorize_sse = false;
232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> T negate(const T& x) { return -x; }
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// NOTE: we disbale inlining for this function to workaround a GCC issue when using -O3 and the i387 FPU.
322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar> EIGEN_DONT_INLINE
332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangbool isApproxAbs(const Scalar& a, const Scalar& b, const typename NumTraits<Scalar>::Real& refvalue)
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return internal::isMuchSmallerThan(a-b, refvalue);
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> bool areApproxAbs(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& refvalue)
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if (!isApproxAbs(a[i],b[i],refvalue))
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      std::cout << "ref: [" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != vec: [" << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "]\n";
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return false;
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return true;
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (a[i]!=b[i] && !internal::isApprox(a[i],b[i]))
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      std::cout << "ref: [" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != vec: [" << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "]\n";
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return false;
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return true;
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define CHECK_CWISE1(REFOP, POP) { \
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i) \
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] = REFOP(data1[i]); \
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(data2, POP(internal::pload<Packet>(data1))); \
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<bool Cond,typename Packet>
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct packet_helper
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline Packet load(const T* from) const { return internal::pload<Packet>(from); }
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline void store(T* to, const Packet& x) const { internal::pstore(to,x); }
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Packet>
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct packet_helper<false,Packet>
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline T load(const T* from) const { return *from; }
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline void store(T* to, const T& x) const { *to = x; }
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define CHECK_CWISE1_IF(COND, REFOP, POP) if(COND) { \
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  packet_helper<COND,Packet> h; \
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i) \
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] = REFOP(data1[i]); \
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  h.store(data2, POP(h.load(data1))); \
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define CHECK_CWISE2_IF(COND, REFOP, POP) if(COND) { \
1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  packet_helper<COND,Packet> h; \
1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<PacketSize; ++i) \
1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    ref[i] = REFOP(data1[i], data1[i+PacketSize]); \
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  h.store(data2, POP(h.load(data1),h.load(data1+PacketSize))); \
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define REF_ADD(a,b) ((a)+(b))
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define REF_SUB(a,b) ((a)-(b))
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define REF_MUL(a,b) ((a)*(b))
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define REF_DIV(a,b) ((a)/(b))
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> void packetmath()
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
1147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  using std::abs;
1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int max_size = PacketSize > 4 ? PacketSize : 4;
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int size = PacketSize*max_size;
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data1[size];
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data2[size];
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Packet packets[PacketSize*2];
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar ref[size];
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar refvalue = 0;
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data2[i] = internal::random<Scalar>()/RealScalar(PacketSize);
1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    refvalue = (std::max)(refvalue,abs(data1[i]));
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(data2, internal::pload<Packet>(data1));
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int offset=0; offset<PacketSize; ++offset)
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::pstore(data2, internal::ploadu<Packet>(data1+offset));
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(areApprox(data1+offset, data2, PacketSize) && "internal::ploadu");
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int offset=0; offset<PacketSize; ++offset)
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::pstoreu(data2+offset, internal::pload<Packet>(data1));
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(areApprox(data1, data2+offset, PacketSize) && "internal::pstoreu");
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int offset=0; offset<PacketSize; ++offset)
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    packets[0] = internal::pload<Packet>(data1);
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    packets[1] = internal::pload<Packet>(data1+PacketSize);
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         if (offset==0) internal::palign<0>(packets[0], packets[1]);
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if (offset==1) internal::palign<1>(packets[0], packets[1]);
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if (offset==2) internal::palign<2>(packets[0], packets[1]);
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if (offset==3) internal::palign<3>(packets[0], packets[1]);
1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==4) internal::palign<4>(packets[0], packets[1]);
1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==5) internal::palign<5>(packets[0], packets[1]);
1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==6) internal::palign<6>(packets[0], packets[1]);
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==7) internal::palign<7>(packets[0], packets[1]);
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==8) internal::palign<8>(packets[0], packets[1]);
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==9) internal::palign<9>(packets[0], packets[1]);
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==10) internal::palign<10>(packets[0], packets[1]);
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==11) internal::palign<11>(packets[0], packets[1]);
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==12) internal::palign<12>(packets[0], packets[1]);
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==13) internal::palign<13>(packets[0], packets[1]);
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==14) internal::palign<14>(packets[0], packets[1]);
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    else if (offset==15) internal::palign<15>(packets[0], packets[1]);
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::pstore(data2, packets[0]);
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (int i=0; i<PacketSize; ++i)
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ref[i] = data1[i+offset];
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(areApprox(ref, data2, PacketSize) && "internal::palign");
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasAdd);
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasSub);
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMul);
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasNegate);
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((internal::is_same<Scalar,int>::value) || (!PacketTraits::Vectorizable) || PacketTraits::HasDiv);
1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasAdd, REF_ADD,  internal::padd);
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasSub, REF_SUB,  internal::psub);
1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasMul, REF_MUL,  internal::pmul);
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasDiv, REF_DIV, internal::pdiv);
1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  CHECK_CWISE1(internal::negate, internal::pnegate);
1897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CHECK_CWISE1(numext::conj, internal::pconj);
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int offset=0;offset<3;++offset)
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (int i=0; i<PacketSize; ++i)
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ref[i] = data1[offset];
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::pstore(data2, internal::pset1<Packet>(data1[offset]));
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pset1");
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<PacketSize*4; ++i)
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i] = data1[i/PacketSize];
2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Packet A0, A1, A2, A3;
2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pbroadcast4<Packet>(data1, A0, A1, A2, A3);
2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+0*PacketSize, A0);
2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+1*PacketSize, A1);
2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+2*PacketSize, A2);
2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+3*PacketSize, A3);
2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(areApprox(ref, data2, 4*PacketSize) && "internal::pbroadcast4");
2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<PacketSize*2; ++i)
2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i] = data1[i/PacketSize];
2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Packet A0, A1;
2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pbroadcast2<Packet>(data1, A0, A1);
2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+0*PacketSize, A0);
2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2+1*PacketSize, A1);
2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(areApprox(ref, data2, 2*PacketSize) && "internal::pbroadcast2");
2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(internal::isApprox(data1[0], internal::pfirst(internal::pload<Packet>(data1))) && "internal::pfirst");
2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(PacketSize>1)
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int offset=0;offset<4;++offset)
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(int i=0;i<PacketSize/2;++i)
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ref[2*i+0] = ref[2*i+1] = data1[offset+i];
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      internal::pstore(data2,internal::ploaddup<Packet>(data1+offset));
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      VERIFY(areApprox(ref, data2, PacketSize) && "ploaddup");
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(PacketSize>2)
2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for(int offset=0;offset<4;++offset)
2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      for(int i=0;i<PacketSize/4;++i)
2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        ref[4*i+0] = ref[4*i+1] = ref[4*i+2] = ref[4*i+3] = data1[offset+i];
2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      internal::pstore(data2,internal::ploadquad<Packet>(data1+offset));
2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(areApprox(ref, data2, PacketSize) && "ploadquad");
2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ref[0] = 0;
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[0] += data1[i];
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(isApproxAbs(ref[0], internal::predux(internal::pload<Packet>(data1)), refvalue) && "internal::predux");
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<4; ++i)
2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i] = 0;
2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<PacketSize; ++i)
2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i%4] += data1[i];
2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2, internal::predux_downto4(internal::pload<Packet>(data1)));
2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(areApprox(ref, data2, PacketSize>4?PacketSize/2:PacketSize) && "internal::predux_downto4");
2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ref[0] = 1;
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[0] *= data1[i];
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(internal::isApprox(ref[0], internal::predux_mul(internal::pload<Packet>(data1))) && "internal::predux_mul");
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int j=0; j<PacketSize; ++j)
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[j] = 0;
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (int i=0; i<PacketSize; ++i)
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ref[j] += data1[i+j*PacketSize];
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    packets[j] = internal::pload<Packet>(data1+j*PacketSize);
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(data2, internal::preduxp(packets));
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApproxAbs(ref, data2, PacketSize, refvalue) && "internal::preduxp");
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] = data1[PacketSize-i-1];
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(data2, internal::preverse(internal::pload<Packet>(data1)));
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, data2, PacketSize) && "internal::preverse");
2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  internal::PacketBlock<Packet> kernel;
2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<PacketSize; ++i) {
2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    kernel.packet[i] = internal::pload<Packet>(data1+i*PacketSize);
2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  ptranspose(kernel);
2842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<PacketSize; ++i) {
2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2, kernel.packet[i]);
2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int j = 0; j < PacketSize; ++j) {
2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isApproxAbs(data2[j], data1[i+j*PacketSize], refvalue) && "ptranspose");
2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if (PacketTraits::HasBlend) {
2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Packet thenPacket = internal::pload<Packet>(data1);
2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Packet elsePacket = internal::pload<Packet>(data2);
2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_ALIGN_MAX internal::Selector<PacketSize> selector;
2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i = 0; i < PacketSize; ++i) {
2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      selector.select[i] = i;
2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Packet blend = internal::pblend(selector, thenPacket, elsePacket);
3002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_ALIGN_MAX Scalar result[size];
3012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(result, blend);
3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i = 0; i < PacketSize; ++i) {
3032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isApproxAbs(result[i], (selector.select[i] ? data1[i] : data2[i]), refvalue));
3042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
3062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if (PacketTraits::HasBlend || g_vectorize_sse) {
3082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // pinsertfirst
3092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<PacketSize; ++i)
3102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i] = data1[i];
3112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Scalar s = internal::random<Scalar>();
3122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    ref[0] = s;
3132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2, internal::pinsertfirst(internal::pload<Packet>(data1),s));
3142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pinsertfirst");
3152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
3162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if (PacketTraits::HasBlend || g_vectorize_sse) {
3182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // pinsertlast
3192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    for (int i=0; i<PacketSize; ++i)
3202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      ref[i] = data1[i];
3212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Scalar s = internal::random<Scalar>();
3222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    ref[PacketSize-1] = s;
3232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    internal::pstore(data2, internal::pinsertlast(internal::pload<Packet>(data1),s));
3242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(areApprox(ref, data2, PacketSize) && "internal::pinsertlast");
3252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> void packetmath_real()
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
3307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  using std::abs;
3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
3322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
3332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const int size = PacketSize*4;
3362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data1[PacketTraits::size*4];
3372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data2[PacketTraits::size*4];
3382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar ref[PacketTraits::size*4];
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
3427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
3437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
3452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasSin, std::sin, internal::psin);
3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasCos, std::cos, internal::pcos);
3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasTan, std::tan, internal::ptan);
3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasRound, numext::round, internal::pround);
3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasCeil, numext::ceil, internal::pceil);
3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasFloor, numext::floor, internal::pfloor);
3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data1[i] = internal::random<Scalar>(-1,1);
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data2[i] = internal::random<Scalar>(-1,1);
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
3582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasASin, std::asin, internal::pasin);
3592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasACos, std::acos, internal::pacos);
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data1[i] = internal::random<Scalar>(-87,88);
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data2[i] = internal::random<Scalar>(-87,88);
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
3662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasExp, std::exp, internal::pexp);
3672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<size; ++i)
3682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
3692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
3702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
3712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
3722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasTanh, std::tanh, internal::ptanh);
3732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(PacketTraits::HasExp && PacketTraits::size>=2)
3742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
3752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
3762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = std::numeric_limits<Scalar>::epsilon();
3772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<PacketTraits::HasExp,Packet> h;
3782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::pexp(h.load(data1)));
3792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
3802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(std::numeric_limits<Scalar>::epsilon()), data2[1]);
3812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = -std::numeric_limits<Scalar>::epsilon();
3832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = 0;
3842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::pexp(h.load(data1)));
3852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(-std::numeric_limits<Scalar>::epsilon()), data2[0]);
3862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(Scalar(0)), data2[1]);
3872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = (std::numeric_limits<Scalar>::min)();
3892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = -(std::numeric_limits<Scalar>::min)();
3902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::pexp(h.load(data1)));
3912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp((std::numeric_limits<Scalar>::min)()), data2[0]);
3922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(-(std::numeric_limits<Scalar>::min)()), data2[1]);
3932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::denorm_min();
3952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = -std::numeric_limits<Scalar>::denorm_min();
3962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::pexp(h.load(data1)));
3972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(std::numeric_limits<Scalar>::denorm_min()), data2[0]);
3982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::exp(-std::numeric_limits<Scalar>::denorm_min()), data2[1]);
3992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
4002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if (PacketTraits::HasTanh) {
4022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // NOTE this test migh fail with GCC prior to 6.3, see MathFunctionsImpl.h for details.
4032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
4042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<internal::packet_traits<Scalar>::HasTanh,Packet> h;
4052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::ptanh(h.load(data1)));
4062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
4082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_HAS_C99_MATH
4102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
4112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
4122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<internal::packet_traits<Scalar>::HasLGamma,Packet> h;
4132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::plgamma(h.load(data1)));
4142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
416615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray  {
417615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
4182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<internal::packet_traits<Scalar>::HasErf,Packet> h;
4192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::perf(h.load(data1)));
4202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
421615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray  }
4222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
4242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<internal::packet_traits<Scalar>::HasErfc,Packet> h;
4252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::perfc(h.load(data1)));
4262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif  // EIGEN_HAS_C99_MATH
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
4327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    data1[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
4337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    data2[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
4352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(internal::random<float>(0,1)<0.1f)
4377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    data1[internal::random<int>(0, PacketSize)] = 0;
4382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasSqrt, std::sqrt, internal::psqrt);
4392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasLog, std::log, internal::plog);
4402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L)
4412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(PacketTraits::HasLog1p, std::log1p, internal::plog1p);
4422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLGamma, std::lgamma, internal::plgamma);
4432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErf, std::erf, internal::perf);
4442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErfc, std::erfc, internal::perfc);
4452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
4462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(PacketTraits::HasLog && PacketTraits::size>=2)
448615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray  {
449615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray    data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
4502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = std::numeric_limits<Scalar>::epsilon();
4512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    packet_helper<PacketTraits::HasLog,Packet> h;
452615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray    h.store(data2, internal::plog(h.load(data1)));
4532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::log(std::numeric_limits<Scalar>::epsilon()), data2[1]);
4552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = -std::numeric_limits<Scalar>::epsilon();
4572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = 0;
4582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::plog(h.load(data1)));
4592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::log(Scalar(0)), data2[1]);
4612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = (std::numeric_limits<Scalar>::min)();
4632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = -(std::numeric_limits<Scalar>::min)();
4642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::plog(h.load(data1)));
4652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_EQUAL(std::log((std::numeric_limits<Scalar>::min)()), data2[0]);
4662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[1]));
4672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = std::numeric_limits<Scalar>::denorm_min();
4692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[1] = -std::numeric_limits<Scalar>::denorm_min();
4702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    h.store(data2, internal::plog(h.load(data1)));
4712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // VERIFY_IS_EQUAL(std::log(std::numeric_limits<Scalar>::denorm_min()), data2[0]);
4722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[1]));
4732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[0] = Scalar(-1.0f);
475615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray    h.store(data2, internal::plog(h.load(data1)));
4762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
477615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray    h.store(data2, internal::psqrt(h.load(data1)));
4782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[0]));
4792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY((numext::isnan)(data2[1]));
480615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murray  }
4817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
4827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar> void packetmath_notcomplex()
4847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
4857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  using std::abs;
4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
4872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
4882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
4892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data1[PacketTraits::size*4];
4912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data2[PacketTraits::size*4];
4922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar ref[PacketTraits::size*4];
4937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Array<Scalar,Dynamic,1>::Map(data1, PacketTraits::size*4).setRandom();
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ref[0] = data1[0];
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[0] = (std::min)(ref[0],data1[i]);
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min");
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMin);
5022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMax);
5032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasMin, (std::min), internal::pmin);
5052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  CHECK_CWISE2_IF(PacketTraits::HasMax, (std::max), internal::pmax);
5067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  CHECK_CWISE1(abs, internal::pabs);
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ref[0] = data1[0];
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[0] = (std::max)(ref[0],data1[i]);
511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max");
5122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<PacketSize; ++i)
514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] = data1[0]+Scalar(i);
5152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  internal::pstore(data2, internal::plset<Packet>(data1[0]));
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, data2, PacketSize) && "internal::plset");
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar,bool ConjLhs,bool ConjRhs> void test_conj_helper(Scalar* data1, Scalar* data2, Scalar* ref, Scalar* pval)
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
5212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
5222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
5232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
5242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::conj_if<ConjLhs> cj0;
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::conj_if<ConjRhs> cj1;
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::conj_helper<Scalar,Scalar,ConjLhs,ConjRhs> cj;
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::conj_helper<Packet,Packet,ConjLhs,ConjRhs> pcj;
5292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i=0;i<PacketSize;++i)
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] = cj0(data1[i]) * cj1(data2[i]);
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(internal::isApprox(ref[i], cj.pmul(data1[i],data2[i])) && "conj_helper pmul");
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(pval,pcj.pmul(internal::pload<Packet>(data1),internal::pload<Packet>(data2)));
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmul");
5372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i=0;i<PacketSize;++i)
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar tmp = ref[i];
541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ref[i] += cj0(data1[i]) * cj1(data2[i]);
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(internal::isApprox(ref[i], cj.pmadd(data1[i],data2[i],tmp)) && "conj_helper pmadd");
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::pstore(pval,pcj.pmadd(internal::pload<Packet>(data1),internal::pload<Packet>(data2),internal::pload<Packet>(pval)));
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmadd");
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> void packetmath_complex()
549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
5502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
5512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
5522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const int size = PacketSize*4;
5552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data1[PacketSize*4];
5562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data2[PacketSize*4];
5572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar ref[PacketSize*4];
5582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar pval[PacketSize*4];
559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<size; ++i)
561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data1[i] = internal::random<Scalar>() * Scalar(1e2);
563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    data2[i] = internal::random<Scalar>() * Scalar(1e2);
564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
5652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  test_conj_helper<Scalar,false,false> (data1,data2,ref,pval);
567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  test_conj_helper<Scalar,false,true>  (data1,data2,ref,pval);
568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  test_conj_helper<Scalar,true,false>  (data1,data2,ref,pval);
569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  test_conj_helper<Scalar,true,true>   (data1,data2,ref,pval);
5702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
571c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int i=0;i<PacketSize;++i)
573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ref[i] = Scalar(std::imag(data1[i]),std::real(data1[i]));
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::pstore(pval,internal::pcplxflip(internal::pload<Packet>(data1)));
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(areApprox(ref, pval, PacketSize) && "pcplxflip");
576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
5772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
5782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Scalar> void packetmath_scatter_gather()
5802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
5812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef internal::packet_traits<Scalar> PacketTraits;
5822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename PacketTraits::type Packet;
5832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename NumTraits<Scalar>::Real RealScalar;
5842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const int PacketSize = PacketTraits::size;
5852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar data1[PacketSize];
5862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  RealScalar refvalue = 0;
5872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<PacketSize; ++i) {
5882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
5892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
5902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  int stride = internal::random<int>(1,20);
5922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_ALIGN_MAX Scalar buffer[PacketSize*20];
5942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  memset(buffer, 0, 20*PacketSize*sizeof(Scalar));
5952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Packet packet = internal::pload<Packet>(data1);
5962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  internal::pscatter<Scalar, Packet>(buffer, packet, stride);
5972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i = 0; i < PacketSize*20; ++i) {
5992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if ((i%stride) == 0 && i<stride*PacketSize) {
6002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isApproxAbs(buffer[i], data1[i/stride], refvalue) && "pscatter");
6012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    } else {
6022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isApproxAbs(buffer[i], Scalar(0), refvalue) && "pscatter");
6032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
6042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
6052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i=0; i<PacketSize*7; ++i) {
6072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    buffer[i] = internal::random<Scalar>()/RealScalar(PacketSize);
6082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
6092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  packet = internal::pgather<Scalar, Packet>(buffer, 7);
6102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  internal::pstore(data1, packet);
6112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for (int i = 0; i < PacketSize; ++i) {
6122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(isApproxAbs(data1[i], buffer[i*7], refvalue) && "pgather");
6132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_packetmath()
617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i = 0; i < g_repeat; i++) {
619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( packetmath<float>() );
620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_2( packetmath<double>() );
621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_3( packetmath<int>() );
6222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_4( packetmath<std::complex<float> >() );
6232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_5( packetmath<std::complex<double> >() );
624c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
6257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    CALL_SUBTEST_1( packetmath_notcomplex<float>() );
6267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    CALL_SUBTEST_2( packetmath_notcomplex<double>() );
6277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    CALL_SUBTEST_3( packetmath_notcomplex<int>() );
6282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
629c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( packetmath_real<float>() );
630c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_2( packetmath_real<double>() );
631c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
6322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_4( packetmath_complex<std::complex<float> >() );
6332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_5( packetmath_complex<std::complex<double> >() );
6342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_1( packetmath_scatter_gather<float>() );
6362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_2( packetmath_scatter_gather<double>() );
6372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_3( packetmath_scatter_gather<int>() );
6382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_4( packetmath_scatter_gather<std::complex<float> >() );
6392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CALL_SUBTEST_5( packetmath_scatter_gather<std::complex<double> >() );
640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
641c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
642