File indexing completed on 2026-08-06 09:38:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef ThePEG_LorentzSpinor_H
0010 #define ThePEG_LorentzSpinor_H
0011
0012 #include "ThePEG/Config/ThePEG.h"
0013 #include "ThePEG/Vectors/LorentzRotation.h"
0014 #include "ThePEG/Vectors/ThreeVector.h"
0015 #include "HelicityDefinitions.h"
0016 #include "LorentzSpinor.fh"
0017 #include "LorentzSpinorBar.h"
0018 #include "LorentzPolarizationVector.h"
0019 #include "LorentzTensor.h"
0020 #include <array>
0021
0022 namespace ThePEG{
0023 namespace Helicity{
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 template<typename Value>
0071 class LorentzSpinor {
0072 public:
0073
0074
0075
0076
0077
0078
0079 LorentzSpinor(SpinorType t = SpinorType::unknown) : _type(t), _spin() {}
0080
0081
0082
0083
0084
0085 LorentzSpinor(complex<Value> a,complex<Value> b,
0086 complex<Value> c,complex<Value> d,
0087 SpinorType s = SpinorType::unknown) : _type(s), _spin{{a,b,c,d}} {}
0088
0089
0090 template <typename U>
0091 LorentzSpinor(const LorentzSpinor<U> & other)
0092 : _type(other._type), _spin(other._spin) {}
0093
0094
0095
0096
0097
0098
0099 complex<Value> operator[](int i) const {
0100 assert( i >= 0 && i <= 3 );
0101 return _spin[i];
0102 }
0103
0104
0105
0106
0107 complex<Value> operator()(int i) const {
0108 assert( i >= 0 && i <= 3 );
0109 return _spin[i];
0110 }
0111
0112
0113
0114
0115 complex<Value> & operator()(int i) {
0116 assert( i >= 0 && i <= 3 );
0117 return _spin[i];
0118 }
0119
0120
0121
0122
0123 complex<Value> & operator[](int i) {
0124 assert( i >= 0 && i <= 3 );
0125 return _spin[i];
0126 }
0127
0128
0129
0130
0131 complex<Value> s1() const {return _spin[0];}
0132
0133
0134
0135
0136 complex<Value> s2() const {return _spin[1];}
0137
0138
0139
0140
0141 complex<Value> s3() const {return _spin[2];}
0142
0143
0144
0145
0146 complex<Value> s4() const {return _spin[3];}
0147
0148
0149
0150
0151 void setS1(complex<Value> in) {_spin[0]=in;}
0152
0153
0154
0155
0156 void setS2(complex<Value> in) {_spin[1]=in;}
0157
0158
0159
0160
0161 void setS3(complex<Value> in) {_spin[2]=in;}
0162
0163
0164
0165
0166 void setS4(complex<Value> in) {_spin[3]=in;}
0167
0168
0169
0170
0171 template <typename ValueB>
0172 LorentzSpinor<Value> & operator+=(const LorentzSpinor<ValueB> & a) {
0173 for(unsigned int ix=0;ix<4;++ix) _spin[ix] += a._spin[ix];
0174 return *this;
0175 }
0176
0177 template <typename ValueB>
0178 LorentzSpinor<Value> & operator-=(const LorentzSpinor<ValueB> & a) {
0179 for(unsigned int ix=0;ix<4;++ix) _spin[ix] -= a._spin[ix];
0180 return *this;
0181 }
0182
0183 LorentzSpinor<Value> & operator*=(double a) {
0184 for(unsigned int ix=0;ix<4;++ix) _spin[ix] *=a;
0185 return *this;
0186 }
0187
0188 LorentzSpinor<Value> & operator/=(double a) {
0189 for(unsigned int ix=0;ix<4;++ix) _spin[ix] /=a;
0190 return *this;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199 LorentzSpinorBar<Value> bar() const;
0200
0201
0202
0203
0204
0205
0206 LorentzSpinor conjugate() const;
0207
0208
0209
0210
0211 LorentzSpinor & boost(double,double,double);
0212
0213
0214
0215
0216 LorentzSpinor & boost(const Boost &);
0217
0218
0219
0220
0221 LorentzSpinor & transform(const SpinHalfLorentzRotation & );
0222
0223
0224
0225
0226 LorentzSpinor & transform(const LorentzRotation & r) {
0227 transform(r.half());
0228 return *this;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237 SpinorType Type() const {return _type;}
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 template<typename ValueB>
0248 auto projectionOperator(const LorentzVector<ValueB> & p,
0249 const ValueB & m) const
0250 -> LorentzSpinor<decltype(m*Value())>
0251 {
0252 LorentzSpinor<decltype(m*Value())> spin;
0253 static const Complex ii(0.,1.);
0254 complex<ValueB> p0pp3=p.t()+p.z();
0255 complex<ValueB> p0mp3=p.t()-p.z();
0256 complex<ValueB> p1pp2=p.x()+ii*p.y();
0257 complex<ValueB> p1mp2=p.x()-ii*p.y();
0258 spin.setS1(m*s1()+p0mp3*s3()-p1mp2*s4());
0259 spin.setS2(m*s2()+p0pp3*s4()-p1pp2*s3());
0260 spin.setS3(m*s3()+p0pp3*s1()+p1mp2*s2());
0261 spin.setS4(m*s4()+p0mp3*s2()+p1pp2*s1());
0262 return spin;
0263 }
0264
0265
0266
0267
0268 LorentzSpinor
0269 helicityProjectionOperator(const Complex & gL, const Complex & gR) const {
0270 LorentzSpinor spin;
0271 spin.setS1(gL*s1());
0272 spin.setS2(gL*s2());
0273 spin.setS3(gR*s3());
0274 spin.setS4(gR*s4());
0275 return spin;
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285 template<typename ValueB>
0286 auto slash(const LorentzVector<ValueB> & p) const
0287 -> LorentzSpinor<decltype(p.t()*Value())>
0288 {
0289 LorentzSpinor<decltype(p.t()*Value())> spin;
0290 static const Complex ii(0.,1.);
0291 complex<ValueB> p0pp3=p.t()+p.z();
0292 complex<ValueB> p0mp3=p.t()-p.z();
0293 complex<ValueB> p1pp2=p.x()+ii*p.y();
0294 complex<ValueB> p1mp2=p.x()-ii*p.y();
0295 spin.setS1(p0mp3*s3()-p1mp2*s4());
0296 spin.setS2(p0pp3*s4()-p1pp2*s3());
0297 spin.setS3(p0pp3*s1()+p1mp2*s2());
0298 spin.setS4(p0mp3*s2()+p1pp2*s1());
0299 return spin;
0300 }
0301
0302
0303
0304
0305 template<typename ValueB>
0306 auto slash(const LorentzVector<complex<ValueB> > & p) const
0307 -> LorentzSpinor<decltype(ValueB()*Value())>
0308 {
0309 LorentzSpinor<decltype(ValueB()*Value())> spin;
0310 static const Complex ii(0.,1.);
0311 complex<ValueB> p0pp3=p.t()+p.z();
0312 complex<ValueB> p0mp3=p.t()-p.z();
0313 complex<ValueB> p1pp2=p.x()+ii*p.y();
0314 complex<ValueB> p1mp2=p.x()-ii*p.y();
0315 spin.setS1(p0mp3*s3()-p1mp2*s4());
0316 spin.setS2(p0pp3*s4()-p1pp2*s3());
0317 spin.setS3(p0pp3*s1()+p1mp2*s2());
0318 spin.setS4(p0mp3*s2()+p1pp2*s1());
0319 return spin;
0320 }
0321
0322
0323
0324
0325
0326 template<typename ValueB>
0327 auto leftCurrent(const LorentzSpinorBar<ValueB>& fb) const
0328 -> LorentzVector<decltype(fb.s3()*this->s2())>
0329 {
0330 typedef decltype(fb.s3()*s2()) ResultT;
0331 LorentzVector<ResultT> vec;
0332 Complex ii(0.,1.);
0333 ResultT p1(fb.s3()*s2()),p2(fb.s4()*s1());
0334 vec.setX( -(p1+p2) );
0335 vec.setY( ii*(p1-p2) );
0336 p1 = fb.s3()*s1();p2 = fb.s4()*s2();
0337 vec.setZ( -(p1-p2) );
0338 vec.setT( (p1+p2) );
0339 return vec;
0340 }
0341
0342
0343
0344
0345
0346 template<typename ValueB>
0347 auto rightCurrent(const LorentzSpinorBar<ValueB>& fb) const
0348 -> LorentzVector<decltype(fb.s1()*this->s4())>
0349 {
0350 typedef decltype(fb.s1()*s4()) ResultT;
0351 LorentzVector<ResultT> vec;
0352 Complex ii(0.,1.);
0353 ResultT p1(fb.s1()*s4()),p2(fb.s2()*s3());
0354 vec.setX( (p1+p2));
0355 vec.setY( -ii*(p1-p2));
0356 p1 = fb.s1()*s3();p2 = fb.s2()*s4();
0357 vec.setZ( (p1-p2));
0358 vec.setT( (p1+p2));
0359 return vec;
0360 }
0361
0362
0363
0364
0365
0366 template<typename ValueB>
0367 auto vectorCurrent(const LorentzSpinorBar<ValueB>& fb) const
0368 -> LorentzVector<decltype(fb.s1()*this->s4())>
0369 {
0370 typedef decltype(fb.s1()*this->s4()) ResultT;
0371 LorentzVector<ResultT> vec;
0372 Complex ii(0.,1.);
0373 ResultT s1s4(fb.s1()*s4()),s2s3(fb.s2()*s3()),
0374 s3s2(fb.s3()*s2()),s4s1(fb.s4()*s1()),
0375 s1s3(fb.s1()*s3()),s2s4(fb.s2()*s4()),
0376 s3s1(fb.s3()*s1()),s4s2(fb.s4()*s2());
0377 vec.setX( s1s4+s2s3-s3s2-s4s1 );
0378 vec.setY( -ii*(s1s4-s2s3-s3s2+s4s1));
0379 vec.setZ( s1s3-s2s4-s3s1+s4s2 );
0380 vec.setT( s1s3+s2s4+s3s1+s4s2);
0381 return vec;
0382 }
0383
0384
0385
0386
0387
0388
0389
0390
0391 template<typename ValueB>
0392 auto generalCurrent(const LorentzSpinorBar<ValueB>& fb,
0393 Complex left, Complex right) const
0394 -> LorentzVector<decltype(fb.s3()*this->s2())>
0395 {
0396 typedef decltype(fb.s3()*this->s2()) ResultT;
0397 LorentzVector<ResultT> vec;
0398 Complex ii(0.,1.);
0399 ResultT p1(fb.s3()*s2()),p2(fb.s4()*s1());
0400 vec.setX( -left*(p1+p2));
0401 vec.setY( ii*left*(p1-p2));
0402 p1 = fb.s3()*s1();p2 = fb.s4()*s2();
0403 vec.setZ( -left*(p1-p2));
0404 vec.setT( left*(p1+p2));
0405 p1=fb.s1()*s4();p2=fb.s2()*s3();
0406 vec.setX(vec.x()+right*(p1+p2));
0407 vec.setY(vec.y()-ii*right*(p1-p2));
0408 p1 = fb.s1()*s3();p2 = fb.s2()*s4();
0409 vec.setZ(vec.z()+right*(p1-p2));
0410 vec.setT(vec.t()+right*(p1+p2));
0411 return vec;
0412 }
0413
0414
0415
0416
0417
0418
0419
0420
0421 template<typename ValueB>
0422 auto leftScalar(const LorentzSpinorBar<ValueB>& fb) const
0423 -> decltype(fb.s1()*this->s1())
0424 {
0425 return fb.s1()*s1()+fb.s2()*s2();
0426 }
0427
0428
0429
0430
0431
0432 template<typename ValueB>
0433 auto rightScalar(const LorentzSpinorBar<ValueB>& fb) const
0434 -> decltype(fb.s3()*this->s3())
0435 {
0436 return fb.s3()*s3()+fb.s4()*s4();
0437 }
0438
0439
0440
0441
0442
0443 template<typename ValueB>
0444 auto scalar(const LorentzSpinorBar<ValueB>& fb) const
0445 -> decltype(fb.s1()*this->s1())
0446 {
0447 return fb.s1()*s1()+fb.s2()*s2()
0448 +fb.s3()*s3()+fb.s4()*s4();
0449 }
0450
0451
0452
0453
0454
0455 template<typename ValueB>
0456 auto pseudoScalar(const LorentzSpinorBar<ValueB>& fb) const
0457 -> decltype(fb.s1()*this->s1())
0458 {
0459 return -fb.s1()*s1()-fb.s2()*s2()
0460 +fb.s3()*s3()+fb.s4()*s4();
0461 }
0462
0463
0464
0465
0466
0467
0468
0469
0470 template<typename ValueB>
0471 auto generalScalar(const LorentzSpinorBar<ValueB>& fb,
0472 Complex left, Complex right) const
0473 -> decltype(left*fb.s1()*this->s1())
0474 {
0475 return left*(fb.s1()*s1()+fb.s2()*s2())
0476 + right*(fb.s3()*s3()+fb.s4()*s4());
0477 }
0478
0479
0480
0481
0482
0483
0484 template<typename ValueB>
0485 auto sigma(const LorentzSpinorBar<ValueB>& fb) const
0486 -> LorentzTensor<decltype(ValueB()*Value())> {
0487 typedef decltype(ValueB()*Value()) ResultT;
0488 LorentzTensor<ResultT> output;
0489 complex<ResultT> s11(fb.s1()*s1()),s22(fb.s2()*s2()),
0490 s33(fb.s3()*s3()),s44(fb.s4()*s4()),
0491 s12(fb.s1()*s2()),s21(fb.s2()*s1()),
0492 s34(fb.s3()*s4()),s43(fb.s4()*s3());
0493 Complex ii(0.,1.);
0494 ResultT zero;
0495 zero = ZERO;
0496 output.setTT( zero );
0497 output.setTX(-ii*( s12+s21-s34-s43));
0498 output.setTY( -s12+s21+s34-s43 );
0499 output.setTZ(-ii*( s11-s22-s33+s44));
0500 output.setXT( -output.tx() );
0501 output.setXX( zero );
0502 output.setXY( s11-s22+s33-s44 );
0503 output.setXZ(-ii*(-s12+s21-s34+s43));
0504 output.setYT( -output.ty() );
0505 output.setYX( -output.xy() );
0506 output.setYY( zero );
0507 output.setYZ( s12+s21+s34+s43 );
0508 output.setZT( -output.tz() );
0509 output.setZX( -output.xz() );
0510 output.setZY( -output.yz() );
0511 output.setZZ( zero );
0512 return output;
0513 }
0514
0515 private:
0516
0517
0518
0519 SpinorType _type;
0520
0521
0522
0523
0524 std::array<complex<Value>,4> _spin;
0525 };
0526
0527
0528
0529 template <typename Value>
0530 inline LorentzSpinor<double>
0531 operator/(const LorentzSpinor<Value> & v, Value a) {
0532 return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
0533 }
0534
0535 inline LorentzSpinor<double>
0536 operator/(const LorentzSpinor<double> & v, Complex a) {
0537 return LorentzSpinor<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
0538 }
0539
0540 template <typename Value>
0541 inline LorentzSpinor<Value> operator-(const LorentzSpinor<Value> & v) {
0542 return LorentzSpinor<Value>(-v.s1(),-v.s2(),-v.s3(),-v.s4(),v.Type());
0543 }
0544
0545 template <typename ValueA, typename ValueB>
0546 inline LorentzSpinor<ValueA>
0547 operator+(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
0548 return a += b;
0549 }
0550
0551 template <typename ValueA, typename ValueB>
0552 inline LorentzSpinor<ValueA>
0553 operator-(LorentzSpinor<ValueA> a, const LorentzSpinor<ValueB> & b) {
0554 return a -= b;
0555 }
0556
0557 template <typename Value>
0558 inline LorentzSpinor<Value>
0559 operator*(const LorentzSpinor<Value> & a, double b) {
0560 return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
0561 }
0562
0563 template <typename Value>
0564 inline LorentzSpinor<Value>
0565 operator*(double b, LorentzSpinor<Value> a) {
0566 return a *= b;
0567 }
0568
0569 template <typename Value>
0570 inline LorentzSpinor<Value>
0571 operator*(const LorentzSpinor<Value> & a, Complex b) {
0572 return LorentzSpinor<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
0573 }
0574
0575 template <typename ValueA, typename ValueB>
0576 inline auto operator*(complex<ValueB> a, const LorentzSpinor<ValueA> & v)
0577 -> LorentzSpinor<decltype(a.real()*v.s1().real())>
0578 {
0579 return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
0580 }
0581
0582 template <typename ValueA, typename ValueB>
0583 inline auto operator*(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
0584 -> LorentzSpinor<decltype(b.real()*v.s1().real())>
0585 {
0586 return b*v;
0587 }
0588
0589 template <typename ValueA, typename ValueB>
0590 inline auto operator/(const LorentzSpinor<ValueA> & v, complex<ValueB> b)
0591 -> LorentzSpinor<decltype(v.s1().real()/b.real())>
0592 {
0593 return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
0594 }
0595
0596 template <typename ValueA, typename ValueB>
0597 inline auto operator*(ValueB a, const LorentzSpinor<ValueA> & v)
0598 -> LorentzSpinor<decltype(a*v.s1().real())>
0599 {
0600 return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
0601 }
0602
0603 template <typename ValueA, typename ValueB>
0604 inline auto operator*(const LorentzSpinor<ValueA> & v, ValueB b)
0605 -> LorentzSpinor<decltype(b*v.s1().real())>
0606 {
0607 return b*v;
0608 }
0609
0610 template <typename ValueA, typename ValueB>
0611 inline auto operator/(const LorentzSpinor<ValueA> & v, ValueB b)
0612 -> LorentzSpinor<decltype(v.s1().real()/b)>
0613 {
0614 return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
0615 }
0616
0617 }
0618 }
0619
0620 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
0621 #include "LorentzSpinor.tcc"
0622 #endif
0623
0624 #endif
0625