thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
LorentzSpinor.h
1 // -*- C++ -*-
2 //
3 // LorentzSpinor.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_LorentzSpinor_H
10 #define ThePEG_LorentzSpinor_H
11 // This is the declaration of the LorentzSpinor class.
12 #include "ThePEG/Config/ThePEG.h"
13 #include "ThePEG/Vectors/LorentzRotation.h"
15 #include "HelicityDefinitions.h"
16 #include "LorentzSpinor.fh"
17 #include "LorentzSpinorBar.h"
18 #include "LorentzPolarizationVector.h"
19 #include "LorentzTensor.h"
20 #include <array>
21 
22 namespace ThePEG{
23 namespace Helicity{
24 
70 template<typename Value>
72 public:
73 
80 
85  LorentzSpinor(complex<Value> a,complex<Value> b,
86  complex<Value> c,complex<Value> d,
87  SpinorType s = SpinorType::unknown) : _type(s), _spin{{a,b,c,d}} {}
89 
90  template <typename U>
91  LorentzSpinor(const LorentzSpinor<U> & other)
92  : _type(other._type), _spin(other._spin) {}
93 
99  complex<Value> operator[](int i) const {
100  assert( i >= 0 && i <= 3 );
101  return _spin[i];
102  }
103 
107  complex<Value> operator()(int i) const {
108  assert( i >= 0 && i <= 3 );
109  return _spin[i];
110  }
111 
115  complex<Value> & operator()(int i) {
116  assert( i >= 0 && i <= 3 );
117  return _spin[i];
118  }
119 
123  complex<Value> & operator[](int i) {
124  assert( i >= 0 && i <= 3 );
125  return _spin[i];
126  }
127 
131  complex<Value> s1() const {return _spin[0];}
132 
136  complex<Value> s2() const {return _spin[1];}
137 
141  complex<Value> s3() const {return _spin[2];}
142 
146  complex<Value> s4() const {return _spin[3];}
147 
151  void setS1(complex<Value> in) {_spin[0]=in;}
152 
156  void setS2(complex<Value> in) {_spin[1]=in;}
157 
161  void setS3(complex<Value> in) {_spin[2]=in;}
162 
166  void setS4(complex<Value> in) {_spin[3]=in;}
168 
170 
171  template <typename ValueB>
172  LorentzSpinor<Value> & operator+=(const LorentzSpinor<ValueB> & a) {
173  for(unsigned int ix=0;ix<4;++ix) _spin[ix] += a._spin[ix];
174  return *this;
175  }
176 
177  template <typename ValueB>
178  LorentzSpinor<Value> & operator-=(const LorentzSpinor<ValueB> & a) {
179  for(unsigned int ix=0;ix<4;++ix) _spin[ix] -= a._spin[ix];
180  return *this;
181  }
182 
183  LorentzSpinor<Value> & operator*=(double a) {
184  for(unsigned int ix=0;ix<4;++ix) _spin[ix] *=a;
185  return *this;
186  }
187 
188  LorentzSpinor<Value> & operator/=(double a) {
189  for(unsigned int ix=0;ix<4;++ix) _spin[ix] /=a;
190  return *this;
191  }
193 
200 
206  LorentzSpinor conjugate() const;
207 
211  LorentzSpinor & boost(double,double,double);
212 
216  LorentzSpinor & boost(const Boost &);
217 
222 
227  transform(r.half());
228  return *this;
229  }
231 
237  SpinorType Type() const {return _type;}
239 
247  template<typename ValueB>
249  const ValueB & m) const
251  {
253  static const Complex ii(0.,1.);
254  complex<ValueB> p0pp3=p.t()+p.z();
255  complex<ValueB> p0mp3=p.t()-p.z();
256  complex<ValueB> p1pp2=p.x()+ii*p.y();
257  complex<ValueB> p1mp2=p.x()-ii*p.y();
258  spin.setS1(m*s1()+p0mp3*s3()-p1mp2*s4());
259  spin.setS2(m*s2()+p0pp3*s4()-p1pp2*s3());
260  spin.setS3(m*s3()+p0pp3*s1()+p1mp2*s2());
261  spin.setS4(m*s4()+p0mp3*s2()+p1pp2*s1());
262  return spin;
263  }
264 
269  helicityProjectionOperator(const Complex & gL, const Complex & gR) const {
270  LorentzSpinor spin;
271  spin.setS1(gL*s1());
272  spin.setS2(gL*s2());
273  spin.setS3(gR*s3());
274  spin.setS4(gR*s4());
275  return spin;
276  }
278 
279 
285  template<typename ValueB>
286  auto slash(const LorentzVector<ValueB> & p) const
287  -> LorentzSpinor<decltype(p.t()*Value())>
288  {
289  LorentzSpinor<decltype(p.t()*Value())> spin;
290  static const Complex ii(0.,1.);
291  complex<ValueB> p0pp3=p.t()+p.z();
292  complex<ValueB> p0mp3=p.t()-p.z();
293  complex<ValueB> p1pp2=p.x()+ii*p.y();
294  complex<ValueB> p1mp2=p.x()-ii*p.y();
295  spin.setS1(p0mp3*s3()-p1mp2*s4());
296  spin.setS2(p0pp3*s4()-p1pp2*s3());
297  spin.setS3(p0pp3*s1()+p1mp2*s2());
298  spin.setS4(p0mp3*s2()+p1pp2*s1());
299  return spin;
300  }
301 
305  template<typename ValueB>
306  auto slash(const LorentzVector<complex<ValueB> > & p) const
308  {
310  static const Complex ii(0.,1.);
311  complex<ValueB> p0pp3=p.t()+p.z();
312  complex<ValueB> p0mp3=p.t()-p.z();
313  complex<ValueB> p1pp2=p.x()+ii*p.y();
314  complex<ValueB> p1mp2=p.x()-ii*p.y();
315  spin.setS1(p0mp3*s3()-p1mp2*s4());
316  spin.setS2(p0pp3*s4()-p1pp2*s3());
317  spin.setS3(p0pp3*s1()+p1mp2*s2());
318  spin.setS4(p0mp3*s2()+p1pp2*s1());
319  return spin;
320  }
321 
326  template<typename ValueB>
327  auto leftCurrent(const LorentzSpinorBar<ValueB>& fb) const
328  -> LorentzVector<decltype(fb.s3()*this->s2())>
329  {
330  typedef decltype(fb.s3()*s2()) ResultT;
332  Complex ii(0.,1.);
333  ResultT p1(fb.s3()*s2()),p2(fb.s4()*s1());
334  vec.setX( -(p1+p2) );
335  vec.setY( ii*(p1-p2) );
336  p1 = fb.s3()*s1();p2 = fb.s4()*s2();
337  vec.setZ( -(p1-p2) );
338  vec.setT( (p1+p2) );
339  return vec;
340  }
341 
346  template<typename ValueB>
347  auto rightCurrent(const LorentzSpinorBar<ValueB>& fb) const
348  -> LorentzVector<decltype(fb.s1()*this->s4())>
349  {
350  typedef decltype(fb.s1()*s4()) ResultT;
352  Complex ii(0.,1.);
353  ResultT p1(fb.s1()*s4()),p2(fb.s2()*s3());
354  vec.setX( (p1+p2));
355  vec.setY( -ii*(p1-p2));
356  p1 = fb.s1()*s3();p2 = fb.s2()*s4();
357  vec.setZ( (p1-p2));
358  vec.setT( (p1+p2));
359  return vec;
360  }
361 
366  template<typename ValueB>
368  -> LorentzVector<decltype(fb.s1()*this->s4())>
369  {
370  typedef decltype(fb.s1()*this->s4()) ResultT;
372  Complex ii(0.,1.);
373  ResultT s1s4(fb.s1()*s4()),s2s3(fb.s2()*s3()),
374  s3s2(fb.s3()*s2()),s4s1(fb.s4()*s1()),
375  s1s3(fb.s1()*s3()),s2s4(fb.s2()*s4()),
376  s3s1(fb.s3()*s1()),s4s2(fb.s4()*s2());
377  vec.setX( s1s4+s2s3-s3s2-s4s1 );
378  vec.setY( -ii*(s1s4-s2s3-s3s2+s4s1));
379  vec.setZ( s1s3-s2s4-s3s1+s4s2 );
380  vec.setT( s1s3+s2s4+s3s1+s4s2);
381  return vec;
382  }
383 
391  template<typename ValueB>
393  Complex left, Complex right) const
394  -> LorentzVector<decltype(fb.s3()*this->s2())>
395  {
396  typedef decltype(fb.s3()*this->s2()) ResultT;
398  Complex ii(0.,1.);
399  ResultT p1(fb.s3()*s2()),p2(fb.s4()*s1());
400  vec.setX( -left*(p1+p2));
401  vec.setY( ii*left*(p1-p2));
402  p1 = fb.s3()*s1();p2 = fb.s4()*s2();
403  vec.setZ( -left*(p1-p2));
404  vec.setT( left*(p1+p2));
405  p1=fb.s1()*s4();p2=fb.s2()*s3();
406  vec.setX(vec.x()+right*(p1+p2));
407  vec.setY(vec.y()-ii*right*(p1-p2));
408  p1 = fb.s1()*s3();p2 = fb.s2()*s4();
409  vec.setZ(vec.z()+right*(p1-p2));
410  vec.setT(vec.t()+right*(p1+p2));
411  return vec;
412  }
414 
421  template<typename ValueB>
422  auto leftScalar(const LorentzSpinorBar<ValueB>& fb) const
423  -> decltype(fb.s1()*this->s1())
424  {
425  return fb.s1()*s1()+fb.s2()*s2();
426  }
427 
432  template<typename ValueB>
433  auto rightScalar(const LorentzSpinorBar<ValueB>& fb) const
434  -> decltype(fb.s3()*this->s3())
435  {
436  return fb.s3()*s3()+fb.s4()*s4();
437  }
438 
443  template<typename ValueB>
444  auto scalar(const LorentzSpinorBar<ValueB>& fb) const
445  -> decltype(fb.s1()*this->s1())
446  {
447  return fb.s1()*s1()+fb.s2()*s2()
448  +fb.s3()*s3()+fb.s4()*s4();
449  }
450 
455  template<typename ValueB>
456  auto pseudoScalar(const LorentzSpinorBar<ValueB>& fb) const
457  -> decltype(fb.s1()*this->s1())
458  {
459  return -fb.s1()*s1()-fb.s2()*s2()
460  +fb.s3()*s3()+fb.s4()*s4();
461  }
462 
470  template<typename ValueB>
472  Complex left, Complex right) const
473  -> decltype(left*fb.s1()*this->s1())
474  {
475  return left*(fb.s1()*s1()+fb.s2()*s2())
476  + right*(fb.s3()*s3()+fb.s4()*s4());
477  }
479 
484  template<typename ValueB>
485  auto sigma(const LorentzSpinorBar<ValueB>& fb) const
486  -> LorentzTensor<decltype(fb.s1()*this->s1())>
487  {
488  typedef decltype(fb.s1()*this->s1()) ResultT;
489  LorentzTensor<ResultT> output;
490  ResultT s11(fb.s1()*s1()),s22(fb.s2()*s2()),
491  s33(fb.s3()*s3()),s44(fb.s4()*s4()),
492  s12(fb.s1()*s2()),s21(fb.s2()*s1()),
493  s34(fb.s3()*s4()),s43(fb.s4()*s3());
494  Complex ii(0.,1.);
495  ResultT zero;
496  zero = ZERO;
497  output.setTT( zero );
498  output.setTX(-ii*( s12+s21-s34-s43));
499  output.setTY( -s12+s21+s34-s43 );
500  output.setTZ(-ii*( s11-s22-s33+s44));
501  output.setXT( -output.tx() );
502  output.setXX( zero );
503  output.setXY( s11-s22+s33-s44 );
504  output.setXZ(-ii*(-s12+s21-s34+s43));
505  output.setYT( -output.ty() );
506  output.setYX( -output.xy() );
507  output.setYY( zero );
508  output.setYZ( s12+s21+s34+s43 );
509  output.setZT( -output.tz() );
510  output.setZX( -output.xz() );
511  output.setZY( -output.yz() );
512  output.setZZ( zero );
513  return output;
514  }
515 
516 private:
521 
525  std::array<complex<Value>,4> _spin;
526 };
527 
529 
530 template <typename Value>
532 operator/(const LorentzSpinor<Value> & v, Value a) {
533  return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
534 }
535 
537 operator/(const LorentzSpinor<double> & v, Complex a) {
538  return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
539 }
540 
541 template <typename Value>
542 inline LorentzSpinor<Value> operator-(const LorentzSpinor<Value> & v) {
543  return LorentzSpinor<Value>(-v.s1(),-v.s2(),-v.s3(),-v.s4(),v.Type());
544 }
545 
546 template <typename ValueA, typename ValueB>
548 operator+(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
549  return a += b;
550 }
551 
552 template <typename ValueA, typename ValueB>
554 operator-(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
555  return a -= b;
556 }
557 
558 template <typename Value>
560 operator*(const LorentzSpinor<Value> & a, double b) {
561  return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
562 }
563 
564 template <typename Value>
566 operator*(double b, LorentzSpinor<Value> a) {
567  return a *= b;
568 }
569 
570 template <typename Value>
572 operator*(const LorentzSpinor<Value> & a, Complex b) {
573  return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
574 }
575 
576 template <typename ValueA, typename ValueB>
577 inline auto operator*(complex<ValueB> a, const LorentzSpinor<ValueA> & v)
578  -> LorentzSpinor<decltype(a.real()*v.s1().real())>
579 {
580  return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
581 }
582 
583 template <typename ValueA, typename ValueB>
584 inline auto operator*(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
585  -> LorentzSpinor<decltype(b.real()*v.s1().real())>
586 {
587  return b*v;
588 }
589 
590 template <typename ValueA, typename ValueB>
591 inline auto operator/(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
592  -> LorentzSpinor<decltype(v.s1().real()/b.real())>
593 {
594  return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
595 }
596 
597 template <typename ValueA, typename ValueB>
598 inline auto operator*(ValueB a, const LorentzSpinor<ValueA> & v)
599  -> LorentzSpinor<decltype(a*v.s1().real())>
600 {
601  return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
602 }
603 
604 template <typename ValueA, typename ValueB>
605 inline auto operator*(const LorentzSpinor<ValueA> & v, ValueB b)
606  -> LorentzSpinor<decltype(b*v.s1().real())>
607 {
608  return b*v;
609 }
610 
611 template <typename ValueA, typename ValueB>
612 inline auto operator/(const LorentzSpinor<ValueA> & v, ValueB b)
613  -> LorentzSpinor<decltype(v.s1().real()/b)>
614 {
615  return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
616 }
617 
618 }
619 }
620 
621 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
622 #include "LorentzSpinor.tcc"
623 #endif
624 
625 #endif
626 
complex< Value > s2() const
Get second component.
LorentzSpinor conjugate() const
Return the conjugated spinor .
A 4-component Lorentz vector.
Definition: LorentzVector.h:35
complex< Value > operator[](int i) const
Subscript operator to return spinor components.
Definition: LorentzSpinor.h:99
LorentzSpinor(SpinorType t=SpinorType::unknown)
Default zero constructor, optionally specifying t, the type.
Definition: LorentzSpinor.h:79
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition: Complex.h:23
complex< Value > & operator[](int i)
Set components by index.
LorentzSpinor helicityProjectionOperator(const Complex &gL, const Complex &gR) const
Apply .
This file contains enumerations used by LorentzSpinor and LorentzSpinorBar classes.
LorentzSpinor(complex< Value > a, complex< Value > b, complex< Value > c, complex< Value > d, SpinorType s=SpinorType::unknown)
Constructor with complex numbers specifying the components, optionally specifying s...
Definition: LorentzSpinor.h:85
A 3-component vector.
Definition: ThreeVector.h:34
The LorentzRotation class combine a SpinOneLorentzRotation and a spin SpinHalfLorentzRotation to prov...
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
ostream & left(ostream &os)
Stream manipulator setting an ostream to left-adjust its ouput.
Definition: std.h:160
This is the main config header file for ThePEG.
The LorentzSpinor class is designed to store a spinor.
Definition: LorentzSpinor.h:71
const SpinHalfLorentzRotation & half() const
The spin- transformation.
auto vectorCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s1() *this->s4())>
Calculate the vector current .
complex< Value > s4() const
Get fourth component.
complex< Value > s3() const
Get third component.
complex< Value > s1() const
Get first component.
auto generalScalar(const LorentzSpinorBar< ValueB > &fb, Complex left, Complex right) const -> decltype(left *fb.s1() *this->s1())
Calculate a general scalar product with arbitary left and right couplings, i.e.
auto generalCurrent(const LorentzSpinorBar< ValueB > &fb, Complex left, Complex right) const -> LorentzVector< decltype(fb.s3() *this->s2())>
Calculate a general current with arbitary left and right couplings, i.e.
auto slash(const LorentzVector< ValueB > &p) const -> LorentzSpinor< decltype(p.t() *Value())>
Apply .
LorentzSpinor & boost(double, double, double)
Standard Lorentz boost specifying the components of the beta vector.
auto rightCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s1() *this->s4())>
Calculate the right-handed current .
LorentzSpinor & transform(const LorentzRotation &r)
General Lorentz transformation.
auto pseudoScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the pseudoscalar .
LorentzSpinorBar< Value > bar() const
Return the barred spinor.
contains the ThreeVector class.
void setS1(complex< Value > in)
Set first component.
LorentzSpinor & transform(const SpinHalfLorentzRotation &)
General Lorentz transformation.
std::array< complex< Value >, 4 > _spin
Storage of the components.
void setS3(complex< Value > in)
Set third component.
SpinorType
Enumeration to specify spinor type.
auto scalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the scalar .
complex< Value > & operator()(int i)
Set components by index.
SpinorType _type
Type of spinor.
auto leftScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the left-handed scalar .
complex< Value > operator()(int i) const
Subscript operator to return spinor components.
void setS2(complex< Value > in)
Set second component.
ostream & right(ostream &os)
Stream manipulator setting an ostream to right-adjust its ouput.
Definition: std.h:166
auto slash(const LorentzVector< complex< ValueB > > &p) const -> LorentzSpinor< decltype(ValueB() *Value())>
Apply .
auto rightScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s3() *this->s3())
Calculate the right-handed scalar .
void setS4(complex< Value > in)
Set fourth component.
The SpinHalfLorentzRotation class is designed to offer the same features as the HepLorentzRotation cl...
The LorentzTensor class is designed to implement the storage of a complex tensor to be used to repres...
Definition: LorentzTensor.h:21
auto projectionOperator(const LorentzVector< ValueB > &p, const ValueB &m) const -> LorentzSpinor< decltype(m *Value())>
Apply .
auto leftCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s3() *this->s2())>
Calculate the left-handed current .
SpinorType Type() const
Return the type of the spinor.
The LorentzSpinorBar class implements the storage of a barred LorentzSpinor.
auto sigma(const LorentzSpinorBar< ValueB > &fb) const -> LorentzTensor< decltype(fb.s1() *this->s1())>
Calculate the product with , i.e.
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35