thepeg
is hosted by
Hepforge
,
IPPP Durham
ThePEG
2.3.0
Vectors
ThreeVector.h
Go to the documentation of this file.
1
// -*- C++ -*-
2
//
3
// ThreeVector.h is a part of ThePEG - Toolkit for HEP Event Generation
4
// Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5
//
6
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8
//
9
#ifndef ThePEG_ThreeVector_H
10
#define ThePEG_ThreeVector_H
11
19
#include "ThreeVector.fh"
20
#include "
ThePEG/Config/ThePEG.h
"
21
#include "ThePEG/Utilities/UnitIO.h"
22
#include <cassert>
23
#include <cmath>
24
25
namespace
ThePEG
{
26
33
template
<
typename
Value>
34
class
ThreeVector
35
{
36
private
:
38
using
Value2
=
decltype
(
sqr
(std::declval<Value>()));
39
40
public
:
43
ThreeVector
()
44
: theX(), theY(), theZ() {}
45
46
ThreeVector
(Value x, Value y, Value z)
47
: theX(x), theY(y), theZ(z) {}
48
49
template
<
typename
ValueB>
50
ThreeVector(
const
ThreeVector<ValueB> & v)
51
: theX(v.x()), theY(v.y()), theZ(v.z()) {}
53
54
public
:
56
57
Value x()
const
{
return
theX; }
58
Value y()
const
{
return
theY; }
59
Value z()
const
{
return
theZ; }
61
63
64
void
setX(Value x) { theX = x; }
65
void
setY(Value y) { theY = y; }
66
void
setZ(Value z) { theZ = z; }
68
69
public
:
71
Value2
mag2
()
const
{
return
sqr
(x()) +
sqr
(y()) +
sqr
(z()); }
72
74
Value
mag
()
const
{
return
sqrt(
mag2
()); }
75
77
Value2
perp2
()
const
{
return
sqr
(x()) +
sqr
(y()); }
78
80
Value
perp
()
const
{
return
sqrt(
perp2
()); }
81
83
template
<
typename
U>
84
auto
dot
(
const
ThreeVector<U>
& a)
const
85
->
decltype
(this->x()*a.x())
86
{
87
return
x()*a.x() + y()*a.y() + z()*a.z();
88
}
89
91
template
<
typename
U>
92
Value2
perp2
(
const
ThreeVector<U>
& p)
const
{
93
const
auto
pMag2 = p.
mag2
();
94
assert( pMag2 >
ZERO
);
95
auto
ss = this->
dot
(p);
96
Value2
ret =
mag2
() -
sqr
(ss)/pMag2;
97
if
( ret <=
ZERO
)
98
ret =
ZERO
;
99
return
ret;
100
}
101
103
template
<
typename
U>
104
Value
perp
(
const
ThreeVector<U>
& p)
const
{
105
return
sqrt(
perp2
(p));
106
}
107
109
110
111
double
theta
()
const
{
112
assert(!(x() ==
ZERO
&& y() ==
ZERO
&& z() ==
ZERO
));
113
return
atan2(
perp
(),z());
114
}
115
117
double
phi
()
const
{
118
return
atan2(y(),x());
119
}
120
122
void
setTheta
(
double
th) {
123
double
ma =
mag
();
124
double
ph =
phi
();
125
setX(ma*sin(th)*cos(ph));
126
setY(ma*sin(th)*sin(ph));
127
setZ(ma*cos(th));
128
}
129
131
void
setPhi
(
double
ph) {
132
double
xy =
perp
();
133
setX(xy*cos(ph));
134
setY(xy*sin(ph));
135
}
137
139
ThreeVector<double>
unit
()
const
{
140
Value2
mg2 =
mag2
();
141
assert(mg2 >
ZERO
);
142
Value mg = sqrt(mg2);
143
return
{x()/mg, y()/mg, z()/mg};
144
}
145
147
ThreeVector<Value>
orthogonal
()
const
{
148
Value xx = abs(x());
149
Value yy = abs(y());
150
Value zz = abs(z());
151
using
TVec =
ThreeVector<Value>
;
152
if
(xx < yy) {
153
return
xx < zz ? TVec{
ZERO
,z(),-y()} : TVec{y(),-x(),
ZERO
};
154
}
else
{
155
return
yy < zz ? TVec{-z(),
ZERO
,x()} : TVec{y(),-x(),
ZERO
};
156
}
157
}
158
160
template
<
typename
U>
161
double
deltaPhi
(
const
ThreeVector<U>
& v2)
const
{
162
double
dphi = v2.
phi
() -
phi
();
163
if
( dphi >
Constants::pi
) {
164
dphi -=
Constants::twopi
;
165
}
else
if
( dphi <= -
Constants::pi
) {
166
dphi +=
Constants::twopi
;
167
}
168
return
dphi;
169
}
170
176
template
<
typename
U>
177
ThreeVector<Value>
&
rotate
(
double
angle
,
const
ThreeVector<U>
& axis) {
178
if
(
angle
== 0.0)
179
return
*
this
;
180
const
U ll = axis.
mag
();
181
assert( ll >
ZERO
);
182
183
const
double
sa = sin(
angle
), ca = cos(
angle
);
184
const
double
dx = axis.x()/ll, dy = axis.y()/ll, dz = axis.z()/ll;
185
const
Value xx = x(), yy = y(), zz = z();
186
187
setX((ca+(1-ca)*dx*dx) * xx
188
+((1-ca)*dx*dy-sa*dz) * yy
189
+((1-ca)*dx*dz+sa*dy) * zz
190
);
191
setY(((1-ca)*dy*dx+sa*dz) * xx
192
+(ca+(1-ca)*dy*dy) * yy
193
+((1-ca)*dy*dz-sa*dx) * zz
194
);
195
setZ(((1-ca)*dz*dx-sa*dy) * xx
196
+((1-ca)*dz*dy+sa*dx) * yy
197
+(ca+(1-ca)*dz*dz) * zz
198
);
199
return
*
this
;
200
}
201
202
206
ThreeVector<Value>
&
rotateUz
(
const
Axis
& axis) {
207
Axis
ax = axis.
unit
();
208
double
u1 = ax.x();
209
double
u2 = ax.y();
210
double
u3 = ax.z();
211
double
up = u1*u1 + u2*u2;
212
if
(up>0) {
213
up = sqrt(up);
214
Value px = x(), py = y(), pz = z();
215
setX( (u1*u3*px - u2*py)/up + u1*pz );
216
setY( (u2*u3*px + u1*py)/up + u2*pz );
217
setZ( -up*px + u3*pz );
218
}
219
else
if
(u3 < 0.) {
220
setX(-x());
221
setZ(-z());
222
}
223
return
*
this
;
224
}
225
229
ThreeVector<Value>
&
rotateUzBack
(
const
Axis
& axis) {
230
Axis
ax = axis.
unit
();
231
double
u1 = ax.x();
232
double
u2 = ax.y();
233
double
u3 = ax.z();
234
double
up = u1*u1 + u2*u2;
235
if
(up>0) {
236
up = sqrt(up);
237
Value px = x(), py = y(), pz = z();
238
setX( ( u1*u3*px + u2*u3*py)/up - up*pz );
239
setY( (-u2*px + u1*py)/up );
240
setZ( u1*px + u2*py + u3*pz );
241
}
242
else
if
(u3 < 0.) {
243
setX(-x());
244
setZ(-z());
245
}
246
return
*
this
;
247
}
248
250
template
<
typename
U>
251
auto
cross
(
const
ThreeVector<U>
& a)
const
252
->
ThreeVector
<
decltype
(this->y()*a.z())>
253
{
254
return
{ y()*a.z()-z()*a.y(),
255
-x()*a.z()+z()*a.x(),
256
x()*a.y()-y()*a.x() };
257
}
258
259
public
:
261
262
bool
operator==(
const
ThreeVector<Value>
& a)
const
{
263
return
(theX == a.x() && theY == a.y() && theZ == a.z());
264
}
265
bool
operator!=(
const
ThreeVector<Value> & a)
const
{
266
return
!(*
this
== a);
267
}
268
bool
almostEqual(
const
ThreeVector<Value> & a,
double
threshold = 1e-04)
const
{
269
return
((std::abs(theX - a.x()) < threshold) && (std::abs(theY - a.y()) < threshold) && (std::abs(theZ - a.z()) < threshold));
270
}
271
bool
almostUnequal(
const
ThreeVector<Value> & a,
double
threshold = 1e-04)
const
{
272
return
! this->almostEqual(a, threshold);
273
}
275
276
public
:
278
279
ThreeVector<Value> & operator+=(
const
ThreeVector<Value> & a) {
280
theX += a.x();
281
theY += a.y();
282
theZ += a.z();
283
return
*
this
;
284
}
285
286
ThreeVector<Value> & operator-=(
const
ThreeVector<Value> & a) {
287
theX -= a.x();
288
theY -= a.y();
289
theZ -= a.z();
290
return
*
this
;
291
}
292
293
ThreeVector<Value> & operator*=(
double
a) {
294
theX *= a;
295
theY *= a;
296
theZ *= a;
297
return
*
this
;
298
}
299
300
ThreeVector<Value> & operator/=(
double
a) {
301
theX /= a;
302
theY /= a;
303
theZ /= a;
304
return
*
this
;
305
}
307
309
template
<
typename
U>
310
double
cosTheta
(
const
ThreeVector<U>
& q)
const
{
311
auto
ptot =
mag
()*q.
mag
();
312
assert( ptot >
ZERO
);
313
double
arg =
dot
(q)/ptot;
314
if
(arg > 1.0) arg = 1.0;
315
else
if
(arg < -1.0) arg = -1.0;
316
return
arg;
317
}
318
320
template
<
typename
U>
321
double
angle
(
const
ThreeVector<U>
& v)
const
{
322
return
acos(
cosTheta
(v));
323
}
324
325
private
:
327
328
Value theX;
329
Value theY;
330
Value theZ;
332
};
333
335
inline
ostream &
336
operator<<
(ostream & os,
const
ThreeVector<double>
& v)
337
{
338
return
os <<
'('
<< v.x() <<
','
<< v.y() <<
','
<< v.z() <<
')'
;
339
}
340
342
343
template
<
typename
Value>
344
inline
ThreeVector<Value>
345
operator+(ThreeVector<Value> a,
346
const
ThreeVector<Value> & b)
347
{
348
return
a += b;
349
}
350
351
template
<
typename
Value>
352
inline
ThreeVector<Value>
353
operator-(ThreeVector<Value> a,
354
const
ThreeVector<Value> & b)
355
{
356
return
a -=
b
;
357
}
358
359
template
<
typename
Value>
360
inline
ThreeVector<Value> operator-(
const
ThreeVector<Value> & v) {
361
return
{-
v
.x(),-
v
.y(),-
v
.z()};
362
}
363
364
template
<
typename
Value>
365
inline
ThreeVector<Value> operator*(ThreeVector<Value> v,
double
a) {
366
return
v
*= a;
367
}
368
369
template
<
typename
Value>
370
inline
ThreeVector<Value> operator*(
double
a, ThreeVector<Value> v) {
371
return
v
*= a;
372
}
373
374
template
<
typename
ValueA,
typename
ValueB>
375
inline
auto
operator*(ValueB a, ThreeVector<ValueA> v)
376
-> ThreeVector<
decltype
(a*
v
.x())>
377
{
378
return
{a*
v
.x(), a*
v
.y(), a*
v
.z()};
379
}
380
381
template
<
typename
ValueA,
typename
ValueB>
382
inline
auto
operator*(ThreeVector<ValueA> v, ValueB a)
383
-> ThreeVector<
decltype
(
v
.x()*a)>
384
{
385
return
{
v
.x()*a,
v
.y()*a,
v
.z()*a};
386
}
388
390
template
<
typename
ValueA,
typename
ValueB>
391
inline
auto
operator*(
const
ThreeVector<ValueA>
& a,
392
const
ThreeVector<ValueB>
& b)
393
->
decltype
(a.x()*b.x())
394
{
395
return
a.dot(b);
396
}
397
399
template
<
typename
Value>
400
ThreeVector<double>
unitVector
(
const
ThreeVector<Value>
& v) {
401
return
v.unit();
402
}
403
404
406
template
<
typename
OStream,
typename
UT,
typename
Value>
407
void
ounitstream
(OStream & os,
const
ThreeVector<Value>
& p, UT & u) {
408
os <<
ounit
(p.x(), u) <<
ounit
(p.y(), u) <<
ounit
(p.z(), u);
409
}
410
412
template
<
typename
IStream,
typename
UT,
typename
Value>
413
void
iunitstream
(IStream & is,
ThreeVector<Value>
& p, UT & u) {
414
Value x, y, z;
415
is >>
iunit
(x, u) >>
iunit
(y, u) >>
iunit
(z, u);
416
p =
ThreeVector<Value>
(x, y, z);
417
}
418
419
}
420
421
#endif
/* ThePEG_ThreeVector_H */
ThePEG.h
This is the main config header file for ThePEG.
ThePEG::ThreeVector
A 3-component vector.
Definition:
ThreeVector.h:35
ThePEG::ThreeVector::rotate
ThreeVector< Value > & rotate(double angle, const ThreeVector< U > &axis)
Apply a rotation.
Definition:
ThreeVector.h:177
ThePEG::ThreeVector::angle
double angle(const ThreeVector< U > &v) const
Angle between two vectors.
Definition:
ThreeVector.h:321
ThePEG::ThreeVector::perp2
Value2 perp2() const
Squared transverse component .
Definition:
ThreeVector.h:77
ThePEG::ThreeVector::mag
Value mag() const
Magnitude .
Definition:
ThreeVector.h:74
ThePEG::ThreeVector::unit
ThreeVector< double > unit() const
Parallel vector with unit length.
Definition:
ThreeVector.h:139
ThePEG::ThreeVector::orthogonal
ThreeVector< Value > orthogonal() const
Orthogonal vector.
Definition:
ThreeVector.h:147
ThePEG::ThreeVector::perp
Value perp() const
Transverse component .
Definition:
ThreeVector.h:80
ThePEG::ThreeVector::dot
auto dot(const ThreeVector< U > &a) const -> decltype(this->x() *a.x())
Dot product.
Definition:
ThreeVector.h:84
ThePEG::ThreeVector::phi
double phi() const
Azimuthal angle.
Definition:
ThreeVector.h:117
ThePEG::ThreeVector::setTheta
void setTheta(double th)
Set the polar angle.
Definition:
ThreeVector.h:122
ThePEG::ThreeVector::setPhi
void setPhi(double ph)
Set the azimuthal angle.
Definition:
ThreeVector.h:131
ThePEG::ThreeVector::perp2
Value2 perp2(const ThreeVector< U > &p) const
Squared transverse component with respect to the given axis.
Definition:
ThreeVector.h:92
ThePEG::ThreeVector::cross
auto cross(const ThreeVector< U > &a) const -> ThreeVector< decltype(this->y() *a.z())>
Vector cross-product.
Definition:
ThreeVector.h:251
ThePEG::ThreeVector::theta
double theta() const
Polar angle.
Definition:
ThreeVector.h:111
ThePEG::ThreeVector::cosTheta
double cosTheta(const ThreeVector< U > &q) const
Cosine of the azimuthal angle between two vectors.
Definition:
ThreeVector.h:310
ThePEG::ThreeVector::rotateUzBack
ThreeVector< Value > & rotateUzBack(const Axis &axis)
Rotate from a reference frame to the z-axis.
Definition:
ThreeVector.h:229
ThePEG::ThreeVector::mag2
Value2 mag2() const
Squared magnitude .
Definition:
ThreeVector.h:71
ThePEG::ThreeVector::deltaPhi
double deltaPhi(const ThreeVector< U > &v2) const
Azimuthal angle difference, brought into the range .
Definition:
ThreeVector.h:161
ThePEG::ThreeVector::Value2
decltype(sqr(std::declval< Value >())) Value2
Value squared.
Definition:
ThreeVector.h:38
ThePEG::ThreeVector::perp
Value perp(const ThreeVector< U > &p) const
Transverse component with respect to the given axis.
Definition:
ThreeVector.h:104
ThePEG::ThreeVector::rotateUz
ThreeVector< Value > & rotateUz(const Axis &axis)
Rotate the reference frame to a new z-axis.
Definition:
ThreeVector.h:206
ThePEG::Constants::twopi
constexpr double twopi
Good old .
Definition:
Constants.h:57
ThePEG::Constants::pi
constexpr double pi
Good old .
Definition:
Constants.h:54
ThePEG::Helicity::SpinorType::v
@ v
v spinor.
ThePEG::ParticleID::b
@ b
(b)
Definition:
EnumParticles.h:48
ThePEG
This is the main namespace within which all identifiers in ThePEG are declared.
Definition:
FactoryBase.h:28
ThePEG::unitVector
ThreeVector< double > unitVector(const ThreeVector< Value > &v)
A parallel vector with unit length.
Definition:
ThreeVector.h:400
ThePEG::iunit
IUnit< T, UT > iunit(T &t, const UT &ut)
Helper function creating a IUnit object given an object and a unit.
Definition:
UnitIO.h:91
ThePEG::iunitstream
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
Definition:
Containers.h:289
ThePEG::operator<<
vector< T > & operator<<(vector< T > &tv, const U &u)
Overload the left shift operator for vector to push_back objects to a vector.
Definition:
Containers.h:179
ThePEG::ounitstream
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
Definition:
Containers.h:275
ThePEG::ZERO
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition:
PhysicalQty.h:35
ThePEG::sqr
constexpr auto sqr(const T &x) -> decltype(x *x)
The square function should really have been included in the standard C++ library.
Definition:
ThePEG.h:117
ThePEG::ounit
OUnit< T, UT > ounit(const T &t, const UT &ut)
Helper function creating a OUnit object given an object and a unit.
Definition:
UnitIO.h:84
Generated on Thu Jun 20 2024 14:47:02 for ThePEG by
1.9.6