1 | // -*- C++ -*-
|
---|
2 | // ---------------------------------------------------------------------------
|
---|
3 | //
|
---|
4 | // This file is a part of the CLHEP - a Class Library for High Energy Physics.
|
---|
5 | //
|
---|
6 | // This is the implementation of the HepBoost class.
|
---|
7 | //
|
---|
8 |
|
---|
9 | #ifdef GNUPRAGMA
|
---|
10 | #pragma implementation
|
---|
11 | #endif
|
---|
12 |
|
---|
13 | #include "CLHEP/Vector/defs.h"
|
---|
14 | #include "CLHEP/Vector/Boost.h"
|
---|
15 | #include "CLHEP/Vector/Rotation.h"
|
---|
16 | #include "CLHEP/Vector/LorentzRotation.h"
|
---|
17 | #include "CLHEP/Vector/ZMxpv.h"
|
---|
18 |
|
---|
19 | namespace CLHEP {
|
---|
20 |
|
---|
21 | // ---------- Constructors and Assignment:
|
---|
22 |
|
---|
23 | HepBoost & HepBoost::set (double bx, double by, double bz) {
|
---|
24 | double bp2 = bx*bx + by*by + bz*bz;
|
---|
25 | if (bp2 >= 1) {
|
---|
26 | ZMthrowA (ZMxpvTachyonic(
|
---|
27 | "Boost Vector supplied to set HepBoost represents speed >= c."));
|
---|
28 | }
|
---|
29 | double gamma = 1.0 / sqrt(1.0 - bp2);
|
---|
30 | double bgamma = gamma * gamma / (1.0 + gamma);
|
---|
31 | rep_.xx_ = 1.0 + bgamma * bx * bx;
|
---|
32 | rep_.yy_ = 1.0 + bgamma * by * by;
|
---|
33 | rep_.zz_ = 1.0 + bgamma * bz * bz;
|
---|
34 | rep_.xy_ = bgamma * bx * by;
|
---|
35 | rep_.xz_ = bgamma * bx * bz;
|
---|
36 | rep_.yz_ = bgamma * by * bz;
|
---|
37 | rep_.xt_ = gamma * bx;
|
---|
38 | rep_.yt_ = gamma * by;
|
---|
39 | rep_.zt_ = gamma * bz;
|
---|
40 | rep_.tt_ = gamma;
|
---|
41 | return *this;
|
---|
42 | }
|
---|
43 |
|
---|
44 | HepBoost & HepBoost::set (const HepRep4x4Symmetric & m) {
|
---|
45 | rep_ = m;
|
---|
46 | return *this;
|
---|
47 | }
|
---|
48 |
|
---|
49 | HepBoost & HepBoost::set (Hep3Vector direction, double beta) {
|
---|
50 | double length = direction.mag();
|
---|
51 | if (length <= 0) { // Nan-proofing
|
---|
52 | ZMthrowA (ZMxpvZeroVector(
|
---|
53 | "Direction supplied to set HepBoost is zero."));
|
---|
54 | set (0,0,0);
|
---|
55 | return *this;
|
---|
56 | }
|
---|
57 | set(beta*direction.x()/length,
|
---|
58 | beta*direction.y()/length,
|
---|
59 | beta*direction.z()/length);
|
---|
60 | return *this;
|
---|
61 | }
|
---|
62 |
|
---|
63 | HepBoost & HepBoost::set (const Hep3Vector & boost) {
|
---|
64 | return set (boost.x(), boost.y(), boost.z());
|
---|
65 | }
|
---|
66 |
|
---|
67 | // ---------- Accessors:
|
---|
68 |
|
---|
69 | // ---------- Decomposition:
|
---|
70 |
|
---|
71 | void HepBoost::decompose (HepRotation & rotation, HepBoost & boost) const {
|
---|
72 | HepAxisAngle vdelta = HepAxisAngle();
|
---|
73 | rotation = HepRotation(vdelta);
|
---|
74 | Hep3Vector beta = boostVector();
|
---|
75 | boost = HepBoost(beta);
|
---|
76 | }
|
---|
77 |
|
---|
78 | void HepBoost::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
|
---|
79 | rotation = HepAxisAngle();
|
---|
80 | boost = boostVector();
|
---|
81 | }
|
---|
82 |
|
---|
83 | void HepBoost::decompose (HepBoost & boost, HepRotation & rotation) const {
|
---|
84 | HepAxisAngle vdelta = HepAxisAngle();
|
---|
85 | rotation = HepRotation(vdelta);
|
---|
86 | Hep3Vector beta = boostVector();
|
---|
87 | boost = HepBoost(beta);
|
---|
88 | }
|
---|
89 |
|
---|
90 | void HepBoost::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
|
---|
91 | rotation = HepAxisAngle();
|
---|
92 | boost = boostVector();
|
---|
93 | }
|
---|
94 |
|
---|
95 | // ---------- Comparisons:
|
---|
96 |
|
---|
97 | double HepBoost::distance2( const HepRotation & r ) const {
|
---|
98 | double db2 = norm2();
|
---|
99 | double dr2 = r.norm2();
|
---|
100 | return (db2 + dr2);
|
---|
101 | }
|
---|
102 |
|
---|
103 | double HepBoost::distance2( const HepLorentzRotation & lt ) const {
|
---|
104 | HepBoost b1;
|
---|
105 | HepRotation r1;
|
---|
106 | lt.decompose(b1,r1);
|
---|
107 | double db2 = distance2(b1);
|
---|
108 | double dr2 = r1.norm2();
|
---|
109 | return (db2 + dr2);
|
---|
110 | }
|
---|
111 |
|
---|
112 | double HepBoost::howNear ( const HepRotation & r ) const {
|
---|
113 | return sqrt(distance2(r));
|
---|
114 | }
|
---|
115 |
|
---|
116 | double HepBoost::howNear ( const HepLorentzRotation & lt ) const {
|
---|
117 | return sqrt(distance2(lt));
|
---|
118 | }
|
---|
119 |
|
---|
120 | bool HepBoost::isNear (const HepRotation & r, double epsilon) const {
|
---|
121 | double db2 = norm2();
|
---|
122 | if (db2 > epsilon*epsilon) return false;
|
---|
123 | double dr2 = r.norm2();
|
---|
124 | return (db2+dr2 <= epsilon*epsilon);
|
---|
125 | }
|
---|
126 |
|
---|
127 | bool HepBoost::isNear (const HepLorentzRotation & lt,
|
---|
128 | double epsilon) const {
|
---|
129 | HepBoost b1;
|
---|
130 | HepRotation r1;
|
---|
131 | double db2 = distance2(b1);
|
---|
132 | lt.decompose(b1,r1);
|
---|
133 | if (db2 > epsilon*epsilon) return false;
|
---|
134 | double dr2 = r1.norm2();
|
---|
135 | return (db2 + dr2);
|
---|
136 | }
|
---|
137 |
|
---|
138 | // ---------- Properties:
|
---|
139 |
|
---|
140 | double HepBoost::norm2() const {
|
---|
141 | register double bgx = rep_.xt_;
|
---|
142 | register double bgy = rep_.yt_;
|
---|
143 | register double bgz = rep_.zt_;
|
---|
144 | return bgx*bgx+bgy*bgy+bgz*bgz;
|
---|
145 | }
|
---|
146 |
|
---|
147 | void HepBoost::rectify() {
|
---|
148 | // Assuming the representation of this is close to a true pure boost,
|
---|
149 | // but may have drifted due to round-off error from many operations,
|
---|
150 | // this forms an "exact" pure boost matrix for the LT again.
|
---|
151 |
|
---|
152 | // The natural way to do this is to use the t column as a boost and set
|
---|
153 | // based on that boost vector.
|
---|
154 |
|
---|
155 | // There is perhaps danger that this boost vector will appear equal to or
|
---|
156 | // greater than a unit vector; the best we can do for such a case is use
|
---|
157 | // a boost in that direction but rescaled to just less than one.
|
---|
158 |
|
---|
159 | // There is in principle no way that gamma could have become negative,
|
---|
160 | // but if that happens, we ZMthrow and (if continuing) just rescale, which
|
---|
161 | // will change the sign of the last column when computing the boost.
|
---|
162 |
|
---|
163 | double gam = tt();
|
---|
164 | if (gam <= 0) { // 4/12/01 mf
|
---|
165 | // ZMthrowA (ZMxpvTachyonic(
|
---|
166 | ZMthrowC (ZMxpvTachyonic(
|
---|
167 | "Attempt to rectify a boost with non-positive gamma."));
|
---|
168 | if (gam==0) return; // NaN-proofing
|
---|
169 | }
|
---|
170 | Hep3Vector boost (xt(), yt(), zt());
|
---|
171 | boost /= tt();
|
---|
172 | if ( boost.mag2() >= 1 ) { // NaN-proofing:
|
---|
173 | boost /= ( boost.mag() * ( 1.0 + 1.0e-16 ) ); // used to just check > 1
|
---|
174 | }
|
---|
175 | set ( boost );
|
---|
176 | }
|
---|
177 |
|
---|
178 | // ---------- Application is all in .icc
|
---|
179 |
|
---|
180 | // ---------- Operations in the group of 4-Rotations
|
---|
181 |
|
---|
182 | HepLorentzRotation
|
---|
183 | HepBoost::matrixMultiplication(const HepRep4x4 & m) const {
|
---|
184 | HepRep4x4Symmetric r = rep4x4Symmetric();
|
---|
185 | return HepLorentzRotation( HepRep4x4 (
|
---|
186 | r.xx_*m.xx_ + r.xy_*m.yx_ + r.xz_*m.zx_ + r.xt_*m.tx_,
|
---|
187 | r.xx_*m.xy_ + r.xy_*m.yy_ + r.xz_*m.zy_ + r.xt_*m.ty_,
|
---|
188 | r.xx_*m.xz_ + r.xy_*m.yz_ + r.xz_*m.zz_ + r.xt_*m.tz_,
|
---|
189 | r.xx_*m.xt_ + r.xy_*m.yt_ + r.xz_*m.zt_ + r.xt_*m.tt_,
|
---|
190 |
|
---|
191 | r.xy_*m.xx_ + r.yy_*m.yx_ + r.yz_*m.zx_ + r.yt_*m.tx_,
|
---|
192 | r.xy_*m.xy_ + r.yy_*m.yy_ + r.yz_*m.zy_ + r.yt_*m.ty_,
|
---|
193 | r.xy_*m.xz_ + r.yy_*m.yz_ + r.yz_*m.zz_ + r.yt_*m.tz_,
|
---|
194 | r.xy_*m.xt_ + r.yy_*m.yt_ + r.yz_*m.zt_ + r.yt_*m.tt_,
|
---|
195 |
|
---|
196 | r.xz_*m.xx_ + r.yz_*m.yx_ + r.zz_*m.zx_ + r.zt_*m.tx_,
|
---|
197 | r.xz_*m.xy_ + r.yz_*m.yy_ + r.zz_*m.zy_ + r.zt_*m.ty_,
|
---|
198 | r.xz_*m.xz_ + r.yz_*m.yz_ + r.zz_*m.zz_ + r.zt_*m.tz_,
|
---|
199 | r.xz_*m.xt_ + r.yz_*m.yt_ + r.zz_*m.zt_ + r.zt_*m.tt_,
|
---|
200 |
|
---|
201 | r.xt_*m.xx_ + r.yt_*m.yx_ + r.zt_*m.zx_ + r.tt_*m.tx_,
|
---|
202 | r.xt_*m.xy_ + r.yt_*m.yy_ + r.zt_*m.zy_ + r.tt_*m.ty_,
|
---|
203 | r.xt_*m.xz_ + r.yt_*m.yz_ + r.zt_*m.zz_ + r.tt_*m.tz_,
|
---|
204 | r.xt_*m.xt_ + r.yt_*m.yt_ + r.zt_*m.zt_ + r.tt_*m.tt_) );
|
---|
205 | }
|
---|
206 |
|
---|
207 | HepLorentzRotation
|
---|
208 | HepBoost::matrixMultiplication(const HepRep4x4Symmetric & m) const {
|
---|
209 | HepRep4x4Symmetric r = rep4x4Symmetric();
|
---|
210 | return HepLorentzRotation( HepRep4x4 (
|
---|
211 | r.xx_*m.xx_ + r.xy_*m.xy_ + r.xz_*m.xz_ + r.xt_*m.xt_,
|
---|
212 | r.xx_*m.xy_ + r.xy_*m.yy_ + r.xz_*m.yz_ + r.xt_*m.yt_,
|
---|
213 | r.xx_*m.xz_ + r.xy_*m.yz_ + r.xz_*m.zz_ + r.xt_*m.zt_,
|
---|
214 | r.xx_*m.xt_ + r.xy_*m.yt_ + r.xz_*m.zt_ + r.xt_*m.tt_,
|
---|
215 |
|
---|
216 | r.xy_*m.xx_ + r.yy_*m.xy_ + r.yz_*m.xz_ + r.yt_*m.xt_,
|
---|
217 | r.xy_*m.xy_ + r.yy_*m.yy_ + r.yz_*m.yz_ + r.yt_*m.yt_,
|
---|
218 | r.xy_*m.xz_ + r.yy_*m.yz_ + r.yz_*m.zz_ + r.yt_*m.zt_,
|
---|
219 | r.xy_*m.xt_ + r.yy_*m.yt_ + r.yz_*m.zt_ + r.yt_*m.tt_,
|
---|
220 |
|
---|
221 | r.xz_*m.xx_ + r.yz_*m.xy_ + r.zz_*m.xz_ + r.zt_*m.xt_,
|
---|
222 | r.xz_*m.xy_ + r.yz_*m.yy_ + r.zz_*m.yz_ + r.zt_*m.yt_,
|
---|
223 | r.xz_*m.xz_ + r.yz_*m.yz_ + r.zz_*m.zz_ + r.zt_*m.zt_,
|
---|
224 | r.xz_*m.xt_ + r.yz_*m.yt_ + r.zz_*m.zt_ + r.zt_*m.tt_,
|
---|
225 |
|
---|
226 | r.xt_*m.xx_ + r.yt_*m.xy_ + r.zt_*m.xz_ + r.tt_*m.xt_,
|
---|
227 | r.xt_*m.xy_ + r.yt_*m.yy_ + r.zt_*m.yz_ + r.tt_*m.yt_,
|
---|
228 | r.xt_*m.xz_ + r.yt_*m.yz_ + r.zt_*m.zz_ + r.tt_*m.zt_,
|
---|
229 | r.xt_*m.xt_ + r.yt_*m.yt_ + r.zt_*m.zt_ + r.tt_*m.tt_) );
|
---|
230 | }
|
---|
231 |
|
---|
232 | HepLorentzRotation
|
---|
233 | HepBoost::operator* (const HepLorentzRotation & lt) const {
|
---|
234 | return matrixMultiplication(lt.rep4x4());
|
---|
235 | }
|
---|
236 |
|
---|
237 | HepLorentzRotation
|
---|
238 | HepBoost::operator* (const HepBoost & b) const {
|
---|
239 | return matrixMultiplication(b.rep_);
|
---|
240 | }
|
---|
241 |
|
---|
242 | HepLorentzRotation
|
---|
243 | HepBoost::operator* (const HepRotation & r) const {
|
---|
244 | return matrixMultiplication(r.rep4x4());
|
---|
245 | }
|
---|
246 |
|
---|
247 | // ---------- I/O:
|
---|
248 |
|
---|
249 | std::ostream & HepBoost::print( std::ostream & os ) const {
|
---|
250 | if ( rep_.tt_ <= 1 ) {
|
---|
251 | os << "Lorentz Boost( IDENTITY )";
|
---|
252 | } else {
|
---|
253 | double norm = boostVector().mag();
|
---|
254 | os << "\nLorentz Boost " << boostVector()/norm <<
|
---|
255 | "\n{beta = " << beta() << " gamma = " << gamma() << "}\n";
|
---|
256 | }
|
---|
257 | return os;
|
---|
258 | }
|
---|
259 |
|
---|
260 | } // namespace CLHEP
|
---|