CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/Math/interface/ExtVec.h

Go to the documentation of this file.
00001 #ifndef DataFormat_Math_ExtVec_H
00002 #define DataFormat_Math_ExtVec_H
00003 
00004 #include<type_traits>
00005 
00006 typedef float  __attribute__( ( vector_size(  8 ) ) ) float32x2_t;
00007 typedef float  __attribute__( ( vector_size( 16 ) ) ) float32x4_t;
00008 typedef float  __attribute__( ( vector_size( 32 ) ) ) float32x8_t;
00009 typedef double __attribute__( ( vector_size( 16 ) ) ) float64x2_t;
00010 typedef double __attribute__( ( vector_size( 32 ) ) ) float64x4_t;
00011 typedef double __attribute__( ( vector_size( 64 ) ) ) float64x8_t;
00012 
00013 
00014 // template<typename T, int N> using ExtVec =  T __attribute__( ( vector_size( N*sizeof(T) ) ) );
00015 
00016 template<typename T, int N>
00017 struct ExtVecTraits {
00018   typedef T __attribute__( ( vector_size( N*sizeof(T) ) ) ) type;
00019 };
00020 
00021 template<typename T, int N> using ExtVec =  typename ExtVecTraits<T,N>::type;
00022 
00023 template<typename T> using Vec4 = ExtVec<T,4>;
00024 template<typename T> using Vec2 = ExtVec<T,2>;
00025 
00026 template<typename V>
00027 inline
00028 auto xy(V v)-> Vec2<typename  std::remove_reference<decltype(v[0])>::type> 
00029 { 
00030   typedef typename std::remove_reference<decltype(v[0])>::type T;
00031   return Vec2<T>{v[0],v[1]};
00032 }
00033 
00034 template<typename V> 
00035 inline
00036 auto zw(V v) -> Vec2<typename  std::remove_reference<decltype(v[0])>::type> 
00037 { 
00038   typedef typename std::remove_reference<decltype(v[0])>::type T;
00039   return Vec2<T>{v[2],v[3]};
00040 }
00041 
00042 template<typename Vec, typename F> 
00043 inline
00044 Vec apply(Vec v, F f) {
00045   typedef typename std::remove_reference<decltype(v[0])>::type T;
00046   constexpr int N = sizeof(Vec)/sizeof(T);
00047   Vec ret;
00048   for (int i=0;i!=N;++i) ret[i] = f(v[i]);
00049   return ret;
00050 }
00051 
00052 
00053 template<typename Vec> 
00054 inline
00055 Vec cross3(Vec x, Vec y) {
00056   //  typedef Vec4<T> Vec;
00057   // yz - zy, zx - xz, xy - yx, 0
00058   Vec x1200{ x[1], x[2], x[0], x[0] };
00059   Vec y2010{ y[2], y[0], y[1], y[0] };
00060   Vec x2010{ x[2], x[0], x[1], x[0] };
00061   Vec y1200{ y[1], y[2], y[0], y[0] };
00062   return x1200 * y2010 - x2010 * y1200;
00063 }
00064 
00065 template<typename V1,typename V2> 
00066 inline
00067 auto cross2(V1 x, V2 y) ->typename std::remove_reference<decltype(x[0])>::type {
00068   return x[0]*y[1]-x[1]*y[0];
00069 }
00070 
00071 
00072 
00073 /*
00074 template<typename T> 
00075 T dot_product(Vec4<T>  x, Vec4<T>  y) {
00076   auto res = x*y;
00077   T ret=0;
00078   for (int i=0;i!=4;++i) ret+=res[i];
00079   return ret;
00080 }
00081 */
00082 
00083 /*
00084 template<typename V, int K> 
00085 inline
00086 V get1(V v) { return (V){v[K]}; }
00087 */
00088 
00089 /*
00090 template<typename T, int N> 
00091 inline
00092 T dot(ExtVec<T,N>  x, ExtVec<T,N>  y) {
00093   T ret=0;
00094   for (int i=0;i!=N;++i) ret+=x[i]*y[i];
00095   return ret;
00096 }
00097 */
00098 
00099 template<typename V>
00100 inline
00101 auto dot(V  x, V y) ->typename  std::remove_reference<decltype(x[0])>::type {
00102   typedef typename std::remove_reference<decltype(x[0])>::type T;
00103   constexpr int N = sizeof(V)/sizeof(T);
00104   T ret=0;
00105   for (int i=0;i!=N;++i) ret+=x[i]*y[i];
00106   return ret;
00107 }
00108 
00109 template<typename V1,typename V2 >
00110 inline
00111 auto dot2(V1  x, V2 y) ->typename  std::remove_reference<decltype(x[0])>::type {
00112   typedef typename std::remove_reference<decltype(x[0])>::type T;
00113   T ret=0;
00114   for (int i=0;i!=2;++i) ret+=x[i]*y[i];
00115   return ret;
00116 }
00117 
00118 
00119 
00120 
00121 typedef Vec2<float> Vec2F;
00122 typedef Vec4<float> Vec4F;
00123 typedef Vec4<float> Vec3F;
00124 typedef Vec2<double> Vec2D;
00125 typedef Vec4<double> Vec3D;
00126 typedef Vec4<double> Vec4D;
00127 
00128 /*
00129 template<typename T>
00130 struct As3D {
00131   Vec4<T> const & v;
00132   As3D(Vec4<T> const &iv ) : v(iv){}
00133 };
00134 template<typename T>
00135 inline As3D<T> as3D(Vec4<T> const &v ) { return v;}
00136 */
00137 
00138 template<typename V>
00139 struct As3D {
00140   V const & v;
00141   As3D(V const &iv ) : v(iv){}
00142 };
00143 template<typename V>
00144 inline As3D<V> as3D(V const &v ) { return v;}
00145 
00146 
00147 // rotations
00148 
00149 template<typename T>
00150 struct Rot3 {
00151   typedef Vec4<T> Vec;
00152   Vec  axis[3];
00153   
00154   constexpr Rot3() :
00155     axis{ (Vec){T(1),0,0,0},
00156       (Vec){0,T(1),0,0},
00157         (Vec){0,0,T(1),0}
00158   }{}
00159     
00160   constexpr Rot3( Vec4<T> ix,  Vec4<T> iy,  Vec4<T> iz) :
00161     axis{ix,iy,iz}{}
00162 
00163   constexpr Rot3( T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) :
00164     axis{ (Vec){xx,xy,xz,0},
00165       (Vec){yx,yy,yz,0},
00166         (Vec){zx,zy,zz,0}
00167   }{}
00168   
00169   constexpr Rot3 transpose() const {
00170     return Rot3( axis[0][0], axis[1][0], axis[2][0],
00171                  axis[0][1], axis[1][1], axis[2][1],
00172                  axis[0][2], axis[1][2], axis[2][2]
00173                  );
00174   }
00175   
00176   constexpr Vec4<T> x() const { return axis[0];}
00177   constexpr Vec4<T> y() const { return axis[1];}
00178   constexpr Vec4<T> z() const { return axis[2];}
00179 
00180     // toLocal...
00181     constexpr Vec4<T> rotate(Vec4<T> v) const {
00182       return transpose().rotateBack(v);
00183     }
00184 
00185 
00186     // toGlobal...
00187     constexpr Vec4<T> rotateBack(Vec4<T> v) const {
00188       return v[0]*axis[0] +  v[1]*axis[1] + v[2]*axis[2];
00189     }
00190 
00191     Rot3 rotate(Rot3 const& r) const {
00192       Rot3 tr = transpose();
00193       return Rot3(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]),tr.rotateBack(r.axis[2]));
00194     }
00195 
00196     constexpr Rot3 rotateBack(Rot3 const& r) const {
00197       return Rot3(rotateBack(r.axis[0]),rotateBack(r.axis[1]),rotateBack(r.axis[2]));
00198     }
00199 
00200 
00201   };
00202 
00203 typedef Rot3<float> Rot3F;
00204 
00205 typedef Rot3<double> Rot3D;
00206 
00207 template<typename T>
00208 inline constexpr Rot3<T>  operator *(Rot3<T> const & rh, Rot3<T> const & lh) {
00209   return lh.rotateBack(rh);
00210 }
00211 
00212 
00213 template<typename T>
00214 struct Rot2 {
00215   typedef Vec2<T> Vec;
00216   Vec2<T>  axis[2];
00217   
00218   constexpr Rot2() :
00219     axis{ (Vec){T(1),0},
00220       (Vec){0,T(1)}
00221   }{}
00222     
00223   constexpr Rot2( Vec2<T> ix,  Vec2<T> iy) :
00224     axis{ix, iy}{}
00225 
00226   constexpr Rot2( T xx, T xy, T yx, T yy) :
00227     Rot2( (Vec){xx,xy},
00228           (Vec){yx,yy}
00229           ){}
00230 
00231   constexpr Rot2 transpose() const {
00232     return Rot2( axis[0][0], axis[1][0],
00233                  axis[0][1], axis[1][1]
00234                  );
00235   }
00236 
00237   constexpr Vec2<T> x() { return axis[0];}
00238   constexpr Vec2<T> y() { return axis[1];}
00239   
00240   // toLocal...
00241   constexpr Vec2<T> rotate(Vec2<T> v) const {
00242     return transpose().rotateBack(v);
00243   }
00244   
00245 
00246     // toGlobal...
00247   constexpr  Vec2<T> rotateBack(Vec2<T> v) const {
00248     return v[0]*axis[0] +  v[1]*axis[1];
00249   }
00250   
00251   Rot2 rotate(Rot2 const& r) const {
00252     Rot2 tr = transpose();
00253     return Rot2(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]));
00254   }
00255   
00256   constexpr Rot2 rotateBack(Rot2 const& r) const {
00257     return Rot2(rotateBack(r.axis[0]),rotateBack(r.axis[1]));
00258   }
00259   
00260   
00261 };
00262 
00263   typedef Rot2<float> Rot2F;
00264 
00265   typedef Rot2<double> Rot2D;
00266 
00267 
00268 
00269 template<typename T>
00270 inline  constexpr Rot2<T>  operator *(Rot2<T> const & rh, Rot2<T> const & lh) {
00271   return lh.rotateBack(rh);
00272 }
00273 
00274 
00275 
00276 #include <iosfwd>
00277 std::ostream & operator<<(std::ostream & out, Vec2D const & v);
00278 std::ostream & operator<<(std::ostream & out, Vec2F const & v);
00279 std::ostream & operator<<(std::ostream & out, Vec4F const & v);
00280 std::ostream & operator<<(std::ostream & out, Vec4D const & v);
00281 
00282 std::ostream & operator<<(std::ostream & out, As3D<Vec4F> const & v);
00283 std::ostream & operator<<(std::ostream & out, As3D<Vec4D> const & v);
00284 
00285 std::ostream & operator<<(std::ostream & out, Rot3F const & v);
00286 std::ostream & operator<<(std::ostream & out, Rot3D const & v);
00287 std::ostream & operator<<(std::ostream & out, Rot2F const & v);
00288 std::ostream & operator<<(std::ostream & out, Rot2D const & v);
00289 
00290 
00291 #ifdef USE_INLINE_IO
00292 #include <ostream>
00293 std::ostream & operator<<(std::ostream & out,  ::Vec4F const & v) {
00294   return out << '(' << v[0] <<", " << v[1] <<", "<< v[2] <<", "<< v[3] <<')';
00295 }
00296 std::ostream & operator<<(std::ostream & out,  ::Vec4D const & v) {
00297   return out << '(' << v[0] <<", " << v[1] <<", "<< v[2] <<", "<< v[3] <<')';
00298 }
00299 std::ostream & operator<<(std::ostream & out,  ::Vec2F const & v) {
00300   return out << '(' << v[0] <<", " << v[1] <<')';
00301 }
00302 std::ostream & operator<<(std::ostream & out,  ::Vec2D const & v) {
00303   return out << '(' << v[0] <<", " << v[1] <<')';
00304 }
00305 
00306 std::ostream & operator<<(std::ostream & out, ::As3D<Vec4F> const & v) {
00307   return out << '(' << v.v[0] <<", " << v.v[1] <<", "<< v.v[2] <<')';
00308 }
00309 
00310 std::ostream & operator<<(std::ostream & out, ::As3D<Vec4D> const & v) {
00311   return out << '(' << v.v[0] <<", " << v.v[1] <<", "<< v.v[2] <<')';
00312 }
00313 
00314 std::ostream & operator<<(std::ostream & out, ::Rot3F const & r){
00315   return out << as3D(r.axis[0]) << '\n' <<  as3D(r.axis[1]) << '\n' <<  as3D(r.axis[2]);
00316 }
00317 
00318 std::ostream & operator<<(std::ostream & out, ::Rot3D const & r){
00319   return out <<  as3D(r.axis[0]) << '\n' <<  as3D(r.axis[1]) << '\n' <<  as3D(r.axis[2]);
00320 }
00321 
00322 std::ostream & operator<<(std::ostream & out, ::Rot2F const & r){
00323   return out << r.axis[0] << '\n' << r.axis[1];
00324 }
00325 
00326 std::ostream & operator<<(std::ostream & out, ::Rot2D const & r){
00327   return out << r.axis[0] << '\n' << r.axis[1];
00328 }
00329 #endif
00330 
00331 
00332 #endif