Version: SMASH-3.4
fourvector.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015,2017-2022,2025
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 #ifndef SRC_INCLUDE_SMASH_FOURVECTOR_H_
8 #define SRC_INCLUDE_SMASH_FOURVECTOR_H_
9 
10 #include <array>
11 #include <cmath>
12 #include <iosfwd>
13 #include <stdexcept>
14 
15 #include "threevector.h"
16 
17 namespace smash {
18 
19 /**
20  * \ingroup data
21  *
22  * The FourVector class holds relevant values in Minkowski spacetime
23  * with (+, −, −, −) metric signature.
24  *
25  * The overloaded operators are built according to Andrew Koenig
26  * recommendations where the compound assignment operators is used as a
27  * base for their non-compound counterparts. This means that the
28  * operator + is implemented in terms of +=. The operator+ returns
29  * a copy of its result. + and friends are non-members, while
30  * the compound assignment counterparts, changing the left
31  * argument, are a member of the FourVector class.
32  */
33 class FourVector {
34  public:
35  /// default constructor nulls the fourvector components
36  FourVector() : x_({0., 0., 0., 0.}) {}
37 
38  /**
39  * copy constructor
40  *
41  * \param[in] y0 The time component to be copied
42  * \param[in] y1 The x component to be copied
43  * \param[in] y2 The y component to be copied
44  * \param[in] y3 the z component to be copied
45  */
46  FourVector(double y0, double y1, double y2, double y3)
47  : x_({y0, y1, y2, y3}) {}
48 
49  /**
50  * construct from time-like component and a ThreeVector.
51  *
52  * \param[in] y0 The time component to be used
53  * \param[in] vec A ThreeVector (x,y,z) to be used
54  */
55  FourVector(double y0, ThreeVector vec)
56  : x_({y0, vec.x1(), vec.x2(), vec.x3()}) {}
57 
58  /**
59  * access the component at offset \p i.
60  * This operator results in the same as using the x0()...x3() functions
61  *
62  * \param[in] i the index of the component to access (has to be 0,1,2 or 3)
63  * \return the component at index i
64  */
65  double &operator[](std::size_t i) { return x_[i]; }
66  /// const overload of the [] operator
67  double operator[](std::size_t i) const { return x_[i]; }
68 
69  /// \return the time-like component
70  double inline x0() const;
71  /// \param[in] t set time-like component
72  void inline set_x0(double t);
73  /// \return the first space-like component
74  double inline x1() const;
75  /// \param[in] x set first space-like component
76  void inline set_x1(double x);
77  /// \return the second space-like component
78  double inline x2() const;
79  /// \param[in] y set second space-like component
80  void inline set_x2(double y);
81  /// \return the third space-like component
82  double inline x3() const;
83  /// \param[in] z set third space-like component
84  void inline set_x3(double z);
85  /// \return the space-like three-vector (x,y,z components)
86  ThreeVector inline threevec() const;
87 
88  /**
89  * Set all the 4-vector components to 0
90  */
91  void inline reset();
92 
93  /**
94  * Get the velocity (3-vector divided by zero component).
95  * Should only be used with momentum 4-vectors (not with space-time ones).
96  *
97  * \return the ThreeVector velocity
98  */
99  ThreeVector inline velocity() const;
100 
101  /**
102  * calculate the scalar product with another four-vector
103  *
104  * \param[in] a the FourVector to dot product with *this
105  * \return \f$x^\mu a_\mu\f$
106  */
107  double inline Dot(const FourVector &a) const;
108 
109  /**
110  * calculate the square of the vector (which is a scalar)
111  *
112  * \return \f$x^\mu x_\mu\f$
113  */
114  double inline sqr() const;
115 
116  /**
117  * calculate the lorentz invariant absolute value
118  *
119  * \return \f$\sqrt{x^\mu x_\mu}\f$
120  *
121  * Note that this will fail for space-like vectors.
122  */
123  double inline abs() const;
124 
125  /**
126  * calculate the square of the spatial three-vector
127  *
128  * \return \f$\mathbf{x} \cdot \mathbf{x}\f$
129  */
130  double inline sqr3() const;
131 
132  /**
133  * calculate the absolute value of the spatial three-vector
134  *
135  * \return \f$\sqrt{\mathbf{x} \cdot \mathbf{x}}\f$
136  */
137  double inline abs3() const;
138 
139  /**
140  * calculate the proper time from the given four vector
141  * \return \f$\sqrt{t^2 - z^2}\f$
142  */
143  double inline tau() const;
144 
145  /**
146  * calculate the space-time rapidity from the given four vector
147  * \return \f$atanh(z/t)\f$
148  */
149  double inline eta() const;
150 
151  /** Returns the FourVector boosted with velocity v.
152  *
153  * The current FourVector is not changed.
154  *
155  * \param[in] v (\f$\mathbf{v}\f$ in the explanation below) is a ThreeVector
156  * representing the boost velocity
157  *
158  * <h3> Algorithmic </h3>
159  *
160  * Notation:
161  * - \f$\mathbf{a}\f$ is a Three-Vector,
162  * - \f$a^\mu\f$ is a Four-Vector.
163  *
164  * The gamma factor is \f$\gamma = 1/\sqrt{1-\mathbf{v}^2}\f$.
165  *
166  * The time-like component of a Lorentz-boosted FourVector \f$x^\mu =
167  * (x_0, x_1, x_2, x_3) = (x_0, \mathbf{r})\f$ with velocity \f$\mathbf{v}\f$
168  * is
169  *
170  * \f{eqnarray*}{
171  * x^\prime_0 = \gamma \cdot (x_0 - \mathbf{r}\cdot\mathbf{v})\;,
172  * \f}
173  *
174  * and the space-like components i = 1, 2, 3 are:
175  * \f{eqnarray*}{
176  * x^\prime_i &=& x_i + v_i \cdot
177  * \Bigl(\frac{\gamma - 1}{\mathbf{v}^2} \cdot
178  * \mathbf{r}\cdot\mathbf{v} - \gamma \cdot x_0\Bigr)\\
179  * &=& x_i + v_i \cdot
180  * \Bigl(\frac{\gamma^2}{\gamma + 1} \cdot
181  * \mathbf{r}\cdot\mathbf{v} - \gamma \cdot x_0\Bigr)\\
182  * &=& x_i - v_i \cdot \frac{\gamma}{\gamma + 1} \cdot
183  * \bigl[\gamma\,(x_0 - \mathbf{r}\cdot\mathbf{v})+x_0\bigr]\\
184  * &=& x_i - v_i \cdot \frac{\gamma}{\gamma + 1} \cdot
185  * (x^\prime_0 + x^{\vphantom{\prime}}_0)
186  * \f}
187  *
188  * Note: This function is equivalent to -velocity Boost from ROOT
189  */
190  FourVector lorentz_boost(const ThreeVector &v) const;
191 
192  /**
193  * Check if all four vector components are almost equal
194  * (accuracy \f$10^{-4}\f$).
195  *
196  * \param[in] a The FourVector to compare to
197  * \return Whether *this and a are almost equal
198  */
199  bool operator==(const FourVector &a) const;
200 
201  /**
202  * checks inequality (logical complement to
203  * FourVector::operator==(const FourVector&) const)
204  *
205  * \param[in] a The FourVector to compare to
206  * \return Whether *this and a are not almost equal
207  */
208  bool inline operator!=(const FourVector &a) const;
209 
210  /**
211  * checks if \f$x^\mu < a^\mu\f$ for all \f$\mu\f$
212  * (all four vector components are below comparison vector)
213  *
214  * \param[in] a The FourVector to compare to
215  * \return Whether all components of *this are strictly below the
216  * corresponding components of a
217  */
218  bool inline operator<(const FourVector &a) const;
219 
220  /**
221  * checks if \f$x^\mu > a^\mu\f$ for all \f$\mu\f$
222  * (all four vector components are above comparison vector)
223  *
224  * \param[in] a The FourVector to compare to
225  * \return Whether all components of *this are strictly above the
226  * corresponding components of a
227  */
228  bool inline operator>(const FourVector &a) const;
229 
230  /**
231  * logical complement to FourVector::operator>(const FourVector&) const
232  *
233  * \param[in] a The FourVector to compare to
234  * \return Whether all components of *this are below or equal to the
235  * corresponding components of a
236  */
237  bool inline operator<=(const FourVector &a) const;
238 
239  /**
240  * logical complement to FourVector::operator<(const FourVector&) const
241  *
242  * \param[in] a The FourVector to compare to
243  * \return Whether all components of *this are above or equal to the
244  * corresponding components of a
245  */
246  bool inline operator>=(const FourVector &a) const;
247 
248  /**
249  * adds \f$a_\mu: x_\mu^\prime = x_\mu + a_\mu\f$
250  *
251  * \param[in] a The FourVector to add
252  * \return FourVector that consists of the added components of *this and a
253  */
254  FourVector inline operator+=(const FourVector &a);
255 
256  /**
257  * subtracts \f$a_\mu: x_\mu^\prime = x_\mu - a_\mu\f$
258  *
259  * \param[in] a The FourVector to subtract
260  * \return FourVector consisting of the components of a subtracted from *this
261  */
262  FourVector inline operator-=(const FourVector &a);
263 
264  /**
265  * multiplies by \f$a: x_\mu^\prime = a \cdot x_\mu\f$
266  *
267  * \param[in] a The value with which to multiply
268  * \return FourVector where each component of *this has been multiplied by a
269  */
270  FourVector inline operator*=(const double &a);
271 
272  /**
273  * divides by \f$a: x_\mu^\prime = \frac{1}{a} \cdot x_\mu\f$
274  *
275  * \param[in] a The value by which to divide
276  * \return FourVector where each component of *this has been divided by a
277  */
278  FourVector inline operator/=(const double &a);
279 
280  /// iterates over the components
281  using iterator = std::array<double, 4>::iterator;
282  /// iterates over the components
283  using const_iterator = std::array<double, 4>::const_iterator;
284 
285  /**
286  * \return An iterator starting at the 0th component.
287  *
288  * The iterator implements the randomIterator concept. Thus, you can simply
289  * write `begin() + 1` to get an iterator that points to the 1st component.
290  */
291  iterator begin() { return x_.begin(); }
292 
293  /// \return An iterator pointing after the 4th component.
294  iterator end() { return x_.end(); }
295 
296  /// \return A const_iterator pointing at the 0th component.
297  const_iterator begin() const { return x_.begin(); }
298  /// \return A const_iterator pointing after the 4th component.
299  const_iterator end() const { return x_.end(); }
300 
301  /// \see begin
302  const_iterator cbegin() const { return x_.cbegin(); }
303  /// \see end
304  const_iterator cend() const { return x_.cend(); }
305 
306  private:
307  /// internal storage of this vector's components
308  std::array<double, 4> x_;
309 };
310 
311 // Definitions of previous inline functions
312 
313 double inline FourVector::x0(void) const { return x_[0]; }
314 
315 void inline FourVector::set_x0(const double t) { x_[0] = t; }
316 
317 double inline FourVector::x1() const { return x_[1]; }
318 
319 void inline FourVector::set_x1(const double x) { x_[1] = x; }
320 
321 double inline FourVector::x2() const { return x_[2]; }
322 
323 void inline FourVector::set_x2(const double y) { x_[2] = y; }
324 
325 double inline FourVector::x3() const { return x_[3]; }
326 
327 void inline FourVector::set_x3(const double z) { x_[3] = z; }
328 
330  return ThreeVector(x_[1], x_[2], x_[3]);
331 }
332 
333 ThreeVector inline FourVector::velocity() const { return threevec() / x0(); }
334 
335 // use == operator for the inverse != check
336 bool inline FourVector::operator!=(const FourVector &a) const {
337  return !(*this == a);
338 }
339 
340 bool inline FourVector::operator<(const FourVector &a) const {
341  return (x_[0] < a.x_[0]) && (x_[1] < a.x_[1]) && (x_[2] < a.x_[2]) &&
342  (x_[3] < a.x_[3]);
343 }
344 
345 // use < operator for the inverse by switching arguments
346 bool inline FourVector::operator>(const FourVector &a) const {
347  return a < *this;
348 }
349 
350 // use > operator for less equal
351 bool inline FourVector::operator<=(const FourVector &a) const {
352  return !(*this > a);
353 }
354 
355 // use < operator for greater equal
356 bool inline FourVector::operator>=(const FourVector &a) const {
357  return !(*this < a);
358 }
359 
361  this->x_[0] += a.x_[0];
362  this->x_[1] += a.x_[1];
363  this->x_[2] += a.x_[2];
364  this->x_[3] += a.x_[3];
365  return *this;
366 }
367 
368 // addition +operator uses +=
369 /**
370  * add two FourVectors
371  *
372  * \param[in] a The first FourVector to add
373  * \param[in] b The second FourVector to add
374  * \return \f$x^\mu = a^\mu + b^\mu\f$
375  */
377  a += b;
378  return a;
379 }
380 
382  this->x_[0] -= a.x_[0];
383  this->x_[1] -= a.x_[1];
384  this->x_[2] -= a.x_[2];
385  this->x_[3] -= a.x_[3];
386  return *this;
387 }
388 
389 // subtraction -operator uses -=
390 /**
391  * subtract two FourVectors
392  *
393  * \param[in] a The FourVector from which to subtract
394  * \param[in] b The FourVector to subtract
395  * \return \f$x^\mu = a^\mu - b^\mu\f$
396  */
398  a -= b;
399  return a;
400 }
401 
402 FourVector inline FourVector::operator*=(const double &a) {
403  this->x_[0] *= a;
404  this->x_[1] *= a;
405  this->x_[2] *= a;
406  this->x_[3] *= a;
407  return *this;
408 }
409 
410 // factor multiplication uses *=
411 /**
412  * multiply a vector with a scalar
413  *
414  * \param[in] a The FourVector to multiply
415  * \param[in] b The value with which to multiply
416  * \return \f$x^\mu = b \cdot a^\mu\f$
417  */
418 inline FourVector operator*(FourVector a, double b) {
419  a *= b;
420  return a;
421 }
422 /**
423  * multiply a vector with a scalar
424  *
425  * \param[in] b The value with which to multiply
426  * \param[in] a The FourVector to multiply
427  * \return \f$x^\mu = b \cdot a^\mu\f$
428  */
429 inline FourVector operator*(double b, FourVector a) {
430  a *= b;
431  return a;
432 }
433 
434 FourVector inline FourVector::operator/=(const double &a) {
435  const double a_inv = 1.0 / a;
436  this->x_[0] *= a_inv;
437  this->x_[1] *= a_inv;
438  this->x_[2] *= a_inv;
439  this->x_[3] *= a_inv;
440  return *this;
441 }
442 
443 // factor division uses /=
444 /**
445  * divide a vector by a scalar
446  *
447  * \param[in] a The FourVector to divide
448  * \param[in] b The value with which to divide
449  * \return \f$x^\mu = \frac{1}{b} \cdot a^\mu\f$
450  */
451 inline FourVector operator/(FourVector a, const double &b) {
452  a /= b;
453  return a;
454 }
455 
456 double inline FourVector::Dot(const FourVector &a) const {
457  return x_[0] * a.x_[0] - x_[1] * a.x_[1] - x_[2] * a.x_[2] - x_[3] * a.x_[3];
458 }
459 
460 double inline FourVector::sqr() const {
461  return x_[0] * x_[0] - x_[1] * x_[1] - x_[2] * x_[2] - x_[3] * x_[3];
462 }
463 
464 double inline FourVector::abs() const {
465  if (this->sqr() > -really_small) {
466  return std::sqrt(std::abs(this->sqr()));
467  } else {
468  throw std::runtime_error(
469  "Absolute value of 4-vector could not be "
470  "determined, taking sqrt of negative value.");
471  }
472 }
473 
474 double inline FourVector::sqr3() const { return this->threevec().sqr(); }
475 
476 double inline FourVector::abs3() const { return this->threevec().abs(); }
477 
478 double inline FourVector::tau() const {
479  return std::sqrt(this->x0() * this->x0() - this->x3() * this->x3());
480 }
481 
482 double inline FourVector::eta() const {
483  return std::atanh(this->x3() / this->x0());
484 }
485 
486 void inline FourVector::reset() {
487  this->x_[0] = 0.;
488  this->x_[1] = 0.;
489  this->x_[2] = 0.;
490  this->x_[3] = 0.;
491 }
492 
493 /**\ingroup logging
494  * Writes the four components of the vector to the output stream.
495  *
496  * \param[in] os The ostream into which to output
497  * \param[in] vec The FourVector to write into os
498  */
499 std::ostream &operator<<(std::ostream &os, const FourVector &vec);
500 
501 } // namespace smash
502 
503 #endif // SRC_INCLUDE_SMASH_FOURVECTOR_H_
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
bool operator==(const FourVector &a) const
Check if all four vector components are almost equal (accuracy ).
Definition: fourvector.cc:30
double & operator[](std::size_t i)
access the component at offset i.
Definition: fourvector.h:65
const_iterator end() const
Definition: fourvector.h:299
double x3() const
Definition: fourvector.h:325
const_iterator cbegin() const
Definition: fourvector.h:302
bool operator<(const FourVector &a) const
checks if for all (all four vector components are below comparison vector)
Definition: fourvector.h:340
double abs3() const
calculate the absolute value of the spatial three-vector
Definition: fourvector.h:476
double x2() const
Definition: fourvector.h:321
bool operator>=(const FourVector &a) const
logical complement to FourVector::operator<(const FourVector&) const
Definition: fourvector.h:356
void set_x2(double y)
Definition: fourvector.h:323
void reset()
Set all the 4-vector components to 0.
Definition: fourvector.h:486
FourVector operator-=(const FourVector &a)
subtracts
Definition: fourvector.h:381
std::array< double, 4 >::const_iterator const_iterator
iterates over the components
Definition: fourvector.h:283
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:464
double sqr() const
calculate the square of the vector (which is a scalar)
Definition: fourvector.h:460
FourVector lorentz_boost(const ThreeVector &v) const
Returns the FourVector boosted with velocity v.
Definition: fourvector.cc:17
double sqr3() const
calculate the square of the spatial three-vector
Definition: fourvector.h:474
FourVector operator*=(const double &a)
multiplies by
Definition: fourvector.h:402
bool operator>(const FourVector &a) const
checks if for all (all four vector components are above comparison vector)
Definition: fourvector.h:346
bool operator<=(const FourVector &a) const
logical complement to FourVector::operator>(const FourVector&) const
Definition: fourvector.h:351
ThreeVector threevec() const
Definition: fourvector.h:329
const_iterator cend() const
Definition: fourvector.h:304
FourVector operator/=(const double &a)
divides by
Definition: fourvector.h:434
FourVector()
default constructor nulls the fourvector components
Definition: fourvector.h:36
double Dot(const FourVector &a) const
calculate the scalar product with another four-vector
Definition: fourvector.h:456
std::array< double, 4 > x_
internal storage of this vector's components
Definition: fourvector.h:308
double x0() const
Definition: fourvector.h:313
std::array< double, 4 >::iterator iterator
iterates over the components
Definition: fourvector.h:281
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:333
FourVector(double y0, double y1, double y2, double y3)
copy constructor
Definition: fourvector.h:46
void set_x3(double z)
Definition: fourvector.h:327
iterator end()
Definition: fourvector.h:294
void set_x1(double x)
Definition: fourvector.h:319
double x1() const
Definition: fourvector.h:317
FourVector(double y0, ThreeVector vec)
construct from time-like component and a ThreeVector.
Definition: fourvector.h:55
FourVector operator+=(const FourVector &a)
adds
Definition: fourvector.h:360
void set_x0(double t)
Definition: fourvector.h:315
bool operator!=(const FourVector &a) const
checks inequality (logical complement to FourVector::operator==(const FourVector&) const)
Definition: fourvector.h:336
double eta() const
calculate the space-time rapidity from the given four vector
Definition: fourvector.h:482
double operator[](std::size_t i) const
const overload of the [] operator
Definition: fourvector.h:67
const_iterator begin() const
Definition: fourvector.h:297
iterator begin()
Definition: fourvector.h:291
double tau() const
calculate the proper time from the given four vector
Definition: fourvector.h:478
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
double abs() const
Definition: threevector.h:277
double sqr() const
Definition: threevector.h:275
double x3() const
Definition: threevector.h:194
double x2() const
Definition: threevector.h:190
double x1() const
Definition: threevector.h:186
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:546
Definition: action.h:24
EnergyMomentumTensor operator-(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct subtraction operator.
EnergyMomentumTensor operator*(EnergyMomentumTensor a, const double b)
Direct multiplication operator.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:41
EnergyMomentumTensor operator+(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct addition operator.
EnergyMomentumTensor operator/(EnergyMomentumTensor a, const double b)
Direct division operator.