File indexing completed on 2025-04-19 09:06:46
0001 #ifndef RIVET_MATH_LORENTZTRANS
0002 #define RIVET_MATH_LORENTZTRANS
0003
0004 #include "Rivet/Math/MathConstants.hh"
0005 #include "Rivet/Math/MathUtils.hh"
0006 #include "Rivet/Math/MatrixN.hh"
0007 #include "Rivet/Math/Matrix3.hh"
0008 #include "Rivet/Math/Vector4.hh"
0009 #include <ostream>
0010
0011 namespace Rivet {
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 class LorentzTransform {
0022 public:
0023
0024
0025
0026
0027
0028 static double beta2gamma(double beta) {
0029 return 1.0 / sqrt(1 - sqr(beta));
0030 }
0031
0032
0033 static double gamma2beta(double gamma) {
0034 return sqrt(1 - sqr(1/gamma));
0035 }
0036
0037
0038
0039
0040
0041
0042
0043
0044 LorentzTransform() {
0045 _boostMatrix = Matrix<4>::mkIdentity();
0046 }
0047
0048
0049 LorentzTransform(const Matrix<4>& boostMatrix) {
0050 _boostMatrix = boostMatrix;
0051 }
0052
0053
0054 static LorentzTransform mkObjTransformFromBeta(const Vector3& vbeta) {
0055 LorentzTransform rtn;
0056 return rtn.setBetaVec(vbeta);
0057 }
0058
0059
0060 static LorentzTransform mkFrameTransformFromBeta(const Vector3& vbeta) {
0061 LorentzTransform rtn;
0062 return rtn.setBetaVec(-vbeta);
0063 }
0064
0065
0066 static LorentzTransform mkObjTransformFromGamma(const Vector3& vgamma) {
0067 LorentzTransform rtn;
0068 if (!vgamma.isZero()) rtn.setGammaVec(vgamma);
0069 return rtn;
0070 }
0071
0072
0073 static LorentzTransform mkFrameTransformFromGamma(const Vector3& vgamma) {
0074 LorentzTransform rtn;
0075 if (!vgamma.isZero()) rtn.setGammaVec(-vgamma);
0076 return rtn;
0077 }
0078
0079
0080 static LorentzTransform mkObjTransform(const FourMomentum& p4) {
0081 return mkObjTransformFromBeta(p4.betaVec());
0082 }
0083
0084
0085 static LorentzTransform mkFrameTransform(const FourMomentum& p4) {
0086 return mkObjTransformFromBeta(-p4.betaVec());
0087 }
0088
0089
0090
0091
0092
0093
0094
0095
0096 LorentzTransform& _setBoost(const Vector3& vec, double beta, double gamma) {
0097
0098 _boostMatrix = Matrix<4>::mkIdentity();
0099 if (isZero(beta)) return *this;
0100
0101
0102 const bool alongxyz = (int(vec.x() == 0) + int(vec.y() == 0) + int(vec.z() == 0) == 2);
0103 const int i = (!alongxyz || vec.x() != 0) ? 1 : (vec.y() != 0) ? 2 : 3;
0104 const int isign = !alongxyz ? 1 : sign(vec[i-1]);
0105
0106 _boostMatrix.set(0, 0, gamma);
0107 _boostMatrix.set(i, i, gamma);
0108 _boostMatrix.set(0, i, +isign*beta*gamma);
0109 _boostMatrix.set(i, 0, +isign*beta*gamma);
0110
0111 if (!alongxyz) _boostMatrix = rotate(Vector3::mkX(), vec)._boostMatrix;
0112 return *this;
0113 }
0114
0115
0116 LorentzTransform& setBetaVec(const Vector3& vbeta) {
0117
0118 _boostMatrix = Matrix<4>::mkIdentity();
0119 if (isZero(vbeta.mod2())) return *this;
0120 const double beta = vbeta.mod();
0121 const double gamma = beta2gamma(beta);
0122 return _setBoost(vbeta.unit(), beta, gamma);
0123 }
0124
0125
0126 Vector3 betaVec() const {
0127 FourMomentum boost(_boostMatrix.getColumn(0));
0128
0129 if (boost.isZero()) return Vector3();
0130 assert(boost.E() > 0);
0131 const double beta = boost.p3().mod() / boost.E();
0132 return boost.p3().unit() * beta;
0133 }
0134
0135
0136 double beta() const {
0137 return betaVec().mod();
0138 }
0139
0140
0141
0142 LorentzTransform& setGammaVec(const Vector3& vgamma) {
0143
0144 _boostMatrix = Matrix<4>::mkIdentity();
0145 if (isZero(vgamma.mod2() - 1)) return *this;
0146 const double gamma = vgamma.mod();
0147 const double beta = gamma2beta(gamma);
0148 return _setBoost(vgamma.unit(), beta, gamma);
0149 }
0150
0151
0152 Vector3 gammaVec() const {
0153 FourMomentum boost(_boostMatrix.getColumn(0));
0154 if (boost.isZero()) return Vector3();
0155 assert(boost.E() > 0);
0156 const double beta = boost.p3().mod() / boost.E();
0157 return boost.p3().unit() * beta;
0158 }
0159
0160
0161 double gamma() const {
0162 return beta2gamma(beta());
0163 }
0164
0165
0166
0167
0168
0169 FourVector transform(const FourVector& v4) const {
0170 return multiply(_boostMatrix, v4);
0171 }
0172
0173
0174 FourMomentum transform(const FourMomentum& v4) const {
0175 return multiply(_boostMatrix, v4);
0176 }
0177
0178
0179 FourVector operator () (const FourVector& v4) const {
0180 return transform(v4);
0181 }
0182
0183
0184 FourMomentum operator () (const FourMomentum& v4) const {
0185 return transform(v4);
0186 }
0187
0188
0189
0190
0191
0192
0193 LorentzTransform rotate(const Vector3& from, const Vector3& to) const {
0194 return rotate(Matrix3(from, to));
0195 }
0196
0197
0198 LorentzTransform rotate(const Vector3& axis, double angle) const {
0199 return rotate(Matrix3(axis, angle));
0200 }
0201
0202
0203 LorentzTransform rotate(const Matrix3& rot) const {
0204 LorentzTransform lt = *this;
0205 const Matrix4 rot4 = _mkMatrix4(rot);
0206 const Matrix4 newlt = rot4 * _boostMatrix * rot4.inverse();
0207 lt._boostMatrix = newlt;
0208 return lt;
0209 }
0210
0211
0212 LorentzTransform inverse() const {
0213 LorentzTransform rtn;
0214 rtn._boostMatrix = _boostMatrix.inverse();
0215 return rtn;
0216 }
0217
0218
0219 LorentzTransform combine(const LorentzTransform& lt) const {
0220 LorentzTransform rtn;
0221 rtn._boostMatrix = _boostMatrix * lt._boostMatrix;
0222 return rtn;
0223 }
0224
0225
0226 LorentzTransform operator*(const LorentzTransform& lt) const {
0227 return combine(lt);
0228 }
0229
0230
0231 LorentzTransform preMult(const Matrix3& m3) {
0232 _boostMatrix = multiply(_mkMatrix4(m3),_boostMatrix);
0233 return *this;
0234 }
0235
0236
0237 LorentzTransform postMult(const Matrix3& m3) {
0238 _boostMatrix *= _mkMatrix4(m3);
0239 return *this;
0240 }
0241
0242
0243
0244
0245
0246 Matrix4 toMatrix() const {
0247 return _boostMatrix;
0248 }
0249
0250
0251 private:
0252
0253 Matrix4 _mkMatrix4(const Matrix3& m3) const {
0254 Matrix4 m4 = Matrix4::mkIdentity();
0255 for (size_t i = 0; i < 3; ++i) {
0256 for (size_t j = 0; j < 3; ++j) {
0257 m4.set(i+1, j+1, m3.get(i, j));
0258 }
0259 }
0260 return m4;
0261 }
0262
0263 Matrix4 _boostMatrix;
0264
0265 };
0266
0267
0268
0269 inline LorentzTransform inverse(const LorentzTransform& lt) {
0270 return lt.inverse();
0271 }
0272
0273 inline LorentzTransform combine(const LorentzTransform& a, const LorentzTransform& b) {
0274 return a.combine(b);
0275 }
0276
0277 inline FourVector transform(const LorentzTransform& lt, const FourVector& v4) {
0278 return lt.transform(v4);
0279 }
0280
0281
0282
0283
0284
0285 inline string toString(const LorentzTransform& lt) {
0286 return toString(lt.toMatrix());
0287 }
0288
0289 inline std::ostream& operator<<(std::ostream& out, const LorentzTransform& lt) {
0290 out << toString(lt);
0291 return out;
0292 }
0293
0294
0295 }
0296
0297 #endif