$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_GENERIC_PACKET_MATH_H 00012 #define EIGEN_GENERIC_PACKET_MATH_H 00013 00014 namespace Eigen { 00015 00016 namespace internal { 00017 00026 #ifndef EIGEN_DEBUG_ALIGNED_LOAD 00027 #define EIGEN_DEBUG_ALIGNED_LOAD 00028 #endif 00029 00030 #ifndef EIGEN_DEBUG_UNALIGNED_LOAD 00031 #define EIGEN_DEBUG_UNALIGNED_LOAD 00032 #endif 00033 00034 #ifndef EIGEN_DEBUG_ALIGNED_STORE 00035 #define EIGEN_DEBUG_ALIGNED_STORE 00036 #endif 00037 00038 #ifndef EIGEN_DEBUG_UNALIGNED_STORE 00039 #define EIGEN_DEBUG_UNALIGNED_STORE 00040 #endif 00041 00042 struct default_packet_traits 00043 { 00044 enum { 00045 HasAdd = 1, 00046 HasSub = 1, 00047 HasMul = 1, 00048 HasNegate = 1, 00049 HasAbs = 1, 00050 HasAbs2 = 1, 00051 HasMin = 1, 00052 HasMax = 1, 00053 HasConj = 1, 00054 HasSetLinear = 1, 00055 00056 HasDiv = 0, 00057 HasSqrt = 0, 00058 HasExp = 0, 00059 HasLog = 0, 00060 HasPow = 0, 00061 00062 HasSin = 0, 00063 HasCos = 0, 00064 HasTan = 0, 00065 HasASin = 0, 00066 HasACos = 0, 00067 HasATan = 0 00068 }; 00069 }; 00070 00071 template<typename T> struct packet_traits : default_packet_traits 00072 { 00073 typedef T type; 00074 enum { 00075 Vectorizable = 0, 00076 size = 1, 00077 AlignedOnScalar = 0 00078 }; 00079 enum { 00080 HasAdd = 0, 00081 HasSub = 0, 00082 HasMul = 0, 00083 HasNegate = 0, 00084 HasAbs = 0, 00085 HasAbs2 = 0, 00086 HasMin = 0, 00087 HasMax = 0, 00088 HasConj = 0, 00089 HasSetLinear = 0 00090 }; 00091 }; 00092 00094 template<typename Packet> inline Packet 00095 padd(const Packet& a, 00096 const Packet& b) { return a+b; } 00097 00099 template<typename Packet> inline Packet 00100 psub(const Packet& a, 00101 const Packet& b) { return a-b; } 00102 00104 template<typename Packet> inline Packet 00105 pnegate(const Packet& a) { return -a; } 00106 00108 template<typename Packet> inline Packet 00109 pconj(const Packet& a) { return numext::conj(a); } 00110 00112 template<typename Packet> inline Packet 00113 pmul(const Packet& a, 00114 const Packet& b) { return a*b; } 00115 00117 template<typename Packet> inline Packet 00118 pdiv(const Packet& a, 00119 const Packet& b) { return a/b; } 00120 00122 template<typename Packet> inline Packet 00123 pmin(const Packet& a, 00124 const Packet& b) { using std::min; return (min)(a, b); } 00125 00127 template<typename Packet> inline Packet 00128 pmax(const Packet& a, 00129 const Packet& b) { using std::max; return (max)(a, b); } 00130 00132 template<typename Packet> inline Packet 00133 pabs(const Packet& a) { using std::abs; return abs(a); } 00134 00136 template<typename Packet> inline Packet 00137 pand(const Packet& a, const Packet& b) { return a & b; } 00138 00140 template<typename Packet> inline Packet 00141 por(const Packet& a, const Packet& b) { return a | b; } 00142 00144 template<typename Packet> inline Packet 00145 pxor(const Packet& a, const Packet& b) { return a ^ b; } 00146 00148 template<typename Packet> inline Packet 00149 pandnot(const Packet& a, const Packet& b) { return a & (!b); } 00150 00152 template<typename Packet> inline Packet 00153 pload(const typename unpacket_traits<Packet>::type* from) { return *from; } 00154 00156 template<typename Packet> inline Packet 00157 ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; } 00158 00164 template<typename Packet> inline Packet 00165 ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; } 00166 00168 template<typename Packet> inline Packet 00169 pset1(const typename unpacket_traits<Packet>::type& a) { return a; } 00170 00172 template<typename Scalar> inline typename packet_traits<Scalar>::type 00173 plset(const Scalar& a) { return a; } 00174 00176 template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from) 00177 { (*to) = from; } 00178 00180 template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from) 00181 { (*to) = from; } 00182 00184 template<typename Scalar> inline void prefetch(const Scalar* addr) 00185 { 00186 #if !defined(_MSC_VER) 00187 __builtin_prefetch(addr); 00188 #endif 00189 } 00190 00192 template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a) 00193 { return a; } 00194 00196 template<typename Packet> inline Packet 00197 preduxp(const Packet* vecs) { return vecs[0]; } 00198 00200 template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a) 00201 { return a; } 00202 00204 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a) 00205 { return a; } 00206 00208 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a) 00209 { return a; } 00210 00212 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a) 00213 { return a; } 00214 00216 template<typename Packet> inline Packet preverse(const Packet& a) 00217 { return a; } 00218 00219 00221 template<typename Packet> inline Packet pcplxflip(const Packet& a) 00222 { 00223 // FIXME: uncomment the following in case we drop the internal imag and real functions. 00224 // using std::imag; 00225 // using std::real; 00226 return Packet(imag(a),real(a)); 00227 } 00228 00229 /************************** 00230 * Special math functions 00231 ***************************/ 00232 00234 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00235 Packet psin(const Packet& a) { using std::sin; return sin(a); } 00236 00238 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00239 Packet pcos(const Packet& a) { using std::cos; return cos(a); } 00240 00242 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00243 Packet ptan(const Packet& a) { using std::tan; return tan(a); } 00244 00246 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00247 Packet pasin(const Packet& a) { using std::asin; return asin(a); } 00248 00250 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00251 Packet pacos(const Packet& a) { using std::acos; return acos(a); } 00252 00254 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00255 Packet pexp(const Packet& a) { using std::exp; return exp(a); } 00256 00258 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00259 Packet plog(const Packet& a) { using std::log; return log(a); } 00260 00262 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS 00263 Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } 00264 00265 /*************************************************************************** 00266 * The following functions might not have to be overwritten for vectorized types 00267 ***************************************************************************/ 00268 00270 // NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type) 00271 template<typename Packet> 00272 inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a) 00273 { 00274 pstore(to, pset1<Packet>(a)); 00275 } 00276 00278 template<typename Packet> inline Packet 00279 pmadd(const Packet& a, 00280 const Packet& b, 00281 const Packet& c) 00282 { return padd(pmul(a, b),c); } 00283 00286 template<typename Packet, int LoadMode> 00287 inline Packet ploadt(const typename unpacket_traits<Packet>::type* from) 00288 { 00289 if(LoadMode == Aligned) 00290 return pload<Packet>(from); 00291 else 00292 return ploadu<Packet>(from); 00293 } 00294 00297 template<typename Scalar, typename Packet, int LoadMode> 00298 inline void pstoret(Scalar* to, const Packet& from) 00299 { 00300 if(LoadMode == Aligned) 00301 pstore(to, from); 00302 else 00303 pstoreu(to, from); 00304 } 00305 00307 template<int Offset,typename PacketType> 00308 struct palign_impl 00309 { 00310 // by default data are aligned, so there is nothing to be done :) 00311 static inline void run(PacketType&, const PacketType&) {} 00312 }; 00313 00329 template<int Offset,typename PacketType> 00330 inline void palign(PacketType& first, const PacketType& second) 00331 { 00332 palign_impl<Offset,PacketType>::run(first,second); 00333 } 00334 00335 /*************************************************************************** 00336 * Fast complex products (GCC generates a function call which is very slow) 00337 ***************************************************************************/ 00338 00339 template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b) 00340 { return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } 00341 00342 template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b) 00343 { return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } 00344 00345 } // end namespace internal 00346 00347 } // end namespace Eigen 00348 00349 #endif // EIGEN_GENERIC_PACKET_MATH_H 00350