Main MRPT website > C++ reference
MRPT logo

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 
00031 /** \internal
00032   * \file GenericPacketMath.h
00033   *
00034   * Default implementation for types not supported by the vectorization.
00035   * In practice these functions are provided to make easier the writing
00036   * of generic vectorized code.
00037   */
00038 
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 
00106 /** \internal \returns a + b (coeff-wise) */
00107 template<typename Packet> inline Packet
00108 padd(const Packet& a,
00109         const Packet& b) { return a+b; }
00110 
00111 /** \internal \returns a - b (coeff-wise) */
00112 template<typename Packet> inline Packet
00113 psub(const Packet& a,
00114         const Packet& b) { return a-b; }
00115 
00116 /** \internal \returns -a (coeff-wise) */
00117 template<typename Packet> inline Packet
00118 pnegate(const Packet& a) { return -a; }
00119 
00120 /** \internal \returns conj(a) (coeff-wise) */
00121 template<typename Packet> inline Packet
00122 pconj(const Packet& a) { return conj(a); }
00123 
00124 /** \internal \returns a * b (coeff-wise) */
00125 template<typename Packet> inline Packet
00126 pmul(const Packet& a,
00127         const Packet& b) { return a*b; }
00128 
00129 /** \internal \returns a / b (coeff-wise) */
00130 template<typename Packet> inline Packet
00131 pdiv(const Packet& a,
00132         const Packet& b) { return a/b; }
00133 
00134 /** \internal \returns the min of \a a and \a b  (coeff-wise) */
00135 template<typename Packet> inline Packet
00136 pmin(const Packet& a,
00137         const Packet& b) { return std::min(a, b); }
00138 
00139 /** \internal \returns the max of \a a and \a b  (coeff-wise) */
00140 template<typename Packet> inline Packet
00141 pmax(const Packet& a,
00142         const Packet& b) { return std::max(a, b); }
00143 
00144 /** \internal \returns the absolute value of \a a */
00145 template<typename Packet> inline Packet
00146 pabs(const Packet& a) { return abs(a); }
00147 
00148 /** \internal \returns the bitwise and of \a a and \a b */
00149 template<typename Packet> inline Packet
00150 pand(const Packet& a, const Packet& b) { return a & b; }
00151 
00152 /** \internal \returns the bitwise or of \a a and \a b */
00153 template<typename Packet> inline Packet
00154 por(const Packet& a, const Packet& b) { return a | b; }
00155 
00156 /** \internal \returns the bitwise xor of \a a and \a b */
00157 template<typename Packet> inline Packet
00158 pxor(const Packet& a, const Packet& b) { return a ^ b; }
00159 
00160 /** \internal \returns the bitwise andnot of \a a and \a b */
00161 template<typename Packet> inline Packet
00162 pandnot(const Packet& a, const Packet& b) { return a & (!b); }
00163 
00164 /** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
00165 template<typename Packet> inline Packet
00166 pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
00167 
00168 /** \internal \returns a packet version of \a *from, (un-aligned load) */
00169 template<typename Packet> inline Packet
00170 ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
00171 
00172 /** \internal \returns a packet with elements of \a *from duplicated, e.g.: (from[0],from[0],from[1],from[1]) */
00173 template<typename Packet> inline Packet
00174 ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
00175 
00176 /** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
00177 template<typename Packet> inline Packet
00178 pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
00179 
00180 /** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
00181 template<typename Scalar> inline typename packet_traits<Scalar>::type
00182 plset(const Scalar& a) { return a; }
00183 
00184 /** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
00185 template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from)
00186 { (*to) = from; }
00187 
00188 /** \internal copy the packet \a from to \a *to, (un-aligned store) */
00189 template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from)
00190 { (*to) = from; }
00191 
00192 /** \internal tries to do cache prefetching of \a addr */
00193 template<typename Scalar> inline void prefetch(const Scalar* addr)
00194 {
00195 #if !defined(_MSC_VER)
00196 __builtin_prefetch(addr);
00197 #endif
00198 }
00199 
00200 /** \internal \returns the first element of a packet */
00201 template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
00202 { return a; }
00203 
00204 /** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
00205 template<typename Packet> inline Packet
00206 preduxp(const Packet* vecs) { return vecs[0]; }
00207 
00208 /** \internal \returns the sum of the elements of \a a*/
00209 template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a)
00210 { return a; }
00211 
00212 /** \internal \returns the product of the elements of \a a*/
00213 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
00214 { return a; }
00215 
00216 /** \internal \returns the min of the elements of \a a*/
00217 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
00218 { return a; }
00219 
00220 /** \internal \returns the max of the elements of \a a*/
00221 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
00222 { return a; }
00223 
00224 /** \internal \returns the reversed elements of \a a*/
00225 template<typename Packet> inline Packet preverse(const Packet& a)
00226 { return a; }
00227 
00228 /**************************
00229 * Special math functions
00230 ***************************/
00231 
00232 /** \internal \returns the sin of \a a (coeff-wise) */
00233 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00234 Packet psin(const Packet& a) { return sin(a); }
00235 
00236 /** \internal \returns the cos of \a a (coeff-wise) */
00237 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00238 Packet pcos(const Packet& a) { return cos(a); }
00239 
00240 /** \internal \returns the exp of \a a (coeff-wise) */
00241 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00242 Packet pexp(const Packet& a) { return exp(a); }
00243 
00244 /** \internal \returns the log of \a a (coeff-wise) */
00245 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00246 Packet plog(const Packet& a) { return log(a); }
00247 
00248 /** \internal \returns the square-root of \a a (coeff-wise) */
00249 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
00250 Packet psqrt(const Packet& a) { return sqrt(a); }
00251 
00252 /***************************************************************************
00253 * The following functions might not have to be overwritten for vectorized types
00254 ***************************************************************************/
00255 
00256 /** \internal \returns a * b + c (coeff-wise) */
00257 template<typename Packet> inline Packet
00258 pmadd(const Packet&  a,
00259          const Packet&  b,
00260          const Packet&  c)
00261 { return padd(pmul(a, b),c); }
00262 
00263 /** \internal \returns a packet version of \a *from.
00264   * \If LoadMode equals Aligned, \a from must be 16 bytes aligned */
00265 template<typename Packet, int LoadMode>
00266 inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
00267 {
00268   if(LoadMode == Aligned)
00269     return pload<Packet>(from);
00270   else
00271     return ploadu<Packet>(from);
00272 }
00273 
00274 /** \internal copy the packet \a from to \a *to.
00275   * If StoreMode equals Aligned, \a to must be 16 bytes aligned */
00276 template<typename Scalar, typename Packet, int LoadMode>
00277 inline void pstoret(Scalar* to, const Packet& from)
00278 {
00279   if(LoadMode == Aligned)
00280     pstore(to, from);
00281   else
00282     pstoreu(to, from);
00283 }
00284 
00285 /** \internal default implementation of palign() allowing partial specialization */
00286 template<int Offset,typename PacketType>
00287 struct palign_impl
00288 {
00289   // by default data are aligned, so there is nothing to be done :)
00290   inline static void run(PacketType&, const PacketType&) {}
00291 };
00292 
00293 /** \internal update \a first using the concatenation of the \a Offset last elements
00294   * of \a first and packet_size minus \a Offset first elements of \a second */
00295 template<int Offset,typename PacketType>
00296 inline void palign(PacketType& first, const PacketType& second)
00297 {
00298   palign_impl<Offset,PacketType>::run(first,second);
00299 }
00300 
00301 /***************************************************************************
00302 * Fast complex products (GCC generates a function call which is very slow)
00303 ***************************************************************************/
00304 
00305 template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
00306 { return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
00307 
00308 template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
00309 { return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
00310 
00311 } // end namespace internal
00312 
00313 #endif // EIGEN_GENERIC_PACKET_MATH_H
00314 



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:40:17 UTC 2011