Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:10:06

0001 #ifndef METOOLS_Explicit_C_Scalar_H
0002 #define METOOLS_Explicit_C_Scalar_H
0003 
0004 #include "METOOLS/Explicit/C_Object.H"
0005 #include "ATOOLS/Math/MathTools.H"
0006 #include "ATOOLS/Org/STL_Tools.H"
0007 
0008 #include <vector>
0009 #include <iostream>
0010  
0011 namespace METOOLS {
0012 
0013   /// @brief Implementation of a scalar current.
0014   template <class Scalar>
0015   class CScalar: public CObject {
0016   public:
0017 
0018     typedef std::complex<Scalar> SComplex;
0019 
0020   private:
0021     /// @brief The spin components of the current. In this case, a single complex number.
0022     SComplex m_x;
0023 
0024     /// @brief The accuracy for all scalars.
0025     /// @note Not used anywhere
0026     static double s_accu;
0027 
0028     /// @brief A vector of CScalars that cleans its memory upon destruction.
0029     ///
0030     /// If threading is enabled, all the CScalars created with the CScalar<Scalar>::New() method 
0031     /// will be allocated inside this vector behind the scenes.
0032     static ATOOLS::AutoDelete_Vector<CScalar> s_objects;
0033 
0034     template <class _Scalar> friend std::ostream &
0035     operator<<(std::ostream &,const CScalar<_Scalar> &);
0036 
0037   public:
0038     /// @name New pointer creator methods
0039     /// @{    
0040     /// Create a pointer to a new CScalar object.
0041     /// If threading is enabled, existing slots inside CScalar<Scalar>::s_objects will be re-used.
0042     static CScalar *New();
0043     static CScalar *New(const CScalar &s);    
0044     /// @}
0045 
0046     CObject* Copy() const;
0047 
0048     /// @brief Delete this object.
0049     ///
0050     /// If threading is enabled, the memory it occupies is added to CScalar<Scalar>::s_objects
0051     /// in order to be re-used in the future.
0052     void Delete();
0053 
0054     /// @brief Return true if CScalar<Scalar>::m_x is zero.
0055     bool IsZero() const;
0056 
0057     /// @name Constructors
0058     /// @{
0059 
0060     /// @brief Default constructor.
0061     ///
0062     /// Initialize all data members to zero (m_x, m_c, m_h, m_s)
0063     inline CScalar(): m_x(Scalar(0.0))
0064     { 
0065       m_h=m_s=0; m_c[0]=m_c[1]=0;
0066     }
0067     /// @brief Copy constructor
0068     inline CScalar(const CScalar &s): m_x(s.m_x)
0069     { 
0070       m_h=s.m_h; m_s=s.m_s; m_c[0]=s.m_c[0]; m_c[1]=s.m_c[1];
0071     }
0072     /// @brief Constructor
0073     ///
0074     /// @param x  the spin components
0075     /// @param cr the color index
0076     /// @param ca the anti-color index
0077     /// @param h  the helicity
0078     /// @param s  the NLO subtraction flag (m_s)
0079     inline CScalar(const Scalar &x,
0080            const int cr=0,const int ca=0,
0081            const size_t &h=0,const size_t &s=0): m_x(x)
0082     { 
0083       m_h=h; m_s=s; m_c[0]=cr; m_c[1]=ca;
0084     }
0085     /// @brief Constructor
0086     ///
0087     /// @param x  the spin components
0088     /// @param cr the color index
0089     /// @param ca the anti-color index
0090     /// @param h  the helicity
0091     /// @param s  the NLO subtraction flag (m_s)
0092     inline CScalar(const SComplex &x,
0093            const int cr=0,const int ca=0,
0094            const size_t &h=0,const size_t &s=0): m_x(x)
0095     { 
0096       m_h=h; m_s=s; m_c[0]=cr; m_c[1]=ca;
0097     }
0098     /// @brief Scaled constructor
0099     ///
0100     /// @param s another CScalar
0101     /// @param c a complex number to scale by
0102     ///
0103     /// The created CScalar is the same as s, but its spin m_x is scaled by c.
0104     inline CScalar(const CScalar &s,const SComplex &c): m_x(s.m_x*c)
0105     {
0106       m_h=s.m_h; m_s=s.m_s; m_c[0]=s.m_c[0]; m_c[1]=s.m_c[1];
0107     }
0108     
0109     /// @}
0110 
0111     /// @name Mathematical operations
0112     /// @{
0113     /// These operations apply only to the CScalar::m_x member (spin components).
0114 
0115     /// @note The argument passed to this function should be a CScalar, otherwise the
0116     /// behavior is undefined
0117     void Add(const CObject *c);
0118     void Divide(const double &d);
0119     void Multiply(const Complex &c);
0120     void Invert();
0121     /// @}
0122 
0123     /// @name Access operators
0124     /// @{
0125     /// Return CScalar::m_x, no matter what the argument value is.
0126     inline SComplex &operator[](const int i) { return m_x;    }
0127     inline const SComplex &operator[](const int i) const { return m_x;    }
0128     /// @}
0129 
0130     /// @name Mathematical operators
0131     /// @{
0132     /// These operators apply only to the CScalar::m_x member (spin components).
0133     inline CScalar operator+(const CScalar &s) const  
0134     { 
0135       return CScalar(m_x+s.m_x,m_c[0],m_c[1],m_h,m_s); 
0136     }
0137     inline CScalar operator-(const CScalar &s) const
0138     { 
0139       return CScalar(m_x-s.m_x,m_c[0],m_c[1],m_h,m_s); 
0140     }
0141     inline CScalar operator-() const
0142     { 
0143       return CScalar(-m_x,m_c[0],m_c[1],m_h,m_s); 
0144     }
0145 
0146     inline CScalar& operator+=(const CScalar &s) 
0147     {
0148       m_x+=s.m_x;
0149       return *this;
0150     }
0151     inline CScalar& operator-=(const CScalar &s) 
0152     {
0153       m_x-=s.m_x;
0154       return *this;
0155     }
0156     inline CScalar& operator*=(const SComplex &c) 
0157     {
0158       m_x*=c;
0159       return *this;
0160     }
0161     /// @}
0162 
0163     /// @brief Return a CScalar with a complex conjugate m_x.
0164     inline CScalar Conj() const 
0165     {
0166       return CScalar(std::conj(m_x),m_c[0],m_c[1],m_h,m_s);
0167     }
0168     /// @brief Return the square of the magnitude of m_x
0169     inline SComplex Abs2() const 
0170     {
0171       return m_x*m_x;
0172     }
0173     /// @brief Return the magnitude of m_x
0174     inline SComplex Abs() const 
0175     { 
0176       return sqrt(Abs2()); 
0177     }
0178 
0179     /// @brief Return true if m_x is NAN
0180     inline bool Nan() const { return ATOOLS::IsNan<SComplex>(m_x); }
0181 
0182     
0183     /// @name Access or manipulate the CScaler::s_accu data member
0184     /// @{
0185 
0186     /// @todo This function is currently buggy. It does not reset s_accu.
0187     static void ResetAccu();
0188     inline static void   SetAccu(const Scalar &accu) { s_accu=accu;   }
0189     inline static Scalar Accu()                      { return s_accu; }
0190     /// @}
0191 
0192   };// end of class CScalar
0193 
0194   template <class Scalar> inline std::complex<Scalar>
0195   operator*(const Scalar &d,const CScalar<Scalar> &s)
0196   { return CScalar<Scalar>(s,d); }
0197   template <class Scalar> inline CScalar<Scalar> 
0198   operator*(const CScalar<Scalar> &s,const Scalar &d)
0199   { return CScalar<Scalar>(s,d); }
0200   template <class Scalar> inline CScalar<Scalar>
0201   operator*(const std::complex<Scalar> &c,const CScalar<Scalar> &s)
0202   { return CScalar<Scalar>(s,c); }
0203   template <class Scalar> inline CScalar<Scalar> 
0204   operator*(const CScalar<Scalar> &s,const std::complex<Scalar> &c)
0205   { return CScalar<Scalar>(s,c); }
0206   template <class Scalar> inline CScalar<Scalar>
0207   operator/(const CScalar<Scalar> &s,const std::complex<Scalar> &c)
0208   { return CScalar<Scalar>(s,1.0/c); }
0209 
0210   template <class Scalar> inline std::complex<Scalar> 
0211   operator*(const CScalar<Scalar> &s1,const CScalar<Scalar> &s2) 
0212   { return s1[0]*s2[0]; }
0213 
0214   template <class Scalar>
0215   std::ostream &operator<<(std::ostream &str,const CScalar<Scalar> &s);
0216 
0217 }// end of namespace ATOOLS
0218 
0219 #define DCScalar METOOLS::CScalar<double>
0220 #define QCScalar METOOLS::CScalar<long double>
0221 
0222 #endif