thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
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.
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
22namespace ThePEG{
23namespace Helicity{
24
70template<typename Value>
72public:
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
207
211 LorentzSpinor & boost(double,double,double);
212
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
250 -> LorentzSpinor<decltype(m*Value())>
251 {
252 LorentzSpinor<decltype(m*Value())> spin;
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
307 -> LorentzSpinor<decltype(ValueB()*Value())>
308 {
309 LorentzSpinor<decltype(ValueB()*Value())> spin;
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>
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>
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>
423 -> decltype(fb.s1()*this->s1())
424 {
425 return fb.s1()*s1()+fb.s2()*s2();
426 }
427
432 template<typename ValueB>
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>
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(ValueB()*Value())> {
487 typedef decltype(ValueB()*Value()) ResultT;
489 complex<ResultT> s11(fb.s1()*s1()),s22(fb.s2()*s2()),
490 s33(fb.s3()*s3()),s44(fb.s4()*s4()),
491 s12(fb.s1()*s2()),s21(fb.s2()*s1()),
492 s34(fb.s3()*s4()),s43(fb.s4()*s3());
493 Complex ii(0.,1.);
494 ResultT zero;
495 zero = ZERO;
496 output.setTT( zero );
497 output.setTX(-ii*( s12+s21-s34-s43));
498 output.setTY( -s12+s21+s34-s43 );
499 output.setTZ(-ii*( s11-s22-s33+s44));
500 output.setXT( -output.tx() );
501 output.setXX( zero );
502 output.setXY( s11-s22+s33-s44 );
503 output.setXZ(-ii*(-s12+s21-s34+s43));
504 output.setYT( -output.ty() );
505 output.setYX( -output.xy() );
506 output.setYY( zero );
507 output.setYZ( s12+s21+s34+s43 );
508 output.setZT( -output.tz() );
509 output.setZX( -output.xz() );
510 output.setZY( -output.yz() );
511 output.setZZ( zero );
512 return output;
513 }
514
515private:
520
524 std::array<complex<Value>,4> _spin;
525};
526
528
529template <typename Value>
531operator/(const LorentzSpinor<Value> & v, Value a) {
532 return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
533}
534
535inline LorentzSpinor<double>
536operator/(const LorentzSpinor<double> & v, Complex a) {
537 return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
538}
539
540template <typename Value>
541inline LorentzSpinor<Value> operator-(const LorentzSpinor<Value> & v) {
542 return LorentzSpinor<Value>(-v.s1(),-v.s2(),-v.s3(),-v.s4(),v.Type());
543}
544
545template <typename ValueA, typename ValueB>
546inline LorentzSpinor<ValueA>
547operator+(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
548 return a += b;
549}
550
551template <typename ValueA, typename ValueB>
552inline LorentzSpinor<ValueA>
553operator-(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
554 return a -= b;
555}
556
557template <typename Value>
558inline LorentzSpinor<Value>
559operator*(const LorentzSpinor<Value> & a, double b) {
560 return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
561}
562
563template <typename Value>
564inline LorentzSpinor<Value>
565operator*(double b, LorentzSpinor<Value> a) {
566 return a *= b;
567}
568
569template <typename Value>
570inline LorentzSpinor<Value>
571operator*(const LorentzSpinor<Value> & a, Complex b) {
572 return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
573}
574
575template <typename ValueA, typename ValueB>
576inline auto operator*(complex<ValueB> a, const LorentzSpinor<ValueA> & v)
577 -> LorentzSpinor<decltype(a.real()*v.s1().real())>
578{
579 return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
580}
581
582template <typename ValueA, typename ValueB>
583inline auto operator*(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
584 -> LorentzSpinor<decltype(b.real()*v.s1().real())>
585{
586 return b*v;
587}
588
589template <typename ValueA, typename ValueB>
590inline auto operator/(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
591 -> LorentzSpinor<decltype(v.s1().real()/b.real())>
592{
593 return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
594}
595
596template <typename ValueA, typename ValueB>
597inline auto operator*(ValueB a, const LorentzSpinor<ValueA> & v)
598 -> LorentzSpinor<decltype(a*v.s1().real())>
599{
600 return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
601}
602
603template <typename ValueA, typename ValueB>
604inline auto operator*(const LorentzSpinor<ValueA> & v, ValueB b)
605 -> LorentzSpinor<decltype(b*v.s1().real())>
606{
607 return b*v;
608}
609
610template <typename ValueA, typename ValueB>
611inline auto operator/(const LorentzSpinor<ValueA> & v, ValueB b)
612 -> LorentzSpinor<decltype(v.s1().real()/b)>
613{
614 return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
615}
616
617}
618}
619
620#ifndef ThePEG_TEMPLATES_IN_CC_FILE
621#include "LorentzSpinor.tcc"
622#endif
623
624#endif
625
This file contains enumerations used by LorentzSpinor and LorentzSpinorBar classes.
This is the main config header file for ThePEG.
contains the ThreeVector class.
The LorentzSpinorBar class implements the storage of a barred LorentzSpinor.
The LorentzSpinor class is designed to store a spinor.
Definition: LorentzSpinor.h:71
auto vectorCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s1() *this->s4())>
Calculate the vector current .
LorentzSpinor conjugate() const
Return the conjugated spinor .
complex< Value > s2() const
Get second component.
void setS2(complex< Value > in)
Set second component.
LorentzSpinor(SpinorType t=SpinorType::unknown)
Default zero constructor, optionally specifying t, the type.
Definition: LorentzSpinor.h:79
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.
SpinorType Type() const
Return the type of the spinor.
void setS4(complex< Value > in)
Set fourth component.
auto slash(const LorentzVector< complex< ValueB > > &p) const -> LorentzSpinor< decltype(ValueB() *Value())>
Apply .
complex< Value > s3() const
Get third component.
LorentzSpinor & boost(double, double, double)
Standard Lorentz boost specifying the components of the beta vector.
complex< Value > s1() const
Get first component.
auto sigma(const LorentzSpinorBar< ValueB > &fb) const -> LorentzTensor< decltype(ValueB() *Value())>
Calculate the product with , i.e.
complex< Value > operator()(int i) const
Subscript operator to return spinor components.
auto slash(const LorentzVector< ValueB > &p) const -> LorentzSpinor< decltype(p.t() *Value())>
Apply .
LorentzSpinor helicityProjectionOperator(const Complex &gL, const Complex &gR) const
Apply .
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 leftScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the left-handed scalar .
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
SpinorType _type
Type of spinor.
auto scalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the scalar .
LorentzSpinor & transform(const LorentzRotation &r)
General Lorentz transformation.
auto rightCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s1() *this->s4())>
Calculate the right-handed current .
complex< Value > operator[](int i) const
Subscript operator to return spinor components.
Definition: LorentzSpinor.h:99
auto leftCurrent(const LorentzSpinorBar< ValueB > &fb) const -> LorentzVector< decltype(fb.s3() *this->s2())>
Calculate the left-handed current .
LorentzSpinor & boost(const Boost &)
Standard Lorentz boost specifying the beta vector.
auto projectionOperator(const LorentzVector< ValueB > &p, const ValueB &m) const -> LorentzSpinor< decltype(m *Value())>
Apply .
LorentzSpinorBar< Value > bar() const
Return the barred spinor.
auto pseudoScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s1() *this->s1())
Calculate the pseudoscalar .
LorentzSpinor & transform(const SpinHalfLorentzRotation &)
General Lorentz transformation.
void setS1(complex< Value > in)
Set first component.
complex< Value > & operator[](int i)
Set components by index.
complex< Value > s4() const
Get fourth component.
std::array< complex< Value >, 4 > _spin
Storage of the components.
auto rightScalar(const LorentzSpinorBar< ValueB > &fb) const -> decltype(fb.s3() *this->s3())
Calculate the right-handed scalar .
void setS3(complex< Value > in)
Set third component.
complex< Value > & operator()(int i)
Set components by index.
The LorentzTensor class is designed to implement the storage of a complex tensor to be used to repres...
Definition: LorentzTensor.h:37
The LorentzRotation class combine a SpinOneLorentzRotation and a spin SpinHalfLorentzRotation to prov...
const SpinHalfLorentzRotation & half() const
The spin- transformation.
A 4-component Lorentz vector.
Definition: LorentzVector.h:44
The SpinHalfLorentzRotation class is designed to offer the same features as the HepLorentzRotation cl...
A 3-component vector.
Definition: ThreeVector.h:35
SpinorType
Enumeration to specify spinor type.
@ unknown
Undefined spinor type.
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
ostream & right(ostream &os)
Stream manipulator setting an ostream to right-adjust its ouput.
Definition: std.h:167
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
ostream & left(ostream &os)
Stream manipulator setting an ostream to left-adjust its ouput.
Definition: std.h:161