rivet is hosted by Hepforge, IPPP Durham
LorentzTrans.hh
Go to the documentation of this file.
00001 #ifndef RIVET_MATH_LORENTZTRANS
00002 #define RIVET_MATH_LORENTZTRANS
00003 
00004 #include <iostream>
00005 
00006 #include "Rivet/Math/MathHeader.hh"
00007 #include "Rivet/Math/MathUtils.hh"
00008 #include "Rivet/Math/MatrixN.hh"
00009 #include "Rivet/Math/Matrix3.hh"
00010 #include "Rivet/Math/Vector4.hh"
00011 
00012 namespace Rivet {
00013 
00014 
00015   inline double lorentzGamma(const double beta) {
00016     return 1.0 / sqrt(1 - beta*beta);
00017   }
00018 
00019 
00020   /// @brief Object implementing Lorentz transform calculations and boosts.
00021   class LorentzTransform {
00022     friend string toString(const LorentzTransform& lt);
00023 
00024   public:
00025     LorentzTransform() {
00026       _boostMatrix = Matrix<4>::mkIdentity();
00027     }
00028 
00029     LorentzTransform(const Vector3& boost) {
00030       setBoost(boost);
00031     }
00032 
00033     LorentzTransform(const double betaX, const double betaY, const double betaZ) {
00034       setBoost(betaX, betaY, betaZ);
00035     }
00036 
00037     LorentzTransform& setBoost(const Vector3& boost) {
00038       assert(boost.mod2() < 1);
00039       const double beta = boost.mod();
00040       const double gamma = lorentzGamma(beta);
00041       _boostMatrix = Matrix<4>::mkIdentity();
00042       _boostMatrix.set(0, 0, gamma);
00043       _boostMatrix.set(1, 1, gamma);
00044       // Positive coeff since these are active boosts
00045       _boostMatrix.set(0, 1, +beta*gamma);
00046       _boostMatrix.set(1, 0, +beta*gamma);
00047       _boostMatrix = rotate(Vector3::mkX(), boost)._boostMatrix;
00048       return *this;
00049     }
00050 
00051   //   LorentzTransform& setBoost(const Vector3& boostdirection, const double beta) {
00052   //     const Vector3 boost = boostdirection.unit() * beta;
00053   //     return setBoost(boost);
00054   //   }
00055 
00056     LorentzTransform& setBoost(const double betaX, const double betaY, const double betaZ) {
00057       return setBoost(Vector3(betaX, betaY, betaZ));
00058     }
00059 
00060     Vector3 boost() const {
00061       FourMomentum boost(_boostMatrix.getColumn(0));
00062       //cout << "!!!" << boost << endl;
00063       if (boost.isZero()) return boost;
00064       assert(boost.E() > 0);
00065       const double beta = boost.p().mod() / boost.E();
00066       return boost.p().unit() * beta;
00067     }
00068 
00069     double beta() const {
00070       return boost().mod();
00071     }
00072 
00073     double gamma() const {
00074       return lorentzGamma(beta());
00075     }
00076 
00077     LorentzTransform rotate(const Vector3& from, const Vector3& to) const {
00078       return rotate(Matrix3(from, to));
00079     }
00080 
00081     LorentzTransform rotate(const Vector3& axis, const double angle) const {
00082       return rotate(Matrix3(axis, angle));
00083     }
00084 
00085     LorentzTransform rotate(const Matrix3& rot) const {
00086       LorentzTransform lt = *this;
00087       const Matrix4 rot4 = mkMatrix4(rot);
00088       const Matrix4 newlt = rot4 * _boostMatrix * rot4.inverse();
00089       lt._boostMatrix = newlt;
00090       return lt;
00091     }
00092 
00093     FourVector transform(const FourVector& v4) const {
00094       return multiply(_boostMatrix, v4);
00095     }
00096 
00097     LorentzTransform inverse() const {
00098       LorentzTransform rtn;
00099       rtn._boostMatrix = _boostMatrix.inverse();
00100       return rtn;
00101     }
00102 
00103 
00104     /// Combine LTs, treating @a this as the LH matrix.
00105     LorentzTransform combine(const LorentzTransform& lt) const {
00106       LorentzTransform rtn;
00107       rtn._boostMatrix = _boostMatrix * lt._boostMatrix;
00108       return rtn;
00109     }
00110 
00111     Matrix4 toMatrix() const {
00112       return _boostMatrix;
00113     }
00114 
00115 
00116     LorentzTransform operator*(const LorentzTransform& lt) const {
00117       return combine(lt);
00118     }
00119 
00120     LorentzTransform preMult(const Matrix3 & m3) {
00121       _boostMatrix = multiply(mkMatrix4(m3),_boostMatrix);
00122       return *this;
00123     }
00124 
00125     LorentzTransform postMult(const Matrix3 & m3) {
00126       _boostMatrix *= mkMatrix4(m3);
00127       return *this;
00128     }
00129 
00130   private:
00131     Matrix4 mkMatrix4(const Matrix3& m3) const {
00132       Matrix4 m4 = Matrix4::mkIdentity();
00133       for (size_t i = 0; i < 3; ++i) {
00134         for (size_t j = 0; j < 3; ++j) {
00135           m4.set(i+1, j+1, m3.get(i, j));
00136         }
00137       }
00138       return m4;
00139     }
00140 
00141 
00142   private:
00143     Matrix4 _boostMatrix;
00144 
00145   };
00146 
00147 
00148 
00149   inline LorentzTransform inverse(const LorentzTransform& lt) {
00150     return lt.inverse();
00151   }
00152 
00153   inline LorentzTransform combine(const LorentzTransform& a, const LorentzTransform& b) {
00154     return a.combine(b);
00155   }
00156 
00157   inline FourVector transform(const LorentzTransform& lt, const FourVector& v4) {
00158       return lt.transform(v4);
00159   }
00160 
00161 
00162   //////////////////////////
00163 
00164 
00165   inline string toString(const LorentzTransform& lt) {
00166     return toString(lt._boostMatrix);
00167   }
00168 
00169   inline ostream& operator<<(std::ostream& out, const LorentzTransform& lt) {
00170     out << toString(lt);
00171     return out;
00172   }
00173 
00174 
00175 }
00176 
00177 #endif