Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:25

0001 // -*- C++ -*-
0002 //
0003 // LorentzSpinorBar.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 2003-2019 Peter Richardson, Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef ThePEG_LorentzSpinorBar_H
0010 #define ThePEG_LorentzSpinorBar_H
0011 // This is the declaration of the LorentzSpinorBar class.
0012 
0013 #include "ThePEG/Config/ThePEG.h"
0014 #include "ThePEG/Vectors/LorentzRotation.h"
0015 #include "ThePEG/Vectors/ThreeVector.h"
0016 #include "HelicityDefinitions.h"
0017 #include "LorentzSpinor.fh"
0018 #include "LorentzSpinorBar.fh"
0019 
0020 namespace ThePEG {
0021 namespace Helicity {
0022 
0023 /**
0024  *  The LorentzSpinorBar class implements the storage of a barred
0025  *  LorentzSpinor. The design is based on that of the LorentzSpinor
0026  *  class where the details of the implemented are discussed in more
0027  *  detail.
0028  *
0029  * @see LorentzSpinor
0030  *
0031  * @author Peter Richardson
0032  */
0033 
0034 template<typename Value>
0035 class LorentzSpinorBar {
0036 public:
0037 
0038   /** @name Standard constructors. */
0039   //@{
0040   /**
0041    * Default zero constructor, optionally specifying \a t, the type
0042    */
0043   LorentzSpinorBar(SpinorType t = SpinorType::unknown) : _type(t), _spin() {}
0044 
0045   /**
0046    * Constructor with complex numbers specifying the components,
0047    * optionally specifying \a t, the type
0048    */
0049   LorentzSpinorBar(complex<Value> a, complex<Value> b,
0050            complex<Value> c, complex<Value> d,
0051            SpinorType t = SpinorType::unknown)
0052     : _type(t), _spin{{a,b,c,d}} {}
0053 
0054   template <typename U>
0055   LorentzSpinorBar(const LorentzSpinorBar<U> & other)
0056     : _type(other._type), _spin(other._spin) {}
0057 
0058   //@}
0059 
0060   /** @name Access the components. */
0061   //@{
0062   /**
0063    * Subscript operator to return spinor components
0064    */
0065   complex<Value> operator[](int i) const {
0066     assert( i>= 0 && i <= 3 );
0067     return _spin[i];
0068   }
0069 
0070   /**
0071    * Subscript operator to return spinor components
0072    */
0073   complex<Value> operator()(int i) const {
0074     assert( i>= 0 && i <= 3 );
0075     return _spin[i];
0076   }
0077 
0078   /**
0079    * Set components by index.
0080    */
0081   complex<Value> & operator()(int i) {
0082     assert( i>= 0 && i <= 3 );
0083     return _spin[i];
0084   }
0085 
0086   /**
0087    * Set components by index.
0088    */
0089   complex<Value> & operator[](int i) {
0090     assert( i>= 0 && i <= 3 );
0091     return _spin[i];
0092   }
0093 
0094   /**
0095    * Get first component.
0096    */
0097   complex<Value> s1() const {return _spin[0];}
0098 
0099   /**
0100    * Get second component.
0101    */
0102   complex<Value> s2() const {return _spin[1];}
0103 
0104   /**
0105    * Get third component.
0106    */
0107   complex<Value> s3() const {return _spin[2];}
0108 
0109   /**
0110    * Get fourth component.
0111    */
0112   complex<Value> s4() const {return _spin[3];}
0113 
0114   /**
0115    * Set first component.
0116    */
0117   void setS1(complex<Value> in) {_spin[0]=in;}
0118 
0119   /**
0120    * Set second component.
0121    */
0122   void setS2(complex<Value> in) {_spin[1]=in;}
0123 
0124   /**
0125    * Set third component.
0126    */
0127   void setS3(complex<Value> in) {_spin[2]=in;}
0128 
0129   /**
0130    * Set fourth component.
0131    */
0132   void setS4(complex<Value> in) {_spin[3]=in;}
0133   //@}
0134 
0135   /// @name Mathematical assignment operators.
0136   //@{
0137   template <typename ValueB>
0138   LorentzSpinorBar<Value> & operator+=(const LorentzSpinorBar<ValueB> & a) {
0139     for(unsigned int ix=0;ix<4;++ix) _spin[ix] += a._spin[ix];
0140     return *this;
0141   }
0142   
0143   template <typename ValueB>
0144   LorentzSpinorBar<Value> & operator-=(const LorentzSpinorBar<ValueB> & a) {
0145     for(unsigned int ix=0;ix<4;++ix) _spin[ix] -= a._spin[ix];
0146     return *this;
0147   }
0148   
0149   LorentzSpinorBar<Value> & operator*=(double a) {
0150     for(unsigned int ix=0;ix<4;++ix) _spin[ix] *=a;
0151     return *this;
0152   }
0153 
0154   LorentzSpinorBar<Value> & operator/=(double a) {
0155     for(unsigned int ix=0;ix<4;++ix) _spin[ix] /=a;
0156     return *this;
0157   }
0158   //@}
0159 
0160   /** @name Transformations. */
0161   //@{
0162   /**
0163    * Return the barred spinor
0164    */
0165   LorentzSpinor<Value> bar() const;
0166 
0167   /**
0168    * Return the conjugated spinor \f$u_c=C\bar{u}^T\f$. This operation
0169    * transforms u-spinors to v-spinors and vice-versa and is required when
0170    * dealing with majorana particles.
0171    */
0172   LorentzSpinorBar conjugate() const;
0173 
0174   /**
0175    * Standard Lorentz boost specifying the components of the beta vector.
0176    */
0177   LorentzSpinorBar & boost(double,double,double);
0178 
0179   /**
0180    * Standard Lorentz boost specifying the beta vector.
0181    */
0182   LorentzSpinorBar & boost(const Boost &);
0183 
0184   /**
0185    * General Lorentz transformation
0186    */
0187   LorentzSpinorBar & transform(const SpinHalfLorentzRotation &) ;
0188   
0189   /**
0190    * General Lorentz transformation
0191    */
0192   LorentzSpinorBar & transform(const LorentzRotation & r) {
0193     transform(r.half());
0194     return *this;
0195   }
0196   //@}
0197 
0198   /** @name Functions related to type. */
0199   //@{
0200   /**
0201    * Return the type of the spinor.
0202    */
0203   SpinorType Type() const {return _type;}
0204   //@}
0205 
0206   /**
0207    *  @name Functions to apply the projection operator
0208    */
0209   //@{
0210   /**
0211    *   Apply \f$p\!\!\!\!\!\not\,\,\,+m\f$
0212    */
0213   template<typename ValueB> 
0214   auto projectionOperator(const LorentzVector<ValueB> & p, 
0215                           const ValueB & m) const 
0216   -> LorentzSpinorBar<decltype(m*Value())>
0217   {
0218     typedef decltype(m*Value()) ResultT;
0219     LorentzSpinorBar<ResultT> spin;
0220     static const Complex ii(0.,1.);
0221     complex<ValueB> p0pp3=p.t()+p.z();
0222     complex<ValueB> p0mp3=p.t()-p.z();
0223     complex<ValueB> p1pp2=p.x()+ii*p.y();
0224     complex<ValueB> p1mp2=p.x()-ii*p.y();
0225     spin.setS1(m*s1()+p0pp3*s3()+p1pp2*s4());
0226     spin.setS2(m*s2()+p0mp3*s4()+p1mp2*s3());
0227     spin.setS3(m*s3()+p0mp3*s1()-p1pp2*s2());
0228     spin.setS4(m*s4()+p0pp3*s2()-p1mp2*s1());
0229     return spin;
0230   }
0231 
0232   /**
0233    *  Apply \f$g^LP_L+g^RP_R\f$
0234    */
0235   LorentzSpinorBar
0236   helicityProjectionOperator(const Complex & gL, const Complex & gR) const {
0237     LorentzSpinorBar spin;
0238     spin.setS1(gL*s1());
0239     spin.setS2(gL*s2());
0240     spin.setS3(gR*s3());
0241     spin.setS4(gR*s4());
0242     return spin;
0243   }
0244   //@}
0245 
0246   /** @name Functions to apply the slash operator */
0247   //@{
0248   /**
0249    *   Apply \f$p\!\!\!\!\!\not\f$
0250    */
0251   template<typename ValueB>
0252   auto slash(const LorentzVector<ValueB> & p) const
0253   -> LorentzSpinorBar<decltype(p.t()*Value())>
0254   {
0255     LorentzSpinorBar<decltype(p.t()*Value())> spin;
0256     static const Complex ii(0.,1.);
0257     complex<ValueB> p0pp3=p.t()+p.z();
0258     complex<ValueB> p0mp3=p.t()-p.z();
0259     complex<ValueB> p1pp2=p.x()+ii*p.y();
0260     complex<ValueB> p1mp2=p.x()-ii*p.y();
0261     spin.setS1(p0pp3*s3()+p1pp2*s4());
0262     spin.setS2(p0mp3*s4()+p1mp2*s3());
0263     spin.setS3(p0mp3*s1()-p1pp2*s2());
0264     spin.setS4(p0pp3*s2()-p1mp2*s1());
0265     return spin;
0266   }
0267 
0268   /**
0269    *   Apply \f$p\!\!\!\!\!\not\f$
0270    */
0271   template<typename ValueB>
0272   auto slash(const LorentzVector<complex<ValueB> > & p) const
0273   -> LorentzSpinor<decltype(ValueB()*Value())>
0274   {
0275     LorentzSpinor<decltype(ValueB()*Value())> spin;
0276     static const Complex ii(0.,1.);
0277     complex<ValueB> p0pp3=p.t()+p.z();
0278     complex<ValueB> p0mp3=p.t()-p.z();
0279     complex<ValueB> p1pp2=p.x()+ii*p.y();
0280     complex<ValueB> p1mp2=p.x()-ii*p.y();
0281     spin.setS1(p0pp3*s3()+p1pp2*s4());
0282     spin.setS2(p0mp3*s4()+p1mp2*s3());
0283     spin.setS3(p0mp3*s1()-p1pp2*s2());
0284     spin.setS4(p0pp3*s2()-p1mp2*s1());
0285     return spin;
0286   }
0287   //@}
0288 
0289 private:
0290   /**
0291    * Type of spinor
0292    */
0293   SpinorType _type;
0294 
0295   /**
0296    * Storage of the components.
0297    */
0298   std::array<complex<Value>,4> _spin;
0299 };
0300 
0301 /// @name Basic mathematical operations
0302 //@{
0303 template <typename Value>
0304 inline LorentzSpinorBar<double>
0305 operator/(const LorentzSpinorBar<Value> & v, Value a) {
0306   return LorentzSpinorBar<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
0307 }
0308 
0309 inline LorentzSpinorBar<double>
0310 operator/(const LorentzSpinorBar<double> & v, Complex a) {
0311   return LorentzSpinorBar<double>(v.s1()/a, v.s2()/a, v.s3()/a, v.s4()/a,v.Type());
0312 }
0313 
0314 template <typename Value>
0315 inline LorentzSpinorBar<Value> operator-(const LorentzSpinorBar<Value> & v) {
0316   return LorentzSpinorBar<Value>(-v.s1(),-v.s2(),-v.s3(),-v.s4(),v.Type());
0317 }
0318 
0319 template <typename ValueA, typename ValueB>
0320 inline LorentzSpinorBar<ValueA>
0321 operator+(LorentzSpinorBar<ValueA> a, const LorentzSpinorBar<ValueB> & b) {
0322   return a += b;
0323 }
0324 
0325 template <typename ValueA, typename ValueB>
0326 inline LorentzSpinorBar<ValueA>
0327 operator-(LorentzSpinorBar<ValueA> a, const LorentzSpinorBar<ValueB> & b) {
0328   return a -= b;
0329 }
0330 
0331 template <typename Value>
0332 inline LorentzSpinorBar<Value>
0333 operator*(const LorentzSpinorBar<Value> & a, double b) {
0334   return LorentzSpinorBar<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
0335 }
0336 
0337 template <typename Value>
0338 inline LorentzSpinorBar<Value>
0339 operator*(double b, LorentzSpinorBar<Value> a) {
0340   return a *= b;
0341 }
0342   
0343 template <typename Value>
0344 inline LorentzSpinorBar<Value>
0345 operator*(const LorentzSpinorBar<Value> & a, Complex b) {
0346   return LorentzSpinorBar<Value>(a.s1()*b, a.s2()*b, a.s3()*b, a.s4()*b,a.Type());
0347 }
0348 
0349 template <typename ValueA, typename ValueB>
0350 inline auto operator*(complex<ValueB> a, const LorentzSpinorBar<ValueA> & v) 
0351   -> LorentzSpinorBar<decltype(a.real()*v.s1().real())>
0352 {
0353   return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
0354 }
0355 
0356 template <typename ValueA, typename ValueB>
0357 inline auto operator*(const LorentzSpinorBar<ValueA> & v, complex<ValueB> b) 
0358   -> LorentzSpinorBar<decltype(b.real()*v.s1().real())>
0359 {
0360   return b*v;
0361 }
0362 
0363 template <typename ValueA, typename ValueB>
0364 inline auto operator/(const LorentzSpinorBar<ValueA> & v, complex<ValueB> b) 
0365   -> LorentzSpinorBar<decltype(v.s1().real()/b.real())>
0366 {
0367   return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
0368 }
0369   
0370 template <typename ValueA, typename ValueB>
0371 inline auto operator*(ValueB a, const LorentzSpinorBar<ValueA> & v) 
0372   -> LorentzSpinorBar<decltype(a*v.s1().real())>
0373 {
0374   return {a*v.s1(), a*v.s2(), a*v.s3(), a*v.s4(),v.Type()};
0375 }
0376 
0377 template <typename ValueA, typename ValueB>
0378 inline auto operator*(const LorentzSpinorBar<ValueA> & v, ValueB b) 
0379   -> LorentzSpinorBar<decltype(b*v.s1().real())>
0380 {
0381   return b*v;
0382 }
0383 
0384 template <typename ValueA, typename ValueB>
0385 inline auto operator/(const LorentzSpinorBar<ValueA> & v, ValueB b) 
0386   -> LorentzSpinorBar<decltype(v.s1().real()/b)>
0387 {
0388   return {v.s1()/b, v.s2()/b, v.s3()/b, v.s4()/b,v.Type()};
0389 }
0390 
0391 }
0392 }
0393 
0394 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
0395 #include "LorentzSpinorBar.tcc"
0396 #endif 
0397 
0398 #endif