Boost.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: Boost.cxx 24923 2008-07-23 15:43:05Z moneta $
00002 // Authors:  M. Fischler  2005  
00003 
00004  /**********************************************************************
00005   *                                                                    *
00006   * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team                    *
00007   *                                                                    *
00008   *                                                                    *
00009   **********************************************************************/
00010 
00011 // Header file for class Boost, a 4x4 symmetric matrix representation of
00012 // an axial Lorentz transformation
00013 //
00014 // Created by: Mark Fischler Mon Nov 1  2005
00015 //
00016 #include "Math/GenVector/Boost.h"
00017 #include "Math/GenVector/LorentzVector.h"
00018 #include "Math/GenVector/PxPyPzE4D.h"
00019 #include "Math/GenVector/DisplacementVector3D.h"
00020 #include "Math/GenVector/Cartesian3D.h"
00021 #include "Math/GenVector/GenVector_exception.h"
00022 
00023 #include <cmath>
00024 #include <algorithm>
00025 
00026 //#ifdef TEX
00027 /**   
00028 
00029         A variable names bgamma appears in several places in this file. A few
00030         words of elaboration are needed to make its meaning clear.  On page 69
00031         of Misner, Thorne and Wheeler, (Exercise 2.7) the elements of the matrix
00032         for a general Lorentz boost are given as
00033 
00034         \f[     \Lambda^{j'}_k = \Lambda^{k'}_j
00035                              = (\gamma - 1) n^j n^k + \delta^{jk}  \f]
00036 
00037         where the n^i are unit vectors in the direction of the three spatial
00038         axes.  Using the definitions, \f$ n^i = \beta_i/\beta \f$ , then, for example,
00039 
00040         \f[     \Lambda_{xy} = (\gamma - 1) n_x n_y
00041                              = (\gamma - 1) \beta_x \beta_y/\beta^2  \f]
00042 
00043         By definition, \f[      \gamma^2 = 1/(1 - \beta^2)  \f]
00044 
00045         so that \f[     \gamma^2 \beta^2 = \gamma^2 - 1  \f]
00046 
00047         or      \f[     \beta^2 = (\gamma^2 - 1)/\gamma^2  \f]
00048 
00049         If we insert this into the expression for \f$ \Lambda_{xy} \f$, we get
00050 
00051         \f[     \Lambda_{xy} = (\gamma - 1) \gamma^2/(\gamma^2 - 1) \beta_x \beta_y \f]
00052 
00053         or, finally
00054 
00055         \f[     \Lambda_{xy} = \gamma^2/(\gamma+1) \beta_x \beta_y  \f]
00056 
00057         The expression \f$ \gamma^2/(\gamma+1) \f$ is what we call <em>bgamma</em> in the code below.
00058 
00059         \class ROOT::Math::Boost
00060 */
00061 //#endif
00062 
00063 namespace ROOT {
00064 
00065 namespace Math {
00066 
00067 void Boost::SetIdentity() {
00068    // set identity boost
00069    fM[kXX] = 1.0;  fM[kXY] = 0.0; fM[kXZ] = 0.0; fM[kXT] = 0.0;
00070    fM[kYY] = 1.0; fM[kYZ] = 0.0; fM[kYT] = 0.0;
00071    fM[kZZ] = 1.0; fM[kZT] = 0.0;
00072    fM[kTT] = 1.0;
00073 }
00074 
00075 
00076 void Boost::SetComponents (Scalar bx, Scalar by, Scalar bz) {
00077    // set the boost beta as 3 components
00078    Scalar bp2 = bx*bx + by*by + bz*bz;
00079    if (bp2 >= 1) {
00080       GenVector::Throw ( 
00081                               "Beta Vector supplied to set Boost represents speed >= c");
00082       // SetIdentity(); 
00083       return;
00084    }    
00085    Scalar gamma = 1.0 / std::sqrt(1.0 - bp2);
00086    Scalar bgamma = gamma * gamma / (1.0 + gamma);
00087    fM[kXX] = 1.0 + bgamma * bx * bx;
00088    fM[kYY] = 1.0 + bgamma * by * by;
00089    fM[kZZ] = 1.0 + bgamma * bz * bz;
00090    fM[kXY] = bgamma * bx * by;
00091    fM[kXZ] = bgamma * bx * bz;
00092    fM[kYZ] = bgamma * by * bz;
00093    fM[kXT] = gamma * bx;
00094    fM[kYT] = gamma * by;
00095    fM[kZT] = gamma * bz;
00096    fM[kTT] = gamma;
00097 }
00098 
00099 void Boost::GetComponents (Scalar& bx, Scalar& by, Scalar& bz) const {
00100    // get beta of the boots as 3 components
00101    Scalar gaminv = 1.0/fM[kTT];
00102    bx = fM[kXT]*gaminv;
00103    by = fM[kYT]*gaminv;
00104    bz = fM[kZT]*gaminv;
00105 }
00106 
00107 DisplacementVector3D< Cartesian3D<Boost::Scalar> >
00108 Boost::BetaVector() const {
00109    // get boost beta vector
00110    Scalar gaminv = 1.0/fM[kTT];
00111    return DisplacementVector3D< Cartesian3D<Scalar> >
00112       ( fM[kXT]*gaminv, fM[kYT]*gaminv, fM[kZT]*gaminv );
00113 }
00114 
00115 void Boost::GetLorentzRotation (Scalar r[]) const {
00116    // get Lorentz rotation corresponding to this boost as an array of 16 values 
00117    r[kLXX] = fM[kXX];  r[kLXY] = fM[kXY];  r[kLXZ] = fM[kXZ];  r[kLXT] = fM[kXT];  
00118    r[kLYX] = fM[kXY];  r[kLYY] = fM[kYY];  r[kLYZ] = fM[kYZ];  r[kLYT] = fM[kYT];  
00119    r[kLZX] = fM[kXZ];  r[kLZY] = fM[kYZ];  r[kLZZ] = fM[kZZ];  r[kLZT] = fM[kZT];  
00120    r[kLTX] = fM[kXT];  r[kLTY] = fM[kYT];  r[kLTZ] = fM[kZT];  r[kLTT] = fM[kTT];  
00121 }
00122 
00123 void Boost::Rectify() {
00124    // Assuming the representation of this is close to a true Lorentz Rotation,
00125    // but may have drifted due to round-off error from many operations,
00126    // this forms an "exact" orthosymplectic matrix for the Lorentz Rotation
00127    // again.
00128    
00129    if (fM[kTT] <= 0) {  
00130       GenVector::Throw ( 
00131                               "Attempt to rectify a boost with non-positive gamma");
00132       return;
00133    }    
00134    DisplacementVector3D< Cartesian3D<Scalar> > beta ( fM[kXT], fM[kYT], fM[kZT] );
00135    beta /= fM[kTT];
00136    if ( beta.mag2() >= 1 ) {                        
00137       beta /= ( beta.R() * ( 1.0 + 1.0e-16 ) );  
00138    }
00139    SetComponents ( beta );
00140 }
00141 
00142 LorentzVector< PxPyPzE4D<double> >
00143 Boost::operator() (const LorentzVector< PxPyPzE4D<double> > & v) const {
00144    // apply bosost to a PxPyPzE LorentzVector
00145    Scalar x = v.Px();
00146    Scalar y = v.Py();
00147    Scalar z = v.Pz();
00148    Scalar t = v.E();
00149    return LorentzVector< PxPyPzE4D<double> > 
00150       ( fM[kXX]*x + fM[kXY]*y + fM[kXZ]*z + fM[kXT]*t 
00151         , fM[kXY]*x + fM[kYY]*y + fM[kYZ]*z + fM[kYT]*t
00152         , fM[kXZ]*x + fM[kYZ]*y + fM[kZZ]*z + fM[kZT]*t
00153         , fM[kXT]*x + fM[kYT]*y + fM[kZT]*z + fM[kTT]*t );
00154 }
00155 
00156 void Boost::Invert() {
00157    // invert in place boost (modifying the object)
00158    fM[kXT] = -fM[kXT];
00159    fM[kYT] = -fM[kYT];
00160    fM[kZT] = -fM[kZT];
00161 }
00162 
00163 Boost Boost::Inverse() const {
00164    // return inverse of boost 
00165    Boost tmp(*this);
00166    tmp.Invert();
00167    return tmp; 
00168 }
00169 
00170 
00171 // ========== I/O =====================
00172 
00173 std::ostream & operator<< (std::ostream & os, const Boost & b) {
00174    // TODO - this will need changing for machine-readable issues
00175    //        and even the human readable form needs formatiing improvements
00176    double m[16];
00177    b.GetLorentzRotation(m);
00178    os << "\n" << m[0]  << "  " << m[1]  << "  " << m[2]  << "  " << m[3]; 
00179    os << "\n" << "\t"  << "  " << m[5]  << "  " << m[6]  << "  " << m[7]; 
00180    os << "\n" << "\t"  << "  " << "\t"  << "  " << m[10] << "  " << m[11]; 
00181    os << "\n" << "\t"  << "  " << "\t"  << "  " << "\t"  << "  " << m[15] << "\n";
00182    return os;
00183 }
00184 
00185 } //namespace Math
00186 } //namespace ROOT

Generated on Tue Jul 5 14:30:53 2011 for ROOT_528-00b_version by  doxygen 1.5.1