Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:24:12

0001 // -*- C++ -*-
0002 
0003 //
0004 // ColourFlowBasis.hpp is part of CVolver, (C) 2013 Simon Plätzer -- simon.plaetzer@desy.de, The Herwig Collaboration
0005 // CVolver is licenced under version 3 of the GPL, see COPYING for details.
0006 //
0007 
0008 #ifndef CVOLVER_ColourFlowBasis_hpp_included
0009 #define CVOLVER_ColourFlowBasis_hpp_included
0010 
0011 #include <vector>
0012 #include <map>
0013 #include <set>
0014 #include <cassert>
0015 #include <algorithm>
0016 
0017 namespace CVolver {
0018 
0019   /**
0020    * Generate the identical permutation.
0021    */
0022   template<class ForwardIterator, class T>
0023   void iota(ForwardIterator begin, ForwardIterator end, T value) {
0024     while ( begin != end ) {
0025       *begin = value; 
0026       value += 1;
0027       ++begin;
0028     }
0029   }
0030 
0031   /**
0032    * Return the identical permutation
0033    */
0034   inline std::vector<std::size_t> identicalPermutation(const std::size_t n) {
0035     std::vector<std::size_t> res(n);
0036     CVolver::iota(res.begin(),res.end(),0);
0037     return res;
0038   }
0039 
0040   /**
0041    * Return a random permutation
0042    */
0043   template<class Rnd>
0044   std::vector<std::size_t> randomPermutation(const std::size_t n, Rnd& rnd) {
0045     std::vector<std::size_t> pick = identicalPermutation(n);
0046     std::vector<std::size_t> res(n);
0047     std::size_t count = 0;
0048     while ( !pick.empty() ) {
0049       std::size_t i = rnd.template uniform_int_distribution<std::size_t>(0,pick.size()-1);
0050       res[count] = pick[i];
0051       pick.erase(pick.begin()+i);
0052       ++count;
0053     }
0054     return res;
0055   }
0056 
0057   /**
0058    * A colour flow (basis tensor).
0059    */
0060   class ColourFlow {
0061 
0062   public:
0063 
0064     /**
0065      * Default constructor
0066      */
0067     ColourFlow() {}
0068 
0069     /**
0070      * Construct a colour flow given a permutation
0071      */
0072     explicit ColourFlow(const std::vector<size_t>& perm)
0073       : thePermutation(perm) {}
0074 
0075     /**
0076      * Generate a random colour flow
0077      */
0078     template<class Rnd>
0079     static ColourFlow randomFlow(const std::size_t& n, Rnd& rnd) {
0080       return ColourFlow(randomPermutation(n,rnd));
0081     }
0082 
0083     /**
0084      * Generate all colour flows
0085      */
0086     static std::set<ColourFlow> allFlows(const std::size_t& n);
0087 
0088     /**
0089      * Compare for equality
0090      */
0091     bool operator==(const ColourFlow& other) const {
0092       return thePermutation == other.thePermutation;
0093     }
0094 
0095     /**
0096      * Compare for inequality
0097      */
0098     bool operator!=(const ColourFlow& other) const {
0099       return thePermutation != other.thePermutation;
0100     }
0101 
0102     /**
0103      * Compare for ordering
0104      */
0105     bool operator<(const ColourFlow& other) const {
0106       return thePermutation < other.thePermutation;
0107     }
0108 
0109     /**
0110      * Conjugate this basis tensor
0111      */
0112     ColourFlow& conjugate() {
0113       std::vector<std::size_t> tmp = thePermutation;
0114       for ( std::size_t k = 0; k < tmp.size(); ++k ) {
0115     thePermutation[tmp[k]] = k;
0116       }
0117       return *this;
0118     }
0119 
0120     /**
0121      * Return the scalar product with another basis tensor as the
0122      * resulting power of N
0123      */
0124     std::size_t scalarProduct(const ColourFlow& other) const;
0125 
0126     /**
0127      * Return the permutation
0128      */
0129     const std::vector<std::size_t>& permutation() const {
0130       return thePermutation;
0131     }
0132 
0133     /**
0134      * Return the anti-colour index connected to the given colour index
0135      */
0136     const std::size_t& antiColour(const std::size_t& i) const {
0137       assert(i < thePermutation.size());
0138       return thePermutation[i];
0139     }
0140 
0141     /**
0142      * Return the colour index connected to the given anti-colour index
0143      */
0144     std::size_t colour(const std::size_t& i) const {
0145       std::vector<std::size_t>::const_iterator k =
0146     std::find(thePermutation.begin(),thePermutation.end(),i);
0147       assert(k != thePermutation.end());
0148       return std::distance(thePermutation.begin(),k);
0149     }
0150 
0151     /**
0152      * Return the swapped indices, if this corresponds to a
0153      * transposition of the given one, or (0,0)
0154      */
0155     std::pair<std::size_t,std::size_t> getTranspositionOf(const ColourFlow& other) const;
0156 
0157     /**
0158      * Act a transposition on this index
0159      */
0160     ColourFlow& swap(const std::size_t& i, const std::size_t& j) {
0161       assert(i < thePermutation.size() && j < thePermutation.size());
0162       std::swap(thePermutation[i],thePermutation[j]);
0163       return *this;
0164     }
0165 
0166     /**
0167      * Add another flow to this basis tensor; this correspons to
0168      * emitting a `singlet' gluon.
0169      */
0170     ColourFlow& emitSinglet() {
0171       thePermutation.push_back(thePermutation.size());
0172       return *this;
0173     }
0174 
0175     /**
0176      * Emit a gluon on a given colour line
0177      */
0178     ColourFlow& emitFromColour(const std::size_t& i) {
0179       assert(i < thePermutation.size());
0180       thePermutation.push_back(thePermutation[i]);
0181       thePermutation[i] = thePermutation.size()-1;
0182       return *this;
0183     }
0184 
0185     /**
0186      * Emit a gluon on a given anti-colour line
0187      */
0188     ColourFlow& emitFromAntiColour(const std::size_t& i) {
0189       return emitFromColour(colour(i));
0190     }
0191 
0192     /**
0193      * Return true, if this colour flow is non-vanishing for the given
0194      * colours and anticolours
0195      */
0196     bool isNonZero(const std::vector<std::size_t>& colours,
0197            const std::vector<std::size_t>& antiColours) const;
0198 
0199     /**
0200      * Return the number of coloured legs
0201      */
0202     size_t nLegs() const { return thePermutation.size(); }
0203 
0204   private:
0205 
0206     /**
0207      * The vector representing the permutation of anti-fundamental
0208      * w.r.t. fundamental indices.
0209      */
0210     std::vector<std::size_t> thePermutation;
0211 
0212   };
0213 
0214   /**
0215    * ParticleData traits
0216    */
0217   template<class ParticleData>
0218   struct ParticleDataTraits {
0219 
0220     /**
0221      * Return true, if singlet
0222      */
0223     static bool isSinglet(const ParticleData&) { return true; }
0224 
0225     /**
0226      * Return true, if anti-fundamental
0227      */
0228     static bool isAntiFundamental(const ParticleData&) { return false; }
0229 
0230     /**
0231      * Return true, if fundamental
0232      */
0233     static bool isFundamental(const ParticleData&) { return false; }
0234 
0235     /**
0236      * Return true, if adjoint
0237      */
0238     static bool isAdjoint(const ParticleData&) { return false; }
0239 
0240   };
0241 
0242   /**
0243    * The crossing of a physical process to a colour flow basis
0244    */
0245   class ColourFlowCrossing {
0246 
0247   private:
0248 
0249     /**
0250      * Add colour leg mapping
0251      */
0252     void addColourCrossing(const std::size_t& leg,
0253                std::size_t& count,
0254                double sign) {
0255       theColourMap[count] = leg;
0256       theColourCrossingSigns[count] = sign;
0257       theReverseColourMap[leg] = count;
0258       ++count;
0259     }
0260 
0261     /**
0262      * Add anti-colour leg mapping
0263      */
0264     void addAntiColourCrossing(const std::size_t& leg,
0265                    std::size_t& count,
0266                    double sign) {
0267       theAntiColourMap[count] = leg;
0268       theAntiColourCrossingSigns[count] = sign;
0269       theReverseAntiColourMap[leg] = count;
0270       ++count;
0271     }
0272 
0273   public:
0274 
0275     /**
0276      * Default constructor
0277      */
0278     ColourFlowCrossing()
0279       : theNFlows(0) {}
0280 
0281     /**
0282      * Construct for the given process
0283      */
0284     template<class ParticleData>
0285     explicit ColourFlowCrossing(const std::vector<ParticleData>& proc,
0286                 bool signs = true) 
0287       : theNFlows(0) {
0288       typedef ParticleDataTraits<ParticleData> Traits;
0289       std::size_t colourCounter = 0;
0290       std::size_t antiColourCounter = 0;
0291       for ( std::size_t k = 0; k < proc.size(); ++k ) {
0292     if ( Traits::isSinglet(proc[k]) )
0293       continue;
0294     double sign = k > 1 ? 1. : -1.;
0295     if ( Traits::isAntiFundamental(proc[k]) ) {
0296       if ( k > 1 )
0297         addAntiColourCrossing(k,antiColourCounter,signs ? sign : 1.0);
0298       else
0299         addColourCrossing(k,colourCounter,signs ? sign : 1.0);
0300     }
0301     if ( Traits::isFundamental(proc[k]) ) {
0302       if ( k > 1 )
0303         addColourCrossing(k,colourCounter,signs ? sign : 1.0);
0304       else
0305         addAntiColourCrossing(k,antiColourCounter,signs ? sign : 1.0);
0306     }
0307     if ( Traits::isAdjoint(proc[k]) ) {
0308       addColourCrossing(k,colourCounter,1.0);
0309       addAntiColourCrossing(k,antiColourCounter,1.0);
0310     }
0311       }
0312       theNFlows = colourCounter;
0313     }
0314 
0315     /**
0316      * Return the number of colour flows
0317      */
0318     const std::size_t& nFlows() const { return theNFlows; }
0319 
0320     /**
0321      * Return the external leg for the given colour
0322      */
0323     std::size_t colourLeg(const std::size_t& i) const {
0324       std::map<std::size_t,std::size_t>::const_iterator l =
0325     theColourMap.find(i);
0326       assert(l != theColourMap.end());
0327       return l->second;
0328     }
0329 
0330     /**
0331      * Return the external leg for the given anti-colour
0332      */
0333     std::size_t antiColourLeg(const std::size_t& i) const {
0334       std::map<std::size_t,std::size_t>::const_iterator l =
0335     theAntiColourMap.find(i);
0336       assert(l != theAntiColourMap.end());
0337       return l->second;
0338     }
0339 
0340     /**
0341      * Return the crossing sign for the given colour
0342      */
0343     std::size_t colourCrossingSign(const std::size_t& i) const {
0344       std::map<std::size_t,double>::const_iterator l =
0345     theColourCrossingSigns.find(i);
0346       assert(l != theColourCrossingSigns.end());
0347       return l->second;
0348     }
0349 
0350     /**
0351      * Return the crossing sign for the given anti-colour
0352      */
0353     double antiColourCrossingSign(const std::size_t& i) const {
0354       std::map<std::size_t,double>::const_iterator l =
0355     theAntiColourCrossingSigns.find(i);
0356       assert(l != theAntiColourCrossingSigns.end());
0357       return l->second;
0358     }
0359 
0360     /**
0361      * Return true, if the external line carries colour
0362      */
0363     bool coloured(const std::size_t& i) const {
0364       return theReverseColourMap.find(i) != theReverseColourMap.end();
0365     }
0366 
0367     /**
0368      * Return the colour line for the given external leg
0369      */
0370     std::size_t colourLine(const std::size_t& i) const {
0371       std::map<std::size_t,std::size_t>::const_iterator l =
0372     theReverseColourMap.find(i);
0373       assert(l != theReverseColourMap.end());
0374       return l->second;
0375     }
0376 
0377     /**
0378      * Return true, if the external line carries anti-colour
0379      */
0380     bool antiColoured(const std::size_t& i) const {
0381       return theReverseAntiColourMap.find(i) != theReverseAntiColourMap.end();
0382     }
0383 
0384     /**
0385      * Return the anti-colour line for the given external leg
0386      */
0387     std::size_t antiColourLine(const std::size_t& i) const {
0388       std::map<std::size_t,std::size_t>::const_iterator l =
0389     theReverseAntiColourMap.find(i);
0390       assert(l != theReverseAntiColourMap.end());
0391       return l->second;
0392     }
0393 
0394   private:
0395 
0396     /**
0397      * The number of colour flows
0398      */
0399     std::size_t theNFlows;
0400 
0401     /**
0402      * Map colour legs to external legs
0403      */
0404     std::map<std::size_t,std::size_t> theColourMap;
0405 
0406     /**
0407      * Map anti-colour legs to external legs
0408      */
0409     std::map<std::size_t,std::size_t> theAntiColourMap;
0410 
0411     /**
0412      * Map external legs to colour legs
0413      */
0414     std::map<std::size_t,std::size_t> theReverseColourMap;
0415 
0416     /**
0417      * Map external legs to anti-colour legs
0418      */
0419     std::map<std::size_t,std::size_t> theReverseAntiColourMap;
0420 
0421     /**
0422      * Map colour legs to crossing signs
0423      */
0424     std::map<std::size_t,double> theColourCrossingSigns;
0425 
0426     /**
0427      * Map anti-colour legs to crossing signs
0428      */
0429     std::map<std::size_t,double> theAntiColourCrossingSigns;
0430 
0431   };
0432 
0433 }
0434 
0435 #endif // CVOLVER_ColourFlowBasis_hpp_included