source: trunk/CLHEP/src/Boost.cc@ 16

Last change on this file since 16 was 4, checked in by Pavel Demin, 16 years ago

first commit

File size: 7.8 KB
Line 
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
19namespace CLHEP {
20
21// ---------- Constructors and Assignment:
22
23HepBoost & 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
44HepBoost & HepBoost::set (const HepRep4x4Symmetric & m) {
45 rep_ = m;
46 return *this;
47}
48
49HepBoost & 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
63HepBoost & HepBoost::set (const Hep3Vector & boost) {
64 return set (boost.x(), boost.y(), boost.z());
65}
66
67// ---------- Accessors:
68
69// ---------- Decomposition:
70
71void 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
78void HepBoost::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
79 rotation = HepAxisAngle();
80 boost = boostVector();
81}
82
83void 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
90void HepBoost::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
91 rotation = HepAxisAngle();
92 boost = boostVector();
93}
94
95// ---------- Comparisons:
96
97double HepBoost::distance2( const HepRotation & r ) const {
98 double db2 = norm2();
99 double dr2 = r.norm2();
100 return (db2 + dr2);
101}
102
103double 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
112double HepBoost::howNear ( const HepRotation & r ) const {
113 return sqrt(distance2(r));
114}
115
116double HepBoost::howNear ( const HepLorentzRotation & lt ) const {
117 return sqrt(distance2(lt));
118}
119
120bool 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
127bool 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
140double 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
147void 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
182HepLorentzRotation
183HepBoost::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
207HepLorentzRotation
208HepBoost::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
232HepLorentzRotation
233HepBoost::operator* (const HepLorentzRotation & lt) const {
234 return matrixMultiplication(lt.rep4x4());
235}
236
237HepLorentzRotation
238HepBoost::operator* (const HepBoost & b) const {
239 return matrixMultiplication(b.rep_);
240}
241
242HepLorentzRotation
243HepBoost::operator* (const HepRotation & r) const {
244 return matrixMultiplication(r.rep4x4());
245}
246
247// ---------- I/O:
248
249std::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
Note: See TracBrowser for help on using the repository browser.