GenericPacketMath.h
Go to the documentation of this file.
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 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
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 * Special math functions
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 * The following functions might not have to be overwritten for vectorized types
00271 ***************************************************************************/
00272 
00274 // NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
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   // by default data are aligned, so there is nothing to be done :)
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 * Fast complex products (GCC generates a function call which is very slow)
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 } // end namespace internal
00337 
00338 #endif // EIGEN_GENERIC_PACKET_MATH_H
00339 


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:44