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 class LorentzTransform {
00021 friend string toString(const LorentzTransform& lt);
00022
00023 public:
00024 LorentzTransform() {
00025 _boostMatrix = Matrix<4>::mkIdentity();
00026 }
00027
00028 LorentzTransform(const Vector3& boost) {
00029 setBoost(boost);
00030 }
00031
00032 LorentzTransform(const double betaX, const double betaY, const double betaZ) {
00033 setBoost(betaX, betaY, betaZ);
00034 }
00035
00036 LorentzTransform& setBoost(const Vector3& boost) {
00037 assert(boost.mod2() < 1);
00038 const double beta = boost.mod();
00039 const double gamma = lorentzGamma(beta);
00040 _boostMatrix = Matrix<4>::mkIdentity();
00041 _boostMatrix.set(0, 0, gamma);
00042 _boostMatrix.set(1, 1, gamma);
00043
00044 _boostMatrix.set(0, 1, +beta*gamma);
00045 _boostMatrix.set(1, 0, +beta*gamma);
00046 _boostMatrix = rotate(Vector3::mkX(), boost)._boostMatrix;
00047 return *this;
00048 }
00049
00050
00051
00052
00053
00054
00055 LorentzTransform& setBoost(const double betaX, const double betaY, const double betaZ) {
00056 return setBoost(Vector3(betaX, betaY, betaZ));
00057 }
00058
00059 Vector3 boost() const {
00060 FourMomentum boost(_boostMatrix.getColumn(0));
00061
00062 if (boost.isZero()) return boost;
00063 assert(boost.E() > 0);
00064 const double beta = boost.p().mod() / boost.E();
00065 return boost.p().unit() * beta;
00066 }
00067
00068 double beta() const {
00069 return boost().mod();
00070 }
00071
00072 double gamma() const {
00073 return lorentzGamma(beta());
00074 }
00075
00076 LorentzTransform rotate(const Vector3& from, const Vector3& to) const {
00077 return rotate(Matrix3(from, to));
00078 }
00079
00080 LorentzTransform rotate(const Vector3& axis, const double angle) const {
00081 return rotate(Matrix3(axis, angle));
00082 }
00083
00084 LorentzTransform rotate(const Matrix3& rot) const {
00085 LorentzTransform lt = *this;
00086 const Matrix4 rot4 = mkMatrix4(rot);
00087 const Matrix4 newlt = rot4 * _boostMatrix * rot4.inverse();
00088 lt._boostMatrix = newlt;
00089 return lt;
00090 }
00091
00092 FourVector transform(const FourVector& v4) const {
00093 return multiply(_boostMatrix, v4);
00094 }
00095
00096 LorentzTransform inverse() const {
00097 LorentzTransform rtn;
00098 rtn._boostMatrix = _boostMatrix.inverse();
00099 return rtn;
00100 }
00101
00102
00103
00104 LorentzTransform combine(const LorentzTransform& lt) const {
00105 LorentzTransform rtn;
00106 rtn._boostMatrix = _boostMatrix * lt._boostMatrix;
00107 return rtn;
00108 }
00109
00110 Matrix4 toMatrix() const {
00111 return _boostMatrix;
00112 }
00113
00114
00115 LorentzTransform operator*(const LorentzTransform& lt) const {
00116 return combine(lt);
00117 }
00118
00119 LorentzTransform preMult(const Matrix3 & m3) {
00120 _boostMatrix = multiply(mkMatrix4(m3),_boostMatrix);
00121 return *this;
00122 }
00123
00124 LorentzTransform postMult(const Matrix3 & m3) {
00125 _boostMatrix *= mkMatrix4(m3);
00126 return *this;
00127 }
00128
00129 private:
00130 Matrix4 mkMatrix4(const Matrix3& m3) const {
00131 Matrix4 m4 = Matrix4::mkIdentity();
00132 for (size_t i = 0; i < 3; ++i) {
00133 for (size_t j = 0; j < 3; ++j) {
00134 m4.set(i+1, j+1, m3.get(i, j));
00135 }
00136 }
00137 return m4;
00138 }
00139
00140
00141 private:
00142 Matrix4 _boostMatrix;
00143
00144 };
00145
00146
00147
00148 inline LorentzTransform inverse(const LorentzTransform& lt) {
00149 return lt.inverse();
00150 }
00151
00152 inline LorentzTransform combine(const LorentzTransform& a, const LorentzTransform& b) {
00153 return a.combine(b);
00154 }
00155
00156 inline FourVector transform(const LorentzTransform& lt, const FourVector& v4) {
00157 return lt.transform(v4);
00158 }
00159
00160
00161
00162
00163
00164 inline string toString(const LorentzTransform& lt) {
00165 return toString(lt._boostMatrix);
00166 }
00167
00168 inline ostream& operator<<(std::ostream& out, const LorentzTransform& lt) {
00169 out << toString(lt);
00170 return out;
00171 }
00172
00173
00174 }
00175
00176 #endif