00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_GENERIC_PACKET_MATH_H
00027 #define EIGEN_GENERIC_PACKET_MATH_H
00028
00029 namespace internal {
00030
00039 #ifndef EIGEN_DEBUG_ALIGNED_LOAD
00040 #define EIGEN_DEBUG_ALIGNED_LOAD
00041 #endif
00042
00043 #ifndef EIGEN_DEBUG_UNALIGNED_LOAD
00044 #define EIGEN_DEBUG_UNALIGNED_LOAD
00045 #endif
00046
00047 #ifndef EIGEN_DEBUG_ALIGNED_STORE
00048 #define EIGEN_DEBUG_ALIGNED_STORE
00049 #endif
00050
00051 #ifndef EIGEN_DEBUG_UNALIGNED_STORE
00052 #define EIGEN_DEBUG_UNALIGNED_STORE
00053 #endif
00054
00055 struct default_packet_traits
00056 {
00057 enum {
00058 HasAdd = 1,
00059 HasSub = 1,
00060 HasMul = 1,
00061 HasNegate = 1,
00062 HasAbs = 1,
00063 HasAbs2 = 1,
00064 HasMin = 1,
00065 HasMax = 1,
00066 HasConj = 1,
00067 HasSetLinear = 1,
00068
00069 HasDiv = 0,
00070 HasSqrt = 0,
00071 HasExp = 0,
00072 HasLog = 0,
00073 HasPow = 0,
00074
00075 HasSin = 0,
00076 HasCos = 0,
00077 HasTan = 0,
00078 HasASin = 0,
00079 HasACos = 0,
00080 HasATan = 0
00081 };
00082 };
00083
00084 template<typename T> struct packet_traits : default_packet_traits
00085 {
00086 typedef T type;
00087 enum {
00088 Vectorizable = 0,
00089 size = 1,
00090 AlignedOnScalar = 0
00091 };
00092 enum {
00093 HasAdd = 0,
00094 HasSub = 0,
00095 HasMul = 0,
00096 HasNegate = 0,
00097 HasAbs = 0,
00098 HasAbs2 = 0,
00099 HasMin = 0,
00100 HasMax = 0,
00101 HasConj = 0,
00102 HasSetLinear = 0
00103 };
00104 };
00105
00107 template<typename Packet> inline Packet
00108 padd(const Packet& a,
00109 const Packet& b) { return a+b; }
00110
00112 template<typename Packet> inline Packet
00113 psub(const Packet& a,
00114 const Packet& b) { return a-b; }
00115
00117 template<typename Packet> inline Packet
00118 pnegate(const Packet& a) { return -a; }
00119
00121 template<typename Packet> inline Packet
00122 pconj(const Packet& a) { return conj(a); }
00123
00125 template<typename Packet> inline Packet
00126 pmul(const Packet& a,
00127 const Packet& b) { return a*b; }
00128
00130 template<typename Packet> inline Packet
00131 pdiv(const Packet& a,
00132 const Packet& b) { return a/b; }
00133
00135 template<typename Packet> inline Packet
00136 pmin(const Packet& a,
00137 const Packet& b) { using std::min; return min(a, b); }
00138
00140 template<typename Packet> inline Packet
00141 pmax(const Packet& a,
00142 const Packet& b) { using std::max; return max(a, b); }
00143
00145 template<typename Packet> inline Packet
00146 pabs(const Packet& a) { return abs(a); }
00147
00149 template<typename Packet> inline Packet
00150 pand(const Packet& a, const Packet& b) { return a & b; }
00151
00153 template<typename Packet> inline Packet
00154 por(const Packet& a, const Packet& b) { return a | b; }
00155
00157 template<typename Packet> inline Packet
00158 pxor(const Packet& a, const Packet& b) { return a ^ b; }
00159
00161 template<typename Packet> inline Packet
00162 pandnot(const Packet& a, const Packet& b) { return a & (!b); }
00163
00165 template<typename Packet> inline Packet
00166 pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
00167
00169 template<typename Packet> inline Packet
00170 ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
00171
00173 template<typename Packet> inline Packet
00174 ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
00175
00177 template<typename Packet> inline Packet
00178 pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
00179
00181 template<typename Scalar> inline typename packet_traits<Scalar>::type
00182 plset(const Scalar& a) { return a; }
00183
00185 template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from)
00186 { (*to) = from; }
00187
00189 template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from)
00190 { (*to) = from; }
00191
00193 template<typename Scalar> inline void prefetch(const Scalar* addr)
00194 {
00195 #if !defined(_MSC_VER)
00196 __builtin_prefetch(addr);
00197 #endif
00198 }
00199
00201 template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
00202 { return a; }
00203
00205 template<typename Packet> inline Packet
00206 preduxp(const Packet* vecs) { return vecs[0]; }
00207
00209 template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a)
00210 { return a; }
00211
00213 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
00214 { return a; }
00215
00217 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
00218 { return a; }
00219
00221 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
00222 { return a; }
00223
00225 template<typename Packet> inline Packet preverse(const Packet& a)
00226 { return a; }
00227
00228
00230 template<typename Packet> inline Packet pcplxflip(const Packet& a)
00231 { return Packet(imag(a),real(a)); }
00232
00233
00234
00235
00236
00238 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00239 Packet psin(const Packet& a) { return sin(a); }
00240
00242 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00243 Packet pcos(const Packet& a) { return cos(a); }
00244
00246 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00247 Packet ptan(const Packet& a) { return tan(a); }
00248
00250 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00251 Packet pasin(const Packet& a) { return asin(a); }
00252
00254 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00255 Packet pacos(const Packet& a) { return acos(a); }
00256
00258 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00259 Packet pexp(const Packet& a) { return exp(a); }
00260
00262 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00263 Packet plog(const Packet& a) { return log(a); }
00264
00266 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00267 Packet psqrt(const Packet& a) { return sqrt(a); }
00268
00269
00270
00271
00272
00274
00275 template<typename Packet>
00276 inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
00277 {
00278 pstore(to, pset1<Packet>(a));
00279 }
00280
00282 template<typename Packet> inline Packet
00283 pmadd(const Packet& a,
00284 const Packet& b,
00285 const Packet& c)
00286 { return padd(pmul(a, b),c); }
00287
00290 template<typename Packet, int LoadMode>
00291 inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
00292 {
00293 if(LoadMode == Aligned)
00294 return pload<Packet>(from);
00295 else
00296 return ploadu<Packet>(from);
00297 }
00298
00301 template<typename Scalar, typename Packet, int LoadMode>
00302 inline void pstoret(Scalar* to, const Packet& from)
00303 {
00304 if(LoadMode == Aligned)
00305 pstore(to, from);
00306 else
00307 pstoreu(to, from);
00308 }
00309
00311 template<int Offset,typename PacketType>
00312 struct palign_impl
00313 {
00314
00315 inline static void run(PacketType&, const PacketType&) {}
00316 };
00317
00320 template<int Offset,typename PacketType>
00321 inline void palign(PacketType& first, const PacketType& second)
00322 {
00323 palign_impl<Offset,PacketType>::run(first,second);
00324 }
00325
00326
00327
00328
00329
00330 template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
00331 { return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
00332
00333 template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
00334 { return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
00335
00336 }
00337
00338 #endif // EIGEN_GENERIC_PACKET_MATH_H
00339