CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/GeometryVector/interface/sseBasic3DVector.h

Go to the documentation of this file.
00001 #ifndef GeometryVector_newBasic3DVector_h
00002 #define GeometryVector_newBasic3DVector_h
00003 
00004 #include "DataFormats/GeometryVector/interface/Basic2DVector.h"
00005 #include "DataFormats/GeometryVector/interface/Theta.h"
00006 #include "DataFormats/GeometryVector/interface/Phi.h"
00007 #include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
00008 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
00009 #include "DataFormats/Math/interface/SSEVec.h"
00010 #include <iosfwd>
00011 #include <cmath>
00012 
00013 namespace detailsBasic3DVector {
00014   inline float __attribute__((always_inline)) __attribute__ ((pure))
00015   eta(float x, float y, float z) { float t(z/std::sqrt(x*x+y*y)); return ::asinhf(t);} 
00016   inline double __attribute__((always_inline)) __attribute__ ((pure))
00017   eta(double x, double y, double z) { double t(z/std::sqrt(x*x+y*y)); return ::asinh(t);} 
00018   inline long double __attribute__((always_inline)) __attribute__ ((pure))
00019   eta(long double x, long double y, long double z) { long double t(z/std::sqrt(x*x+y*y)); return ::asinhl(t);} 
00020 }
00021 
00022 
00023 template < typename T> 
00024 class Basic3DVector {
00025 public:
00026 
00027   typedef T                                   ScalarType;
00028   typedef mathSSE::Vec4<T>                    VectorType;
00029   typedef mathSSE::Vec4<T>                    MathVector;
00030   typedef Geom::Cylindrical2Cartesian<T>      Cylindrical;
00031   typedef Geom::Spherical2Cartesian<T>        Spherical;
00032   typedef Spherical                           Polar; // synonym
00033     
00038   Basic3DVector() {}
00039 
00041   Basic3DVector( const Basic3DVector & p) : 
00042     v(p.v) {}
00043 
00045   template <class U>
00046   Basic3DVector( const Basic3DVector<U> & p) : 
00047     v(p.v) {}
00048 
00049 
00051   Basic3DVector( const Basic2DVector<T> & p) : 
00052     v(p.x(),p.y(),0) {}
00053 
00054  
00063   template <class OtherPoint> 
00064   explicit Basic3DVector( const OtherPoint& p) : 
00065         v(p.x(),p.y(),p.z()) {}
00066 
00067 
00068   // constructor from Vec4
00069   template<class U>
00070   Basic3DVector(mathSSE::Vec4<U> const& iv) : v(iv){}
00071 
00073   Basic3DVector( const T& x, const T& y, const T& z, const T&w=0) : 
00074     v(x,y,z,w){}
00075 
00080   template <typename U>
00081   Basic3DVector( const Geom::Theta<U>& theta, 
00082                  const Geom::Phi<U>& phi, const T& r) {
00083     Polar p( theta.value(), phi.value(), r);
00084     v.o.theX = p.x(); v.o.theY = p.y(); v.o.theZ = p.z();
00085   }
00086 
00087   MathVector const & mathVector() const { return v;}
00088   MathVector & mathVector() { return v;}
00089 
00090   T operator[](int i) const { return v[i];}
00091   T & operator[](int i) { return v[i];}
00092 
00094   T x() const { return v.o.theX;}
00095 
00097   T y() const { return v.o.theY;}
00098 
00100   T z() const { return v.o.theZ;}
00101 
00102   T w() const { return v.o.theW;}
00103 
00104   Basic2DVector<T> xy() const { return v.xy();}
00105 
00106   // equality
00107   bool operator==(const Basic3DVector& rh) const {
00108     return v==rh.v;
00109   }
00110 
00112   T mag2() const { return  ::dot(v,v);}
00113 
00115   T mag() const  { return std::sqrt( mag2());}
00116 
00118   T perp2() const { return ::dotxy(v,v);}
00119 
00121   T perp() const { return std::sqrt( perp2());}
00122 
00124   T transverse() const { return perp();}
00125 
00130   T barePhi() const {return std::atan2(y(),x());}
00131   Geom::Phi<T> phi() const {return Geom::Phi<T>(barePhi());}
00132 
00137   T bareTheta() const {return std::atan2(perp(),z());}
00138   Geom::Theta<T> theta() const {return Geom::Theta<T>(std::atan2(perp(),z()));}
00139 
00144   // T eta() const { return -log( tan( theta()/2.));} 
00145   T eta() const { return detailsBasic3DVector::eta(x(),y(),z());} // correct 
00146 
00150   Basic3DVector unit() const {
00151     T my_mag = mag2();
00152     return (0!=my_mag) ? (*this)*(T(1)/std::sqrt(my_mag)) : *this;
00153   }
00154 
00157   template <class U> 
00158   Basic3DVector& operator+= ( const Basic3DVector<U>& p) {
00159     v = v + p.v;
00160     return *this;
00161   } 
00162 
00165   template <class U> 
00166   Basic3DVector& operator-= ( const Basic3DVector<U>& p) {
00167     v = v - p.v;
00168     return *this;
00169   } 
00170 
00172   Basic3DVector operator-() const { return Basic3DVector(-v);}
00173 
00175   Basic3DVector& operator*= ( T t) {
00176     v = t*v;
00177     return *this;
00178   } 
00179 
00181   Basic3DVector& operator/= ( T t) {
00182     //t = T(1)/t;
00183     v = v/t;
00184     return *this;
00185   } 
00186 
00188   T dot( const Basic3DVector& rh) const { 
00189     return ::dot(v,rh.v);
00190   }
00191 
00197   template <class U> 
00198   typename PreciseFloatType<T,U>::Type dot( const Basic3DVector<U>& lh) const { 
00199     return Basic3DVector<typename PreciseFloatType<T,U>::Type>(*this)
00200       .dot(Basic3DVector<typename PreciseFloatType<T,U>::Type>(lh));
00201   }
00202 
00204   Basic3DVector cross( const Basic3DVector& lh) const {
00205     return ::cross(v,lh.v);
00206   }
00207 
00208 
00214   template <class U> 
00215   Basic3DVector<typename PreciseFloatType<T,U>::Type> 
00216   cross( const Basic3DVector<U>& lh) const {
00217     return Basic3DVector<typename PreciseFloatType<T,U>::Type>(*this)
00218       .cross(Basic3DVector<typename PreciseFloatType<T,U>::Type>(lh));
00219   }
00220 
00221 public:
00222   mathSSE::Vec4<T> v;
00223 }  __attribute__ ((aligned (16)));
00224 
00225 
00226 namespace geometryDetails {
00227   std::ostream & print3D(std::ostream& s, double x, double y, double z);
00228 }
00229 
00231 template <class T>
00232 inline std::ostream & operator<<( std::ostream& s, const Basic3DVector<T>& v) {
00233   return geometryDetails::print3D(s, v.x(),v.y(), v.z());
00234 }
00235 
00236 
00238 template <class T>
00239 inline Basic3DVector<T>
00240 operator+( const Basic3DVector<T>& a, const Basic3DVector<T>& b) {
00241   return a.v+b.v;
00242 }
00243 template <class T>
00244 inline Basic3DVector<T>
00245 operator-( const Basic3DVector<T>& a, const Basic3DVector<T>& b) {
00246   return a.v-b.v;
00247 }
00248 
00249 template <class T, class U>
00250 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00251 operator+( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00252   typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00253   return RT(a).v+RT(b).v;
00254 }
00255 
00256 template <class T, class U>
00257 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00258 operator-( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00259   typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00260   return RT(a).v-RT(b).v;
00261 }
00262 
00264 template <class T>
00265 inline T operator*( const Basic3DVector<T>& v1, const Basic3DVector<T>& v2) {
00266   return v1.dot(v2);
00267 }
00268 
00270 template <class T, class U>
00271 inline typename PreciseFloatType<T,U>::Type operator*( const Basic3DVector<T>& v1, 
00272                                                        const Basic3DVector<U>& v2) {
00273   return  v1.dot(v2);
00274 }
00275 
00279 template <class T>
00280 inline Basic3DVector<T> operator*( const Basic3DVector<T>& v, T t) {
00281   return v.v*t;
00282 }
00283 
00285 template <class T>
00286 inline Basic3DVector<T> operator*(T t, const Basic3DVector<T>& v) {
00287   return v.v*t;
00288 }
00289 
00290 
00291 
00292 template <class T, typename S>
00293 inline Basic3DVector<T> operator*(S t,  const Basic3DVector<T>& v) {
00294   return static_cast<T>(t)*v;
00295 }
00296 
00297 template <class T, typename S>
00298 inline Basic3DVector<T> operator*(const Basic3DVector<T>& v, S t) {
00299   return static_cast<T>(t)*v;
00300 }
00301 
00302 
00306 template <class T>
00307 inline Basic3DVector<T> operator/(const Basic3DVector<T>& v, T t) {
00308   return v.v/t;
00309 }
00310 
00311 template <class T, typename S>
00312 inline Basic3DVector<T> operator/( const Basic3DVector<T>& v, S s) {
00313   //  T t = S(1)/s; return v*t;
00314   T t = s;
00315   return v/t;
00316 }
00317 
00318 
00319 typedef Basic3DVector<float> Basic3DVectorF;
00320 typedef Basic3DVector<double> Basic3DVectorD;
00321 
00322 
00323 //  add long double specialization
00324 #include "Basic3DVectorLD.h"
00325 
00326 #endif // GeometryVector_Basic3DVector_h
00327 
00328