thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
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
15#include "LorentzPolarizationVector.h"
16
17namespace ThePEG {
18namespace Helicity {
19
20// compiler magic needs these pre-declarations to make friend templates work
21template<typename Value> class LorentzTensor;
22
36template<typename Value>
38
39public:
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;
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
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 }
350
354 template<typename ValueB>
355 auto innerProduct(const LorentzTensor<ValueB> & ten) const
356 -> LorentzTensor<decltype(ten.xx().real()*this->xx().real())> {
357 LorentzTensor<decltype(ten.xx().real()*this->xx().real())> output;
358 for(unsigned int ix=0;ix<4;++ix) {
359 for(unsigned int iy=0;iy<4;++iy) {
360 output(ix,iy) = _tensor[ix][3]*ten(3,iy);
361 for(unsigned int iz=0;iz<3;++iz) {
362 output(ix,iy) -= _tensor[ix][iz]*ten(iz,iy);
363 }
364 }
365 }
366 return output;
367 }
368
372 template<typename ValueB>
373 auto outerProduct(const LorentzTensor<ValueB> & ten) const
374 -> LorentzTensor<decltype(ten.xx().real()*this->xx().real())> {
375 LorentzTensor<decltype(ten.xx().real()*this->xx().real())> output;
376 for(unsigned int ix=0;ix<4;++ix) {
377 for(unsigned int iy=0;iy<4;++iy) {
378 output(ix,iy) = _tensor[3][ix]*ten(iy,3);
379 for(unsigned int iz=0;iz<3;++iz) {
380 output(ix,iy) -= _tensor[iz][ix]*ten(iy,iz);
381 }
382 }
383 }
384 return output;
385 }
386
388
396 template<typename ValueB>
397 auto preDot (const LorentzVector<complex<ValueB> > & vec) const
398 -> LorentzVector<decltype(vec.x()*this->xx())> {
399 LorentzVector<decltype(vec.x()*this->xx())> output;
400 output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]-
401 vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]);
402 output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]-
403 vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]);
404 output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]-
405 vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]);
406 output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]-
407 vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]);
408 return output;
409 }
410
414 template<typename ValueB>
415 auto postDot(const LorentzVector<complex<ValueB> > & vec) const
416 -> LorentzVector<decltype(vec.x()*this->xx())> {
417 LorentzVector<decltype(vec.x()*this->xx())> output;
418 output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]-
419 vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]);
420 output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]-
421 vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]);
422 output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]-
423 vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]);
424 output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]-
425 vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]);
426 return output;
427 }
428
432 auto preDot (const Lorentz5Momentum & vec) const
433 -> LorentzVector<decltype(vec.x()*this->xx())>
434 {
435 LorentzVector<decltype(vec.x()*this->xx())> output;
436 output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]-
437 vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]);
438 output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]-
439 vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]);
440 output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]-
441 vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]);
442 output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]-
443 vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]);
444 return output;
445 }
446
450 auto postDot(const Lorentz5Momentum & vec) const
451 -> LorentzVector<decltype(vec.x()*this->xx())>
452 {
453 LorentzVector<decltype(vec.x()*this->xx())> output;
454 output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]-
455 vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]);
456 output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]-
457 vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]);
458 output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]-
459 vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]);
460 output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]-
461 vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]);
462 return output;
463 }
465private:
466
470 std::array<std::array<complex<Value>,4>,4> _tensor;
471
472};
473
477template<typename T, typename U>
478inline auto
479operator*(complex<U> a, const LorentzTensor<T> & t)
480-> LorentzTensor<decltype(a.real()*t.xx().real())>
481{
482 return
483 {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(),
484 a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(),
485 a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(),
486 a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()};
487}
488
492template<typename T, typename U>
493inline auto
494operator*(const LorentzTensor<T> & t,complex<U> a)
495-> LorentzTensor<decltype(a.real()*t.xx().real())>
496{
497 return
498 {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(),
499 a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(),
500 a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(),
501 a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()};
502}
503
507template<typename T, typename U>
508inline auto
509operator*(const LorentzVector<U> & v,
510 const LorentzTensor<T> & t)
511-> LorentzVector<decltype(v.t()*t(3,0))>
512{
513 LorentzVector<decltype(v.t()*t(3,0))> outvec;
514 outvec.setX( v.t()*t(3,0)-v.x()*t(0,0)
515 -v.y()*t(1,0)-v.z()*t(2,0));
516 outvec.setY( v.t()*t(3,1)-v.x()*t(0,1)
517 -v.y()*t(1,1)-v.z()*t(2,1));
518 outvec.setZ( v.t()*t(3,2)-v.x()*t(0,2)
519 -v.y()*t(1,2)-v.z()*t(2,2));
520 outvec.setT( v.t()*t(3,3)-v.x()*t(0,3)
521 -v.y()*t(1,3)-v.z()*t(2,3));
522 return outvec;
523}
524
528template<typename T, typename U>
529inline auto
530operator*(const LorentzTensor<T> & t, const LorentzVector<U> & v)
531-> LorentzVector<decltype(v.t()*t(0,3))>
532{
533 LorentzVector<decltype(v.t()*t(0,3))> outvec;
534 outvec.setX( v.t()*t(0,3)-v.x()*t(0,0)
535 -v.y()*t(0,1)-v.z()*t(0,2));
536 outvec.setY( v.t()*t(1,3)-v.x()*t(1,0)
537 -v.y()*t(1,1)-v.z()*t(1,2));
538 outvec.setZ( v.t()*t(2,3)-v.x()*t(2,0)
539 -v.y()*t(2,1)-v.z()*t(2,2));
540 outvec.setT( v.t()*t(3,3)-v.x()*t(3,0)
541 -v.y()*t(3,1)-v.z()*t(3,2));
542 return outvec;
543}
544
548template <typename T, typename U>
549inline auto
550operator*(const LorentzTensor<T> & t,
551 const LorentzTensor<U> & u)
552-> decltype(t.xx()*u.xx())
553{
554 using RetT = decltype(t.xx()*u.xx());
555 RetT output=RetT(),temp;
556 for(unsigned int ix=0;ix<4;++ix) {
557 temp = t._tensor[ix][3]*u._tensor[ix][3];
558 for(unsigned int iy=0;iy<3;++iy) {
559 temp -= t._tensor[ix][iy]*u._tensor[ix][iy];
560 }
561 if(ix<3) output-=temp;
562 else output+=temp;
563 }
564 return output;
565}
566
567}
568}
569
570#ifndef ThePEG_TEMPLATES_IN_CC_FILE
571#include "LorentzTensor.tcc"
572#endif
573
574#endif
Overloads for operations on complex physical quantities.
This is the main config header file for ThePEG.
The LorentzTensor class is designed to implement the storage of a complex tensor to be used to repres...
Definition: LorentzTensor.h:37
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
auto postDot(const LorentzVector< complex< ValueB > > &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
Second index dot product with polarization vector.
complex< Value > tt() const
Get t,t component.
complex< Value > zx() const
Get z,x component.
Definition: LorentzTensor.h:93
void setZX(complex< Value > a)
Set z,x component.
LorentzTensor(const LorentzPolarizationVector &p, const LorentzPolarizationVector &q)
Constructor in terms of two polarization vectors.
Definition: LorentzTensor.h:66
complex< Value > xx() const
Get x,x component.
Definition: LorentzTensor.h:84
void setXX(complex< Value > a)
Set x,x component.
auto outerProduct(const LorentzTensor< ValueB > &ten) const -> LorentzTensor< decltype(ten.xx().real() *this->xx().real())>
Outer product with another tensor.
complex< Value > yz() const
Get y,z component.
friend auto operator*(const LorentzTensor< T > &t, const LorentzTensor< U > &u) -> decltype(t.xx() *u.xx())
Scalar product with other tensor.
complex< Value > zt() const
Get z,t component.
std::array< std::array< complex< Value >, 4 >, 4 > _tensor
The components.
complex< Value > xz() const
Get x,z component.
complex< Value > yt() const
Get y,t component.
void setZT(complex< Value > a)
Set z,t component.
LorentzTensor & boost(double, double, double)
Standard Lorentz boost specifying the components of the beta vector.
void setZY(complex< Value > a)
Set z,y component.
complex< Value > ty() const
Get t,y component.
void setTZ(complex< Value > a)
Set t,z component.
complex< Value > zz() const
Get z,z component.
complex< Value > zy() const
Get z,y component.
complex< Value > xy() const
Get x,y component.
void setXT(complex< Value > a)
Set x,t component.
complex< Value > tz() const
Get t,z component.
LorentzTensor()=default
Default zero constructor.
LorentzTensor< Value > & boost(const Boost &b)
Standard Lorentz boost specifying the beta vector.
void setXZ(complex< Value > a)
Set x,z component.
void setZZ(complex< Value > a)
Set z,z component.
void setYT(complex< Value > a)
Set y,t component.
void setTX(complex< Value > a)
Set t,x component.
LorentzTensor< Value > conjugate()
Return the complex conjugate.
complex< Value > trace() const
Trace.
void setXY(complex< Value > a)
Set x,y component.
LorentzTensor< Value > operator*=(Complex a)
Scaling with a complex number.
complex< Value > tx() const
Get t,x component.
Definition: LorentzTensor.h:98
void setYY(complex< Value > a)
Set y,y component.
void setYX(complex< Value > a)
Set y,x component.
auto preDot(const Lorentz5Momentum &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
First index dot product with momentum.
void setTY(complex< Value > a)
Set t,y component.
LorentzTensor< Value > operator-(const LorentzTensor< Value > &in) const
Subtraction.
complex< Value > xt() const
Get x,t component.
LorentzTensor & transform(const SpinOneLorentzRotation &r)
General Lorentz transformation.
auto preDot(const LorentzVector< complex< ValueB > > &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
Various dot products.
complex< Value > yx() const
Get y,x component.
Definition: LorentzTensor.h:89
void setYZ(complex< Value > a)
Set y,z component.
complex< Value > yy() const
Get y,y component.
auto innerProduct(const LorentzTensor< ValueB > &ten) const -> LorentzTensor< decltype(ten.xx().real() *this->xx().real())>
Inner product with another tensor.
auto postDot(const Lorentz5Momentum &vec) const -> LorentzVector< decltype(vec.x() *this->xx())>
Second index dot product with momentum.
void setTT(complex< Value > a)
Set t,t component.
LorentzTensor< Value > operator+(const LorentzTensor< Value > &in) const
Addition.
The SpinOneLorentzRotation class is ...
A 3-component vector.
Definition: ThreeVector.h:35
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition: Complex.h:23