thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
LorentzTensor.h
1 // -*- C++ -*-
2 //
3 // LorentzTensor.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 2003-2019 Peter Richardson, 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_LorentzTensor_H
10 #define ThePEG_LorentzTensor_H
11 // This is the declaration of the LorentzTensor class.
12 
14 #include "ThePEG/Config/ThePEG.h"
15 #include "LorentzPolarizationVector.h"
16 
17 namespace ThePEG {
18 namespace Helicity {
19 
20 // compiler magic needs these pre-declarations to make friend templates work
21 template<typename Value> class LorentzTensor;
22 
36 template<typename Value>
37 class LorentzTensor {
38 
39 public:
40 
46  LorentzTensor() = default;
47 
51  LorentzTensor(complex<Value> xx, complex<Value> xy,
52  complex<Value> xz, complex<Value> xt,
53  complex<Value> yx, complex<Value> yy,
54  complex<Value> yz, complex<Value> yt,
55  complex<Value> zx, complex<Value> zy,
56  complex<Value> zz, complex<Value> zt,
57  complex<Value> tx, complex<Value> ty,
58  complex<Value> tz, complex<Value> tt)
59  : _tensor{{ {{xx,xy,xz,xt}},
60  {{yx,yy,yz,yt}},
61  {{zx,zy,zz,zt}},
62  {{tx,ty,tz,tt}} }} {}
67  const LorentzPolarizationVector & q) {
68  setXX(p.x() * q.x()); setYX(p.y() * q.x());
69  setZX(p.z() * q.x()); setTX(p.t() * q.x());
70  setXY(p.x() * q.y()); setYY(p.y() * q.y());
71  setZY(p.z() * q.y()); setTY(p.t() * q.y());
72  setXZ(p.x() * q.z()); setYZ(p.y() * q.z());
73  setZZ(p.z() * q.z()); setTZ(p.t() * q.z());
74  setXT(p.x() * q.t()); setYT(p.y() * q.t());
75  setZT(p.z() * q.t()); setTT(p.t() * q.t());
76  }
78 
84  complex<Value> xx() const {return _tensor[0][0];}
85 
89  complex<Value> yx() const {return _tensor[1][0];}
93  complex<Value> zx() const {return _tensor[2][0];}
94 
98  complex<Value> tx() const {return _tensor[3][0];}
99 
103  complex<Value> xy() const {return _tensor[0][1];}
104 
108  complex<Value> yy() const {return _tensor[1][1];}
109 
113  complex<Value> zy() const {return _tensor[2][1];}
114 
118  complex<Value> ty() const {return _tensor[3][1];}
119 
123  complex<Value> xz() const {return _tensor[0][2];}
124 
128  complex<Value> yz() const {return _tensor[1][2];}
129 
133  complex<Value> zz() const {return _tensor[2][2];}
134 
138  complex<Value> tz() const {return _tensor[3][2];}
139 
143  complex<Value> xt() const {return _tensor[0][3];}
144 
148  complex<Value> yt() const {return _tensor[1][3];}
149 
153  complex<Value> zt() const {return _tensor[2][3];}
154 
158  complex<Value> tt() const {return _tensor[3][3];}
159 
163  void setXX(complex<Value> a) {_tensor[0][0]=a;}
164 
168  void setYX(complex<Value> a) {_tensor[1][0]=a;}
169 
173  void setZX(complex<Value> a) {_tensor[2][0]=a;}
174 
178  void setTX(complex<Value> a) {_tensor[3][0]=a;}
179 
183  void setXY(complex<Value> a) {_tensor[0][1]=a;}
184 
188  void setYY(complex<Value> a) {_tensor[1][1]=a;}
189 
193  void setZY(complex<Value> a) {_tensor[2][1]=a;}
194 
198  void setTY(complex<Value> a) {_tensor[3][1]=a;}
199 
203  void setXZ(complex<Value> a) {_tensor[0][2]=a;}
204 
208  void setYZ(complex<Value> a) {_tensor[1][2]=a;}
209 
213  void setZZ(complex<Value> a) {_tensor[2][2]=a;}
214 
218  void setTZ(complex<Value> a) {_tensor[3][2]=a;}
219 
223  void setXT(complex<Value> a) {_tensor[0][3]=a;}
224 
228  void setYT(complex<Value> a) {_tensor[1][3]=a;}
229 
233  void setZT(complex<Value> a) {_tensor[2][3]=a;}
234 
238  void setTT(complex<Value> a) {_tensor[3][3]=a;}
239 
243  complex<Value> operator () (int i, int j) const {
244  assert( i>=0 && i<=3 && j>=0 && j<=3);
245  return _tensor[i][j];
246  }
247 
251  complex<Value> & operator () (int i, int j) {
252  assert( i>=0 && i<=3 && j>=0 && j<=3);
253  return _tensor[i][j];
254  }
256 
262  LorentzTensor & boost(double,double,double);
263 
268  return boost(b.x(), b.y(), b.z());
269  }
270 
275  unsigned int ix,iy,ixa,iya;
276  LorentzTensor<Value> output;
277  complex<Value> temp;
278  for(ix=0;ix<4;++ix) {
279  for(iy=0;iy<4;++iy) {
280  temp=complex<Value>();
281  for(ixa=0;ixa<4;++ixa) {
282  for(iya=0;iya<4;++iya)
283  temp+=r(ix,ixa)*r(iy,iya)*(*this)(ixa,iya);
284  }
285  output(ix,iy)=temp;
286  }
287  }
288  *this=output;
289  return *this;
290  }
291 
296  return LorentzTensor<Value>(conj(xx()), conj(xy()), conj(xz()), conj(xt()),
297  conj(yx()), conj(yy()), conj(yz()), conj(yt()),
298  conj(zx()), conj(zy()), conj(zz()), conj(zt()),
299  conj(tx()), conj(ty()), conj(tz()), conj(tt()));
300  }
301 
303 
310  for(int ix=0;ix<4;++ix)
311  for(int iy=0;iy<4;++iy) _tensor[ix][iy]*=a;
312  return *this;
313  }
314 
318  template <typename T, typename U>
319  friend auto
320  operator*(const LorentzTensor<T> & t, const LorentzTensor<U> & u)
321  -> decltype(t.xx()*u.xx())
322  ;
323 
328  return LorentzTensor<Value>(xx()+in.xx(),xy()+in.xy(),xz()+in.xz(),xt()+in.xt(),
329  yx()+in.yx(),yy()+in.yy(),yz()+in.yz(),yt()+in.yt(),
330  zx()+in.zx(),zy()+in.zy(),zz()+in.zz(),zt()+in.zt(),
331  tx()+in.tx(),ty()+in.ty(),tz()+in.tz(),tt()+in.tt());
332  }
333 
338  return LorentzTensor<Value>(xx()-in.xx(),xy()-in.xy(),xz()-in.xz(),xt()-in.xt(),
339  yx()-in.yx(),yy()-in.yy(),yz()-in.yz(),yt()-in.yt(),
340  zx()-in.zx(),zy()-in.zy(),zz()-in.zz(),zt()-in.zt(),
341  tx()-in.tx(),ty()-in.ty(),tz()-in.tz(),tt()-in.tt());
342  }
343 
347  complex<Value> trace() const {
348  return _tensor[3][3]-_tensor[0][0]-_tensor[1][1]-_tensor[2][2];
349  }
351 
361  output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]-
362  vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]);
363  output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]-
364  vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]);
365  output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]-
366  vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]);
367  output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]-
368  vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]);
369  return output;
370  }
371 
377  output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]-
378  vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]);
379  output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]-
380  vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]);
381  output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]-
382  vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]);
383  output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]-
384  vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]);
385  return output;
386  }
387 
391  auto preDot (const Lorentz5Momentum & vec) const
392  -> LorentzVector<decltype(vec.x()*this->xx())>
393  {
394  LorentzVector<decltype(vec.x()*this->xx())> output;
395  output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]-
396  vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]);
397  output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]-
398  vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]);
399  output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]-
400  vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]);
401  output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]-
402  vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]);
403  return output;
404  }
405 
409  auto postDot(const Lorentz5Momentum & vec) const
410  -> LorentzVector<decltype(vec.x()*this->xx())>
411  {
412  LorentzVector<decltype(vec.x()*this->xx())> output;
413  output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]-
414  vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]);
415  output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]-
416  vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]);
417  output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]-
418  vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]);
419  output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]-
420  vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]);
421  return output;
422  }
424 private:
425 
429  std::array<std::array<complex<Value>,4>,4> _tensor;
430 
431 };
432 
436 template<typename T, typename U>
437 inline auto
438 operator*(complex<U> a, const LorentzTensor<T> & t)
439 -> LorentzTensor<decltype(a.real()*t.xx().real())>
440 {
441  return
442  {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(),
443  a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(),
444  a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(),
445  a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()};
446 }
447 
451 template<typename T, typename U>
452 inline auto
453 operator*(const LorentzTensor<T> & t,complex<U> a)
454 -> LorentzTensor<decltype(a.real()*t.xx().real())>
455 {
456  return
457  {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(),
458  a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(),
459  a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(),
460  a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()};
461 }
462 
466 template<typename T, typename U>
467 inline auto
469  const LorentzTensor<T> & t)
470 -> LorentzVector<decltype(v.t()*t(3,0))>
471 {
472  LorentzVector<decltype(v.t()*t(3,0))> outvec;
473  outvec.setX( v.t()*t(3,0)-v.x()*t(0,0)
474  -v.y()*t(1,0)-v.z()*t(2,0));
475  outvec.setY( v.t()*t(3,1)-v.x()*t(0,1)
476  -v.y()*t(1,1)-v.z()*t(2,1));
477  outvec.setZ( v.t()*t(3,2)-v.x()*t(0,2)
478  -v.y()*t(1,2)-v.z()*t(2,2));
479  outvec.setT( v.t()*t(3,3)-v.x()*t(0,3)
480  -v.y()*t(1,3)-v.z()*t(2,3));
481  return outvec;
482 }
483 
487 template<typename T, typename U>
488 inline auto
490 -> LorentzVector<decltype(v.t()*t(0,3))>
491 {
492  LorentzVector<decltype(v.t()*t(0,3))> outvec;
493  outvec.setX( v.t()*t(0,3)-v.x()*t(0,0)
494  -v.y()*t(0,1)-v.z()*t(0,2));
495  outvec.setY( v.t()*t(1,3)-v.x()*t(1,0)
496  -v.y()*t(1,1)-v.z()*t(1,2));
497  outvec.setZ( v.t()*t(2,3)-v.x()*t(2,0)
498  -v.y()*t(2,1)-v.z()*t(2,2));
499  outvec.setT( v.t()*t(3,3)-v.x()*t(3,0)
500  -v.y()*t(3,1)-v.z()*t(3,2));
501  return outvec;
502 }
503 
507 template <typename T, typename U>
508 inline auto
510  const LorentzTensor<U> & u)
511 -> decltype(t.xx()*u.xx())
512 {
513  using RetT = decltype(t.xx()*u.xx());
514  RetT output=RetT(),temp;
515  for(unsigned int ix=0;ix<4;++ix) {
516  temp = t._tensor[ix][3]*u._tensor[ix][3];
517  for(unsigned int iy=0;iy<3;++iy) {
518  temp+= t._tensor[ix][iy]*u._tensor[ix][iy];
519  }
520  if(ix<3) output-=temp;
521  else output+=temp;
522  }
523  return output;
524 }
525 
526 }
527 }
528 
529 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
530 #include "LorentzTensor.tcc"
531 #endif
532 
533 #endif
LorentzTensor< Value > conjugate()
Return the complex conjugate.
LorentzTensor< Value > operator+(const LorentzTensor< Value > &in) const
Addition.
void setTY(complex< Value > a)
Set t,y component.
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition: Complex.h:23
LorentzTensor()=default
Default zero constructor.
complex< Value > tx() const
Get t,x component.
Definition: LorentzTensor.h:98
LorentzVector< complex< Value > > preDot(const LorentzPolarizationVector &vec) const
Various dot products.
void setYY(complex< Value > a)
Set y,y component.
complex< Value > ty() const
Get t,y component.
void setZZ(complex< Value > a)
Set z,z component.
complex< Value > operator()(int i, int j) const
Get components by indices.
void setYX(complex< Value > a)
Set y,x component.
A 3-component vector.
Definition: ThreeVector.h:34
complex< Value > xz() const
Get x,z component.
void setTZ(complex< Value > a)
Set t,z component.
LorentzTensor< Value > operator-(const LorentzTensor< Value > &in) const
Subtraction.
std::array< std::array< complex< Value >, 4 >, 4 > _tensor
The components.
LorentzTensor(complex< Value > xx, complex< Value > xy, complex< Value > xz, complex< Value > xt, complex< Value > yx, complex< Value > yy, complex< Value > yz, complex< Value > yt, complex< Value > zx, complex< Value > zy, complex< Value > zz, complex< Value > zt, complex< Value > tx, complex< Value > ty, complex< Value > tz, complex< Value > tt)
Constructor specifyign all components.
Definition: LorentzTensor.h:51
complex< Value > zz() const
Get z,z component.
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
complex< Value > zy() const
Get z,y component.
This is the main config header file for ThePEG.
complex< Value > tz() const
Get t,z component.
complex< Value > yy() const
Get y,y component.
complex< Value > xy() const
Get x,y component.
void setTT(complex< Value > a)
Set t,t component.
void setXZ(complex< Value > a)
Set x,z component.
complex< Value > zx() const
Get z,x component.
Definition: LorentzTensor.h:93
The SpinOneLorentzRotation class is ...
complex< Value > yt() const
Get y,t component.
LorentzTensor & boost(double, double, double)
Standard Lorentz boost specifying the components of the beta vector.
complex< Value > zt() const
Get z,t component.
auto preDot(const Lorentz5Momentum &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
First index dot product with momentum.
complex< Value > xt() const
Get x,t component.
complex< Value > trace() const
Trace.
Overloads for operations on complex physical quantities.
LorentzTensor< Value > & boost(const Boost &b)
Standard Lorentz boost specifying the beta vector.
void setZT(complex< Value > a)
Set z,t component.
void setZX(complex< Value > a)
Set z,x component.
complex< Value > yz() const
Get y,z component.
The LorentzTensor class is designed to implement the storage of a complex tensor to be used to repres...
Definition: LorentzTensor.h:21
void setTX(complex< Value > a)
Set t,x component.
friend auto operator*(const LorentzTensor< T > &t, const LorentzTensor< U > &u) -> decltype(t.xx() *u.xx())
Scalar product with other tensor.
complex< Value > tt() const
Get t,t component.
LorentzTensor & transform(const SpinOneLorentzRotation &r)
General Lorentz transformation.
void setXX(complex< Value > a)
Set x,x component.
void setYZ(complex< Value > a)
Set y,z component.
void setXT(complex< Value > a)
Set x,t component.
auto postDot(const Lorentz5Momentum &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
Second index dot product with momentum.
complex< Value > yx() const
Get y,x component.
Definition: LorentzTensor.h:89
complex< Value > xx() const
Get x,x component.
Definition: LorentzTensor.h:84
LorentzTensor(const LorentzPolarizationVector &p, const LorentzPolarizationVector &q)
Constructor in terms of two polarization vectors.
Definition: LorentzTensor.h:66
LorentzVector< complex< Value > > postDot(const LorentzPolarizationVector &vec) const
Second index dot product with polarization vector.
void setXY(complex< Value > a)
Set x,y component.
void setZY(complex< Value > a)
Set z,y component.
LorentzTensor< Value > operator*=(Complex a)
Scaling with a complex number.
void setYT(complex< Value > a)
Set y,t component.