Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
--- a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
@@ -1,517 +1,531 @@
// -*- C++ -*-
//
// MatchboxAmplitude.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxAmplitude class.
//
#include "MatchboxAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SpinorHelicity.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "MatchboxMEBase.h"
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
MatchboxAmplitude::MatchboxAmplitude()
: Amplitude(), theNLight(0), theColourBasisDim(0),
calculateTrees(true), calculateLoops(true) {}
MatchboxAmplitude::~MatchboxAmplitude() {}
void MatchboxAmplitude::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theProcessData << theColourBasis << theColourBasisDim
<< theNLight;
}
void MatchboxAmplitude::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> theProcessData >> theColourBasis >> theColourBasisDim
>> theNLight;
}
void MatchboxAmplitude::cloneDependencies(const std::string&) {
}
Ptr<MatchboxMEBase>::ptr MatchboxAmplitude::makeME(const vector<PDVector>&) const {
return new_ptr(MatchboxMEBase());
}
struct orderPartonData {
bool operator()(const pair<tcPDPtr,int>& a,
const pair<tcPDPtr,int>& b) const {
if ( a.first == b.first )
return a.second < b.second;
int acolour = a.first->iColour();
int bcolour = b.first->iColour();
if ( abs(acolour) != abs(bcolour) )
return abs(acolour) < abs(bcolour);
if ( a.first->iSpin() != b.first->iSpin() )
return a.first->iSpin() < b.first->iSpin();
int acharge = a.first->iCharge();
int bcharge = b.first->iCharge();
if ( abs(acharge) != abs(bcharge) )
return abs(acharge) < abs(bcharge);
if ( abs(a.first->id()) != abs(b.first->id()) )
return abs(a.first->id()) < abs(b.first->id());
return a.first->id() > b.first->id();
}
};
void MatchboxAmplitude::additionalKinematics(const double * r) {
if ( nDimAdditional() ) {
additionalRandomNumbers.resize(nDimAdditional());
copy(r,r+nDimAdditional(),additionalRandomNumbers.begin());
}
}
void MatchboxAmplitude::fillCrossingMap(size_t shift) {
theLastCrossingMap = crossingMap().find(lastXCombPtr());
if ( theLastCrossingMap != crossingMap().end() ) {
assert(amplitudePartonData().find(lastXCombPtr()) != amplitudePartonData().end());
assert(amplitudeToColourMap().find(lastXCombPtr()) != amplitudeToColourMap().end());
assert(colourToAmplitudeMap().find(lastXCombPtr()) != colourToAmplitudeMap().end());
theLastAmplitudePartonData = amplitudePartonData().find(lastXCombPtr());
theLastAmplitudeToColourMap = amplitudeToColourMap().find(lastXCombPtr());
theLastColourToAmplitudeMap = colourToAmplitudeMap().find(lastXCombPtr());
assert(crossingSigns().find(lastXCombPtr()) != crossingSigns().end());
theLastCrossingSign = crossingSigns().find(lastXCombPtr())->second;
return;
} else {
crossingMap()[lastXCombPtr()] = vector<int>(mePartonData().size());
amplitudePartonData()[lastXCombPtr()] = cPDVector(mePartonData().size());
amplitudeToColourMap()[lastXCombPtr()] = map<size_t,size_t>();
colourToAmplitudeMap()[lastXCombPtr()] = map<size_t,size_t>();
theLastCrossingMap = crossingMap().find(lastXCombPtr());
theLastAmplitudePartonData = amplitudePartonData().find(lastXCombPtr());
theLastAmplitudeToColourMap = amplitudeToColourMap().find(lastXCombPtr());
theLastColourToAmplitudeMap = colourToAmplitudeMap().find(lastXCombPtr());
}
double csign = 1.;
set<pair<tcPDPtr,int>,orderPartonData > processLegs;
for ( unsigned int l = 0; l < mePartonData().size(); ++l ) {
if ( l > 1 )
processLegs.insert(make_pair(mePartonData()[l],l));
else {
if ( mePartonData()[l]->CC() ) {
processLegs.insert(make_pair(mePartonData()[l]->CC(),l));
if ( mePartonData()[l]->iSpin() == PDT::Spin1Half )
csign *= -1.;
} else {
processLegs.insert(make_pair(mePartonData()[l],l));
}
}
}
lastCrossingSign(csign);
crossingSigns()[lastXCombPtr()] = csign;
set<pair<tcPDPtr,int> > amplitudeLegs;
int ampCount = 0;
// process legs are already sorted, we only need to arrange for
// adjacent particles and anti-particles
while ( !processLegs.empty() ) {
set<pair<tcPDPtr,int>,orderPartonData >::iterator next
= processLegs.begin();
while ( next->first->id() < 0 ) {
if ( ++next == processLegs.end() )
break;
}
assert(next != processLegs.end());
lastCrossingMap()[ampCount] = next->second - shift;
amplitudeLegs.insert(make_pair(next->first,ampCount));
tcPDPtr check = next->first;
processLegs.erase(next);
++ampCount;
if ( check->CC() ) {
set<pair<tcPDPtr,int>,orderPartonData>::iterator checkcc
= processLegs.end();
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( c->first == check->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() )
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check) )
continue;
if ( c->first == SU2Helper::SU2CC(check)->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() ) {
int f = SU2Helper::family(check);
for ( int i = 1 - f; i < 5 - f; i++ ) {
bool gotone = false;
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check,i) )
continue;
if ( c->first == SU2Helper::SU2CC(check,i)->CC() ) {
checkcc = c; gotone = true; break;
}
}
if ( gotone )
break;
}
}
assert(checkcc != processLegs.end());
lastCrossingMap()[ampCount] = checkcc->second - shift;
amplitudeLegs.insert(make_pair(checkcc->first,ampCount));
processLegs.erase(checkcc);
++ampCount;
}
}
for ( set<pair<tcPDPtr,int> >::const_iterator l = amplitudeLegs.begin();
l != amplitudeLegs.end(); ++l )
lastAmplitudePartonData()[l->second] = l->first;
if ( colourBasis() ) {
assert(colourBasis()->indexMap().find(mePartonData()) !=
colourBasis()->indexMap().end());
const map<size_t,size_t> colourCross =
colourBasis()->indexMap().find(mePartonData())->second;
for ( size_t k = 0; k < lastCrossingMap().size(); ++k ) {
if ( colourCross.find(lastCrossingMap()[k]) !=
colourCross.end() ) {
size_t ccross = colourCross.find(lastCrossingMap()[k])->second;
lastAmplitudeToColourMap()[k] = ccross;
lastColourToAmplitudeMap()[ccross] = k;
}
}
}
}
const string& MatchboxAmplitude::colourOrdering(size_t id) const {
static string empty = "";
if ( !colourBasis() ) {
return empty;
}
return colourBasis()->ordering(mePartonData(),lastColourToAmplitudeMap(),id);
}
Lorentz5Momentum MatchboxAmplitude::amplitudeMomentum(int i) const {
int iCrossed = lastCrossingMap()[i];
Lorentz5Momentum res = meMomenta()[iCrossed];
if ( iCrossed < 2 )
res = -res;
res.setMass(meMomenta()[iCrossed].mass());
res.rescaleRho();
return res;
}
set<vector<int> > MatchboxAmplitude::generateHelicities() const {
set<vector<int> > res;
vector<int> current(lastAmplitudePartonData().size());
doGenerateHelicities(res,current,0);
return res;
}
void MatchboxAmplitude::doGenerateHelicities(set<vector<int> >& res,
vector<int>& current,
size_t pos) const {
if ( pos == lastAmplitudePartonData().size() ) {
res.insert(current);
return;
}
if ( lastAmplitudePartonData()[pos]->iSpin() == PDT::Spin0 ||
( lastAmplitudePartonData()[pos]->iSpin() == PDT::Spin1 &&
lastAmplitudePartonData()[pos]->mass() != ZERO ) ) {
current[pos] = 0;
doGenerateHelicities(res,current,pos+1);
} else if ( lastAmplitudePartonData()[pos]->iSpin() == PDT::Spin1Half ||
lastAmplitudePartonData()[pos]->iSpin() == PDT::Spin1 ) {
current[pos] = 1;
doGenerateHelicities(res,current,pos+1);
current[pos] = -1;
doGenerateHelicities(res,current,pos+1);
}
}
void MatchboxAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateTrees )
return;
theLastAmplitudes = theLastAmplitudeMap.find(lastXCombPtr());
theLastLargeNAmplitudes = theLastLargeNAmplitudeMap.find(lastXCombPtr());
bool initialized = theLastAmplitudes != theLastAmplitudeMap.end();
if ( !initialized ) {
theLastAmplitudeMap[lastXCombPtr()] = AmplitudeMap();
theLastLargeNAmplitudeMap[lastXCombPtr()] = AmplitudeMap();
theLastAmplitudes = theLastAmplitudeMap.find(lastXCombPtr());
theLastLargeNAmplitudes = theLastLargeNAmplitudeMap.find(lastXCombPtr());
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
lastAmplitudes().insert(make_pair(*h,CVector(colourBasisDim())));
lastLargeNAmplitudes().insert(make_pair(*h,CVector(colourBasisDim())));
}
}
AmplitudeIterator amp = lastAmplitudes().begin();
AmplitudeIterator lamp = lastLargeNAmplitudes().begin();
for ( ;amp != lastAmplitudes().end(); ++amp, ++lamp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k )
amp->second(k) = evaluate(k,amp->first,lamp->second(k));
}
if ( !initialized ) {
map<vector<int>,CVector> clean;
for ( map<vector<int>,CVector>::const_iterator amp = lastAmplitudes().begin();
amp != lastAmplitudes().end(); ++amp ) {
bool nonZero = false;
for ( size_t k = 0; k < colourBasisDim(); ++k ) {
if ( amp->second(k) != Complex(0.0) ) {
nonZero = true;
break;
}
}
if ( nonZero )
clean.insert(*amp);
}
lastAmplitudes() = clean;
clean.clear();
for ( map<vector<int>,CVector>::const_iterator amp = lastLargeNAmplitudes().begin();
amp != lastLargeNAmplitudes().end(); ++amp ) {
bool nonZero = false;
for ( size_t k = 0; k < colourBasisDim(); ++k ) {
if ( amp->second(k) != Complex(0.0) ) {
nonZero = true;
break;
}
}
if ( nonZero )
clean.insert(*amp);
}
lastLargeNAmplitudes() = clean;
}
calculateTrees = false;
}
void MatchboxAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateLoops )
return;
theLastOneLoopAmplitudes = theLastOneLoopAmplitudeMap.find(lastXCombPtr());
bool initialized = theLastOneLoopAmplitudes != theLastOneLoopAmplitudeMap.end();
if ( !initialized ) {
theLastOneLoopAmplitudeMap[lastXCombPtr()] = AmplitudeMap();
theLastOneLoopAmplitudes = theLastOneLoopAmplitudeMap.find(lastXCombPtr());
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
lastOneLoopAmplitudes().insert(make_pair(*h,CVector(colourBasisDim())));
}
}
for ( AmplitudeIterator amp = lastOneLoopAmplitudes().begin();
amp != lastOneLoopAmplitudes().end(); ++amp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k )
amp->second(k) = evaluateOneLoop(k,amp->first);
}
if ( !initialized ) {
map<vector<int>,CVector> clean;
for ( map<vector<int>,CVector>::const_iterator amp = lastOneLoopAmplitudes().begin();
amp != lastOneLoopAmplitudes().end(); ++amp ) {
bool nonZero = false;
for ( size_t k = 0; k < colourBasisDim(); ++k ) {
if ( amp->second(k) != Complex(0.0) ) {
nonZero = true;
break;
}
}
if ( nonZero )
clean.insert(*amp);
}
lastOneLoopAmplitudes() = clean;
}
calculateLoops = false;
}
Complex MatchboxAmplitude::value(const tcPDVector&,
const vector<Lorentz5Momentum>&,
const vector<int>&) {
assert(false && "ThePEG::Amplitude interface is not sufficient at the moment.");
throw Exception() << "ThePEG::Amplitude interface is not sufficient at the moment."
<< Exception::abortnow;
return 0.;
}
double MatchboxAmplitude::colourCorrelatedME2(pair<int,int> ij) const {
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
lastCrossingSign()*colourBasis()->colourCorrelatedME2(ij,mePartonData(),lastAmplitudes())/cfac;
}
+double MatchboxAmplitude::largeNColourCorrelatedME2(pair<int,int> ij,
+ Ptr<ColourBasis>::tptr largeNBasis) const {
+ double Nc = generator()->standardModel()->Nc();
+ double cfac = 1.;
+ if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
+ cfac = Nc;
+ } else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
+ mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
+ cfac = Nc/2.;
+ } else assert(false);
+ return
+ lastCrossingSign()*largeNBasis->colourCorrelatedME2(ij,mePartonData(),lastAmplitudes())/cfac;
+}
+
// compare int vectors modulo certain element
// which needs to differe between the two
bool equalsModulo(unsigned int i, const vector<int>& a, const vector<int>& b) {
assert(a.size()==b.size());
if ( a[i] == b[i] )
return false;
for ( unsigned int k = 0; k < a.size(); ++k ) {
if ( k == i )
continue;
if ( a[k] != b[k] )
return false;
}
return true;
}
LorentzVector<Complex> MatchboxAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n) const {
using namespace SpinorHelicity;
LorentzVector<complex<Energy> > num =
PlusSpinorCurrent(PlusConjugateSpinor(n),MinusSpinor(p)).eval();
complex<Energy> den =
sqrt(2.)*PlusSpinorProduct(PlusConjugateSpinor(n),PlusSpinor(p)).eval();
LorentzVector<Complex> polarization(num.x()/den,num.y()/den,num.z()/den,num.t()/den);
return polarization;
}
double MatchboxAmplitude::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
double corr = 0.;
int iCrossed = -1;
for ( unsigned int k = 0; k < lastCrossingMap().size(); ++k )
if ( lastCrossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
assert(iCrossed >= 0);
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
corr +=
2.*real(colourBasis()->colourCorrelatedInterference(ij,mePartonData(),a->second,b->second)*sqr(pFactor));
}
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + lastCrossingSign()*(c.scale() > ZERO ? 1. : -1.)*corr/cfac;
}
void MatchboxAmplitude::Init() {
static ClassDocumentation<MatchboxAmplitude> documentation
("MatchboxAmplitude is the base class for amplitude "
"implementations inside Matchbox.");
static Reference<MatchboxAmplitude,ColourBasis> interfaceColourBasis
("ColourBasis",
"Set the colour basis implementation.",
&MatchboxAmplitude::theColourBasis, false, false, true, true, false);
static Reference<MatchboxAmplitude,ProcessData> interfaceProcessData
("ProcessData",
"Set the process data object.",
&MatchboxAmplitude::theProcessData, false, false, true, true, false);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<MatchboxAmplitude,Amplitude>
describeMatchboxAmplitude("Herwig::MatchboxAmplitude", "HwMatchbox.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxAmplitude.h b/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
--- a/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
+++ b/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
@@ -1,659 +1,665 @@
// -*- C++ -*-
//
// MatchboxAmplitude.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxAmplitude_H
#define HERWIG_MatchboxAmplitude_H
//
// This is the declaration of the MatchboxAmplitude class.
//
#include "ThePEG/MatrixElement/Amplitude.h"
#include "ThePEG/Handlers/LastXCombInfo.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/ColourBasis.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/ProcessData.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitude is the base class for amplitude
* implementations inside Matchbox.
*
* @see \ref MatchboxAmplitudeInterfaces "The interfaces"
* defined for MatchboxAmplitude.
*/
class MatchboxAmplitude: public Amplitude, public LastXCombInfo<StandardXComb> {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
MatchboxAmplitude();
/**
* The destructor.
*/
virtual ~MatchboxAmplitude();
//@}
public:
typedef map<vector<int>,CVector> AmplitudeMap;
typedef map<vector<int>,CVector>::iterator AmplitudeIterator;
typedef map<vector<int>,CVector>::const_iterator AmplitudeConstIterator;
/**
* Return the amplitude. Needs to be implemented from
* ThePEG::Amplitude but is actually ill-defined, as colours of the
* external particles are not specified. To this extent, this
* implementation just asserts.
*/
virtual Complex value(const tcPDVector & particles,
const vector<Lorentz5Momentum> & momenta,
const vector<int> & helicities);
/** @name Subprocess information */
//@{
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const { return false; }
/**
* Provide the additional random numbers
*/
void additionalKinematics(const double *);
/**
* Return the number of random numbers required to evaluate this
* amplitude at a fixed phase space point.
*/
virtual int nDimAdditional() const { return 0; }
/**
* Return a ME instance appropriate for this amplitude and the given
* subprocesses
*/
virtual Ptr<MatchboxMEBase>::ptr makeME(const vector<PDVector>&) const;
/**
* Return the process data.
*/
Ptr<ProcessData>::tptr processData() const { return theProcessData; }
/**
* Set the process data.
*/
void processData(Ptr<ProcessData>::ptr pd) { theProcessData = pd; }
/**
* Return the amplitude parton data.
*/
const cPDVector& lastAmplitudePartonData() const { return theLastAmplitudePartonData->second; }
/**
* Access the amplitude parton data.
*/
cPDVector& lastAmplitudePartonData() { return theLastAmplitudePartonData->second; }
/**
* Access the amplitude parton data.
*/
map<tStdXCombPtr,cPDVector>& amplitudePartonData() { return processData()->amplitudePartonData(); }
/**
* Return the number of light flavours
*/
unsigned int nLight() const { return theNLight; }
/**
* Set the number of light flavours
*/
void nLight(unsigned int n) { theNLight = n; }
/**
* Set the (tree-level) order in \f$g_S\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGs(unsigned int) {}
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const = 0;
/**
* Set the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGem(unsigned int) {}
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const = 0;
/**
* Return the Herwig++ StandardModel object
*/
Ptr<StandardModel>::tcptr standardModel() {
if ( !theStandardModel )
theStandardModel =
dynamic_ptr_cast<Ptr<StandardModel>::tcptr>(HandlerBase::standardModel());
return theStandardModel;
}
//@}
/** @name Colour basis. */
//@{
/**
* Return the colour basis.
*/
Ptr<ColourBasis>::tptr colourBasis() const { return theColourBasis; }
/**
* Set the colour basis dimensionality.
*/
void colourBasisDim(size_t dim) { theColourBasisDim = dim; }
/**
* Get the colour basis dimensionality.
*/
size_t colourBasisDim() const { return theColourBasisDim; }
/**
* Return true, if this amplitude will not require colour correlations.
*/
virtual bool noCorrelations() const { return !haveOneLoop(); }
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const {
return colourBasis() ? colourBasis()->haveColourFlows() : false;
}
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
*/
virtual Selector<const ColourLines *> colourGeometries(tcDiagPtr diag) const {
return
haveColourFlows() ?
theColourBasis->colourGeometries(diag,lastLargeNAmplitudes()) :
Selector<const ColourLines *>();
}
/**
* Return the colour crossing information as filled by the last call to
* fillCrossingMap(...), mapping amplitude ids to colour basis ids.
*/
const map<size_t,size_t>& lastAmplitudeToColourMap() const { return theLastAmplitudeToColourMap->second; }
/**
* Access the colour crossing information.
*/
map<size_t,size_t>& lastAmplitudeToColourMap() { return theLastAmplitudeToColourMap->second; }
/**
* Access the colour crossing information.
*/
map<tStdXCombPtr,map<size_t,size_t> >& amplitudeToColourMap() { return processData()->amplitudeToColourMap(); }
/**
* Return the colour crossing information as filled by the last call to
* fillCrossingMap(...), mapping amplitude ids to colour basis ids.
*/
const map<size_t,size_t>& lastColourToAmplitudeMap() const { return theLastColourToAmplitudeMap->second; }
/**
* Access the colour crossing information.
*/
map<size_t,size_t>& lastColourToAmplitudeMap() { return theLastColourToAmplitudeMap->second; }
/**
* Access the colour crossing information.
*/
map<tStdXCombPtr,map<size_t,size_t> >& colourToAmplitudeMap() { return processData()->colourToAmplitudeMap(); }
/**
* Return an ordering identifier for the current subprocess and
* colour absis tensor index.
*/
const string& colourOrdering(size_t id) const;
//@}
/** @name Phasespace point, crossing and helicities */
//@{
/**
* Set the xcomb object.
*/
virtual void setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
fillCrossingMap();
}
/**
* Return the momentum as crossed appropriate for this amplitude.
*/
Lorentz5Momentum amplitudeMomentum(int) const;
/**
* Perform a normal ordering of external legs and fill the
* crossing information as. This default implementation sorts
* lexicographically in (abs(colour)/spin/abs(charge)), putting pairs
* of particles/anti-particles where possible.
*/
virtual void fillCrossingMap(size_t shift = 0);
/**
* Return the crossing sign.
*/
double lastCrossingSign() const { return theLastCrossingSign; }
/**
* Set the crossing sign.
*/
void lastCrossingSign(double s) { theLastCrossingSign = s; }
/**
* Return the crossing information as filled by the last call to
* fillCrossingMap(...), mapping amplitude ids to process ids.
*/
const vector<int>& lastCrossingMap() const { return theLastCrossingMap->second; }
/**
* Access the crossing information.
*/
vector<int>& lastCrossingMap() { return theLastCrossingMap->second; }
/**
* Access the crossing information.
*/
map<tStdXCombPtr,vector<int> >& crossingMap() { return processData()->crossingMap(); }
/**
* Access the crossing signs.
*/
map<tStdXCombPtr,double>& crossingSigns() { return processData()->crossingSigns(); }
/**
* Generate the helicity combinations.
*/
virtual set<vector<int> > generateHelicities() const;
//@}
/** @name Tree-level amplitudes */
//@{
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return last evaluated helicity amplitudes.
*/
const AmplitudeMap& lastAmplitudes() const { return theLastAmplitudes->second; }
/**
* Access the last evaluated helicity amplitudes.
*/
AmplitudeMap& lastAmplitudes() { return theLastAmplitudes->second; }
/**
* Return last evaluated, leading colour helicity amplitudes.
*/
const AmplitudeMap& lastLargeNAmplitudes() const { return theLastLargeNAmplitudes->second; }
/**
* Access the last evaluated, leading colour helicity amplitudes.
*/
AmplitudeMap& lastLargeNAmplitudes() { return theLastLargeNAmplitudes->second; }
/**
* Return the matrix element squared.
*/
virtual double me2() const {
return
lastCrossingSign()*colourBasis()->me2(mePartonData(),lastAmplitudes());
}
/**
* Return the colour correlated matrix element.
*/
virtual double colourCorrelatedME2(pair<int,int> ij) const;
/**
+ * Return the large-N colour correlated matrix element.
+ */
+ virtual double largeNColourCorrelatedME2(pair<int,int> ij,
+ Ptr<ColourBasis>::tptr largeNBasis) const;
+
+ /**
* Return a positive helicity polarization vector for a gluon of
* momentum p (with reference vector n) to be used when evaluating
* spin correlations.
*/
virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n) const;
/**
* Return the colour and spin correlated matrix element.
*/
virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
/**
* Return true, if tree-level contributions will be evaluated at amplitude level.
*/
virtual bool treeAmplitudes() const { return true; }
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&) { return 0.; }
//@}
/** @name One-loop amplitudes */
//@{
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Return true, if this amplitude only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const { return false; }
/**
* Return true, if one-loop contributions will be evaluated at amplitude level.
*/
virtual bool oneLoopAmplitudes() const { return true; }
/**
* Return true, if one loop corrections have been calculated in
* dimensional reduction. Otherwise conventional dimensional
* regularization is assumed. Note that renormalization is always
* assumed to be MSbar.
*/
virtual bool isDR() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of the integrated dipoles.
*/
virtual bool isCS() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const { return false; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return 0.*GeV2; }
/**
* If defined, return the coefficient of the pole in epsilon^2
*/
virtual double oneLoopDoublePole() const { return 0.; }
/**
* If defined, return the coefficient of the pole in epsilon
*/
virtual double oneLoopSinglePole() const { return 0.; }
/**
* Calculate the one-loop amplitudes for the phasespace point
* stored in lastXComb, if provided.
*/
virtual void prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return last evaluated one-loop helicity amplitudes.
*/
const AmplitudeMap& lastOneLoopAmplitudes() const { return theLastOneLoopAmplitudes->second; }
/**
* Access the last evaluated one-loop helicity amplitudes.
*/
AmplitudeMap& lastOneLoopAmplitudes() { return theLastOneLoopAmplitudes->second; }
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const {
return
lastCrossingSign()*colourBasis()->interference(mePartonData(),
lastOneLoopAmplitudes(),lastAmplitudes());
}
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&) { return 0.; }
//@}
/** @name Caching and helpers to setup amplitude objects. */
//@{
/**
* Flush all cashes.
*/
virtual void flushCaches() {
calculateTrees = true;
calculateLoops = true;
}
/**
* Clone this amplitude.
*/
Ptr<MatchboxAmplitude>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix = "");
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
protected:
/**
* The additional random numbers requested by
* this virtual correction.
*/
vector<double> additionalRandomNumbers;
private:
/**
* Recursively generate helicities
*/
void doGenerateHelicities(set<vector<int> >& res,
vector<int>& current,
size_t pos) const;
/**
* The Herwig++ StandardModel object
*/
Ptr<StandardModel>::tcptr theStandardModel;
/**
* The process data object to be used
*/
Ptr<ProcessData>::ptr theProcessData;
/**
* The number of light flavours to be used.
*/
unsigned int theNLight;
/**
* The colour basis implementation to be used.
*/
Ptr<ColourBasis>::ptr theColourBasis;
/**
* The dimensionality of the colour basis for the processes covered
* by the colour basis.
*/
size_t theColourBasisDim;
/**
* References to the amplitude values which have been contributing
* to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> > theLastAmplitudeMap;
/**
* References to the leading N amplitude values which have been
* contributing to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> > theLastLargeNAmplitudeMap;
/**
* References to the one-loop amplitude values which have been contributing
* to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> > theLastOneLoopAmplitudeMap;
/**
* References to the amplitude values which have been contributing
* to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> >::iterator theLastAmplitudes;
/**
* References to the leading N amplitude values which have been
* contributing to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> >::iterator theLastLargeNAmplitudes;
/**
* References to the one-loop amplitude values which have been contributing
* to the last call of prepareAmplitudes.
*/
map<tStdXCombPtr,map<vector<int>,CVector> >::iterator theLastOneLoopAmplitudes;
/**
* The crossing information as filled by the last call to
* fillCrossingMap()
*/
map<tStdXCombPtr,vector<int> >::iterator theLastCrossingMap;
/**
* The colour crossing information as filled by the last call to
* fillCrossingMap()
*/
map<tStdXCombPtr,map<size_t,size_t> >::iterator theLastAmplitudeToColourMap;
/**
* The colour crossing information as filled by the last call to
* fillCrossingMap()
*/
map<tStdXCombPtr,map<size_t,size_t> >::iterator theLastColourToAmplitudeMap;
/**
* The amplitude parton data.
*/
map<tStdXCombPtr,cPDVector>::iterator theLastAmplitudePartonData;
/**
* The crossing sign.
*/
double theLastCrossingSign;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitude & operator=(const MatchboxAmplitude &);
protected:
/**
* True, if tree amplitudes need to be recalculated.
*/
bool calculateTrees;
/**
* True, if loop amplitudes need to be recalculated.
*/
bool calculateLoops;
};
}
#endif /* HERWIG_MatchboxAmplitude_H */
diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
@@ -1,1227 +1,1251 @@
// -*- C++ -*-
//
// MatchboxMEBase.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxMEBase class.
//
#include "MatchboxMEBase.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDF/PDF.h"
#include "ThePEG/PDT/PDT.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "Herwig++/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
MatchboxMEBase::MatchboxMEBase()
: MEBase(),
theFactorizationScaleFactor(1.0),
theRenormalizationScaleFactor(1.0),
theVerbose(false),
theFixedCouplings(false), theFixedQEDCouplings(false),
theNLight(0), theGetColourCorrelatedMEs(false),
theCheckPoles(false), theOneLoop(false),
theOneLoopNoBorn(false) {}
MatchboxMEBase::~MatchboxMEBase() {}
void MatchboxMEBase::getDiagrams() const {
if ( diagramGenerator() && processData() ) {
vector<Ptr<Tree2toNDiagram>::ptr> diags;
for ( vector<PDVector>::const_iterator p = subProcesses().begin();
p != subProcesses().end(); ++p ) {
vector<Ptr<Tree2toNDiagram>::ptr>& res =
theProcessData->diagramMap()[*p];
if ( res.empty() ) {
res = diagramGenerator()->generate(*p,orderInAlphaS(),orderInAlphaEW());
}
copy(res.begin(),res.end(),back_inserter(diags));
}
if ( diags.empty() )
return;
for ( vector<Ptr<Tree2toNDiagram>::ptr>::iterator d = diags.begin();
d != diags.end(); ++d ) {
add(*d);
}
if ( theVerbose ) {
string fname = name() + ".diagrams";
ifstream test(fname.c_str());
if ( !test ) {
test.close();
ofstream out(fname.c_str());
for ( vector<Ptr<Tree2toNDiagram>::ptr>::const_iterator d = diags.begin();
d != diags.end(); ++d ) {
DiagramDrawer::drawDiag(out,**d);
out << "\n";
}
}
}
return;
}
throw Exception()
<< "MatchboxMEBase::getDiagrams() expects a Tree2toNGenerator and ProcessData object.\n"
<< "Please check your setup." << Exception::abortnow;
}
Selector<MEBase::DiagramIndex>
MatchboxMEBase::diagrams(const DiagramVector & diags) const {
if ( phasespace() ) {
return phasespace()->selectDiagrams(diags);
}
throw Exception()
<< "MatchboxMEBase::diagrams() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::abortnow;
return Selector<MEBase::DiagramIndex>();
}
Selector<const ColourLines *>
MatchboxMEBase::colourGeometries(tcDiagPtr diag) const {
if ( matchboxAmplitude() ) {
if ( !matchboxAmplitude()->haveColourFlows() )
throw Exception() << "A colour flow implementation is not present."
<< Exception::abortnow;
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
return matchboxAmplitude()->colourGeometries(diag);
}
throw Exception()
<< "MatchboxMEBase::colourGeometries() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return Selector<const ColourLines *>();
}
unsigned int MatchboxMEBase::orderInAlphaS() const {
if ( matchboxAmplitude() ) {
return matchboxAmplitude()->orderInGs();
}
throw Exception()
<< "MatchboxMEBase::orderInAlphaS() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0;
}
unsigned int MatchboxMEBase::orderInAlphaEW() const {
if ( matchboxAmplitude() ) {
return matchboxAmplitude()->orderInGem();
}
throw Exception()
<< "MatchboxMEBase::orderInAlphaEW() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0;
}
void MatchboxMEBase::setXComb(tStdXCombPtr xc) {
MEBase::setXComb(xc);
if ( phasespace() && !xc->head() )
phasespace()->prepare(xc,theVerbose);
if ( scaleChoice() )
scaleChoice()->setXComb(xc);
if ( cache() )
cache()->setXComb(xc);
if ( matchboxAmplitude() )
matchboxAmplitude()->setXComb(xc);
}
double MatchboxMEBase::generateIncomingPartons(const double* r1, const double* r2) {
// shamelessly stolen from PartonExtractor.cc
Energy2 shmax = lastCuts().sHatMax();
Energy2 shmin = lastCuts().sHatMin();
Energy2 sh = shmin*pow(shmax/shmin, *r1);
double ymax = lastCuts().yHatMax();
double ymin = lastCuts().yHatMin();
double km = log(shmax/shmin);
ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh)));
ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh)));
double y = ymin + (*r2)*(ymax - ymin);
double x1 = exp(-0.5*log(lastS()/sh) + y);
double x2 = exp(-0.5*log(lastS()/sh) - y);
Lorentz5Momentum P1 = lastParticles().first->momentum();
LorentzMomentum p1 = lightCone((P1.rho() + P1.e())*x1, Energy());
p1.rotateY(P1.theta());
p1.rotateZ(P1.phi());
meMomenta()[0] = p1;
Lorentz5Momentum P2 = lastParticles().second->momentum();
LorentzMomentum p2 = lightCone((P2.rho() + P2.e())*x2, Energy());
p2.rotateY(P2.theta());
p2.rotateZ(P2.phi());
meMomenta()[1] = p2;
lastXCombPtr()->lastX1X2(make_pair(x1,x2));
lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
return km*(ymax - ymin);
}
bool MatchboxMEBase::generateKinematics(const double * r) {
if ( phasespace() ) {
jacobian(phasespace()->generateKinematics(r,meMomenta()));
if ( jacobian() == 0.0 )
return false;
setScale();
logGenerateKinematics(r);
int ampShift = 0;
int nBorn = nDimBorn();
if ( matchboxAmplitude() ) {
ampShift = matchboxAmplitude()->nDimAdditional();
if ( ampShift )
matchboxAmplitude()->additionalKinematics(r + nBorn);
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).additionalKinematics(r + nBorn + ampShift);
}
return true;
}
throw Exception()
<< "MatchboxMEBase::generateKinematics() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::abortnow;
return false;
}
int MatchboxMEBase::nDim() const {
int ampAdd = 0;
if ( matchboxAmplitude() ) {
ampAdd = matchboxAmplitude()->nDimAdditional();
}
int insertionAdd = 0;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
insertionAdd = max(insertionAdd,(**v).nDimAdditional());
}
return nDimBorn() + ampAdd + insertionAdd;
}
int MatchboxMEBase::nDimBorn() const {
if ( phasespace() ) {
size_t nout = diagrams().front()->partons().size()-2;
int n = phasespace()->nDim(nout);
return n;
}
throw Exception()
<< "MatchboxMEBase::nDim() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0;
}
void MatchboxMEBase::setScale() const {
if ( haveX1X2() ) {
lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
}
Energy2 fscale = factorizationScale()*factorizationScaleFactor();
Energy2 rscale = renormalizationScale()*renormalizationScaleFactor();
Energy2 ewrscale = renormalizationScaleQED();
lastXCombPtr()->lastScale(fscale);
if ( !fixedCouplings() ) {
if ( rscale > lastCuts().scaleMin() )
lastXCombPtr()->lastAlphaS(SM().alphaS(rscale));
else
lastXCombPtr()->lastAlphaS(SM().alphaS(lastCuts().scaleMin()));
} else {
lastXCombPtr()->lastAlphaS(SM().alphaS());
}
if ( !fixedQEDCouplings() ) {
lastXCombPtr()->lastAlphaEM(SM().alphaEM(ewrscale));
} else {
lastXCombPtr()->lastAlphaEM(SM().alphaEMMZ());
}
logSetScale();
}
Energy2 MatchboxMEBase::factorizationScale() const {
if ( scaleChoice() ) {
return scaleChoice()->factorizationScale();
}
throw Exception()
<< "MatchboxMEBase::factorizationScale() expects a MatchboxScaleChoice object.\n"
<< "Please check your setup." << Exception::abortnow;
return ZERO;
}
Energy2 MatchboxMEBase::renormalizationScale() const {
if ( scaleChoice() ) {
return scaleChoice()->renormalizationScale();
}
throw Exception()
<< "MatchboxMEBase::renormalizationScale() expects a MatchboxScaleChoice object.\n"
<< "Please check your setup." << Exception::abortnow;
return ZERO;
}
Energy2 MatchboxMEBase::renormalizationScaleQED() const {
if ( scaleChoice() ) {
return scaleChoice()->renormalizationScaleQED();
}
return renormalizationScale();
}
void MatchboxMEBase::setVetoScales(tSubProPtr) const {}
void MatchboxMEBase::getPDFWeight(Energy2 factorizationScale) const {
if ( !mePartonData()[0]->coloured() &&
!mePartonData()[1]->coloured() ) {
lastMEPDFWeight(1.0);
logPDFWeight();
return;
}
double w = 1.;
if ( mePartonData()[0]->coloured() && havePDFWeight1() )
w *= pdf1(factorizationScale);
if ( mePartonData()[1]->coloured() && havePDFWeight2() )
w *= pdf2(factorizationScale);
lastMEPDFWeight(w);
logPDFWeight();
}
double MatchboxMEBase::pdf1(Energy2 fscale, double xEx) const {
assert(lastXCombPtr()->partonBins().first->pdf());
if ( xEx < 1. && lastX1() >= xEx ) {
return
( ( 1. - lastX1() ) / ( 1. - xEx ) ) *
lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
lastPartons().first->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
xEx)/xEx;
}
return lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
lastPartons().first->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
lastX1())/lastX1();
}
double MatchboxMEBase::pdf2(Energy2 fscale, double xEx) const {
assert(lastXCombPtr()->partonBins().second->pdf());
if ( xEx < 1. && lastX2() >= xEx ) {
return
( ( 1. - lastX2() ) / ( 1. - xEx ) ) *
lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
lastPartons().second->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
xEx)/xEx;
}
return lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
lastPartons().second->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
lastX2())/lastX2();
}
double MatchboxMEBase::me2() const {
if ( matchboxAmplitude() ) {
double res;
if ( !calculateME2(res) )
return res;
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
lastME2(matchboxAmplitude()->me2()*
matchboxAmplitude()->lastCrossingSign()*
me2Norm());
cacheME2(lastME2());
logME2();
return lastME2();
}
throw Exception()
<< "MatchboxMEBase::me2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0.;
}
double MatchboxMEBase::finalStateSymmetry() const {
map<tStdXCombPtr,double>::const_iterator s =
symmetryFactors.find(lastXCombPtr());
if ( s != symmetryFactors.end() )
return s->second;
double symmetryFactor = 1.;
map<long,int> counts;
cPDVector checkData;
copy(mePartonData().begin()+2,mePartonData().end(),back_inserter(checkData));
cPDVector::iterator p = checkData.begin();
while ( !checkData.empty() ) {
if ( counts.find((**p).id()) != counts.end() ) {
counts[(**p).id()] += 1;
} else {
counts[(**p).id()] = 1;
}
checkData.erase(p);
p = checkData.begin();
continue;
}
for ( map<long,int>::const_iterator c = counts.begin();
c != counts.end(); ++c ) {
if ( c->second == 1 )
continue;
if ( c->second == 2 )
symmetryFactor /= 2.;
else if ( c->second == 3 )
symmetryFactor /= 6.;
else if ( c->second == 4 )
symmetryFactor /= 24.;
}
symmetryFactors[lastXCombPtr()] = symmetryFactor;
return symmetryFactor;
}
double MatchboxMEBase::me2Norm(unsigned int addAlphaS) const {
// assume that we always have incoming
// spin-1/2 or massless spin-1 particles
double fac = 1./4.;
if ( orderInAlphaS() > 0 || addAlphaS != 0 )
fac *= pow(lastAlphaS()/SM().alphaS(),double(orderInAlphaS()+addAlphaS));
if ( orderInAlphaEW() > 0 )
fac *= pow(lastAlphaEM()/SM().alphaEM(),double(orderInAlphaEW()));
if ( mePartonData()[0]->iColour() == PDT::Colour3 ||
mePartonData()[0]->iColour() == PDT::Colour3bar )
fac /= SM().Nc();
else if ( mePartonData()[0]->iColour() == PDT::Colour8 )
fac /= (SM().Nc()*SM().Nc()-1.);
if ( mePartonData()[1]->iColour() == PDT::Colour3 ||
mePartonData()[1]->iColour() == PDT::Colour3bar )
fac /= SM().Nc();
else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
fac /= (SM().Nc()*SM().Nc()-1.);
return finalStateSymmetry()*fac;
}
void MatchboxMEBase::storeColourCorrelatedMEs(double xme2) const {
map<pair<int,int>,double>& ccs =
colourCorrelatedMEs[lastXCombPtr()];
int n = meMomenta().size();
for ( int i = 0; i < n; ++i ) {
if ( !mePartonData()[i]->coloured() )
continue;
for ( int j = i+1; j < n; ++j ) {
if ( !mePartonData()[j]->coloured() )
continue;
if ( noDipole(i,j) )
continue;
ccs[make_pair(i,j)] = colourCorrelatedME2(make_pair(i,j));
}
}
lastXCombPtr()->meta(MatchboxMetaKeys::ColourCorrelatedMEs,ccs);
double& bme2 = bornMEs[lastXCombPtr()];
bme2 = xme2 >= 0. ? xme2 : me2();
lastXCombPtr()->meta(MatchboxMetaKeys::BornME,bme2);
}
CrossSection MatchboxMEBase::dSigHatDR() const {
getPDFWeight();
if ( !lastXCombPtr()->willPassCuts() ) {
lastME2(0.0);
lastMECrossSection(ZERO);
return lastMECrossSection();
}
double xme2 = me2();
lastME2(xme2);
if ( xme2 == 0. && !oneLoopNoBorn() ) {
lastME2(0.0);
lastMECrossSection(ZERO);
return lastMECrossSection();
}
if ( getColourCorrelatedMEs() )
storeColourCorrelatedMEs(xme2);
double vme2 = 0.;
if ( oneLoop() )
vme2 = oneLoopInterference();
CrossSection res = ZERO;
if ( !oneLoopNoBorn() )
res +=
(sqr(hbarc)/(2.*lastSHat())) *
jacobian()* lastMEPDFWeight() * xme2;
if ( oneLoop() )
res +=
(sqr(hbarc)/(2.*lastSHat())) *
jacobian()* lastMEPDFWeight() * vme2;
if ( !onlyOneLoop() ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).setXComb(lastXCombPtr());
res += (**v).dSigHatDR();
}
}
double weight = 0.0;
bool applied = false;
for ( vector<Ptr<MatchboxReweightBase>::ptr>::const_iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).setXComb(lastXCombPtr());
if ( !(**rw).apply() )
continue;
weight += (**rw).evaluate();
applied = true;
}
if ( applied )
res *= weight;
lastMECrossSection(res);
return lastMECrossSection();
}
double MatchboxMEBase::oneLoopInterference() const {
if ( matchboxAmplitude() ) {
double res;
if ( !calculateME2(res,make_pair<int,int>(-1,-1)) )
return res;
if ( matchboxAmplitude()->oneLoopAmplitudes() )
matchboxAmplitude()->prepareOneLoopAmplitudes(this);
lastME2(matchboxAmplitude()->oneLoopInterference()*
matchboxAmplitude()->lastCrossingSign()*
me2Norm(1));
cacheME2(lastME2(),make_pair<int,int>(-1,-1));
logME2();
return lastME2();
}
throw Exception()
<< "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0.;
}
void MatchboxMEBase::logPoles() const {
double res2me = oneLoopDoublePole();
double res1me = oneLoopSinglePole();
double res2i = 0.;
double res1i = 0.;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
res2i += (**v).oneLoopDoublePole();
res1i += (**v).oneLoopSinglePole();
}
double diff2 = abs(res2me) != 0. ? 1.-abs(res2i/res2me) : abs(res2i)-abs(res2me);
double diff1 = abs(res1me) != 0. ? 1.-abs(res1i/res1me) : abs(res1i)-abs(res1me);
generator()->log()
<< "check "
<< log10(abs(diff2)) << " " << log10(abs(diff1)) << "\n"
<< flush;
}
bool MatchboxMEBase::haveOneLoop() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->haveOneLoop();
return false;
}
bool MatchboxMEBase::onlyOneLoop() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->onlyOneLoop();
return false;
}
bool MatchboxMEBase::isDR() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isDR();
return false;
}
bool MatchboxMEBase::isCS() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isCS();
return false;
}
bool MatchboxMEBase::isBDK() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isBDK();
return false;
}
bool MatchboxMEBase::isExpanded() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isExpanded();
return false;
}
Energy2 MatchboxMEBase::mu2() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->mu2();
return 0*GeV2;
}
double MatchboxMEBase::oneLoopDoublePole() const {
if ( matchboxAmplitude() ) {
return
matchboxAmplitude()->oneLoopDoublePole()*
matchboxAmplitude()->lastCrossingSign()*
me2Norm(1);
}
return 0.;
}
double MatchboxMEBase::oneLoopSinglePole() const {
if ( matchboxAmplitude() ) {
return
matchboxAmplitude()->oneLoopSinglePole()*
matchboxAmplitude()->lastCrossingSign()*
me2Norm(1);
}
return 0.;
}
vector<Ptr<SubtractionDipole>::ptr>
MatchboxMEBase::getDipoles(const vector<Ptr<SubtractionDipole>::ptr>& dipoles,
const vector<Ptr<MatchboxMEBase>::ptr>& borns) const {
vector<Ptr<SubtractionDipole>::ptr> res;
// keep track of the dipoles we already did set up
set<pair<pair<pair<int,int>,int>,pair<Ptr<MatchboxMEBase>::tptr,Ptr<SubtractionDipole>::tptr> > > done;
cPDVector rep = diagrams().front()->partons();
int nreal = rep.size();
// now loop over configs
for ( int emitter = 0; emitter < nreal; ++emitter ) {
for ( int spectator = 0; spectator < nreal; ++spectator ) {
if ( emitter == spectator )
continue;
for ( int emission = 2; emission < nreal; ++emission ) {
if ( emission == emitter || emission == spectator )
continue;
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator b =
borns.begin(); b != borns.end(); ++b ) {
if ( (**b).onlyOneLoop() )
continue;
for ( vector<Ptr<SubtractionDipole>::ptr>::const_iterator d =
dipoles.begin(); d != dipoles.end(); ++d ) {
if ( !rep[emitter]->coloured() ||
!rep[emission]->coloured() ||
!rep[spectator]->coloured() ) {
continue;
}
if ( noDipole(emitter,emission,spectator) ) {
continue;
}
if ( done.find(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d)))
!= done.end() ) {
continue;
}
if ( !(**d).canHandle(rep,emitter,emission,spectator) ) {
continue;
}
// now get to work
Ptr<SubtractionDipole>::ptr nDipole = (**d).cloneMe();
nDipole->realEmitter(emitter);
nDipole->realEmission(emission);
nDipole->realSpectator(spectator);
nDipole->realEmissionME(const_cast<MatchboxMEBase*>(this));
nDipole->underlyingBornME(*b);
nDipole->setupBookkeeping();
if ( !(nDipole->empty()) ) {
res.push_back(nDipole);
done.insert(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d)));
if ( nDipole->isSymmetric() )
done.insert(make_pair(make_pair(make_pair(emission,emitter),spectator),make_pair(*b,*d)));
ostringstream dname;
dname << fullName() << "." << (**b).name() << "."
<< (**d).name() << ".[("
<< emitter << "," << emission << ")," << spectator << "]";
if ( ! (generator()->preinitRegister(nDipole,dname.str()) ) )
throw InitException() << "Dipole " << dname.str() << " already existing.";
nDipole->cloneDependencies(dname.str());
}
}
}
}
}
}
for ( vector<Ptr<SubtractionDipole>::ptr>::iterator d = res.begin();
d != res.end(); ++d )
(**d).partnerDipoles(res);
return res;
}
double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const {
if ( matchboxAmplitude() ) {
double res;
if ( !calculateME2(res,ij) )
return res;
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
lastME2(matchboxAmplitude()->colourCorrelatedME2(ij)*
matchboxAmplitude()->lastCrossingSign()*
me2Norm());
cacheME2(lastME2(),ij);
logME2();
return lastME2();
}
throw Exception()
<< "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0.;
}
+double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij,
+ Ptr<ColourBasis>::tptr largeNBasis) const {
+
+ if ( matchboxAmplitude() ) {
+
+ if ( matchboxAmplitude()->treeAmplitudes() )
+ matchboxAmplitude()->prepareAmplitudes(this);
+ lastME2(matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)*
+ matchboxAmplitude()->lastCrossingSign()*
+ me2Norm());
+
+ logME2();
+
+ return lastME2();
+
+ }
+
+ throw Exception()
+ << "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
+ << "Please check your setup." << Exception::abortnow;
+ return 0.;
+
+}
+
double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
if ( matchboxAmplitude() ) {
double res;
if ( !calculateME2(res,ij) )
return res;
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
lastME2(matchboxAmplitude()->spinColourCorrelatedME2(ij,c)*
matchboxAmplitude()->lastCrossingSign()*
me2Norm());
cacheME2(lastME2(),ij);
logME2();
return lastME2();
}
throw Exception()
<< "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::abortnow;
return 0.;
}
void MatchboxMEBase::flushCaches() {
MEBase::flushCaches();
if ( cache() )
cache()->flush();
if ( matchboxAmplitude() )
matchboxAmplitude()->flushCaches();
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator r =
reweights().begin(); r != reweights().end(); ++r ) {
(**r).flushCaches();
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).flushCaches();
}
}
void MatchboxMEBase::print(ostream& os) const {
os << "--- MatchboxMEBase setup -------------------------------------------------------\n";
os << " '" << name() << "' for subprocesses:\n";
for ( vector<PDVector>::const_iterator p = subProcesses().begin();
p != subProcesses().end(); ++p ) {
os << " ";
for ( PDVector::const_iterator pp = p->begin();
pp != p->end(); ++pp ) {
os << (**pp).PDGName() << " ";
if ( pp == p->begin() + 1 )
os << "-> ";
}
os << "\n";
}
os << " including " << (oneLoop() ? "" : "no ") << "virtual corrections";
if ( oneLoopNoBorn() )
os << " without Born contributions";
os << "\n";
if ( oneLoop() && !onlyOneLoop() ) {
os << " using insertion operators\n";
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
os << " '" << (**v).name() << "' with "
<< ((**v).isDR() ? "" : "C") << "DR/";
if ( (**v).isCS() )
os << "CS";
if ( (**v).isBDK() )
os << "BDK";
if ( (**v).isExpanded() )
os << "expanded";
os << " conventions\n";
}
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void MatchboxMEBase::printLastEvent(ostream& os) const {
os << "--- MatchboxMEBase last event information --------------------------------------\n";
os << " for matrix element '" << name() << "'\n";
os << " process considered:\n ";
int in = 0;
for ( cPDVector::const_iterator p = mePartonData().begin();
p != mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
if ( ++in == 2 )
os << " -> ";
}
os << " kinematic environment as set by the XComb " << lastXCombPtr() << ":\n"
<< " sqrt(shat)/GeV = " << sqrt(lastSHat()/GeV2)
<< " x1 = " << lastX1() << " x2 = " << lastX2()
<< " alphaS = " << lastAlphaS() << "\n";
os << " momenta/GeV generated from random numbers\n ";
copy(lastXComb().lastRandomNumbers().begin(),
lastXComb().lastRandomNumbers().end(),ostream_iterator<double>(os," "));
os << ":\n ";
for ( vector<Lorentz5Momentum>::const_iterator p = meMomenta().begin();
p != meMomenta().end(); ++p ) {
os << (*p/GeV) << "\n ";
}
os << "last cross section/nb calculated was:\n "
<< (lastMECrossSection()/nanobarn) << " (pdf weight " << lastMEPDFWeight() << ")\n";
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void MatchboxMEBase::logGenerateKinematics(const double * r) const {
if ( !theVerbose )
return;
generator()->log() << "'" << name() << "' generated kinematics\nfrom "
<< nDim() << " random numbers:\n";
copy(r,r+nDim(),ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n";
generator()->log() << "storing phase space information in XComb "
<< lastXCombPtr() << "\n";
generator()->log() << "generated phase space point (in GeV):\n";
vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
cPDVector::const_iterator dit = mePartonData().begin();
for ( ; pit != meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
<< "and Jacobian = " << jacobian() << " sHat/GeV2 = "
<< (lastSHat()/GeV2) << "\n" << flush;
}
void MatchboxMEBase::logSetScale() const {
if ( !theVerbose )
return;
generator()->log() << "'" << name() << "' set scales using XComb " << lastXCombPtr() << ":\n"
<< "scale/GeV2 = " << (scale()/GeV2) << " xi_R = "
<< renormalizationScaleFactor() << " xi_F = "
<< factorizationScaleFactor() << "\n"
<< "alpha_s = " << lastAlphaS() << "\n" << flush;
}
void MatchboxMEBase::logPDFWeight() const {
if ( !theVerbose )
return;
generator()->log() << "'" << name() << "' calculated pdf weight = "
<< lastMEPDFWeight() << " from XComb "
<< lastXCombPtr() << "\n"
<< "x1 = " << lastX1() << " (" << (mePartonData()[0]->coloured() ? "" : "not ") << "used) "
<< "x2 = " << lastX2() << " (" << (mePartonData()[1]->coloured() ? "" : "not ") << "used)\n"
<< flush;
}
void MatchboxMEBase::logME2() const {
if ( !theVerbose )
return;
generator()->log() << "'" << name() << "' evaluated me2 using XComb "
<< lastXCombPtr() << "\n"
<< "and phase space point (in GeV):\n";
vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
cPDVector::const_iterator dit = mePartonData().begin();
for ( ; pit != meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
<< "sHat/GeV2 = " << (lastSHat()/GeV2)
<< " me2 = " << lastME2() << "\n" << flush;
}
void MatchboxMEBase::logDSigHatDR() const {
if ( !theVerbose )
return;
generator()->log() << "'" << name() << "' evaluated cross section using XComb "
<< lastXCombPtr() << "\n"
<< "Jacobian = " << jacobian() << " sHat/GeV2 = "
<< (lastSHat()/GeV2) << " dsig/nb = "
<< (lastMECrossSection()/nanobarn) << "\n" << flush;
}
void MatchboxMEBase::cloneDependencies(const std::string& prefix) {
if ( phasespace() ) {
Ptr<MatchboxPhasespace>::ptr myPhasespace = phasespace()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myPhasespace->name();
if ( ! (generator()->preinitRegister(myPhasespace,pname.str()) ) )
throw InitException() << "Phasespace generator " << pname.str() << " already existing.";
myPhasespace->cloneDependencies(pname.str());
phasespace(myPhasespace);
}
theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
if ( matchboxAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myAmplitude = matchboxAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myAmplitude->name();
if ( ! (generator()->preinitRegister(myAmplitude,pname.str()) ) )
throw InitException() << "Amplitude " << pname.str() << " already existing.";
myAmplitude->cloneDependencies(pname.str());
matchboxAmplitude(myAmplitude);
amplitude(myAmplitude);
matchboxAmplitude()->orderInGs(orderInAlphaS());
matchboxAmplitude()->orderInGem(orderInAlphaEW());
matchboxAmplitude()->processData(processData());
}
if ( scaleChoice() ) {
Ptr<MatchboxScaleChoice>::ptr myScaleChoice = scaleChoice()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myScaleChoice->name();
if ( ! (generator()->preinitRegister(myScaleChoice,pname.str()) ) )
throw InitException() << "Scale choice " << pname.str() << " already existing.";
scaleChoice(myScaleChoice);
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
Ptr<MatchboxReweightBase>::ptr myReweight = (**rw).cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << (**rw).name();
if ( ! (generator()->preinitRegister(myReweight,pname.str()) ) )
throw InitException() << "Reweight " << pname.str() << " already existing.";
myReweight->cloneDependencies(pname.str());
*rw = myReweight;
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
Ptr<MatchboxInsertionOperator>::ptr myIOP = (**v).cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << (**v).name();
if ( ! (generator()->preinitRegister(myIOP,pname.str()) ) )
throw InitException() << "Insertion operator " << pname.str() << " already existing.";
*v = myIOP;
(**v).setBorn(this);
}
}
void MatchboxMEBase::persistentOutput(PersistentOStream & os) const {
os << theReweights << thePhasespace << theAmplitude << theScaleChoice
<< theDiagramGenerator << theProcessData << theSubprocesses
<< theFactorizationScaleFactor << theRenormalizationScaleFactor
<< theVerbose << theCache << theVirtuals << theFixedCouplings << theFixedQEDCouplings
<< theNLight << theGetColourCorrelatedMEs << theCheckPoles
<< theOneLoop << theOneLoopNoBorn << symmetryFactors;
}
void MatchboxMEBase::persistentInput(PersistentIStream & is, int) {
is >> theReweights >> thePhasespace >> theAmplitude >> theScaleChoice
>> theDiagramGenerator >> theProcessData >> theSubprocesses
>> theFactorizationScaleFactor >> theRenormalizationScaleFactor
>> theVerbose >> theCache >> theVirtuals >> theFixedCouplings >> theFixedQEDCouplings
>> theNLight >> theGetColourCorrelatedMEs >> theCheckPoles
>> theOneLoop >> theOneLoopNoBorn >> symmetryFactors;
}
void MatchboxMEBase::Init() {
static ClassDocumentation<MatchboxMEBase> documentation
("MatchboxMEBase is the base class for matrix elements "
"in the context of the matchbox NLO interface.");
static RefVector<MatchboxMEBase,MatchboxReweightBase> interfaceReweights
("Reweights",
"Reweight objects to be applied to this matrix element.",
&MatchboxMEBase::theReweights, -1, false, false, true, true, false);
static Reference<MatchboxMEBase,MatchboxPhasespace> interfacePhasespace
("Phasespace",
"Set the phasespace generator to be used.",
&MatchboxMEBase::thePhasespace, false, false, true, true, false);
static Reference<MatchboxMEBase,Tree2toNGenerator> interfaceDiagramGenerator
("DiagramGenerator",
"Set the diagram generator to be used.",
&MatchboxMEBase::theDiagramGenerator, false, false, true, true, false);
static Reference<MatchboxMEBase,ProcessData> interfaceProcessData
("ProcessData",
"Set the process data object to be used.",
&MatchboxMEBase::theProcessData, false, false, true, true, false);
static Reference<MatchboxMEBase,MatchboxScaleChoice> interfaceScaleChoice
("ScaleChoice",
"Set the scale choice to be used.",
&MatchboxMEBase::theScaleChoice, false, false, true, true, false);
static Reference<MatchboxMEBase,MatchboxMECache> interfaceMECache
("Cache",
"Set the cache object to be used.",
&MatchboxMEBase::theCache, false, false, true, true, false);
static RefVector<MatchboxMEBase,MatchboxInsertionOperator> interfaceVirtuals
("Virtuals",
"The virtual corrections to be added.",
&MatchboxMEBase::theVirtuals, -1, false, false, true, true, false);
static Parameter<MatchboxMEBase,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&MatchboxMEBase::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxMEBase,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&MatchboxMEBase::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxMEBase,bool> interfaceVerbose
("Verbose",
"Print full infomation on each evaluated phase space point.",
&MatchboxMEBase::theVerbose, false, false, false);
static SwitchOption interfaceVerboseOn
(interfaceVerbose,
"On",
"On",
true);
static SwitchOption interfaceVerboseOff
(interfaceVerbose,
"Off",
"Off",
false);
static Switch<MatchboxMEBase,bool> interfaceFixedCouplings
("FixedCouplings",
"Indicate that no running couplings should be used.",
&MatchboxMEBase::theFixedCouplings, false, false, false);
static SwitchOption interfaceFixedCouplingsOn
(interfaceFixedCouplings,
"On",
"On",
true);
static SwitchOption interfaceFixedCouplingsOff
(interfaceFixedCouplings,
"Off",
"Off",
false);
static Switch<MatchboxMEBase,bool> interfaceFixedQEDCouplings
("FixedQEDCouplings",
"Indicate that no running QED couplings should be used.",
&MatchboxMEBase::theFixedQEDCouplings, false, false, false);
static SwitchOption interfaceFixedQEDCouplingsOn
(interfaceFixedQEDCouplings,
"On",
"On",
true);
static SwitchOption interfaceFixedQEDCouplingsOff
(interfaceFixedQEDCouplings,
"Off",
"Off",
false);
}
IBPtr MatchboxMEBase::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxMEBase::fullclone() const {
return new_ptr(*this);
}
void MatchboxMEBase::doinit() {
MEBase::doinit();
theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->colourBasis() ) {
size_t dim =
matchboxAmplitude()->colourBasis()->prepare(diagrams(),matchboxAmplitude()->noCorrelations());
matchboxAmplitude()->colourBasisDim(dim);
}
matchboxAmplitude()->nLight(nLight());
}
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxMEBase,MEBase>
describeHerwigMatchboxMEBase("Herwig::MatchboxMEBase", "HwMatchbox.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.h b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.h
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
@@ -1,951 +1,960 @@
// -*- C++ -*-
//
// MatchboxMEBase.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxMEBase_H
#define HERWIG_MatchboxMEBase_H
//
// This is the declaration of the MatchboxMEBase class.
//
#include "ThePEG/MatrixElement/MEBase.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/MatchboxMECache.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/ProcessData.h"
#include "Herwig++/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxReweightBase.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
#include "Herwig++/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig++/MatrixElement/Matchbox/InsertionOperators/MatchboxInsertionOperator.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Keys for XComb meta information
*/
struct MatchboxMetaKeys {
enum Keys {
BornME,
ColourCorrelatedMEs
};
};
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxMEBase is the base class for matrix elements
* in the context of the matchbox NLO interface.
*
* @see \ref MatchboxMEBaseInterfaces "The interfaces"
* defined for MatchboxMEBase.
*/
class MatchboxMEBase: public MEBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
MatchboxMEBase();
/**
* The destructor.
*/
virtual ~MatchboxMEBase();
//@}
public:
/** @name Subprocess and diagram information. */
//@{
/**
* Return the subprocesses.
*/
const vector<PDVector>& subProcesses() const { return theSubprocesses; }
/**
* Access the subprocesses.
*/
vector<PDVector>& subProcesses() { return theSubprocesses; }
/**
* Return the diagram generator.
*/
Ptr<Tree2toNGenerator>::tptr diagramGenerator() const { return theDiagramGenerator; }
/**
* Set the diagram generator.
*/
void diagramGenerator(Ptr<Tree2toNGenerator>::ptr gen) { theDiagramGenerator = gen; }
/**
* Return the process data.
*/
Ptr<ProcessData>::tptr processData() const { return theProcessData; }
/**
* Set the process data.
*/
void processData(Ptr<ProcessData>::ptr pd) { theProcessData = pd; }
/**
* Return true, if this matrix element does not want to
* make use of mirroring processes; in this case all
* possible partonic subprocesses with a fixed assignment
* of incoming particles need to be provided through the diagrams
* added with the add(...) method.
*/
virtual bool noMirror () const { return true; }
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
using MEBase::getDiagrams;
/**
* With the information previously supplied with the
* setKinematics(...) method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector &) const;
using MEBase::diagrams;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
/**
* Return the order in \f$\alpha_S\f$ in which this matrix element
* is given.
*/
virtual unsigned int orderInAlphaS() const;
using MEBase::orderInAlphaS;
/**
* Return the order in \f$\alpha_{EM}\f$ in which this matrix
* element is given. Returns 0.
*/
virtual unsigned int orderInAlphaEW() const;
using MEBase::orderInAlphaEW;
/**
* Return the number of light flavours, this matrix
* element is calculated for.
*/
virtual unsigned int nLight() const { return theNLight; }
/**
* Set the number of light flavours, this matrix
* element is calculated for.
*/
void nLight(unsigned int n) { theNLight = n; }
//@}
/** @name Phasespace generation */
//@{
/**
* Return the phase space generator to be used.
*/
Ptr<MatchboxPhasespace>::tptr phasespace() const { return thePhasespace; }
/**
* Set the phase space generator to be used.
*/
void phasespace(Ptr<MatchboxPhasespace>::ptr ps) { thePhasespace = ps; }
/**
* Set the XComb object to be used in the next call to
* generateKinematics() and dSigHatDR().
*/
virtual void setXComb(tStdXCombPtr xc);
/**
* Return true, if the XComb steering this matrix element
* should keep track of the random numbers used to generate
* the last phase space point
*/
virtual bool keepRandomNumbers() const { return true; }
/**
* Generate incoming parton momenta. This default
* implementation performs the standard mapping
* from x1,x2 -> tau,y making 1/tau flat; incoming
* parton momenta are stored in meMomenta()[0,1],
* only massless partons are supported so far;
* return the Jacobian of the mapping
*/
double generateIncomingPartons(const double* r1, const double* r2);
/**
* Generate internal degrees of freedom given nDim() uniform random
* numbers in the interval ]0,1[. To help the phase space generator,
* the 'dSigHatDR' should be a smooth function of these numbers,
* although this is not strictly necessary. The return value should
* be true of the generation succeeded. If so the generated momenta
* should be stored in the meMomenta() vector. Derived classes
* must call this method once internal degrees of freedom are setup
* and finally return the result of this method.
*/
virtual bool generateKinematics(const double * r);
/**
* The number of internal degreed of freedom used in the matrix
* element.
*/
virtual int nDim() const;
/**
* The number of internal degrees of freedom used in the matrix
* element for generating a Born phase space point
*/
virtual int nDimBorn() const;
/**
* Return true, if this matrix element will generate momenta for the
* incoming partons itself. The matrix element is required to store
* the incoming parton momenta in meMomenta()[0,1]. No mapping in
* tau and y is performed by the PartonExtractor object, if a
* derived class returns true here. The phase space jacobian is to
* include a factor 1/(x1 x2).
*/
virtual bool haveX1X2() const {
return
(phasespace() ? phasespace()->haveX1X2() : false) ||
diagrams().front()->partons().size() == 3;
}
/**
* Return true, if this matrix element expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const {
return
(phasespace() ? phasespace()->wantCMS() : true) &&
diagrams().front()->partons().size() != 3; }
/**
* Return the meMomenta as generated at the last
* phase space point.
*/
const vector<Lorentz5Momentum>& lastMEMomenta() const { return meMomenta(); }
/**
* Access the meMomenta.
*/
vector<Lorentz5Momentum>& lastMEMomenta() { return meMomenta(); }
//@}
/** @name Scale choices, couplings and PDFs */
//@{
/**
* Set the scale choice object
*/
void scaleChoice(Ptr<MatchboxScaleChoice>::ptr sc) { theScaleChoice = sc; }
/**
* Return the scale choice object
*/
Ptr<MatchboxScaleChoice>::tptr scaleChoice() const { return theScaleChoice; }
/**
* Set scales and alphaS
*/
void setScale() const;
/**
* Return the scale associated with the phase space point provided
* by the last call to setKinematics().
*/
virtual Energy2 scale() const { return lastScale(); }
/**
* Return the renormalization scale for the last generated phasespace point.
*/
virtual Energy2 factorizationScale() const;
/**
* Get the factorization scale factor
*/
virtual double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
/**
* Set the factorization scale factor
*/
void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
/**
* Return the (QCD) renormalization scale for the last generated phasespace point.
*/
virtual Energy2 renormalizationScale() const;
/**
* Get the renormalization scale factor
*/
virtual double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
/**
* Set the renormalization scale factor
*/
void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
/**
* Return the QED renormalization scale for the last generated phasespace point.
*/
virtual Energy2 renormalizationScaleQED() const;
/**
* Set veto scales on the particles at the given
* SubProcess which has been generated using this
* matrix element.
*/
virtual void setVetoScales(tSubProPtr) const;
/**
* Return true, if fixed couplings are used.
*/
bool fixedCouplings() const { return theFixedCouplings; }
/**
* Switch on fixed couplings.
*/
void setFixedCouplings(bool on = true) { theFixedCouplings = on; }
/**
* Return true, if fixed couplings are used.
*/
bool fixedQEDCouplings() const { return theFixedQEDCouplings; }
/**
* Switch on fixed couplings.
*/
void setFixedQEDCouplings(bool on = true) { theFixedQEDCouplings = on; }
/**
* Return the value of \f$\alpha_S\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaS(scale()).
*/
virtual double alphaS() const { return lastAlphaS(); }
/**
* Return the value of \f$\alpha_EM\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaEM(scale()).
*/
virtual double alphaEM() const { return lastAlphaEM(); }
/**
* Return true, if this matrix element provides the PDF
* weight for the first incoming parton itself.
*/
virtual bool havePDFWeight1() const {
return diagrams().front()->partons()[0]->coloured();
}
/**
* Return true, if this matrix element provides the PDF
* weight for the second incoming parton itself.
*/
virtual bool havePDFWeight2() const {
return diagrams().front()->partons()[1]->coloured();
}
/**
* Set the PDF weight.
*/
void getPDFWeight(Energy2 factorizationScale = ZERO) const;
/**
* Supply the PDF weight for the first incoming parton.
*/
double pdf1(Energy2 factorizationScale = ZERO,
double xEx = 1.) const;
/**
* Supply the PDF weight for the second incoming parton.
*/
double pdf2(Energy2 factorizationScale = ZERO,
double xEx = 1.) const;
//@}
/** @name Amplitude information and matrix element evaluation */
//@{
/**
* Return the amplitude.
*/
Ptr<MatchboxAmplitude>::tptr matchboxAmplitude() const { return theAmplitude; }
/**
* Set the amplitude.
*/
void matchboxAmplitude(Ptr<MatchboxAmplitude>::ptr amp) { theAmplitude = amp; }
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the symmetry factor for identical final state particles.
*/
virtual double finalStateSymmetry() const;
/**
* Return the normalizing factor for the matrix element averaged
* over quantum numbers and including running couplings.
*/
double me2Norm(unsigned int addAlphaS = 0) const;
/**
* Return the matrix element squared differential in the variables
* given by the last call to generateKinematics().
*/
virtual CrossSection dSigHatDR() const;
//@}
/** @name One-loop corrections */
//@{
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const;
/**
* Return true, if this matrix element is capable of calculating
* one-loop (QCD) corrections.
*/
virtual bool haveOneLoop() const;
/**
* Return true, if this matrix element only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const;
/**
* Return true, if one loop corrections have been calculated in
* dimensional reduction. Otherwise conventional dimensional
* regularization is assumed. Note that renormalization is always
* assumed to be MSbar.
*/
virtual bool isDR() const;
/**
* Return true, if one loop corrections are given in the conventions
* of the integrated dipoles.
*/
virtual bool isCS() const;
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const;
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const;
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const;
/**
* If defined, return the coefficient of the pole in epsilon^2
*/
virtual double oneLoopDoublePole() const;
/**
* If defined, return the coefficient of the pole in epsilon
*/
virtual double oneLoopSinglePole() const;
/**
* Return true, if cancellationn of epsilon poles should be checked.
*/
bool checkPoles() const { return theCheckPoles; }
/**
* Switch on checking of epsilon pole cancellation.
*/
void doCheckPoles() { theCheckPoles = true; }
/**
* Perform the check of epsilon pole cancellation. Results will be
* written to the log file, one per phasespace point.
*/
void logPoles() const;
/**
* Return the virtual corrections
*/
const vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() const {
return theVirtuals;
}
/**
* Return the virtual corrections
*/
vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() {
return theVirtuals;
}
/**
* Instruct this matrix element to include one-loop corrections
*/
void doOneLoop() { theOneLoop = true; }
/**
* Return true, if this matrix element includes one-loop corrections
*/
bool oneLoop() const { return theOneLoop; }
/**
* Instruct this matrix element to include one-loop corrections but
* no Born contributions
*/
void doOneLoopNoBorn() { theOneLoop = true; theOneLoopNoBorn = true; }
/**
* Return true, if this matrix element includes one-loop corrections
* but no Born contributions
*/
bool oneLoopNoBorn() const { return theOneLoopNoBorn || onlyOneLoop(); }
//@}
/** @name Dipole subtraction */
//@{
/**
* If this matrix element is considered a real
* emission matrix element, return all subtraction
* dipoles needed given a set of subtraction terms
* and underlying Born matrix elements to choose
* from.
*/
vector<Ptr<SubtractionDipole>::ptr>
getDipoles(const vector<Ptr<SubtractionDipole>::ptr>&,
const vector<Ptr<MatchboxMEBase>::ptr>&) const;
/**
* If this matrix element is considered a real emission matrix
* element, but actually neglecting a subclass of the contributing
* diagrams, return true if the given emitter-emission-spectator
* configuration should not be considered when setting up
* subtraction dipoles.
*/
virtual bool noDipole(int,int,int) const { return false; }
/**
* If this matrix element is considered an underlying Born matrix
* element in the context of a subtracted real emission, but
* actually neglecting a subclass of the contributing diagrams,
* return true if the given emitter-spectator configuration
* should not be considered when setting up subtraction dipoles.
*/
virtual bool noDipole(int,int) const { return false; }
/**
* Return the colour correlated matrix element squared with
* respect to the given two partons as appearing in mePartonData(),
* suitably scaled by sHat() to give a dimension-less number.
*/
virtual double colourCorrelatedME2(pair<int,int>) const;
/**
+ * Return the colour correlated matrix element squared in the
+ * large-N approximation with respect to the given two partons as
+ * appearing in mePartonData(), suitably scaled by sHat() to give a
+ * dimension-less number.
+ */
+ virtual double largeNColourCorrelatedME2(pair<int,int> ij,
+ Ptr<ColourBasis>::tptr largeNBasis) const;
+
+ /**
* Return the colour and spin correlated matrix element squared for
* the gluon indexed by the first argument using the given
* correlation tensor.
*/
virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
/**
* Return true, if colour correlated matrix elements should be calculated
* for later use
*/
bool getColourCorrelatedMEs() const { return theGetColourCorrelatedMEs; }
/**
* Switch on calculation of colour correlated matrix elements for
* later use
*/
void doColourCorrelatedMEs() { theGetColourCorrelatedMEs = true; }
/**
* Calculate colour correlated matrix elements for later use
*/
void storeColourCorrelatedMEs(double xme2 = -1.) const;
//@}
/** @name Caching and diagnostic information */
//@{
/**
* Set the ME cache object
*/
void cache(Ptr<MatchboxMECache>::ptr c) { theCache = c; }
/**
* Get the ME cache object
*/
Ptr<MatchboxMECache>::tptr cache() const { return theCache; }
/**
* Inform this matrix element that a new phase space
* point is about to be generated, so all caches should
* be flushed.
*/
virtual void flushCaches();
/**
* Return true, if the matrix element needs to be
* recalculated for the given phase space point.
* If not, return the cached value in the given reference.
*/
bool calculateME2(double& xme2,
const pair<int,int>& corr = make_pair(0,0)) const {
if ( !cache() ) {
xme2 = 0.;
return true;
}
cache()->setXComb(lastXCombPtr());
return cache()->calculateME2(xme2,corr);
}
/**
* Cache a calculated matrix element
* for the last phase space point.
*/
void cacheME2(double xme2,
const pair<int,int>& corr = make_pair(0,0)) const {
if ( !cache() )
return;
cache()->cacheME2(xme2,corr);
}
/**
* Return true, if verbose
*/
bool verbose() const { return theVerbose; }
/**
* Switch on diagnostic information.
*/
void setVerbose(bool on = true) { theVerbose = on; }
/**
* Dump the setup to an ostream
*/
void print(ostream&) const;
/**
* Print debug information on the last event
*/
virtual void printLastEvent(ostream&) const;
/**
* Write out diagnostic information for
* generateKinematics
*/
void logGenerateKinematics(const double * r) const;
/**
* Write out diagnostic information for
* setting scales
*/
void logSetScale() const;
/**
* Write out diagnostic information for
* pdf evaluation
*/
void logPDFWeight() const;
/**
* Write out diagnostic information for
* me2 evaluation
*/
void logME2() const;
/**
* Write out diagnostic information
* for dsigdr evaluation
*/
void logDSigHatDR() const;
//@}
/** @name Reweight objects */
//@{
/**
* Insert a reweight object
*/
void addReweight(Ptr<MatchboxReweightBase>::ptr rw) { theReweights.push_back(rw); }
/**
* Return the reweights
*/
const vector<Ptr<MatchboxReweightBase>::ptr>& reweights() const { return theReweights; }
/**
* Access the reweights
*/
vector<Ptr<MatchboxReweightBase>::ptr>& reweights() { return theReweights; }
//@}
/** @name Methods used to setup MatchboxMEBase objects */
//@{
/**
* Return true if this object needs to be initialized before all
* other objects (except those for which this function also returns
* true). This default version always returns false, but subclasses
* may override it to return true.
*/
virtual bool preInitialize() const { return true; }
/**
* Clone this matrix element.
*/
Ptr<MatchboxMEBase>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
void cloneDependencies(const std::string& prefix = "");
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
protected:
/**
* The final state symmetry factors.
*/
mutable map<tStdXCombPtr,double> symmetryFactors;
private:
/**
* A vector of reweight objects the sum of which
* should be applied to reweight this matrix element
*/
vector<Ptr<MatchboxReweightBase>::ptr> theReweights;
/**
* The phase space generator to be used.
*/
Ptr<MatchboxPhasespace>::ptr thePhasespace;
/**
* The amplitude to be used
*/
Ptr<MatchboxAmplitude>::ptr theAmplitude;
/**
* The diagram generator to be used.
*/
Ptr<Tree2toNGenerator>::ptr theDiagramGenerator;
/**
* The process data object to be used
*/
Ptr<ProcessData>::ptr theProcessData;
/**
* The scale choice object
*/
Ptr<MatchboxScaleChoice>::ptr theScaleChoice;
/**
* The ME cache object
*/
Ptr<MatchboxMECache>::ptr theCache;
/**
* The virtual corrections.
*/
vector<Ptr<MatchboxInsertionOperator>::ptr> theVirtuals;
/**
* The subprocesses to be considered, if a diagram generator is
* present.
*/
vector<PDVector> theSubprocesses;
/**
* The factorization scale factor.
*/
double theFactorizationScaleFactor;
/**
* The renormalization scale factor.
*/
double theRenormalizationScaleFactor;
/**
* Wether or not diagnostic information
* should be written to the generator log
*/
bool theVerbose;
/**
* Use non-running couplings.
*/
bool theFixedCouplings;
/**
* Use non-running couplings.
*/
bool theFixedQEDCouplings;
/**
* The number of light flavours, this matrix
* element is calculated for.
*/
unsigned int theNLight;
/**
* True, if colour correlated matrix elements should be calculated
* for later use
*/
bool theGetColourCorrelatedMEs;
/**
* True, if cancellationn of epsilon poles should be checked.
*/
bool theCheckPoles;
/**
* True, if this matrix element includes one-loop corrections
*/
bool theOneLoop;
/**
* True, if this matrix element includes one-loop corrections
* but no Born contributions
*/
bool theOneLoopNoBorn;
/**
* Map xcomb's to storage of Born matrix elements squared.
*/
mutable map<tStdXCombPtr,double> bornMEs;
/**
* Map xcomb's to storage of colour correlated matrix elements.
*/
mutable map<tStdXCombPtr,map<pair<int,int>,double> > colourCorrelatedMEs;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxMEBase & operator=(const MatchboxMEBase &);
};
}
#endif /* HERWIG_MatchboxMEBase_H */
diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.cc b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
--- a/MatrixElement/Matchbox/Matching/DipoleMatching.cc
+++ b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
@@ -1,87 +1,124 @@
// -*- C++ -*-
//
// DipoleMatching.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleMatching class.
//
#include "DipoleMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
-#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
using namespace Herwig;
-DipoleMatching::DipoleMatching() {}
+DipoleMatching::DipoleMatching()
+ : theShowerKernels(true) {}
DipoleMatching::~DipoleMatching() {}
IBPtr DipoleMatching::clone() const {
return new_ptr(*this);
}
IBPtr DipoleMatching::fullclone() const {
return new_ptr(*this);
}
CrossSection DipoleMatching::dSigHatDR() const {
- double xme2 = dipole()->me2();
+ double xme2 = 0.;
+
+ if ( theShowerKernels ) {
+ xme2 = dipole()->me2();
+ } else {
+ pair<int,int> ij(dipole()->bornEmitter(),
+ dipole()->bornSpectator());
+ double ccme2 =
+ dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis);
+ xme2 = dipole()->me2Avg(-ccme2);
+ }
+
xme2 /= dipole()->underlyingBornME()->lastXComb().lastAlphaS();
xme2 *= bornPDFWeight(dipole()->underlyingBornME()->lastScale());
return
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
}
double DipoleMatching::me2() const {
throw Exception() << "Not intented to use. Disable the ShowerApproximationGenerator."
<< Exception::abortnow;
return 0.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
-void DipoleMatching::persistentOutput(PersistentOStream &) const {}
+void DipoleMatching::persistentOutput(PersistentOStream & os) const {
+ os << theShowerKernels << theLargeNBasis;
+}
-void DipoleMatching::persistentInput(PersistentIStream &, int) {}
+void DipoleMatching::persistentInput(PersistentIStream & is, int) {
+ is >> theShowerKernels >> theLargeNBasis;
+}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<DipoleMatching,Herwig::ShowerApproximation>
describeHerwigDipoleMatching("Herwig::DipoleMatching", "HwMatchbox.so");
void DipoleMatching::Init() {
static ClassDocumentation<DipoleMatching> documentation
- ("DipoleMatching implements naive NLO matching with the dipole shower.");
+ ("DipoleMatching implements NLO matching with the dipole shower.");
+
+ static Reference<DipoleMatching,ColourBasis> interfaceLargeNBasis
+ ("LargeNBasis",
+ "Set the large-N colour basis implementation.",
+ &DipoleMatching::theLargeNBasis, false, false, true, true, false);
+
+
+ static Switch<DipoleMatching,bool> interfaceShowerKernels
+ ("ShowerKernels",
+ "Switch between exact and shower approximated dipole functions.",
+ &DipoleMatching::theShowerKernels, true, false, false);
+ static SwitchOption interfaceShowerKernelsOn
+ (interfaceShowerKernels,
+ "On",
+ "Switch to shower approximated dipole functions.",
+ true);
+ static SwitchOption interfaceShowerKernelsOff
+ (interfaceShowerKernels,
+ "Off",
+ "Switch to full dipole functions.",
+ false);
}
diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.h b/MatrixElement/Matchbox/Matching/DipoleMatching.h
--- a/MatrixElement/Matchbox/Matching/DipoleMatching.h
+++ b/MatrixElement/Matchbox/Matching/DipoleMatching.h
@@ -1,122 +1,134 @@
// -*- C++ -*-
//
// DipoleMatching.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_DipoleMatching_H
#define Herwig_DipoleMatching_H
//
// This is the declaration of the DipoleMatching class.
//
#include "Herwig++/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
+#include "Herwig++/MatrixElement/Matchbox/Utility/ColourBasis.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief DipoleMatching implements naive NLO matching with the dipole shower.
*
*/
class DipoleMatching: public Herwig::ShowerApproximation {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleMatching();
/**
* The destructor.
*/
virtual ~DipoleMatching();
//@}
public:
/**
* Return the shower approximation to the real emission cross
* section for the given pair of Born and real emission
* configurations.
*/
virtual CrossSection dSigHatDR() const;
/**
* Return the shower approximation splitting kernel for the given
* pair of Born and real emission configurations in units of the
* Born center of mass energy squared, and including a weight to
* project onto the splitting given by the dipole used.
*/
virtual double me2() const;
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleMatching & operator=(const DipoleMatching &);
+ /**
+ * True, if the shower kernels should be reproduced.
+ */
+ bool theShowerKernels;
+
+ /**
+ * A large-N colour basis to be used when reproducing the shower
+ * kernels.
+ */
+ Ptr<ColourBasis>::ptr theLargeNBasis;
+
};
}
#endif /* Herwig_DipoleMatching_H */
diff --git a/MatrixElement/Matchbox/Utility/ColourBasis.cc b/MatrixElement/Matchbox/Utility/ColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/ColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/ColourBasis.cc
@@ -1,1151 +1,1167 @@
// -*- C++ -*-
//
// ColourBasis.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ColourBasis class.
//
#include "ColourBasis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <iterator>
using std::ostream_iterator;
#include "DiagramDrawer.h"
using namespace Herwig;
using boost::numeric::ublas::trans;
using boost::numeric::ublas::conj;
using boost::numeric::ublas::row;
using boost::numeric::ublas::column;
using boost::numeric::ublas::prod;
ColourBasis::ColourBasis()
- : theSearchPath("."),didRead(false), didWrite(false) {}
+ : theLargeN(false), theSearchPath("."), didRead(false), didWrite(false) {}
ColourBasis::~ColourBasis() {
for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::iterator cl =
theColourLineMap.begin(); cl != theColourLineMap.end(); ++cl ) {
for ( vector<ColourLines*>::iterator c = cl->second.begin();
c != cl->second.end(); ++c ) {
if ( *c )
delete *c;
}
}
theColourLineMap.clear();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
bool ColourBasis::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
return colourConnected(basis,idColoured,idAntiColoured,a);
}
const string& ColourBasis::ordering(const cPDVector& sub,
const map<size_t,size_t>& colourToAmplitude,
size_t tensorId) {
const vector<PDT::Colour>& basis = normalOrderedLegs(sub);
map<size_t,string>& orderings = theOrderingIdentifiers[basis][colourToAmplitude];
if ( orderings.empty() ) {
map<size_t,vector<vector<size_t> > > tensors =
basisList(basis);
for ( map<size_t,vector<vector<size_t> > >::const_iterator t =
tensors.begin(); t != tensors.end(); ++t ) {
ostringstream oid;
for ( vector<vector<size_t> >::const_iterator s = t->second.begin();
s != t->second.end(); ++s ) {
oid << "[";
for ( vector<size_t>::const_iterator l = s->begin();
l != s->end(); ++l ) {
map<size_t,size_t>::const_iterator trans =
colourToAmplitude.find(*l);
assert(trans != colourToAmplitude.end());
oid << trans->second << (l != --(s->end()) ? "," : "");
}
oid << "]";
}
orderings[t->first] = oid.str();
}
}
return orderings[tensorId];
}
vector<PDT::Colour> ColourBasis::normalOrderMap(const cPDVector& sub) {
vector<PDT::Colour> allLegs = projectColour(sub);
vector<PDT::Colour> legs = normalOrder(allLegs);
if ( allLegs[0] == PDT::Colour3 )
allLegs[0] = PDT::Colour3bar;
else if ( allLegs[0] == PDT::Colour3bar )
allLegs[0] = PDT::Colour3;
if ( allLegs[1] == PDT::Colour3 )
allLegs[1] = PDT::Colour3bar;
else if ( allLegs[1] == PDT::Colour3bar )
allLegs[1] = PDT::Colour3;
if ( theIndexMap.find(sub) == theIndexMap.end() ) {
map<size_t,size_t> trans;
vector<PDT::Colour> checkLegs = legs;
size_t n = checkLegs.size();
for ( size_t i = 0; i < allLegs.size(); ++i ) {
size_t j = 0;
while ( checkLegs[j] != allLegs[i] ) {
++j; if ( j == n ) break;
}
if ( j == n ) continue;
trans[i] = j;
checkLegs[j] = PDT::ColourUndefined;
}
theIndexMap[sub] = trans;
}
return legs;
}
const vector<PDT::Colour>& ColourBasis::normalOrderedLegs(const cPDVector& sub) const {
static vector<PDT::Colour> empty;
map<cPDVector,vector<PDT::Colour> >::const_iterator n =
theNormalOrderedLegs.find(sub);
if ( n != theNormalOrderedLegs.end() )
return n->second;
return empty;
}
size_t ColourBasis::prepare(const cPDVector& sub,
bool noCorrelations) {
vector<PDT::Colour> legs = normalOrderMap(sub);
bool doPrepare = false;
if ( theNormalOrderedLegs.find(sub) == theNormalOrderedLegs.end() )
theNormalOrderedLegs[sub] = legs;
if ( theScalarProducts.find(legs) == theScalarProducts.end() )
doPrepare = true;
if ( doPrepare )
doPrepare = !readBasis(legs);
size_t dim = doPrepare ? prepareBasis(legs) : theScalarProducts[legs].size1();
if ( theCharges.find(legs) != theCharges.end() )
return dim;
if ( !doPrepare && noCorrelations )
return dim;
symmetric_matrix<double,upper>& sp =
theScalarProducts.insert(make_pair(legs,symmetric_matrix<double,upper>(dim,dim))).first->second;
for ( size_t a = 0; a < dim; ++a )
for ( size_t b = a; b < dim; ++b )
sp(a,b) = scalarProduct(a,b,legs);
if ( noCorrelations )
return dim;
vector<PDT::Colour> legsPlus = legs;
legsPlus.push_back(PDT::Colour8);
legsPlus = normalOrder(legsPlus);
bool doPreparePlus = theScalarProducts.find(legsPlus) == theScalarProducts.end();
size_t dimPlus = doPreparePlus ? prepareBasis(legsPlus) : theScalarProducts[legsPlus].size1();
symmetric_matrix<double,upper>& spPlus =
doPreparePlus ?
theScalarProducts.insert(make_pair(legsPlus,symmetric_matrix<double,upper>(dimPlus,dimPlus))).first->second :
theScalarProducts[legsPlus];
if ( doPreparePlus ) {
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = a; b < dimPlus; ++b )
spPlus(a,b) = scalarProduct(a,b,legsPlus);
}
typedef map<size_t,compressed_matrix<double> > cMap;
cMap& cm = theCharges.insert(make_pair(legs,cMap())).first->second;
typedef map<size_t,vector<pair<size_t,size_t> > > ccMap;
ccMap& ccm = theChargeNonZeros.insert(make_pair(legs,ccMap())).first->second;
tmp.resize(dimPlus,dim);
for ( size_t i = 0; i < legs.size(); ++i ) {
size_t nonZero = 0;
vector<pair<size_t,size_t> > nonZeros;
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = 0; b < dim; ++b ) {
tmp(a,b) = tMatrixElement(i,a,b,legsPlus,legs);
if ( tmp(a,b) != 0. ) {
++nonZero;
nonZeros.push_back(make_pair(a,b));
}
}
ccm.insert(make_pair(i,nonZeros));
compressed_matrix<double>& tm =
cm.insert(make_pair(i,compressed_matrix<double>(dimPlus,dim,nonZero))).first->second;
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = 0; b < dim; ++b ) {
if ( tmp(a,b) != 0. )
tm(a,b) = tmp(a,b);
}
}
map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& xm = theCorrelators[legs];
for ( size_t i = 0; i < legs.size(); ++i )
for ( size_t j = i+1; j < legs.size(); ++j ) {
symmetric_matrix<double,upper>& mm =
xm.insert(make_pair(make_pair(i,j),symmetric_matrix<double,upper>(dim,dim))).first->second;
chargeProduct(cm[i],ccm[i],spPlus,cm[j],ccm[j],mm);
}
return dim;
}
void ColourBasis::chargeProduct(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const symmetric_matrix<double,upper>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
symmetric_matrix<double,upper>& result) const {
for ( size_t i = 0; i < result.size1(); ++i )
for ( size_t j = i; j < result.size1(); ++j )
result(i,j) = 0.;
for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
i != tiNonZero.end(); ++i )
for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
j != tjNonZero.end(); ++j ) {
if ( j->second < i->second )
continue;
result(i->second,j->second) +=
ti(i->first,i->second)*tj(j->first,j->second)*X(i->first,j->first);
}
}
void ColourBasis::chargeProductAdd(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const matrix<Complex>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
matrix<Complex>& result,
double factor) const {
for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
i != tiNonZero.end(); ++i )
for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
j != tjNonZero.end(); ++j ) {
result(i->first,j->first) += factor*
ti(i->first,i->second)*tj(j->first,j->second)*X(i->second,j->second);
}
}
string ColourBasis::cfstring(const list<list<pair<int,bool> > >& flow) {
ostringstream out("");
for ( list<list<pair<int,bool> > >::const_iterator line =
flow.begin(); line != flow.end(); ++line ) {
for ( list<pair<int,bool> >::const_iterator node =
line->begin(); node != line->end(); ++node ) {
out << (node->second ? "-" : "") << (node->first+1) << " ";
}
if ( line != --(flow.end()) )
out << ", ";
}
return out.str();
}
vector<string> ColourBasis::makeFlows(Ptr<Tree2toNDiagram>::tcptr diag,
size_t dim) const {
vector<string> res(dim);
list<list<list<pair<int,bool> > > > fdata =
colourFlows(diag);
cPDVector ext;
tcPDVector dext = diag->external();
copy(dext.begin(),dext.end(),back_inserter(ext));
vector<PDT::Colour> colouredLegs =
normalOrder(projectColour(ext));
for ( list<list<list<pair<int,bool> > > >::const_iterator flow =
fdata.begin(); flow != fdata.end(); ++flow ) {
for ( size_t i = 0; i < dim; ++i ) {
bool matches = true;
for ( list<list<pair<int,bool> > >::const_iterator line =
flow->begin(); line != flow->end(); ++line ) {
pair<int,bool> front(diag->externalId(line->front().first),line->front().second);
if ( front.first < 2 )
front.second = !front.second;
pair<int,bool> back(diag->externalId(line->back().first),line->back().second);
if ( back.first < 2 )
back.second = !back.second;
if ( !colourConnected(ext,colouredLegs,front,back,i) ) {
matches = false;
break;
}
}
if ( matches ) {
res[i] = cfstring(*flow);
}
}
}
bool gotone = false;
for ( vector<string>::const_iterator f = res.begin();
f != res.end(); ++f ) {
if ( *f != "" ) {
gotone = true;
break;
}
}
if ( !gotone ) {
generator()->log() << "warning no color flow found for diagram\n";
DiagramDrawer::drawDiag(generator()->log(),*diag);
}
return res;
}
size_t ColourBasis::prepare(const MEBase::DiagramVector& diags,
bool noCorrelations) {
size_t dim = 0;
for ( MEBase::DiagramVector::const_iterator d = diags.begin();
d != diags.end(); ++d ) {
Ptr<Tree2toNDiagram>::tcptr dd = dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(*d);
assert(dd);
dim = prepare(dd->partons(),noCorrelations);
if ( !haveColourFlows() || theFlowMap.find(dd) != theFlowMap.end() )
continue;
theFlowMap[dd] = makeFlows(dd,dim);
}
return dim;
}
bool matchEnd(int a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag) {
if ( a != b.first )
return false;
if ( b.first != diag->nSpace()-1 ) {
return
!b.second ?
diag->allPartons()[b.first]->hasColour() :
diag->allPartons()[b.first]->hasAntiColour();
} else {
return
!b.second ?
diag->allPartons()[b.first]->hasAntiColour() :
diag->allPartons()[b.first]->hasColour();
}
return false;
}
bool findPath(pair<int,bool> a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag,
list<pair<int,bool> >& path,
bool backward) {
assert(a.first==0 ? !backward : true);
if ( path.empty() )
path.push_back(a);
if ( !backward ) {
if ( diag->children(a.first).first == -1 )
return matchEnd(a.first,b,diag);
pair<int,int> children = diag->children(a.first);
bool cc = (children.first == diag->nSpace()-1);
if ( diag->allPartons()[children.first]->coloured() )
if ( !cc ?
(!a.second ?
diag->allPartons()[children.first]->hasColour() :
diag->allPartons()[children.first]->hasAntiColour()) :
(!a.second ?
diag->allPartons()[children.first]->hasAntiColour() :
diag->allPartons()[children.first]->hasColour()) ) {
pair<int,bool> next(children.first,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
cc = (children.second == diag->nSpace()-1);
if ( diag->allPartons()[children.second]->coloured() )
if ( !cc ?
(!a.second ?
diag->allPartons()[children.second]->hasColour() :
diag->allPartons()[children.second]->hasAntiColour()) :
(!a.second ?
diag->allPartons()[children.second]->hasAntiColour() :
diag->allPartons()[children.second]->hasColour()) ) {
pair<int,bool> next(children.second,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
if ( path.size() == 1 )
path.pop_back();
return false;
} else {
int parent = diag->parent(a.first);
pair<int,int> neighbours = diag->children(parent);
int neighbour = a.first == neighbours.first ? neighbours.second : neighbours.first;
if ( matchEnd(parent,b,diag) ) {
path.push_back(b);
return true;
}
if ( matchEnd(neighbour,b,diag) ) {
path.push_back(b);
return true;
}
if ( diag->allPartons()[neighbour]->coloured() )
if ( a.second ?
diag->allPartons()[neighbour]->hasColour() :
diag->allPartons()[neighbour]->hasAntiColour() ) {
pair<int,bool> next(neighbour,!a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
if ( parent == 0 ) {
if ( path.size() == 1 )
path.pop_back();
return false;
}
if ( diag->allPartons()[parent]->coloured() )
if ( !a.second ?
diag->allPartons()[parent]->hasColour() :
diag->allPartons()[parent]->hasAntiColour() ) {
pair<int,bool> next(parent,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,true) ) {
path.pop_back();
} else return true;
}
if ( path.size() == 1 )
path.pop_back();
return false;
}
return false;
}
list<pair<int,bool> > ColourBasis::colouredPath(pair<int,bool> a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag) {
list<pair<int,bool> > res;
if ( a.first == b.first )
return res;
bool aIn = (a.first < 2);
bool bIn = (b.first < 2);
if ( (aIn && bIn) || (!aIn && !bIn) )
if ( (a.second && b.second) ||
(!a.second && !b.second) )
return res;
if ( (aIn && !bIn) || (!aIn && bIn) )
if ( (!a.second && b.second) ||
(a.second && !b.second) )
return res;
if ( a.first > b.first )
swap(a,b);
a.first = diag->diagramId(a.first);
b.first = diag->diagramId(b.first);
if ( a.first == diag->nSpace()-1 )
a.second = !a.second;
if ( b.first == diag->nSpace()-1 )
b.second = !b.second;
if ( !findPath(a,b,diag,res,a.first != 0) )
return res;
if ( b.first == diag->nSpace()-1 ) {
res.back().second = !res.back().second;
}
if ( a.first == diag->nSpace()-1 ) {
res.front().second = !res.front().second;
}
return res;
}
list<list<list<pair<int,bool> > > >
ColourBasis::colourFlows(Ptr<Tree2toNDiagram>::tcptr diag) {
vector<pair<int,bool> > connectSource;
vector<pair<int,bool> > connectSink;
for ( size_t i = 0; i != diag->partons().size(); ++i ) {
if ( i < 2 && diag->partons()[i]->hasAntiColour() )
connectSource.push_back(make_pair(i,true));
if ( i < 2 && diag->partons()[i]->hasColour() )
connectSink.push_back(make_pair(i,false));
if ( i > 1 && diag->partons()[i]->hasColour() )
connectSource.push_back(make_pair(i,false));
if ( i > 1 && diag->partons()[i]->hasAntiColour() )
connectSink.push_back(make_pair(i,true));
}
assert(connectSource.size() == connectSink.size());
list<list<list<pair<int,bool> > > > ret;
do {
vector<pair<int,bool> >::iterator source =
connectSource.begin();
vector<pair<int,bool> >::iterator sink =
connectSink.begin();
list<list<pair<int,bool> > > res;
for ( ; source != connectSource.end(); ++source, ++sink ) {
if ( source->first == sink->first ) {
res.clear();
break;
}
list<pair<int,bool> > line =
colouredPath(*source,*sink,diag);
if ( line.empty() ) {
res.clear();
break;
}
res.push_back(line);
}
if ( !res.empty() ) {
// check, if all dressed properly
vector<pair<int,int> > dressed((*diag).allPartons().size(),make_pair(0,0));
for ( size_t p = 0; p < diag->allPartons().size(); ++p ) {
if ( diag->allPartons()[p]->hasColour() &&
!diag->allPartons()[p]->hasAntiColour() )
dressed[p].first = 1;
if ( diag->allPartons()[p]->hasAntiColour() &&
!diag->allPartons()[p]->hasColour() )
dressed[p].second = 1;
if ( diag->allPartons()[p]->hasAntiColour() &&
diag->allPartons()[p]->hasColour() ) {
dressed[p].first = 1; dressed[p].second = 1;
}
}
for ( list<list<pair<int,bool> > >::const_iterator l = res.begin();
l != res.end(); ++l ) {
for ( list<pair<int,bool> >::const_iterator n = l->begin();
n != l->end(); ++n ) {
if ( !(n->second) )
dressed[n->first].first -= 1;
else
dressed[n->first].second -= 1;
}
}
for ( vector<pair<int,int> >::const_iterator d = dressed.begin();
d != dressed.end(); ++d ) {
if ( d->first != 0 || d->second != 0 ) {
res.clear();
break;
}
}
if ( !res.empty() )
ret.push_back(res);
}
} while ( std::next_permutation(connectSink.begin(),connectSink.end()) );
return ret;
}
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >&
ColourBasis::colourLineMap() {
if ( !theColourLineMap.empty() )
return theColourLineMap;
for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<string> >::const_iterator cl =
theFlowMap.begin(); cl != theFlowMap.end(); ++cl ) {
vector<ColourLines*> clines(cl->second.size());
for ( size_t k = 0; k < cl->second.size(); ++k ) {
if ( cl->second[k] == "" ) {
clines[k] = 0;
continue;
}
clines[k] = new ColourLines(cl->second[k]);
}
theColourLineMap[cl->first] = clines;
}
return theColourLineMap;
}
Selector<const ColourLines *> ColourBasis::colourGeometries(tcDiagPtr diag,
const map<vector<int>,CVector>& amps) {
Ptr<Tree2toNDiagram>::tcptr dd =
dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
assert(dd && theFlowMap.find(dd) != theFlowMap.end());
const vector<ColourLines*>& cl = colourLineMap()[dd];
Selector<const ColourLines *> sel;
size_t dim = amps.begin()->second.size();
assert(dim == cl.size());
double w = 0.;
for ( size_t i = 0; i < dim; ++i ) {
if ( !cl[i] )
continue;
w = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a )
w += real(conj((a->second)(i))*((a->second)(i)));
if ( w > 0. )
sel.insert(w,cl[i]);
}
assert(!sel.empty());
return sel;
}
const symmetric_matrix<double,upper>& ColourBasis::scalarProducts(const cPDVector& sub) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ScalarProductMap::const_iterator spit =
theScalarProducts.find(lit->second);
assert(spit != theScalarProducts.end());
return spit->second;
}
const compressed_matrix<double>& ColourBasis::charge(const cPDVector& sub, size_t iIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ChargeMap::const_iterator ct =
theCharges.find(lit->second);
assert(ct != theCharges.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
size_t i = trans->second.find(iIn)->second;
map<size_t,compressed_matrix<double> >::const_iterator cit
= ct->second.find(i);
assert(cit != ct->second.end());
return cit->second;
}
const vector<pair<size_t,size_t> >& ColourBasis::chargeNonZero(const cPDVector& sub, size_t iIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ChargeNonZeroMap::const_iterator ct =
theChargeNonZeros.find(lit->second);
assert(ct != theChargeNonZeros.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
size_t i = trans->second.find(iIn)->second;
map<size_t,vector<pair<size_t,size_t> > >::const_iterator cit
= ct->second.find(i);
assert(cit != ct->second.end());
return cit->second;
}
const symmetric_matrix<double,upper>& ColourBasis::correlator(const cPDVector& sub,
const pair<size_t,size_t>& ijIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
CorrelatorMap::const_iterator cit =
theCorrelators.find(lit->second);
assert(cit != theCorrelators.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
pair<size_t,size_t> ij(trans->second.find(ijIn.first)->second,
trans->second.find(ijIn.second)->second);
if ( ij.first > ij.second )
swap(ij.first,ij.second);
map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator cijit
= cit->second.find(ij);
assert(cijit != cit->second.end());
return cijit->second;
}
double ColourBasis::me2(const cPDVector& sub,
const map<vector<int>,CVector>& amps) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double res = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a ) {
res += real(inner_prod(conj(a->second),prod(sp,a->second)));
}
return res;
}
double ColourBasis::interference(const cPDVector& sub,
const map<vector<int>,CVector>& amps1,
const map<vector<int>,CVector>& amps2) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double res = 0.;
map<vector<int>,CVector>::const_iterator a = amps1.begin();
map<vector<int>,CVector>::const_iterator b = amps2.begin();
for ( ; a != amps1.end(); ++a, ++b ) {
assert(a->first == b->first);
res += 2.*real(inner_prod(conj(a->second),prod(sp,b->second)));
}
assert(!isnan(res));
return res;
}
double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const map<vector<int>,CVector>& amps) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
double res = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a ) {
res += real(inner_prod(conj(a->second),prod(cij,a->second)));
}
return res;
}
Complex ColourBasis::interference(const cPDVector& sub,
const CVector& left,
const CVector& right) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
return inner_prod(conj(left),prod(sp,right));
}
Complex ColourBasis::colourCorrelatedInterference(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const CVector& left,
const CVector& right) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
return inner_prod(conj(left),prod(cij,right));
}
double ColourBasis::me2(const cPDVector& sub,
const matrix<Complex>& amp) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double tr = 0;
size_t n = amp.size1();
for ( size_t i = 0; i < n; ++i ) {
tr += real(inner_prod(row(sp,i),column(amp,i)));
}
return tr;
}
double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const matrix<Complex>& amp) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
double tr = 0;
size_t n = amp.size1();
for ( size_t i = 0; i < n; ++i ) {
tr += real(inner_prod(row(cij,i),column(amp,i)));
}
return tr;
}
struct pickColour {
PDT::Colour operator()(tcPDPtr p) const {
return p->iColour();
}
};
vector<PDT::Colour> ColourBasis::projectColour(const cPDVector& sub) const {
vector<PDT::Colour> res(sub.size());
transform(sub.begin(),sub.end(),res.begin(),pickColour());
return res;
}
vector<PDT::Colour> ColourBasis::normalOrder(const vector<PDT::Colour>& legs) const {
vector<PDT::Colour> crosslegs = legs;
if ( crosslegs[0] == PDT::Colour3 )
crosslegs[0] = PDT::Colour3bar;
else if ( crosslegs[0] == PDT::Colour3bar )
crosslegs[0] = PDT::Colour3;
if ( crosslegs[1] == PDT::Colour3 )
crosslegs[1] = PDT::Colour3bar;
else if ( crosslegs[1] == PDT::Colour3bar )
crosslegs[1] = PDT::Colour3;
int n3 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour3));
int n8 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour8));
vector<PDT::Colour> ordered(2*n3+n8,PDT::Colour8);
int i = 0;
while ( i < 2*n3 ) {
ordered[i] = PDT::Colour3;
ordered[i+1] = PDT::Colour3bar;
i+=2;
}
return ordered;
}
string ColourBasis::file(const vector<PDT::Colour>& sub) const {
string res = "";
for ( vector<PDT::Colour>::const_iterator lit = sub.begin();
lit != sub.end(); ++lit ) {
if ( *lit == PDT::Colour3 )
res += "3";
if ( *lit == PDT::Colour3bar )
res += "3bar";
if ( *lit == PDT::Colour8 )
res += "8";
}
if ( largeN() )
res += "largeN";
return res;
}
void ColourBasis::writeBasis(const string& prefix) const {
if ( didWrite )
return;
set<vector<PDT::Colour> > legs;
for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
= theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit ) {
legs.insert(lit->second);
}
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
known != legs.end(); ++known ) {
string fname = searchPath + prefix + file(*known) + ".cdat";
ifstream check(fname.c_str());
if ( check ) continue;
ofstream out(fname.c_str());
if ( !out )
throw Exception() << "ColourBasis failed to open "
<< fname << " for storing colour basis information."
<< Exception::abortnow;
out << setprecision(18);
const symmetric_matrix<double,upper>& sp =
theScalarProducts.find(*known)->second;
write(sp,out);
if ( theCharges.find(*known) != theCharges.end() ) {
out << "#charges\n";
const map<size_t,compressed_matrix<double> >& tm =
theCharges.find(*known)->second;
const map<size_t,vector<pair<size_t,size_t> > >& tc =
theChargeNonZeros.find(*known)->second;
map<size_t,vector<pair<size_t,size_t> > >::const_iterator kc =
tc.begin();
for ( map<size_t,compressed_matrix<double> >::const_iterator k = tm.begin();
k != tm.end(); ++k, ++kc ) {
out << k->first << "\n";
write(k->second,out,kc->second);
}
const map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& cm =
theCorrelators.find(*known)->second;
for ( map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator k =
cm.begin(); k != cm.end(); ++k ) {
out << k->first.first << "\n" << k->first.second << "\n";
write(k->second,out);
}
} else {
out << "#nocharges\n";
}
out << flush;
}
didWrite = true;
}
bool ColourBasis::readBasis(const vector<PDT::Colour>& legs) {
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
string fname = searchPath + file(legs) + ".cdat";
ifstream in(fname.c_str());
if ( !in )
return false;
read(theScalarProducts[legs],in);
string tag; in >> tag;
if ( tag != "#nocharges" ) {
for ( size_t k = 0; k < legs.size(); ++k ) {
size_t i; in >> i;
read(theCharges[legs][i],in,theChargeNonZeros[legs][i]);
}
for ( size_t k = 0; k < legs.size()*(legs.size()-1)/2; ++k ) {
size_t i,j; in >> i >> j;
read(theCorrelators[legs][make_pair(i,j)],in);
}
}
readBasisDetails(legs);
return true;
}
void ColourBasis::readBasis() {
if ( didRead )
return;
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
set<vector<PDT::Colour> > legs;
for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
= theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit )
legs.insert(lit->second);
for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
known != legs.end(); ++known ) {
if ( theScalarProducts.find(*known) != theScalarProducts.end() )
continue;
string fname = searchPath + file(*known) + ".cdat";
if ( !readBasis(*known) )
throw Exception() << "ColourBasis failed to open "
<< fname << " for reading colour basis information."
<< Exception::abortnow;
}
didRead = true;
}
void ColourBasis::write(const symmetric_matrix<double,upper>& m, ostream& os) const {
os << m.size1() << "\n";
for ( size_t i = 0; i < m.size1(); ++i )
for ( size_t j = i; j < m.size1(); ++j )
os << m(i,j) << "\n";
os << flush;
}
void ColourBasis::read(symmetric_matrix<double,upper>& m, istream& is) {
size_t s; is >> s;
m.resize(s);
for ( size_t i = 0; i < m.size1(); ++i )
for ( size_t j = i; j < m.size1(); ++j )
is >> m(i,j);
}
void ColourBasis::write(const compressed_matrix<double>& m, ostream& os,
const vector<pair<size_t,size_t> >& nonZeros) const {
os << nonZeros.size() << "\n"
<< m.size1() << "\n"
<< m.size2() << "\n";
for ( vector<pair<size_t,size_t> >::const_iterator nz = nonZeros.begin();
nz != nonZeros.end(); ++nz )
os << nz->first << "\n" << nz->second << "\n"
<< m(nz->first,nz->second) << "\n";
os << flush;
}
void ColourBasis::read(compressed_matrix<double>& m, istream& is,
vector<pair<size_t,size_t> >& nonZeros) {
size_t nonZero, size1, size2;
is >> nonZero >> size1 >> size2;
nonZeros.resize(nonZero);
m = compressed_matrix<double>(size1,size2,nonZero);
for ( size_t k = 0; k < nonZero; ++k ) {
size_t i,j; double val;
is >> i >> j >> val;
nonZeros[k] = make_pair(i,j);
m(i,j) = val;
}
}
void ColourBasis::doinit() {
HandlerBase::doinit();
readBasis();
}
void ColourBasis::dofinish() {
HandlerBase::dofinish();
writeBasis();
}
void ColourBasis::doinitrun() {
HandlerBase::doinitrun();
readBasis();
}
void ColourBasis::persistentOutput(PersistentOStream & os) const {
- os << theSearchPath << theNormalOrderedLegs
+ os << theLargeN << theSearchPath << theNormalOrderedLegs
<< theIndexMap << theFlowMap << theOrderingIdentifiers;
writeBasis();
}
void ColourBasis::persistentInput(PersistentIStream & is, int) {
- is >> theSearchPath >> theNormalOrderedLegs
+ is >> theLargeN >> theSearchPath >> theNormalOrderedLegs
>> theIndexMap >> theFlowMap >> theOrderingIdentifiers;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<ColourBasis,HandlerBase>
describeColourBasis("Herwig::ColourBasis", "HwMatchbox.so");
void ColourBasis::Init() {
static ClassDocumentation<ColourBasis> documentation
("ColourBasis is an interface to a colour basis "
"implementation.");
static Parameter<ColourBasis,string> interfaceSearchPath
("SearchPath",
"Set the search path for pre-computed colour basis data.",
&ColourBasis::theSearchPath, ".",
false, false);
+ static Switch<ColourBasis,bool> interfaceLargeN
+ ("LargeN",
+ "Switch on or off large-N evaluation.",
+ &ColourBasis::theLargeN, false, false, false);
+ static SwitchOption interfaceLargeNOn
+ (interfaceLargeN,
+ "On",
+ "Work in N=infinity",
+ true);
+ static SwitchOption interfaceLargeNOff
+ (interfaceLargeN,
+ "Off",
+ "Work in N=3",
+ false);
+
}
diff --git a/MatrixElement/Matchbox/Utility/ColourBasis.h b/MatrixElement/Matchbox/Utility/ColourBasis.h
--- a/MatrixElement/Matchbox/Utility/ColourBasis.h
+++ b/MatrixElement/Matchbox/Utility/ColourBasis.h
@@ -1,525 +1,530 @@
// -*- C++ -*-
//
// ColourBasis.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ColourBasis_H
#define HERWIG_ColourBasis_H
//
// This is the declaration of the ColourBasis class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <iterator>
namespace Herwig {
using std::iterator_traits;
using std::distance;
using namespace ThePEG;
using boost::numeric::ublas::matrix;
using boost::numeric::ublas::symmetric_matrix;
using boost::numeric::ublas::compressed_matrix;
using boost::numeric::ublas::upper;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Define compolex vector from boost::uBLAS
*
*/
typedef boost::numeric::ublas::vector<Complex> CVector;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief ColourBasis is an interface to a colour basis
* implementation.
*
*/
class ColourBasis: public HandlerBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
ColourBasis();
/**
* The destructor.
*/
virtual ~ColourBasis();
//@}
public:
/**
* Prepare for the given sub process and return the basis
* dimensionality.
*/
size_t prepare(const cPDVector&, bool);
/**
* Prepare for the given diagrams.
*/
size_t prepare(const MEBase::DiagramVector&, bool);
/**
* Return the index map.
*/
const map<cPDVector,map<size_t,size_t> >& indexMap() const { return theIndexMap; }
/**
* Return a map of basis tensor indices to vectors identifying a
* certain ordering corresponding to the given colour structure. May
* not be supported by all colour basis implementations.
*/
virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) const {
return map<size_t,vector<vector<size_t> > >();
}
/**
* Given a physical subprocess, a colour to amplitude label map and
* a basis tensor index, return an identifier of the ordering
* coresponding to the given colour structure. This will only return
* sensible results for colour bases which implement the basisList
* query.
*/
const string& ordering(const cPDVector& sub,
const map<size_t,size_t>& colourToAmplitude,
size_t tensorId);
/**
* For the given subprocess and amplitude vectors
* calculate the amplitude squared.
*/
double me2(const cPDVector&, const map<vector<int>,CVector>&) const;
/**
* For the given subprocess and amplitude vectors
* calculate the interference.
*/
double interference(const cPDVector&,
const map<vector<int>,CVector>&,
const map<vector<int>,CVector>&) const;
/**
* For the given subprocess and amplitude vector
* calculate the colour correlated amplitude.
*/
double colourCorrelatedME2(const pair<size_t,size_t>&,
const cPDVector&,
const map<vector<int>,CVector>&) const;
/**
* For the given subprocess and amplitude vector
* calculate the amplitude squared.
*/
Complex interference(const cPDVector&,
const CVector&, const CVector&) const;
/**
* For the given subprocess and amplitude vector
* calculate the colour correlated amplitude.
*/
Complex colourCorrelatedInterference(const pair<size_t,size_t>&,
const cPDVector&,
const CVector&, const CVector&) const;
/**
* For the given subprocess and amplitude given as amp amp^\dagger
* calculate the amplitude squared.
*/
double me2(const cPDVector&, const matrix<Complex>&) const;
/**
* For the given subprocess and amplitude given as amp amp^\dagger
* calculate the colour correlated amplitude.
*/
double colourCorrelatedME2(const pair<size_t,size_t>&,
const cPDVector&,
const matrix<Complex>&) const;
/**
* Return the scalar product matrix for the given process.
*/
const symmetric_matrix<double,upper>& scalarProducts(const cPDVector&) const;
/**
* Return the matrix representation of a colour charge.
*/
const compressed_matrix<double>& charge(const cPDVector&, size_t) const;
/**
* Return the non-vanishing elements of a colour charge.
*/
const vector<pair<size_t,size_t> >& chargeNonZero(const cPDVector&, size_t) const;
/**
* Return the correlator matrix for the given process.
*/
const symmetric_matrix<double,upper>& correlator(const cPDVector&,
const pair<size_t,size_t>&) const;
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const { return false; }
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
*/
Selector<const ColourLines *> colourGeometries(tcDiagPtr diag,
const map<vector<int>,CVector>& amps);
/**
* Match colour representation.
*/
struct matchRep {
PDT::Colour m;
matchRep(PDT::Colour n)
: m(n) {}
bool operator()(PDT::Colour c) const {
return c == m;
}
};
/**
* Return true, if this basis is running in large-N mode
*/
- virtual bool largeN() const { return false; }
+ virtual bool largeN() const { return theLargeN; }
/**
* Convert particle data to colour information
*/
vector<PDT::Colour> projectColour(const cPDVector&) const;
/**
* Perform a normal ordering of the external legs. This default
* implementation assumes normal ordered legs as 3 3bar ... 3 3bar 8 ... 8
* while removing all non-coloured particles.
*/
virtual vector<PDT::Colour> normalOrder(const vector<PDT::Colour>&) const;
/**
* Determine the mapping of process to colour indices and return the
* normal ordered vector of colour indices
*/
vector<PDT::Colour> normalOrderMap(const cPDVector& sub);
/**
* Get the normal ordered legs
*/
const vector<PDT::Colour>& normalOrderedLegs(const cPDVector& sub) const;
/**
* Convert the legs to a string.
*/
string file(const vector<PDT::Colour>&) const;
/**
* Calculate T_i^\dagger X T_j
*/
void chargeProduct(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const symmetric_matrix<double,upper>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
symmetric_matrix<double,upper>& result) const;
/**
* Calculate T_i X T_j^\dagger
*/
void chargeProductAdd(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const matrix<Complex>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
matrix<Complex>& result,
double factor = 1.) const;
public:
/**
* Find a coloured path from a to b within the given diagram.
*/
static list<pair<int,bool> > colouredPath(pair<int,bool> a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr);
/**
* Get all colour flows for the given diagram.
*/
static list<list<list<pair<int,bool> > > > colourFlows(Ptr<Tree2toNDiagram>::tcptr);
/**
* Convert a flow to a string representation appropriate for
* ColourLines
*/
static string cfstring(const list<list<pair<int,bool> > >&);
protected:
/**
* Prepare the basis for the normal ordered legs and return the
* dimensionality of the basis.
*/
virtual size_t prepareBasis(const vector<PDT::Colour>&) = 0;
/**
* Return the scalar product of basis tensors labelled a and b in
* the basis used for the given normal ordered legs.
*/
virtual double scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const = 0;
/**
* Return the matrix element of a colour charge
* <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
* respect to aBasis and bBasis
*/
virtual double tMatrixElement(size_t i, size_t a, size_t b,
const vector<PDT::Colour>& aBasis,
const vector<PDT::Colour>& bBasis) const = 0;
/**
* Return true, if a large-N colour connection exists for the
* given external legs and basis tensor.
*/
virtual bool colourConnected(const cPDVector&,
const vector<PDT::Colour>&,
const pair<int,bool>&,
const pair<int,bool>&,
size_t) const;
/**
* Return true, if a large-N colour connection exists for the
* given external legs and basis tensor.
*/
virtual bool colourConnected(const vector<PDT::Colour>&,
int, int, size_t) const {
return false;
}
/**
* Match up colour flows for given diagram to basis tensors.
*/
vector<string> makeFlows(Ptr<Tree2toNDiagram>::tcptr, size_t) const;
/**
* Return the colour line map.
*/
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >&
colourLineMap();
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
//@}
private:
typedef map<vector<PDT::Colour>,symmetric_matrix<double,upper> >
ScalarProductMap;
typedef map<vector<PDT::Colour>,map<size_t,compressed_matrix<double> > > ChargeMap;
typedef map<vector<PDT::Colour>,map<size_t,vector<pair<size_t,size_t > > > > ChargeNonZeroMap;
typedef map<vector<PDT::Colour>,map<pair<size_t,size_t>,symmetric_matrix<double,upper> > > CorrelatorMap;
/**
+ * True, if this basis is running in large-N mode
+ */
+ bool theLargeN;
+
+ /**
* A search path for already calculated and stored matrices.
*/
string theSearchPath;
/**
* Map external legs to normal ordered versions
*/
map<cPDVector,vector<PDT::Colour> > theNormalOrderedLegs;
/**
* Index mappings to normal order from given leg assignments,
* indexed by the original leg assignment.
*/
map<cPDVector,map<size_t,size_t> > theIndexMap;
/**
* The scalar product matrix S_n = <c_{n,a}|c_{n,b}> , indexed
* by normal ordered leg assignments.
*/
ScalarProductMap theScalarProducts;
/**
* The colour charge matrices <c_{n+1,a}|T_i|c_{n,b}> indexed by
* the `n' normal ordered legs and the index i.
*/
ChargeMap theCharges;
/**
* The nonzero elements of the charge matrices.
*/
ChargeNonZeroMap theChargeNonZeros;
/**
* The correlator matrices T_i\cdot T_j -> T_i^\dagger S_{n+1} T_j
* with T_i = <c_{n+1,a}|T_i|c_{n,b}> indexed by the `n' basis
* normal ordered legs and indices i,j
*/
CorrelatorMap theCorrelators;
/**
* Map diagrams to colour flows indexed by basis tensor.
*/
map<Ptr<Tree2toNDiagram>::tcptr,vector<string> > theFlowMap;
/**
* Map diagrams to colour line objects.
*/
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> > theColourLineMap;
/**
* Store ordering identifiers
*/
map<vector<PDT::Colour>,map<map<size_t,size_t>,map<size_t,string> > > theOrderingIdentifiers;
/**
* Write out yet unknown basis computations.
*/
void writeBasis(const string& prefix = "") const;
/**
* Read in the basis computation which are supposed to be known.
*/
void readBasis();
/**
* Read in the basis computation which are supposed to be known.
*/
bool readBasis(const vector<PDT::Colour>&);
/**
* Gather any implementation dependend details when reading a basis
*/
virtual void readBasisDetails(const vector<PDT::Colour>&) {}
/**
* Write out symmetric matrices.
*/
void write(const symmetric_matrix<double,upper>&, ostream&) const;
/**
* Read in symmetric matrices.
*/
void read(symmetric_matrix<double,upper>&, istream&);
/**
* Write out compressed matrices.
*/
void write(const compressed_matrix<double>&, ostream&,
const vector<pair<size_t,size_t> >&) const;
/**
* Read in compressed matrices.
*/
void read(compressed_matrix<double>&, istream&,
vector<pair<size_t,size_t> >&);
/**
* True, if an attempt to read in basis information has been
* completed.
*/
bool didRead;
/**
* True, if an attempt to write out basis information has been
* completed.
*/
mutable bool didWrite;
/**
* Temporary storage.
*/
matrix<double> tmp;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ColourBasis & operator=(const ColourBasis &);
};
}
#endif /* HERWIG_ColourBasis_H */
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
@@ -1,358 +1,396 @@
// -*- C++ -*-
//
// SimpleColourBasis.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis class.
//
#include "SimpleColourBasis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
SimpleColourBasis::SimpleColourBasis() {}
SimpleColourBasis::~SimpleColourBasis() {}
IBPtr SimpleColourBasis::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 || basis == id33bar || basis == id33bar8 )
return 1;
if ( basis == id888 || basis == id33bar88 || basis == id33bar33bar )
return 2;
if ( basis == id8888 )
return 6;
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return 0;
}
double SimpleColourBasis::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
+ double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
double Nc6 = Nc2*Nc4;
if ( a > b )
swap(a,b);
- if ( abBasis == id88 ) {
- return ( Nc2 - 1. )/4.;
- }
+ if ( !largeN() ) {
- if ( abBasis == id33bar ) {
- return Nc;
- }
+ if ( abBasis == id88 ) {
+ return ( Nc2 - 1. )/4.;
+ }
- if ( abBasis == id888 ) {
- if ( a == b )
- return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc);
- return -( Nc2 - 1. )/(4.*Nc);
- }
+ if ( abBasis == id33bar ) {
+ return Nc;
+ }
- if ( abBasis == id33bar8 ) {
- return ( Nc2 - 1. )/2.;
- }
+ if ( abBasis == id888 ) {
+ if ( a == b )
+ return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc);
+ return -( Nc2 - 1. )/(4.*Nc);
+ }
- if ( abBasis == id8888 ) {
- if ( a == b )
- return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2);
- if ( ( a == 0 && b == 1 ) ||
- ( a == 2 && b == 3 ) ||
- ( a == 4 && b == 5 ) )
- return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2);
- return -( Nc2 - 4. + 3./Nc2 )/16.;
- }
+ if ( abBasis == id33bar8 ) {
+ return ( Nc2 - 1. )/2.;
+ }
- if ( abBasis == id33bar88 ) {
- if ( a == b )
- return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc);
- return -( Nc2 - 1. )/(4.*Nc);
- }
+ if ( abBasis == id8888 ) {
+ if ( a == b )
+ return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2);
+ if ( ( a == 0 && b == 1 ) ||
+ ( a == 2 && b == 3 ) ||
+ ( a == 4 && b == 5 ) )
+ return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2);
+ return -( Nc2 - 4. + 3./Nc2 )/16.;
+ }
- if ( abBasis == id33bar33bar ) {
- if ( a == b )
+ if ( abBasis == id33bar88 ) {
+ if ( a == b )
+ return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc);
+ return -( Nc2 - 1. )/(4.*Nc);
+ }
+
+ if ( abBasis == id33bar33bar ) {
+ if ( a == b )
+ return Nc2;
+ return Nc;
+ }
+
+ } else {
+
+ if ( a != b )
+ return 0.;
+
+ if ( abBasis == id88 ) {
+ return Nc2/4.;
+ }
+
+ if ( abBasis == id33bar ) {
+ return Nc;
+ }
+
+ if ( abBasis == id888 ) {
+ return Nc3/8.;
+ }
+
+ if ( abBasis == id33bar8 ) {
+ return Nc2/2.;
+ }
+
+ if ( abBasis == id8888 ) {
+ return Nc4/16.;
+ }
+
+ if ( abBasis == id33bar88 ) {
+ return Nc3/4.;
+ }
+
+ if ( abBasis == id33bar33bar ) {
return Nc2;
- return Nc;
+ }
+
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
}
double SimpleColourBasis::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& bBasis) const {
if ( id33bar.empty() )
makeIds();
if ( bBasis == id88 ) {
if ( i == 0 )
return a == 0 ? -1. : 1.;
else
return a == 0 ? 1. : -1.;
}
if ( bBasis == id33bar ) {
return i == 0 ? 1. : -1.;
}
if ( bBasis == id888 ) {
if ( i == 0 ) {
if ( a == 3 && b == 0 )
return 1.;
if ( a == 0 && b == 0 )
return -1.;
if ( a == 1 && b == 1 )
return 1.;
if ( a == 2 && b == 1 )
return -1.;
}
if ( i == 1 ) {
if ( a == 4 && b == 0 )
return 1.;
if ( a == 3 && b == 0 )
return -1.;
if ( a == 2 && b == 1 )
return 1.;
if ( a == 5 && b == 1 )
return -1.;
}
if ( i == 2 ) {
if ( a == 0 && b == 0 )
return 1.;
if ( a == 4 && b == 0 )
return -1.;
if ( a == 5 && b == 1 )
return 1.;
if ( a == 1 && b == 1 )
return -1.;
}
return 0.;
}
if ( bBasis == id33bar8 ) {
if ( i == 0 )
return a == 1 ? 1. : 0.;
if ( i == 1 )
return a == 0 ? -1. : 0.;
if ( i == 2 )
return a == 0 ? 1. : -1.;
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return 0.;
}
bool SimpleColourBasis::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar ) {
return
idColoured == 0 && idAntiColoured == 1;
}
if ( basis == id888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar8 ) {
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id8888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
if ( a == 2 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 3 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 4 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 5 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar88 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id33bar33bar ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 2 && idAntiColoured == 3 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
return false;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis::makeIds() const {
id88.push_back(PDT::Colour8);
id88.push_back(PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id33bar8.push_back(PDT::Colour3);
id33bar8.push_back(PDT::Colour3bar);
id33bar8.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour3);
id33bar88.push_back(PDT::Colour3bar);
id33bar88.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour8);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
}
void SimpleColourBasis::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<SimpleColourBasis,ColourBasis>
describeHerwigSimpleColourBasis("Herwig::SimpleColourBasis", "HwMatchbox.so");
void SimpleColourBasis::Init() {
static ClassDocumentation<SimpleColourBasis> documentation
("SimpleColourBasis implements the colour algebra needed for "
"electroweak boson and electroweak boson + jet production at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
@@ -1,2822 +1,2864 @@
// -*- C++ -*-
//
// SimpleColourBasis2.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis2 class.
//
#include "SimpleColourBasis2.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
SimpleColourBasis2::SimpleColourBasis2() {}
SimpleColourBasis2::~SimpleColourBasis2() {}
IBPtr SimpleColourBasis2::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis2::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis2::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
return 1;
}
if ( basis == id33bar ) {
return 1;
}
if ( basis == id888 ) {
return 2;
}
if ( basis == id33bar8 ) {
return 1;
}
if ( basis == id8888 ) {
return 9;
}
if ( basis == id33bar88 ) {
return 3;
}
if ( basis == id33bar33bar ) {
return 2;
}
if ( basis == id88888 ) {
return 44;
}
if ( basis == id33bar888 ) {
return 11;
}
if ( basis == id33bar33bar8 ) {
return 4;
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return 0;
}
double SimpleColourBasis2::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
+ double Nc5 = Nc*Nc4;
double Nc6 = Nc2*Nc4;
double Nc8 = Nc2*Nc6;
if ( a > b )
swap(a,b);
- if ( basis == id88 ) {
- if( ( a == 0 ) ||
- ( b == 0 ) )
- return (-1 + Nc2)/4.;
- }
+ if ( !largeN() ) {
- if ( basis == id33bar ) {
- if( ( a == 0 ) ||
- ( b == 0 ) )
+ if ( basis == id88 ) {
+ if( a == 0 && b == 0 )
+ return (-1 + Nc2)/4.;
+ }
+
+ if ( basis == id33bar ) {
+ if( a == 0 && b == 0 )
+ return Nc;
+ }
+
+ if ( basis == id888 ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) )
+ return (2 - 3*Nc2 + Nc4)/(8.*Nc);
+ if( ( a == 0 ) && ( b == 1 ) )
+ return -(-1 + Nc2)/(4.*Nc);
+ }
+
+ if ( basis == id33bar8 ) {
+ if( a == 0 && b == 0 )
+ return (-1 + Nc2)/2.;
+ }
+
+ if ( basis == id8888 ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) ||
+ ( a == 2 && b == 2 ) )
+ return sqr(-1 + Nc2)/16.;
+ if( ( a == 0 && b == 1 ) ||
+ ( a == 0 && b == 2 ) ||
+ ( a == 1 && b == 2 ) )
+ return (-1 + Nc2)/16.;
+ if( ( a == 0 && b == 3 ) ||
+ ( a == 0 && b == 5 ) ||
+ ( a == 0 && b == 7 ) ||
+ ( a == 0 && b == 8 ) ||
+ ( a == 1 && b == 4 ) ||
+ ( a == 1 && b == 5 ) ||
+ ( a == 1 && b == 6 ) ||
+ ( a == 1 && b == 7 ) ||
+ ( a == 2 && b == 3 ) ||
+ ( a == 2 && b == 4 ) ||
+ ( a == 2 && b == 6 ) ||
+ ( a == 2 && b == 8 ) )
+ return sqr(-1 + Nc2)/(16.*Nc);
+ if( ( a == 0 && b == 4 ) ||
+ ( a == 0 && b == 6 ) ||
+ ( a == 1 && b == 3 ) ||
+ ( a == 1 && b == 8 ) ||
+ ( a == 2 && b == 5 ) ||
+ ( a == 2 && b == 7 ) )
+ return -(-1 + Nc2)/(16.*Nc);
+ if( ( a == 3 && b == 3 ) ||
+ ( a == 4 && b == 4 ) ||
+ ( a == 5 && b == 5 ) ||
+ ( a == 6 && b == 6 ) ||
+ ( a == 7 && b == 7 ) ||
+ ( a == 8 && b == 8 ) )
+ return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2);
+ if( ( a == 3 && b == 4 ) ||
+ ( a == 3 && b == 5 ) ||
+ ( a == 3 && b == 6 ) ||
+ ( a == 3 && b == 7 ) ||
+ ( a == 4 && b == 5 ) ||
+ ( a == 4 && b == 7 ) ||
+ ( a == 4 && b == 8 ) ||
+ ( a == 5 && b == 6 ) ||
+ ( a == 5 && b == 8 ) ||
+ ( a == 6 && b == 7 ) ||
+ ( a == 6 && b == 8 ) ||
+ ( a == 7 && b == 8 ) )
+ return (4 - 3/Nc2 - Nc2)/16.;
+ if( ( a == 3 && b == 8 ) ||
+ ( a == 4 && b == 6 ) ||
+ ( a == 5 && b == 7 ) )
+ return (-3 + 2*Nc2 + Nc4)/(16.*Nc2);
+ }
+
+ if ( basis == id33bar88 ) {
+ if( a == 0 && b == 0 )
+ return (Nc*(-1 + Nc2))/4.;
+ if( ( a == 0 && b == 1 ) ||
+ ( a == 0 && b == 2 ) )
+ return (-1 + Nc2)/4.;
+ if( ( a == 1 && b == 1 ) ||
+ ( a == 2 && b == 2 ) )
+ return sqr(-1 + Nc2)/(4.*Nc);
+ if( a == 1 && b == 2 )
+ return -(-1 + Nc2)/(4.*Nc);
+ }
+
+ if ( basis == id33bar33bar ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) )
+ return Nc2;
+ if( a == 0 && b == 1 )
+ return Nc;
+ }
+
+ if ( basis == id88888 ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) ||
+ ( a == 2 && b == 2 ) ||
+ ( a == 3 && b == 3 ) ||
+ ( a == 4 && b == 4 ) ||
+ ( a == 5 && b == 5 ) ||
+ ( a == 6 && b == 6 ) ||
+ ( a == 7 && b == 7 ) ||
+ ( a == 8 && b == 8 ) ||
+ ( a == 9 && b == 9 ) ||
+ ( a == 10 && b == 10 ) ||
+ ( a == 11 && b == 11 ) ||
+ ( a == 12 && b == 12 ) ||
+ ( a == 13 && b == 13 ) ||
+ ( a == 14 && b == 14 ) ||
+ ( a == 15 && b == 15 ) ||
+ ( a == 16 && b == 16 ) ||
+ ( a == 17 && b == 17 ) ||
+ ( a == 18 && b == 18 ) ||
+ ( a == 19 && b == 19 ) )
+ return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc);
+ if( ( a == 0 && b == 1 ) ||
+ ( a == 0 && b == 2 ) ||
+ ( a == 0 && b == 7 ) ||
+ ( a == 0 && b == 10 ) ||
+ ( a == 0 && b == 12 ) ||
+ ( a == 0 && b == 13 ) ||
+ ( a == 1 && b == 2 ) ||
+ ( a == 1 && b == 4 ) ||
+ ( a == 1 && b == 11 ) ||
+ ( a == 1 && b == 14 ) ||
+ ( a == 1 && b == 15 ) ||
+ ( a == 2 && b == 5 ) ||
+ ( a == 2 && b == 8 ) ||
+ ( a == 2 && b == 16 ) ||
+ ( a == 2 && b == 17 ) ||
+ ( a == 3 && b == 4 ) ||
+ ( a == 3 && b == 5 ) ||
+ ( a == 3 && b == 6 ) ||
+ ( a == 3 && b == 9 ) ||
+ ( a == 3 && b == 14 ) ||
+ ( a == 3 && b == 16 ) ||
+ ( a == 4 && b == 5 ) ||
+ ( a == 4 && b == 11 ) ||
+ ( a == 4 && b == 12 ) ||
+ ( a == 4 && b == 18 ) ||
+ ( a == 5 && b == 8 ) ||
+ ( a == 5 && b == 13 ) ||
+ ( a == 5 && b == 19 ) ||
+ ( a == 6 && b == 7 ) ||
+ ( a == 6 && b == 8 ) ||
+ ( a == 6 && b == 9 ) ||
+ ( a == 6 && b == 12 ) ||
+ ( a == 6 && b == 17 ) ||
+ ( a == 7 && b == 8 ) ||
+ ( a == 7 && b == 10 ) ||
+ ( a == 7 && b == 14 ) ||
+ ( a == 7 && b == 19 ) ||
+ ( a == 8 && b == 15 ) ||
+ ( a == 8 && b == 18 ) ||
+ ( a == 9 && b == 10 ) ||
+ ( a == 9 && b == 11 ) ||
+ ( a == 9 && b == 13 ) ||
+ ( a == 9 && b == 15 ) ||
+ ( a == 10 && b == 11 ) ||
+ ( a == 10 && b == 16 ) ||
+ ( a == 10 && b == 18 ) ||
+ ( a == 11 && b == 17 ) ||
+ ( a == 11 && b == 19 ) ||
+ ( a == 12 && b == 13 ) ||
+ ( a == 12 && b == 17 ) ||
+ ( a == 12 && b == 18 ) ||
+ ( a == 13 && b == 15 ) ||
+ ( a == 13 && b == 19 ) ||
+ ( a == 14 && b == 15 ) ||
+ ( a == 14 && b == 16 ) ||
+ ( a == 14 && b == 19 ) ||
+ ( a == 15 && b == 18 ) ||
+ ( a == 16 && b == 17 ) ||
+ ( a == 16 && b == 18 ) ||
+ ( a == 17 && b == 19 ) )
+ return (2 - 3*Nc2 + Nc4)/(32.*Nc);
+ if( ( a == 0 && b == 3 ) ||
+ ( a == 1 && b == 6 ) ||
+ ( a == 2 && b == 9 ) ||
+ ( a == 4 && b == 7 ) ||
+ ( a == 5 && b == 10 ) ||
+ ( a == 8 && b == 11 ) ||
+ ( a == 12 && b == 14 ) ||
+ ( a == 13 && b == 16 ) ||
+ ( a == 15 && b == 17 ) ||
+ ( a == 18 && b == 19 ) )
+ return -sqr(-1 + Nc2)/(16.*Nc);
+ if( ( a == 0 && b == 4 ) ||
+ ( a == 0 && b == 5 ) ||
+ ( a == 0 && b == 6 ) ||
+ ( a == 0 && b == 9 ) ||
+ ( a == 0 && b == 14 ) ||
+ ( a == 0 && b == 16 ) ||
+ ( a == 1 && b == 3 ) ||
+ ( a == 1 && b == 7 ) ||
+ ( a == 1 && b == 8 ) ||
+ ( a == 1 && b == 9 ) ||
+ ( a == 1 && b == 12 ) ||
+ ( a == 1 && b == 17 ) ||
+ ( a == 2 && b == 3 ) ||
+ ( a == 2 && b == 6 ) ||
+ ( a == 2 && b == 10 ) ||
+ ( a == 2 && b == 11 ) ||
+ ( a == 2 && b == 13 ) ||
+ ( a == 2 && b == 15 ) ||
+ ( a == 3 && b == 7 ) ||
+ ( a == 3 && b == 10 ) ||
+ ( a == 3 && b == 12 ) ||
+ ( a == 3 && b == 13 ) ||
+ ( a == 4 && b == 6 ) ||
+ ( a == 4 && b == 8 ) ||
+ ( a == 4 && b == 10 ) ||
+ ( a == 4 && b == 14 ) ||
+ ( a == 4 && b == 19 ) ||
+ ( a == 5 && b == 7 ) ||
+ ( a == 5 && b == 9 ) ||
+ ( a == 5 && b == 11 ) ||
+ ( a == 5 && b == 16 ) ||
+ ( a == 5 && b == 18 ) ||
+ ( a == 6 && b == 11 ) ||
+ ( a == 6 && b == 14 ) ||
+ ( a == 6 && b == 15 ) ||
+ ( a == 7 && b == 11 ) ||
+ ( a == 7 && b == 12 ) ||
+ ( a == 7 && b == 18 ) ||
+ ( a == 8 && b == 9 ) ||
+ ( a == 8 && b == 10 ) ||
+ ( a == 8 && b == 17 ) ||
+ ( a == 8 && b == 19 ) ||
+ ( a == 9 && b == 16 ) ||
+ ( a == 9 && b == 17 ) ||
+ ( a == 10 && b == 13 ) ||
+ ( a == 10 && b == 19 ) ||
+ ( a == 11 && b == 15 ) ||
+ ( a == 11 && b == 18 ) ||
+ ( a == 12 && b == 15 ) ||
+ ( a == 12 && b == 16 ) ||
+ ( a == 12 && b == 19 ) ||
+ ( a == 13 && b == 14 ) ||
+ ( a == 13 && b == 17 ) ||
+ ( a == 13 && b == 18 ) ||
+ ( a == 14 && b == 17 ) ||
+ ( a == 14 && b == 18 ) ||
+ ( a == 15 && b == 16 ) ||
+ ( a == 15 && b == 19 ) ||
+ ( a == 16 && b == 19 ) ||
+ ( a == 17 && b == 18 ) )
+ return -(-1 + Nc2)/(16.*Nc);
+ if( ( a == 0 && b == 8 ) ||
+ ( a == 0 && b == 11 ) ||
+ ( a == 0 && b == 15 ) ||
+ ( a == 0 && b == 17 ) ||
+ ( a == 0 && b == 18 ) ||
+ ( a == 0 && b == 19 ) ||
+ ( a == 1 && b == 5 ) ||
+ ( a == 1 && b == 10 ) ||
+ ( a == 1 && b == 13 ) ||
+ ( a == 1 && b == 16 ) ||
+ ( a == 1 && b == 18 ) ||
+ ( a == 1 && b == 19 ) ||
+ ( a == 2 && b == 4 ) ||
+ ( a == 2 && b == 7 ) ||
+ ( a == 2 && b == 12 ) ||
+ ( a == 2 && b == 14 ) ||
+ ( a == 2 && b == 18 ) ||
+ ( a == 2 && b == 19 ) ||
+ ( a == 3 && b == 8 ) ||
+ ( a == 3 && b == 11 ) ||
+ ( a == 3 && b == 15 ) ||
+ ( a == 3 && b == 17 ) ||
+ ( a == 3 && b == 18 ) ||
+ ( a == 3 && b == 19 ) ||
+ ( a == 4 && b == 9 ) ||
+ ( a == 4 && b == 13 ) ||
+ ( a == 4 && b == 15 ) ||
+ ( a == 4 && b == 16 ) ||
+ ( a == 4 && b == 17 ) ||
+ ( a == 5 && b == 6 ) ||
+ ( a == 5 && b == 12 ) ||
+ ( a == 5 && b == 14 ) ||
+ ( a == 5 && b == 15 ) ||
+ ( a == 5 && b == 17 ) ||
+ ( a == 6 && b == 10 ) ||
+ ( a == 6 && b == 13 ) ||
+ ( a == 6 && b == 16 ) ||
+ ( a == 6 && b == 18 ) ||
+ ( a == 6 && b == 19 ) ||
+ ( a == 7 && b == 9 ) ||
+ ( a == 7 && b == 13 ) ||
+ ( a == 7 && b == 15 ) ||
+ ( a == 7 && b == 16 ) ||
+ ( a == 7 && b == 17 ) ||
+ ( a == 8 && b == 12 ) ||
+ ( a == 8 && b == 13 ) ||
+ ( a == 8 && b == 14 ) ||
+ ( a == 8 && b == 16 ) ||
+ ( a == 9 && b == 12 ) ||
+ ( a == 9 && b == 14 ) ||
+ ( a == 9 && b == 18 ) ||
+ ( a == 9 && b == 19 ) ||
+ ( a == 10 && b == 12 ) ||
+ ( a == 10 && b == 14 ) ||
+ ( a == 10 && b == 15 ) ||
+ ( a == 10 && b == 17 ) ||
+ ( a == 11 && b == 12 ) ||
+ ( a == 11 && b == 13 ) ||
+ ( a == 11 && b == 14 ) ||
+ ( a == 11 && b == 16 ) )
+ return 0;
+ if( ( a == 0 && b == 20 ) ||
+ ( a == 0 && b == 21 ) ||
+ ( a == 0 && b == 23 ) ||
+ ( a == 0 && b == 25 ) ||
+ ( a == 0 && b == 36 ) ||
+ ( a == 0 && b == 42 ) ||
+ ( a == 1 && b == 21 ) ||
+ ( a == 1 && b == 22 ) ||
+ ( a == 1 && b == 23 ) ||
+ ( a == 1 && b == 24 ) ||
+ ( a == 1 && b == 30 ) ||
+ ( a == 1 && b == 40 ) ||
+ ( a == 2 && b == 20 ) ||
+ ( a == 2 && b == 22 ) ||
+ ( a == 2 && b == 24 ) ||
+ ( a == 2 && b == 25 ) ||
+ ( a == 2 && b == 28 ) ||
+ ( a == 2 && b == 34 ) ||
+ ( a == 3 && b == 26 ) ||
+ ( a == 3 && b == 27 ) ||
+ ( a == 3 && b == 29 ) ||
+ ( a == 3 && b == 31 ) ||
+ ( a == 3 && b == 37 ) ||
+ ( a == 3 && b == 43 ) ||
+ ( a == 4 && b == 24 ) ||
+ ( a == 4 && b == 27 ) ||
+ ( a == 4 && b == 28 ) ||
+ ( a == 4 && b == 29 ) ||
+ ( a == 4 && b == 30 ) ||
+ ( a == 4 && b == 38 ) ||
+ ( a == 5 && b == 22 ) ||
+ ( a == 5 && b == 26 ) ||
+ ( a == 5 && b == 28 ) ||
+ ( a == 5 && b == 30 ) ||
+ ( a == 5 && b == 31 ) ||
+ ( a == 5 && b == 32 ) ||
+ ( a == 6 && b == 31 ) ||
+ ( a == 6 && b == 32 ) ||
+ ( a == 6 && b == 33 ) ||
+ ( a == 6 && b == 35 ) ||
+ ( a == 6 && b == 37 ) ||
+ ( a == 6 && b == 41 ) ||
+ ( a == 7 && b == 25 ) ||
+ ( a == 7 && b == 33 ) ||
+ ( a == 7 && b == 34 ) ||
+ ( a == 7 && b == 35 ) ||
+ ( a == 7 && b == 36 ) ||
+ ( a == 7 && b == 39 ) ||
+ ( a == 8 && b == 20 ) ||
+ ( a == 8 && b == 26 ) ||
+ ( a == 8 && b == 32 ) ||
+ ( a == 8 && b == 34 ) ||
+ ( a == 8 && b == 36 ) ||
+ ( a == 8 && b == 37 ) ||
+ ( a == 9 && b == 29 ) ||
+ ( a == 9 && b == 35 ) ||
+ ( a == 9 && b == 38 ) ||
+ ( a == 9 && b == 39 ) ||
+ ( a == 9 && b == 41 ) ||
+ ( a == 9 && b == 43 ) ||
+ ( a == 10 && b == 23 ) ||
+ ( a == 10 && b == 33 ) ||
+ ( a == 10 && b == 39 ) ||
+ ( a == 10 && b == 40 ) ||
+ ( a == 10 && b == 41 ) ||
+ ( a == 10 && b == 42 ) ||
+ ( a == 11 && b == 21 ) ||
+ ( a == 11 && b == 27 ) ||
+ ( a == 11 && b == 38 ) ||
+ ( a == 11 && b == 40 ) ||
+ ( a == 11 && b == 42 ) ||
+ ( a == 11 && b == 43 ) ||
+ ( a == 12 && b == 20 ) ||
+ ( a == 12 && b == 28 ) ||
+ ( a == 12 && b == 32 ) ||
+ ( a == 12 && b == 38 ) ||
+ ( a == 12 && b == 41 ) ||
+ ( a == 12 && b == 42 ) ||
+ ( a == 13 && b == 21 ) ||
+ ( a == 13 && b == 30 ) ||
+ ( a == 13 && b == 32 ) ||
+ ( a == 13 && b == 35 ) ||
+ ( a == 13 && b == 36 ) ||
+ ( a == 13 && b == 38 ) ||
+ ( a == 14 && b == 22 ) ||
+ ( a == 14 && b == 26 ) ||
+ ( a == 14 && b == 34 ) ||
+ ( a == 14 && b == 39 ) ||
+ ( a == 14 && b == 40 ) ||
+ ( a == 14 && b == 43 ) ||
+ ( a == 15 && b == 23 ) ||
+ ( a == 15 && b == 26 ) ||
+ ( a == 15 && b == 29 ) ||
+ ( a == 15 && b == 30 ) ||
+ ( a == 15 && b == 36 ) ||
+ ( a == 15 && b == 39 ) ||
+ ( a == 16 && b == 24 ) ||
+ ( a == 16 && b == 27 ) ||
+ ( a == 16 && b == 33 ) ||
+ ( a == 16 && b == 34 ) ||
+ ( a == 16 && b == 37 ) ||
+ ( a == 16 && b == 40 ) ||
+ ( a == 17 && b == 25 ) ||
+ ( a == 17 && b == 27 ) ||
+ ( a == 17 && b == 28 ) ||
+ ( a == 17 && b == 31 ) ||
+ ( a == 17 && b == 33 ) ||
+ ( a == 17 && b == 42 ) ||
+ ( a == 18 && b == 20 ) ||
+ ( a == 18 && b == 23 ) ||
+ ( a == 18 && b == 24 ) ||
+ ( a == 18 && b == 29 ) ||
+ ( a == 18 && b == 37 ) ||
+ ( a == 18 && b == 41 ) ||
+ ( a == 19 && b == 21 ) ||
+ ( a == 19 && b == 22 ) ||
+ ( a == 19 && b == 25 ) ||
+ ( a == 19 && b == 31 ) ||
+ ( a == 19 && b == 35 ) ||
+ ( a == 19 && b == 43 ) )
+ return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2);
+ if( ( a == 0 && b == 22 ) ||
+ ( a == 0 && b == 24 ) ||
+ ( a == 0 && b == 32 ) ||
+ ( a == 0 && b == 33 ) ||
+ ( a == 0 && b == 38 ) ||
+ ( a == 0 && b == 39 ) ||
+ ( a == 1 && b == 20 ) ||
+ ( a == 1 && b == 25 ) ||
+ ( a == 1 && b == 26 ) ||
+ ( a == 1 && b == 27 ) ||
+ ( a == 1 && b == 38 ) ||
+ ( a == 1 && b == 39 ) ||
+ ( a == 2 && b == 21 ) ||
+ ( a == 2 && b == 23 ) ||
+ ( a == 2 && b == 26 ) ||
+ ( a == 2 && b == 27 ) ||
+ ( a == 2 && b == 32 ) ||
+ ( a == 2 && b == 33 ) ||
+ ( a == 3 && b == 28 ) ||
+ ( a == 3 && b == 30 ) ||
+ ( a == 3 && b == 34 ) ||
+ ( a == 3 && b == 35 ) ||
+ ( a == 3 && b == 40 ) ||
+ ( a == 3 && b == 41 ) ||
+ ( a == 4 && b == 20 ) ||
+ ( a == 4 && b == 21 ) ||
+ ( a == 4 && b == 26 ) ||
+ ( a == 4 && b == 31 ) ||
+ ( a == 4 && b == 40 ) ||
+ ( a == 4 && b == 41 ) ||
+ ( a == 5 && b == 20 ) ||
+ ( a == 5 && b == 21 ) ||
+ ( a == 5 && b == 27 ) ||
+ ( a == 5 && b == 29 ) ||
+ ( a == 5 && b == 34 ) ||
+ ( a == 5 && b == 35 ) ||
+ ( a == 6 && b == 28 ) ||
+ ( a == 6 && b == 29 ) ||
+ ( a == 6 && b == 34 ) ||
+ ( a == 6 && b == 36 ) ||
+ ( a == 6 && b == 42 ) ||
+ ( a == 6 && b == 43 ) ||
+ ( a == 7 && b == 22 ) ||
+ ( a == 7 && b == 23 ) ||
+ ( a == 7 && b == 32 ) ||
+ ( a == 7 && b == 37 ) ||
+ ( a == 7 && b == 42 ) ||
+ ( a == 7 && b == 43 ) ||
+ ( a == 8 && b == 22 ) ||
+ ( a == 8 && b == 23 ) ||
+ ( a == 8 && b == 28 ) ||
+ ( a == 8 && b == 29 ) ||
+ ( a == 8 && b == 33 ) ||
+ ( a == 8 && b == 35 ) ||
+ ( a == 9 && b == 30 ) ||
+ ( a == 9 && b == 31 ) ||
+ ( a == 9 && b == 36 ) ||
+ ( a == 9 && b == 37 ) ||
+ ( a == 9 && b == 40 ) ||
+ ( a == 9 && b == 42 ) ||
+ ( a == 10 && b == 24 ) ||
+ ( a == 10 && b == 25 ) ||
+ ( a == 10 && b == 36 ) ||
+ ( a == 10 && b == 37 ) ||
+ ( a == 10 && b == 38 ) ||
+ ( a == 10 && b == 43 ) ||
+ ( a == 11 && b == 24 ) ||
+ ( a == 11 && b == 25 ) ||
+ ( a == 11 && b == 30 ) ||
+ ( a == 11 && b == 31 ) ||
+ ( a == 11 && b == 39 ) ||
+ ( a == 11 && b == 41 ) ||
+ ( a == 12 && b == 21 ) ||
+ ( a == 12 && b == 24 ) ||
+ ( a == 12 && b == 29 ) ||
+ ( a == 12 && b == 31 ) ||
+ ( a == 12 && b == 33 ) ||
+ ( a == 12 && b == 36 ) ||
+ ( a == 13 && b == 20 ) ||
+ ( a == 13 && b == 22 ) ||
+ ( a == 13 && b == 29 ) ||
+ ( a == 13 && b == 31 ) ||
+ ( a == 13 && b == 39 ) ||
+ ( a == 13 && b == 42 ) ||
+ ( a == 14 && b == 23 ) ||
+ ( a == 14 && b == 25 ) ||
+ ( a == 14 && b == 27 ) ||
+ ( a == 14 && b == 30 ) ||
+ ( a == 14 && b == 35 ) ||
+ ( a == 14 && b == 37 ) ||
+ ( a == 15 && b == 20 ) ||
+ ( a == 15 && b == 22 ) ||
+ ( a == 15 && b == 35 ) ||
+ ( a == 15 && b == 37 ) ||
+ ( a == 15 && b == 38 ) ||
+ ( a == 15 && b == 40 ) ||
+ ( a == 16 && b == 23 ) ||
+ ( a == 16 && b == 25 ) ||
+ ( a == 16 && b == 26 ) ||
+ ( a == 16 && b == 28 ) ||
+ ( a == 16 && b == 41 ) ||
+ ( a == 16 && b == 43 ) ||
+ ( a == 17 && b == 21 ) ||
+ ( a == 17 && b == 24 ) ||
+ ( a == 17 && b == 32 ) ||
+ ( a == 17 && b == 34 ) ||
+ ( a == 17 && b == 41 ) ||
+ ( a == 17 && b == 43 ) ||
+ ( a == 18 && b == 26 ) ||
+ ( a == 18 && b == 28 ) ||
+ ( a == 18 && b == 33 ) ||
+ ( a == 18 && b == 36 ) ||
+ ( a == 18 && b == 38 ) ||
+ ( a == 18 && b == 40 ) ||
+ ( a == 19 && b == 27 ) ||
+ ( a == 19 && b == 30 ) ||
+ ( a == 19 && b == 32 ) ||
+ ( a == 19 && b == 34 ) ||
+ ( a == 19 && b == 39 ) ||
+ ( a == 19 && b == 42 ) )
+ return -(2 - 3*Nc2 + Nc4)/(32.*Nc2);
+ if( ( a == 0 && b == 26 ) ||
+ ( a == 0 && b == 27 ) ||
+ ( a == 0 && b == 29 ) ||
+ ( a == 0 && b == 31 ) ||
+ ( a == 0 && b == 37 ) ||
+ ( a == 0 && b == 43 ) ||
+ ( a == 1 && b == 31 ) ||
+ ( a == 1 && b == 32 ) ||
+ ( a == 1 && b == 33 ) ||
+ ( a == 1 && b == 35 ) ||
+ ( a == 1 && b == 37 ) ||
+ ( a == 1 && b == 41 ) ||
+ ( a == 2 && b == 29 ) ||
+ ( a == 2 && b == 35 ) ||
+ ( a == 2 && b == 38 ) ||
+ ( a == 2 && b == 39 ) ||
+ ( a == 2 && b == 41 ) ||
+ ( a == 2 && b == 43 ) ||
+ ( a == 3 && b == 20 ) ||
+ ( a == 3 && b == 21 ) ||
+ ( a == 3 && b == 23 ) ||
+ ( a == 3 && b == 25 ) ||
+ ( a == 3 && b == 36 ) ||
+ ( a == 3 && b == 42 ) ||
+ ( a == 4 && b == 25 ) ||
+ ( a == 4 && b == 33 ) ||
+ ( a == 4 && b == 34 ) ||
+ ( a == 4 && b == 35 ) ||
+ ( a == 4 && b == 36 ) ||
+ ( a == 4 && b == 39 ) ||
+ ( a == 5 && b == 23 ) ||
+ ( a == 5 && b == 33 ) ||
+ ( a == 5 && b == 39 ) ||
+ ( a == 5 && b == 40 ) ||
+ ( a == 5 && b == 41 ) ||
+ ( a == 5 && b == 42 ) ||
+ ( a == 6 && b == 21 ) ||
+ ( a == 6 && b == 22 ) ||
+ ( a == 6 && b == 23 ) ||
+ ( a == 6 && b == 24 ) ||
+ ( a == 6 && b == 30 ) ||
+ ( a == 6 && b == 40 ) ||
+ ( a == 7 && b == 24 ) ||
+ ( a == 7 && b == 27 ) ||
+ ( a == 7 && b == 28 ) ||
+ ( a == 7 && b == 29 ) ||
+ ( a == 7 && b == 30 ) ||
+ ( a == 7 && b == 38 ) ||
+ ( a == 8 && b == 21 ) ||
+ ( a == 8 && b == 27 ) ||
+ ( a == 8 && b == 38 ) ||
+ ( a == 8 && b == 40 ) ||
+ ( a == 8 && b == 42 ) ||
+ ( a == 8 && b == 43 ) ||
+ ( a == 9 && b == 20 ) ||
+ ( a == 9 && b == 22 ) ||
+ ( a == 9 && b == 24 ) ||
+ ( a == 9 && b == 25 ) ||
+ ( a == 9 && b == 28 ) ||
+ ( a == 9 && b == 34 ) ||
+ ( a == 10 && b == 22 ) ||
+ ( a == 10 && b == 26 ) ||
+ ( a == 10 && b == 28 ) ||
+ ( a == 10 && b == 30 ) ||
+ ( a == 10 && b == 31 ) ||
+ ( a == 10 && b == 32 ) ||
+ ( a == 11 && b == 20 ) ||
+ ( a == 11 && b == 26 ) ||
+ ( a == 11 && b == 32 ) ||
+ ( a == 11 && b == 34 ) ||
+ ( a == 11 && b == 36 ) ||
+ ( a == 11 && b == 37 ) ||
+ ( a == 12 && b == 22 ) ||
+ ( a == 12 && b == 26 ) ||
+ ( a == 12 && b == 34 ) ||
+ ( a == 12 && b == 39 ) ||
+ ( a == 12 && b == 40 ) ||
+ ( a == 12 && b == 43 ) ||
+ ( a == 13 && b == 24 ) ||
+ ( a == 13 && b == 27 ) ||
+ ( a == 13 && b == 33 ) ||
+ ( a == 13 && b == 34 ) ||
+ ( a == 13 && b == 37 ) ||
+ ( a == 13 && b == 40 ) ||
+ ( a == 14 && b == 20 ) ||
+ ( a == 14 && b == 28 ) ||
+ ( a == 14 && b == 32 ) ||
+ ( a == 14 && b == 38 ) ||
+ ( a == 14 && b == 41 ) ||
+ ( a == 14 && b == 42 ) ||
+ ( a == 15 && b == 25 ) ||
+ ( a == 15 && b == 27 ) ||
+ ( a == 15 && b == 28 ) ||
+ ( a == 15 && b == 31 ) ||
+ ( a == 15 && b == 33 ) ||
+ ( a == 15 && b == 42 ) ||
+ ( a == 16 && b == 21 ) ||
+ ( a == 16 && b == 30 ) ||
+ ( a == 16 && b == 32 ) ||
+ ( a == 16 && b == 35 ) ||
+ ( a == 16 && b == 36 ) ||
+ ( a == 16 && b == 38 ) ||
+ ( a == 17 && b == 23 ) ||
+ ( a == 17 && b == 26 ) ||
+ ( a == 17 && b == 29 ) ||
+ ( a == 17 && b == 30 ) ||
+ ( a == 17 && b == 36 ) ||
+ ( a == 17 && b == 39 ) ||
+ ( a == 18 && b == 21 ) ||
+ ( a == 18 && b == 22 ) ||
+ ( a == 18 && b == 25 ) ||
+ ( a == 18 && b == 31 ) ||
+ ( a == 18 && b == 35 ) ||
+ ( a == 18 && b == 43 ) ||
+ ( a == 19 && b == 20 ) ||
+ ( a == 19 && b == 23 ) ||
+ ( a == 19 && b == 24 ) ||
+ ( a == 19 && b == 29 ) ||
+ ( a == 19 && b == 37 ) ||
+ ( a == 19 && b == 41 ) )
+ return -sqr(-1 + Nc2)/(16.*Nc2);
+ if( ( a == 0 && b == 28 ) ||
+ ( a == 0 && b == 30 ) ||
+ ( a == 0 && b == 34 ) ||
+ ( a == 0 && b == 35 ) ||
+ ( a == 0 && b == 40 ) ||
+ ( a == 0 && b == 41 ) ||
+ ( a == 1 && b == 28 ) ||
+ ( a == 1 && b == 29 ) ||
+ ( a == 1 && b == 34 ) ||
+ ( a == 1 && b == 36 ) ||
+ ( a == 1 && b == 42 ) ||
+ ( a == 1 && b == 43 ) ||
+ ( a == 2 && b == 30 ) ||
+ ( a == 2 && b == 31 ) ||
+ ( a == 2 && b == 36 ) ||
+ ( a == 2 && b == 37 ) ||
+ ( a == 2 && b == 40 ) ||
+ ( a == 2 && b == 42 ) ||
+ ( a == 3 && b == 22 ) ||
+ ( a == 3 && b == 24 ) ||
+ ( a == 3 && b == 32 ) ||
+ ( a == 3 && b == 33 ) ||
+ ( a == 3 && b == 38 ) ||
+ ( a == 3 && b == 39 ) ||
+ ( a == 4 && b == 22 ) ||
+ ( a == 4 && b == 23 ) ||
+ ( a == 4 && b == 32 ) ||
+ ( a == 4 && b == 37 ) ||
+ ( a == 4 && b == 42 ) ||
+ ( a == 4 && b == 43 ) ||
+ ( a == 5 && b == 24 ) ||
+ ( a == 5 && b == 25 ) ||
+ ( a == 5 && b == 36 ) ||
+ ( a == 5 && b == 37 ) ||
+ ( a == 5 && b == 38 ) ||
+ ( a == 5 && b == 43 ) ||
+ ( a == 6 && b == 20 ) ||
+ ( a == 6 && b == 25 ) ||
+ ( a == 6 && b == 26 ) ||
+ ( a == 6 && b == 27 ) ||
+ ( a == 6 && b == 38 ) ||
+ ( a == 6 && b == 39 ) ||
+ ( a == 7 && b == 20 ) ||
+ ( a == 7 && b == 21 ) ||
+ ( a == 7 && b == 26 ) ||
+ ( a == 7 && b == 31 ) ||
+ ( a == 7 && b == 40 ) ||
+ ( a == 7 && b == 41 ) ||
+ ( a == 8 && b == 24 ) ||
+ ( a == 8 && b == 25 ) ||
+ ( a == 8 && b == 30 ) ||
+ ( a == 8 && b == 31 ) ||
+ ( a == 8 && b == 39 ) ||
+ ( a == 8 && b == 41 ) ||
+ ( a == 9 && b == 21 ) ||
+ ( a == 9 && b == 23 ) ||
+ ( a == 9 && b == 26 ) ||
+ ( a == 9 && b == 27 ) ||
+ ( a == 9 && b == 32 ) ||
+ ( a == 9 && b == 33 ) ||
+ ( a == 10 && b == 20 ) ||
+ ( a == 10 && b == 21 ) ||
+ ( a == 10 && b == 27 ) ||
+ ( a == 10 && b == 29 ) ||
+ ( a == 10 && b == 34 ) ||
+ ( a == 10 && b == 35 ) ||
+ ( a == 11 && b == 22 ) ||
+ ( a == 11 && b == 23 ) ||
+ ( a == 11 && b == 28 ) ||
+ ( a == 11 && b == 29 ) ||
+ ( a == 11 && b == 33 ) ||
+ ( a == 11 && b == 35 ) ||
+ ( a == 12 && b == 23 ) ||
+ ( a == 12 && b == 25 ) ||
+ ( a == 12 && b == 27 ) ||
+ ( a == 12 && b == 30 ) ||
+ ( a == 12 && b == 35 ) ||
+ ( a == 12 && b == 37 ) ||
+ ( a == 13 && b == 23 ) ||
+ ( a == 13 && b == 25 ) ||
+ ( a == 13 && b == 26 ) ||
+ ( a == 13 && b == 28 ) ||
+ ( a == 13 && b == 41 ) ||
+ ( a == 13 && b == 43 ) ||
+ ( a == 14 && b == 21 ) ||
+ ( a == 14 && b == 24 ) ||
+ ( a == 14 && b == 29 ) ||
+ ( a == 14 && b == 31 ) ||
+ ( a == 14 && b == 33 ) ||
+ ( a == 14 && b == 36 ) ||
+ ( a == 15 && b == 21 ) ||
+ ( a == 15 && b == 24 ) ||
+ ( a == 15 && b == 32 ) ||
+ ( a == 15 && b == 34 ) ||
+ ( a == 15 && b == 41 ) ||
+ ( a == 15 && b == 43 ) ||
+ ( a == 16 && b == 20 ) ||
+ ( a == 16 && b == 22 ) ||
+ ( a == 16 && b == 29 ) ||
+ ( a == 16 && b == 31 ) ||
+ ( a == 16 && b == 39 ) ||
+ ( a == 16 && b == 42 ) ||
+ ( a == 17 && b == 20 ) ||
+ ( a == 17 && b == 22 ) ||
+ ( a == 17 && b == 35 ) ||
+ ( a == 17 && b == 37 ) ||
+ ( a == 17 && b == 38 ) ||
+ ( a == 17 && b == 40 ) ||
+ ( a == 18 && b == 27 ) ||
+ ( a == 18 && b == 30 ) ||
+ ( a == 18 && b == 32 ) ||
+ ( a == 18 && b == 34 ) ||
+ ( a == 18 && b == 39 ) ||
+ ( a == 18 && b == 42 ) ||
+ ( a == 19 && b == 26 ) ||
+ ( a == 19 && b == 28 ) ||
+ ( a == 19 && b == 33 ) ||
+ ( a == 19 && b == 36 ) ||
+ ( a == 19 && b == 38 ) ||
+ ( a == 19 && b == 40 ) )
+ return (1 - 1/Nc2)/16.;
+ if( ( a == 20 && b == 20 ) ||
+ ( a == 21 && b == 21 ) ||
+ ( a == 22 && b == 22 ) ||
+ ( a == 23 && b == 23 ) ||
+ ( a == 24 && b == 24 ) ||
+ ( a == 25 && b == 25 ) ||
+ ( a == 26 && b == 26 ) ||
+ ( a == 27 && b == 27 ) ||
+ ( a == 28 && b == 28 ) ||
+ ( a == 29 && b == 29 ) ||
+ ( a == 30 && b == 30 ) ||
+ ( a == 31 && b == 31 ) ||
+ ( a == 32 && b == 32 ) ||
+ ( a == 33 && b == 33 ) ||
+ ( a == 34 && b == 34 ) ||
+ ( a == 35 && b == 35 ) ||
+ ( a == 36 && b == 36 ) ||
+ ( a == 37 && b == 37 ) ||
+ ( a == 38 && b == 38 ) ||
+ ( a == 39 && b == 39 ) ||
+ ( a == 40 && b == 40 ) ||
+ ( a == 41 && b == 41 ) ||
+ ( a == 42 && b == 42 ) ||
+ ( a == 43 && b == 43 ) )
+ return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3);
+ if( ( a == 20 && b == 21 ) ||
+ ( a == 20 && b == 22 ) ||
+ ( a == 20 && b == 26 ) ||
+ ( a == 20 && b == 29 ) ||
+ ( a == 20 && b == 38 ) ||
+ ( a == 21 && b == 24 ) ||
+ ( a == 21 && b == 27 ) ||
+ ( a == 21 && b == 31 ) ||
+ ( a == 21 && b == 32 ) ||
+ ( a == 22 && b == 23 ) ||
+ ( a == 22 && b == 32 ) ||
+ ( a == 22 && b == 35 ) ||
+ ( a == 22 && b == 39 ) ||
+ ( a == 23 && b == 25 ) ||
+ ( a == 23 && b == 26 ) ||
+ ( a == 23 && b == 33 ) ||
+ ( a == 23 && b == 37 ) ||
+ ( a == 24 && b == 25 ) ||
+ ( a == 24 && b == 33 ) ||
+ ( a == 24 && b == 38 ) ||
+ ( a == 24 && b == 41 ) ||
+ ( a == 25 && b == 27 ) ||
+ ( a == 25 && b == 39 ) ||
+ ( a == 25 && b == 43 ) ||
+ ( a == 26 && b == 27 ) ||
+ ( a == 26 && b == 28 ) ||
+ ( a == 26 && b == 40 ) ||
+ ( a == 27 && b == 30 ) ||
+ ( a == 27 && b == 34 ) ||
+ ( a == 28 && b == 29 ) ||
+ ( a == 28 && b == 33 ) ||
+ ( a == 28 && b == 34 ) ||
+ ( a == 28 && b == 41 ) ||
+ ( a == 29 && b == 31 ) ||
+ ( a == 29 && b == 35 ) ||
+ ( a == 29 && b == 36 ) ||
+ ( a == 30 && b == 31 ) ||
+ ( a == 30 && b == 35 ) ||
+ ( a == 30 && b == 39 ) ||
+ ( a == 30 && b == 40 ) ||
+ ( a == 31 && b == 41 ) ||
+ ( a == 31 && b == 42 ) ||
+ ( a == 32 && b == 33 ) ||
+ ( a == 32 && b == 34 ) ||
+ ( a == 32 && b == 42 ) ||
+ ( a == 33 && b == 36 ) ||
+ ( a == 34 && b == 35 ) ||
+ ( a == 34 && b == 43 ) ||
+ ( a == 35 && b == 37 ) ||
+ ( a == 36 && b == 37 ) ||
+ ( a == 36 && b == 38 ) ||
+ ( a == 36 && b == 42 ) ||
+ ( a == 37 && b == 40 ) ||
+ ( a == 37 && b == 43 ) ||
+ ( a == 38 && b == 39 ) ||
+ ( a == 38 && b == 40 ) ||
+ ( a == 39 && b == 42 ) ||
+ ( a == 40 && b == 41 ) ||
+ ( a == 41 && b == 43 ) ||
+ ( a == 42 && b == 43 ) )
+ return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3);
+ if( ( a == 20 && b == 23 ) ||
+ ( a == 20 && b == 24 ) ||
+ ( a == 20 && b == 28 ) ||
+ ( a == 20 && b == 32 ) ||
+ ( a == 20 && b == 36 ) ||
+ ( a == 21 && b == 22 ) ||
+ ( a == 21 && b == 25 ) ||
+ ( a == 21 && b == 30 ) ||
+ ( a == 21 && b == 38 ) ||
+ ( a == 21 && b == 42 ) ||
+ ( a == 22 && b == 25 ) ||
+ ( a == 22 && b == 26 ) ||
+ ( a == 22 && b == 30 ) ||
+ ( a == 22 && b == 34 ) ||
+ ( a == 23 && b == 24 ) ||
+ ( a == 23 && b == 36 ) ||
+ ( a == 23 && b == 39 ) ||
+ ( a == 23 && b == 40 ) ||
+ ( a == 24 && b == 27 ) ||
+ ( a == 24 && b == 28 ) ||
+ ( a == 24 && b == 40 ) ||
+ ( a == 25 && b == 33 ) ||
+ ( a == 25 && b == 34 ) ||
+ ( a == 25 && b == 42 ) ||
+ ( a == 26 && b == 29 ) ||
+ ( a == 26 && b == 30 ) ||
+ ( a == 26 && b == 34 ) ||
+ ( a == 26 && b == 37 ) ||
+ ( a == 27 && b == 28 ) ||
+ ( a == 27 && b == 31 ) ||
+ ( a == 27 && b == 40 ) ||
+ ( a == 27 && b == 43 ) ||
+ ( a == 28 && b == 31 ) ||
+ ( a == 28 && b == 32 ) ||
+ ( a == 29 && b == 30 ) ||
+ ( a == 29 && b == 37 ) ||
+ ( a == 29 && b == 38 ) ||
+ ( a == 29 && b == 41 ) ||
+ ( a == 30 && b == 38 ) ||
+ ( a == 31 && b == 32 ) ||
+ ( a == 31 && b == 35 ) ||
+ ( a == 31 && b == 43 ) ||
+ ( a == 32 && b == 35 ) ||
+ ( a == 32 && b == 36 ) ||
+ ( a == 33 && b == 34 ) ||
+ ( a == 33 && b == 37 ) ||
+ ( a == 33 && b == 41 ) ||
+ ( a == 33 && b == 42 ) ||
+ ( a == 34 && b == 37 ) ||
+ ( a == 35 && b == 36 ) ||
+ ( a == 35 && b == 39 ) ||
+ ( a == 35 && b == 43 ) ||
+ ( a == 36 && b == 39 ) ||
+ ( a == 37 && b == 41 ) ||
+ ( a == 38 && b == 41 ) ||
+ ( a == 38 && b == 42 ) ||
+ ( a == 39 && b == 40 ) ||
+ ( a == 39 && b == 43 ) ||
+ ( a == 40 && b == 43 ) ||
+ ( a == 41 && b == 42 ) )
+ return (2 - 3*Nc2 + Nc4)/(16.*Nc3);
+ if( ( a == 20 && b == 25 ) ||
+ ( a == 20 && b == 34 ) ||
+ ( a == 20 && b == 37 ) ||
+ ( a == 20 && b == 41 ) ||
+ ( a == 20 && b == 42 ) ||
+ ( a == 21 && b == 23 ) ||
+ ( a == 21 && b == 35 ) ||
+ ( a == 21 && b == 36 ) ||
+ ( a == 21 && b == 40 ) ||
+ ( a == 21 && b == 43 ) ||
+ ( a == 22 && b == 24 ) ||
+ ( a == 22 && b == 28 ) ||
+ ( a == 22 && b == 31 ) ||
+ ( a == 22 && b == 40 ) ||
+ ( a == 22 && b == 43 ) ||
+ ( a == 23 && b == 29 ) ||
+ ( a == 23 && b == 30 ) ||
+ ( a == 23 && b == 41 ) ||
+ ( a == 23 && b == 42 ) ||
+ ( a == 24 && b == 29 ) ||
+ ( a == 24 && b == 30 ) ||
+ ( a == 24 && b == 34 ) ||
+ ( a == 24 && b == 37 ) ||
+ ( a == 25 && b == 28 ) ||
+ ( a == 25 && b == 31 ) ||
+ ( a == 25 && b == 35 ) ||
+ ( a == 25 && b == 36 ) ||
+ ( a == 26 && b == 31 ) ||
+ ( a == 26 && b == 32 ) ||
+ ( a == 26 && b == 36 ) ||
+ ( a == 26 && b == 39 ) ||
+ ( a == 26 && b == 43 ) ||
+ ( a == 27 && b == 29 ) ||
+ ( a == 27 && b == 33 ) ||
+ ( a == 27 && b == 37 ) ||
+ ( a == 27 && b == 38 ) ||
+ ( a == 27 && b == 42 ) ||
+ ( a == 28 && b == 30 ) ||
+ ( a == 28 && b == 38 ) ||
+ ( a == 28 && b == 42 ) ||
+ ( a == 29 && b == 39 ) ||
+ ( a == 29 && b == 43 ) ||
+ ( a == 30 && b == 32 ) ||
+ ( a == 30 && b == 36 ) ||
+ ( a == 31 && b == 33 ) ||
+ ( a == 31 && b == 37 ) ||
+ ( a == 32 && b == 37 ) ||
+ ( a == 32 && b == 38 ) ||
+ ( a == 32 && b == 41 ) ||
+ ( a == 33 && b == 35 ) ||
+ ( a == 33 && b == 39 ) ||
+ ( a == 33 && b == 40 ) ||
+ ( a == 34 && b == 36 ) ||
+ ( a == 34 && b == 39 ) ||
+ ( a == 34 && b == 40 ) ||
+ ( a == 35 && b == 38 ) ||
+ ( a == 35 && b == 41 ) ||
+ ( a == 38 && b == 43 ) ||
+ ( a == 39 && b == 41 ) ||
+ ( a == 40 && b == 42 ) )
+ return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3);
+ if( ( a == 20 && b == 27 ) ||
+ ( a == 20 && b == 31 ) ||
+ ( a == 20 && b == 35 ) ||
+ ( a == 20 && b == 39 ) ||
+ ( a == 20 && b == 40 ) ||
+ ( a == 21 && b == 26 ) ||
+ ( a == 21 && b == 29 ) ||
+ ( a == 21 && b == 33 ) ||
+ ( a == 21 && b == 34 ) ||
+ ( a == 21 && b == 41 ) ||
+ ( a == 22 && b == 29 ) ||
+ ( a == 22 && b == 33 ) ||
+ ( a == 22 && b == 37 ) ||
+ ( a == 22 && b == 38 ) ||
+ ( a == 22 && b == 42 ) ||
+ ( a == 23 && b == 27 ) ||
+ ( a == 23 && b == 28 ) ||
+ ( a == 23 && b == 32 ) ||
+ ( a == 23 && b == 35 ) ||
+ ( a == 23 && b == 43 ) ||
+ ( a == 24 && b == 31 ) ||
+ ( a == 24 && b == 32 ) ||
+ ( a == 24 && b == 36 ) ||
+ ( a == 24 && b == 39 ) ||
+ ( a == 24 && b == 43 ) ||
+ ( a == 25 && b == 26 ) ||
+ ( a == 25 && b == 30 ) ||
+ ( a == 25 && b == 37 ) ||
+ ( a == 25 && b == 38 ) ||
+ ( a == 25 && b == 41 ) ||
+ ( a == 26 && b == 33 ) ||
+ ( a == 26 && b == 38 ) ||
+ ( a == 26 && b == 41 ) ||
+ ( a == 27 && b == 32 ) ||
+ ( a == 27 && b == 35 ) ||
+ ( a == 27 && b == 39 ) ||
+ ( a == 28 && b == 35 ) ||
+ ( a == 28 && b == 36 ) ||
+ ( a == 28 && b == 40 ) ||
+ ( a == 28 && b == 43 ) ||
+ ( a == 29 && b == 33 ) ||
+ ( a == 29 && b == 34 ) ||
+ ( a == 29 && b == 42 ) ||
+ ( a == 30 && b == 34 ) ||
+ ( a == 30 && b == 37 ) ||
+ ( a == 30 && b == 41 ) ||
+ ( a == 30 && b == 42 ) ||
+ ( a == 31 && b == 36 ) ||
+ ( a == 31 && b == 39 ) ||
+ ( a == 31 && b == 40 ) ||
+ ( a == 32 && b == 39 ) ||
+ ( a == 32 && b == 43 ) ||
+ ( a == 33 && b == 38 ) ||
+ ( a == 34 && b == 41 ) ||
+ ( a == 34 && b == 42 ) ||
+ ( a == 35 && b == 40 ) ||
+ ( a == 36 && b == 40 ) ||
+ ( a == 36 && b == 43 ) ||
+ ( a == 37 && b == 38 ) ||
+ ( a == 37 && b == 42 ) )
+ return -(-1 + Nc2)/(8.*Nc3);
+ if( ( a == 20 && b == 30 ) ||
+ ( a == 20 && b == 33 ) ||
+ ( a == 21 && b == 28 ) ||
+ ( a == 21 && b == 39 ) ||
+ ( a == 22 && b == 27 ) ||
+ ( a == 22 && b == 36 ) ||
+ ( a == 23 && b == 34 ) ||
+ ( a == 23 && b == 38 ) ||
+ ( a == 24 && b == 26 ) ||
+ ( a == 24 && b == 42 ) ||
+ ( a == 25 && b == 32 ) ||
+ ( a == 25 && b == 40 ) ||
+ ( a == 26 && b == 35 ) ||
+ ( a == 27 && b == 41 ) ||
+ ( a == 28 && b == 37 ) ||
+ ( a == 29 && b == 32 ) ||
+ ( a == 29 && b == 40 ) ||
+ ( a == 30 && b == 43 ) ||
+ ( a == 31 && b == 34 ) ||
+ ( a == 31 && b == 38 ) ||
+ ( a == 33 && b == 43 ) ||
+ ( a == 35 && b == 42 ) ||
+ ( a == 36 && b == 41 ) ||
+ ( a == 37 && b == 39 ) )
+ return (4 - 5*Nc2 + Nc4)/(32.*Nc3);
+ if( ( a == 20 && b == 43 ) ||
+ ( a == 21 && b == 37 ) ||
+ ( a == 22 && b == 41 ) ||
+ ( a == 23 && b == 31 ) ||
+ ( a == 24 && b == 35 ) ||
+ ( a == 25 && b == 29 ) ||
+ ( a == 26 && b == 42 ) ||
+ ( a == 27 && b == 36 ) ||
+ ( a == 28 && b == 39 ) ||
+ ( a == 30 && b == 33 ) ||
+ ( a == 32 && b == 40 ) ||
+ ( a == 34 && b == 38 ) )
+ return -(-1 + Nc4)/(8.*Nc3);
+ }
+
+ if ( basis == id33bar888 ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) )
+ return (2 - 3*Nc2 + Nc4)/8.;
+ if( a == 0 && b == 1 )
+ return (1 - Nc2)/4.;
+ if( ( a == 0 && b == 2 ) ||
+ ( a == 0 && b == 3 ) ||
+ ( a == 0 && b == 4 ) ||
+ ( a == 1 && b == 2 ) ||
+ ( a == 1 && b == 3 ) ||
+ ( a == 1 && b == 4 ) )
+ return 0;
+ if( ( a == 0 && b == 5 ) ||
+ ( a == 0 && b == 8 ) ||
+ ( a == 0 && b == 9 ) ||
+ ( a == 1 && b == 6 ) ||
+ ( a == 1 && b == 7 ) ||
+ ( a == 1 && b == 10 ) )
+ return (2 - 3*Nc2 + Nc4)/(8.*Nc);
+ if( ( a == 0 && b == 6 ) ||
+ ( a == 0 && b == 7 ) ||
+ ( a == 0 && b == 10 ) ||
+ ( a == 1 && b == 5 ) ||
+ ( a == 1 && b == 8 ) ||
+ ( a == 1 && b == 9 ) )
+ return -(-1 + Nc2)/(4.*Nc);
+ if( ( a == 2 && b == 2 ) ||
+ ( a == 3 && b == 3 ) ||
+ ( a == 4 && b == 4 ) )
+ return sqr(-1 + Nc2)/8.;
+ if( ( a == 2 && b == 3 ) ||
+ ( a == 2 && b == 4 ) ||
+ ( a == 3 && b == 4 ) )
+ return (-1 + Nc2)/8.;
+ if( ( a == 2 && b == 5 ) ||
+ ( a == 2 && b == 6 ) ||
+ ( a == 2 && b == 8 ) ||
+ ( a == 2 && b == 10 ) ||
+ ( a == 3 && b == 6 ) ||
+ ( a == 3 && b == 7 ) ||
+ ( a == 3 && b == 8 ) ||
+ ( a == 3 && b == 9 ) ||
+ ( a == 4 && b == 5 ) ||
+ ( a == 4 && b == 7 ) ||
+ ( a == 4 && b == 9 ) ||
+ ( a == 4 && b == 10 ) )
+ return sqr(-1 + Nc2)/(8.*Nc);
+ if( ( a == 2 && b == 7 ) ||
+ ( a == 2 && b == 9 ) ||
+ ( a == 3 && b == 5 ) ||
+ ( a == 3 && b == 10 ) ||
+ ( a == 4 && b == 6 ) ||
+ ( a == 4 && b == 8 ) )
+ return -(-1 + Nc2)/(8.*Nc);
+ if( ( a == 5 && b == 5 ) ||
+ ( a == 6 && b == 6 ) ||
+ ( a == 7 && b == 7 ) ||
+ ( a == 8 && b == 8 ) ||
+ ( a == 9 && b == 9 ) ||
+ ( a == 10 && b == 10 ) )
+ return pow(-1 + Nc2,3.)/(8.*Nc2);
+ if( ( a == 5 && b == 6 ) ||
+ ( a == 5 && b == 7 ) ||
+ ( a == 6 && b == 9 ) ||
+ ( a == 7 && b == 8 ) ||
+ ( a == 8 && b == 10 ) ||
+ ( a == 9 && b == 10 ) )
+ return -sqr(-1 + Nc2)/(8.*Nc2);
+ if( ( a == 5 && b == 8 ) ||
+ ( a == 5 && b == 9 ) ||
+ ( a == 6 && b == 7 ) ||
+ ( a == 6 && b == 10 ) ||
+ ( a == 7 && b == 10 ) ||
+ ( a == 8 && b == 9 ) )
+ return 0.125 - 1/(8.*Nc2);
+ if( ( a == 5 && b == 10 ) ||
+ ( a == 6 && b == 8 ) ||
+ ( a == 7 && b == 9 ) )
+ return (-1 + Nc4)/(8.*Nc2);
+ }
+
+ if ( basis == id33bar33bar8 ) {
+ if( ( a == 0 && b == 0 ) ||
+ ( a == 1 && b == 1 ) ||
+ ( a == 2 && b == 2 ) ||
+ ( a == 3 && b == 3 ) )
+ return (Nc*(-1 + Nc2))/2.;
+ if( ( a == 0 && b == 1 ) ||
+ ( a == 0 && b == 3 ) ||
+ ( a == 1 && b == 2 ) ||
+ ( a == 2 && b == 3 ) )
+ return (-1 + Nc2)/2.;
+ if( ( a == 0 && b == 2 ) ||
+ ( a == 1 && b == 3 ) )
+ return 0;
+ }
+
+ } else {
+
+ if ( a != b )
+ return 0.;
+
+ if ( basis == id88 ) {
+ return Nc2/4.;
+ }
+
+ if ( basis == id33bar ) {
return Nc;
- }
+ }
- if ( basis == id888 ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) )
- return (2 - 3*Nc2 + Nc4)/(8.*Nc);
- if( ( a == 0 ) ||
- ( b == 1 ) )
- return -(-1 + Nc2)/(4.*Nc);
- }
+ if ( basis == id888 ) {
+ return Nc3/8.;
+ }
- if ( basis == id33bar8 ) {
- if( ( a == 0 ) ||
- ( b == 0 ) )
- return (-1 + Nc2)/2.;
- }
+ if ( basis == id33bar8 ) {
+ return Nc2/2.;
+ }
- if ( basis == id8888 ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) ||
- ( a == 2 && b == 2 ) )
- return sqr(-1 + Nc2)/16.;
- if( ( a == 0 && b == 1 ) ||
- ( a == 0 && b == 2 ) ||
- ( a == 1 && b == 2 ) )
- return (-1 + Nc2)/16.;
- if( ( a == 0 && b == 3 ) ||
- ( a == 0 && b == 5 ) ||
- ( a == 0 && b == 7 ) ||
- ( a == 0 && b == 8 ) ||
- ( a == 1 && b == 4 ) ||
- ( a == 1 && b == 5 ) ||
- ( a == 1 && b == 6 ) ||
- ( a == 1 && b == 7 ) ||
- ( a == 2 && b == 3 ) ||
- ( a == 2 && b == 4 ) ||
- ( a == 2 && b == 6 ) ||
- ( a == 2 && b == 8 ) )
- return sqr(-1 + Nc2)/(16.*Nc);
- if( ( a == 0 && b == 4 ) ||
- ( a == 0 && b == 6 ) ||
- ( a == 1 && b == 3 ) ||
- ( a == 1 && b == 8 ) ||
- ( a == 2 && b == 5 ) ||
- ( a == 2 && b == 7 ) )
- return -(-1 + Nc2)/(16.*Nc);
- if( ( a == 3 && b == 3 ) ||
- ( a == 4 && b == 4 ) ||
- ( a == 5 && b == 5 ) ||
- ( a == 6 && b == 6 ) ||
- ( a == 7 && b == 7 ) ||
- ( a == 8 && b == 8 ) )
- return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2);
- if( ( a == 3 && b == 4 ) ||
- ( a == 3 && b == 5 ) ||
- ( a == 3 && b == 6 ) ||
- ( a == 3 && b == 7 ) ||
- ( a == 4 && b == 5 ) ||
- ( a == 4 && b == 7 ) ||
- ( a == 4 && b == 8 ) ||
- ( a == 5 && b == 6 ) ||
- ( a == 5 && b == 8 ) ||
- ( a == 6 && b == 7 ) ||
- ( a == 6 && b == 8 ) ||
- ( a == 7 && b == 8 ) )
- return (4 - 3/Nc2 - Nc2)/16.;
- if( ( a == 3 && b == 8 ) ||
- ( a == 4 && b == 6 ) ||
- ( a == 5 && b == 7 ) )
- return (-3 + 2*Nc2 + Nc4)/(16.*Nc2);
- }
+ if ( basis == id8888 ) {
+ return Nc4/16.;
+ }
- if ( basis == id33bar88 ) {
- if( ( a == 0 ) ||
- ( b == 0 ) )
- return (Nc*(-1 + Nc2))/4.;
- if( ( a == 0 && b == 1 ) ||
- ( a == 0 && b == 2 ) )
- return (-1 + Nc2)/4.;
- if( ( a == 1 && b == 1 ) ||
- ( a == 2 && b == 2 ) )
- return sqr(-1 + Nc2)/(4.*Nc);
- if( ( a == 1 ) ||
- ( b == 2 ) )
- return -(-1 + Nc2)/(4.*Nc);
- }
+ if ( basis == id33bar88 ) {
+ return Nc3/4.;
+ }
- if ( basis == id33bar33bar ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) )
+ if ( basis == id33bar33bar ) {
return Nc2;
- if( ( a == 0 ) ||
- ( b == 1 ) )
- return Nc;
- }
+ }
- if ( basis == id88888 ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) ||
- ( a == 2 && b == 2 ) ||
- ( a == 3 && b == 3 ) ||
- ( a == 4 && b == 4 ) ||
- ( a == 5 && b == 5 ) ||
- ( a == 6 && b == 6 ) ||
- ( a == 7 && b == 7 ) ||
- ( a == 8 && b == 8 ) ||
- ( a == 9 && b == 9 ) ||
- ( a == 10 && b == 10 ) ||
- ( a == 11 && b == 11 ) ||
- ( a == 12 && b == 12 ) ||
- ( a == 13 && b == 13 ) ||
- ( a == 14 && b == 14 ) ||
- ( a == 15 && b == 15 ) ||
- ( a == 16 && b == 16 ) ||
- ( a == 17 && b == 17 ) ||
- ( a == 18 && b == 18 ) ||
- ( a == 19 && b == 19 ) )
- return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc);
- if( ( a == 0 && b == 1 ) ||
- ( a == 0 && b == 2 ) ||
- ( a == 0 && b == 7 ) ||
- ( a == 0 && b == 10 ) ||
- ( a == 0 && b == 12 ) ||
- ( a == 0 && b == 13 ) ||
- ( a == 1 && b == 2 ) ||
- ( a == 1 && b == 4 ) ||
- ( a == 1 && b == 11 ) ||
- ( a == 1 && b == 14 ) ||
- ( a == 1 && b == 15 ) ||
- ( a == 2 && b == 5 ) ||
- ( a == 2 && b == 8 ) ||
- ( a == 2 && b == 16 ) ||
- ( a == 2 && b == 17 ) ||
- ( a == 3 && b == 4 ) ||
- ( a == 3 && b == 5 ) ||
- ( a == 3 && b == 6 ) ||
- ( a == 3 && b == 9 ) ||
- ( a == 3 && b == 14 ) ||
- ( a == 3 && b == 16 ) ||
- ( a == 4 && b == 5 ) ||
- ( a == 4 && b == 11 ) ||
- ( a == 4 && b == 12 ) ||
- ( a == 4 && b == 18 ) ||
- ( a == 5 && b == 8 ) ||
- ( a == 5 && b == 13 ) ||
- ( a == 5 && b == 19 ) ||
- ( a == 6 && b == 7 ) ||
- ( a == 6 && b == 8 ) ||
- ( a == 6 && b == 9 ) ||
- ( a == 6 && b == 12 ) ||
- ( a == 6 && b == 17 ) ||
- ( a == 7 && b == 8 ) ||
- ( a == 7 && b == 10 ) ||
- ( a == 7 && b == 14 ) ||
- ( a == 7 && b == 19 ) ||
- ( a == 8 && b == 15 ) ||
- ( a == 8 && b == 18 ) ||
- ( a == 9 && b == 10 ) ||
- ( a == 9 && b == 11 ) ||
- ( a == 9 && b == 13 ) ||
- ( a == 9 && b == 15 ) ||
- ( a == 10 && b == 11 ) ||
- ( a == 10 && b == 16 ) ||
- ( a == 10 && b == 18 ) ||
- ( a == 11 && b == 17 ) ||
- ( a == 11 && b == 19 ) ||
- ( a == 12 && b == 13 ) ||
- ( a == 12 && b == 17 ) ||
- ( a == 12 && b == 18 ) ||
- ( a == 13 && b == 15 ) ||
- ( a == 13 && b == 19 ) ||
- ( a == 14 && b == 15 ) ||
- ( a == 14 && b == 16 ) ||
- ( a == 14 && b == 19 ) ||
- ( a == 15 && b == 18 ) ||
- ( a == 16 && b == 17 ) ||
- ( a == 16 && b == 18 ) ||
- ( a == 17 && b == 19 ) )
- return (2 - 3*Nc2 + Nc4)/(32.*Nc);
- if( ( a == 0 && b == 3 ) ||
- ( a == 1 && b == 6 ) ||
- ( a == 2 && b == 9 ) ||
- ( a == 4 && b == 7 ) ||
- ( a == 5 && b == 10 ) ||
- ( a == 8 && b == 11 ) ||
- ( a == 12 && b == 14 ) ||
- ( a == 13 && b == 16 ) ||
- ( a == 15 && b == 17 ) ||
- ( a == 18 && b == 19 ) )
- return -sqr(-1 + Nc2)/(16.*Nc);
- if( ( a == 0 && b == 4 ) ||
- ( a == 0 && b == 5 ) ||
- ( a == 0 && b == 6 ) ||
- ( a == 0 && b == 9 ) ||
- ( a == 0 && b == 14 ) ||
- ( a == 0 && b == 16 ) ||
- ( a == 1 && b == 3 ) ||
- ( a == 1 && b == 7 ) ||
- ( a == 1 && b == 8 ) ||
- ( a == 1 && b == 9 ) ||
- ( a == 1 && b == 12 ) ||
- ( a == 1 && b == 17 ) ||
- ( a == 2 && b == 3 ) ||
- ( a == 2 && b == 6 ) ||
- ( a == 2 && b == 10 ) ||
- ( a == 2 && b == 11 ) ||
- ( a == 2 && b == 13 ) ||
- ( a == 2 && b == 15 ) ||
- ( a == 3 && b == 7 ) ||
- ( a == 3 && b == 10 ) ||
- ( a == 3 && b == 12 ) ||
- ( a == 3 && b == 13 ) ||
- ( a == 4 && b == 6 ) ||
- ( a == 4 && b == 8 ) ||
- ( a == 4 && b == 10 ) ||
- ( a == 4 && b == 14 ) ||
- ( a == 4 && b == 19 ) ||
- ( a == 5 && b == 7 ) ||
- ( a == 5 && b == 9 ) ||
- ( a == 5 && b == 11 ) ||
- ( a == 5 && b == 16 ) ||
- ( a == 5 && b == 18 ) ||
- ( a == 6 && b == 11 ) ||
- ( a == 6 && b == 14 ) ||
- ( a == 6 && b == 15 ) ||
- ( a == 7 && b == 11 ) ||
- ( a == 7 && b == 12 ) ||
- ( a == 7 && b == 18 ) ||
- ( a == 8 && b == 9 ) ||
- ( a == 8 && b == 10 ) ||
- ( a == 8 && b == 17 ) ||
- ( a == 8 && b == 19 ) ||
- ( a == 9 && b == 16 ) ||
- ( a == 9 && b == 17 ) ||
- ( a == 10 && b == 13 ) ||
- ( a == 10 && b == 19 ) ||
- ( a == 11 && b == 15 ) ||
- ( a == 11 && b == 18 ) ||
- ( a == 12 && b == 15 ) ||
- ( a == 12 && b == 16 ) ||
- ( a == 12 && b == 19 ) ||
- ( a == 13 && b == 14 ) ||
- ( a == 13 && b == 17 ) ||
- ( a == 13 && b == 18 ) ||
- ( a == 14 && b == 17 ) ||
- ( a == 14 && b == 18 ) ||
- ( a == 15 && b == 16 ) ||
- ( a == 15 && b == 19 ) ||
- ( a == 16 && b == 19 ) ||
- ( a == 17 && b == 18 ) )
- return -(-1 + Nc2)/(16.*Nc);
- if( ( a == 0 && b == 8 ) ||
- ( a == 0 && b == 11 ) ||
- ( a == 0 && b == 15 ) ||
- ( a == 0 && b == 17 ) ||
- ( a == 0 && b == 18 ) ||
- ( a == 0 && b == 19 ) ||
- ( a == 1 && b == 5 ) ||
- ( a == 1 && b == 10 ) ||
- ( a == 1 && b == 13 ) ||
- ( a == 1 && b == 16 ) ||
- ( a == 1 && b == 18 ) ||
- ( a == 1 && b == 19 ) ||
- ( a == 2 && b == 4 ) ||
- ( a == 2 && b == 7 ) ||
- ( a == 2 && b == 12 ) ||
- ( a == 2 && b == 14 ) ||
- ( a == 2 && b == 18 ) ||
- ( a == 2 && b == 19 ) ||
- ( a == 3 && b == 8 ) ||
- ( a == 3 && b == 11 ) ||
- ( a == 3 && b == 15 ) ||
- ( a == 3 && b == 17 ) ||
- ( a == 3 && b == 18 ) ||
- ( a == 3 && b == 19 ) ||
- ( a == 4 && b == 9 ) ||
- ( a == 4 && b == 13 ) ||
- ( a == 4 && b == 15 ) ||
- ( a == 4 && b == 16 ) ||
- ( a == 4 && b == 17 ) ||
- ( a == 5 && b == 6 ) ||
- ( a == 5 && b == 12 ) ||
- ( a == 5 && b == 14 ) ||
- ( a == 5 && b == 15 ) ||
- ( a == 5 && b == 17 ) ||
- ( a == 6 && b == 10 ) ||
- ( a == 6 && b == 13 ) ||
- ( a == 6 && b == 16 ) ||
- ( a == 6 && b == 18 ) ||
- ( a == 6 && b == 19 ) ||
- ( a == 7 && b == 9 ) ||
- ( a == 7 && b == 13 ) ||
- ( a == 7 && b == 15 ) ||
- ( a == 7 && b == 16 ) ||
- ( a == 7 && b == 17 ) ||
- ( a == 8 && b == 12 ) ||
- ( a == 8 && b == 13 ) ||
- ( a == 8 && b == 14 ) ||
- ( a == 8 && b == 16 ) ||
- ( a == 9 && b == 12 ) ||
- ( a == 9 && b == 14 ) ||
- ( a == 9 && b == 18 ) ||
- ( a == 9 && b == 19 ) ||
- ( a == 10 && b == 12 ) ||
- ( a == 10 && b == 14 ) ||
- ( a == 10 && b == 15 ) ||
- ( a == 10 && b == 17 ) ||
- ( a == 11 && b == 12 ) ||
- ( a == 11 && b == 13 ) ||
- ( a == 11 && b == 14 ) ||
- ( a == 11 && b == 16 ) )
- return 0;
- if( ( a == 0 && b == 20 ) ||
- ( a == 0 && b == 21 ) ||
- ( a == 0 && b == 23 ) ||
- ( a == 0 && b == 25 ) ||
- ( a == 0 && b == 36 ) ||
- ( a == 0 && b == 42 ) ||
- ( a == 1 && b == 21 ) ||
- ( a == 1 && b == 22 ) ||
- ( a == 1 && b == 23 ) ||
- ( a == 1 && b == 24 ) ||
- ( a == 1 && b == 30 ) ||
- ( a == 1 && b == 40 ) ||
- ( a == 2 && b == 20 ) ||
- ( a == 2 && b == 22 ) ||
- ( a == 2 && b == 24 ) ||
- ( a == 2 && b == 25 ) ||
- ( a == 2 && b == 28 ) ||
- ( a == 2 && b == 34 ) ||
- ( a == 3 && b == 26 ) ||
- ( a == 3 && b == 27 ) ||
- ( a == 3 && b == 29 ) ||
- ( a == 3 && b == 31 ) ||
- ( a == 3 && b == 37 ) ||
- ( a == 3 && b == 43 ) ||
- ( a == 4 && b == 24 ) ||
- ( a == 4 && b == 27 ) ||
- ( a == 4 && b == 28 ) ||
- ( a == 4 && b == 29 ) ||
- ( a == 4 && b == 30 ) ||
- ( a == 4 && b == 38 ) ||
- ( a == 5 && b == 22 ) ||
- ( a == 5 && b == 26 ) ||
- ( a == 5 && b == 28 ) ||
- ( a == 5 && b == 30 ) ||
- ( a == 5 && b == 31 ) ||
- ( a == 5 && b == 32 ) ||
- ( a == 6 && b == 31 ) ||
- ( a == 6 && b == 32 ) ||
- ( a == 6 && b == 33 ) ||
- ( a == 6 && b == 35 ) ||
- ( a == 6 && b == 37 ) ||
- ( a == 6 && b == 41 ) ||
- ( a == 7 && b == 25 ) ||
- ( a == 7 && b == 33 ) ||
- ( a == 7 && b == 34 ) ||
- ( a == 7 && b == 35 ) ||
- ( a == 7 && b == 36 ) ||
- ( a == 7 && b == 39 ) ||
- ( a == 8 && b == 20 ) ||
- ( a == 8 && b == 26 ) ||
- ( a == 8 && b == 32 ) ||
- ( a == 8 && b == 34 ) ||
- ( a == 8 && b == 36 ) ||
- ( a == 8 && b == 37 ) ||
- ( a == 9 && b == 29 ) ||
- ( a == 9 && b == 35 ) ||
- ( a == 9 && b == 38 ) ||
- ( a == 9 && b == 39 ) ||
- ( a == 9 && b == 41 ) ||
- ( a == 9 && b == 43 ) ||
- ( a == 10 && b == 23 ) ||
- ( a == 10 && b == 33 ) ||
- ( a == 10 && b == 39 ) ||
- ( a == 10 && b == 40 ) ||
- ( a == 10 && b == 41 ) ||
- ( a == 10 && b == 42 ) ||
- ( a == 11 && b == 21 ) ||
- ( a == 11 && b == 27 ) ||
- ( a == 11 && b == 38 ) ||
- ( a == 11 && b == 40 ) ||
- ( a == 11 && b == 42 ) ||
- ( a == 11 && b == 43 ) ||
- ( a == 12 && b == 20 ) ||
- ( a == 12 && b == 28 ) ||
- ( a == 12 && b == 32 ) ||
- ( a == 12 && b == 38 ) ||
- ( a == 12 && b == 41 ) ||
- ( a == 12 && b == 42 ) ||
- ( a == 13 && b == 21 ) ||
- ( a == 13 && b == 30 ) ||
- ( a == 13 && b == 32 ) ||
- ( a == 13 && b == 35 ) ||
- ( a == 13 && b == 36 ) ||
- ( a == 13 && b == 38 ) ||
- ( a == 14 && b == 22 ) ||
- ( a == 14 && b == 26 ) ||
- ( a == 14 && b == 34 ) ||
- ( a == 14 && b == 39 ) ||
- ( a == 14 && b == 40 ) ||
- ( a == 14 && b == 43 ) ||
- ( a == 15 && b == 23 ) ||
- ( a == 15 && b == 26 ) ||
- ( a == 15 && b == 29 ) ||
- ( a == 15 && b == 30 ) ||
- ( a == 15 && b == 36 ) ||
- ( a == 15 && b == 39 ) ||
- ( a == 16 && b == 24 ) ||
- ( a == 16 && b == 27 ) ||
- ( a == 16 && b == 33 ) ||
- ( a == 16 && b == 34 ) ||
- ( a == 16 && b == 37 ) ||
- ( a == 16 && b == 40 ) ||
- ( a == 17 && b == 25 ) ||
- ( a == 17 && b == 27 ) ||
- ( a == 17 && b == 28 ) ||
- ( a == 17 && b == 31 ) ||
- ( a == 17 && b == 33 ) ||
- ( a == 17 && b == 42 ) ||
- ( a == 18 && b == 20 ) ||
- ( a == 18 && b == 23 ) ||
- ( a == 18 && b == 24 ) ||
- ( a == 18 && b == 29 ) ||
- ( a == 18 && b == 37 ) ||
- ( a == 18 && b == 41 ) ||
- ( a == 19 && b == 21 ) ||
- ( a == 19 && b == 22 ) ||
- ( a == 19 && b == 25 ) ||
- ( a == 19 && b == 31 ) ||
- ( a == 19 && b == 35 ) ||
- ( a == 19 && b == 43 ) )
- return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2);
- if( ( a == 0 && b == 22 ) ||
- ( a == 0 && b == 24 ) ||
- ( a == 0 && b == 32 ) ||
- ( a == 0 && b == 33 ) ||
- ( a == 0 && b == 38 ) ||
- ( a == 0 && b == 39 ) ||
- ( a == 1 && b == 20 ) ||
- ( a == 1 && b == 25 ) ||
- ( a == 1 && b == 26 ) ||
- ( a == 1 && b == 27 ) ||
- ( a == 1 && b == 38 ) ||
- ( a == 1 && b == 39 ) ||
- ( a == 2 && b == 21 ) ||
- ( a == 2 && b == 23 ) ||
- ( a == 2 && b == 26 ) ||
- ( a == 2 && b == 27 ) ||
- ( a == 2 && b == 32 ) ||
- ( a == 2 && b == 33 ) ||
- ( a == 3 && b == 28 ) ||
- ( a == 3 && b == 30 ) ||
- ( a == 3 && b == 34 ) ||
- ( a == 3 && b == 35 ) ||
- ( a == 3 && b == 40 ) ||
- ( a == 3 && b == 41 ) ||
- ( a == 4 && b == 20 ) ||
- ( a == 4 && b == 21 ) ||
- ( a == 4 && b == 26 ) ||
- ( a == 4 && b == 31 ) ||
- ( a == 4 && b == 40 ) ||
- ( a == 4 && b == 41 ) ||
- ( a == 5 && b == 20 ) ||
- ( a == 5 && b == 21 ) ||
- ( a == 5 && b == 27 ) ||
- ( a == 5 && b == 29 ) ||
- ( a == 5 && b == 34 ) ||
- ( a == 5 && b == 35 ) ||
- ( a == 6 && b == 28 ) ||
- ( a == 6 && b == 29 ) ||
- ( a == 6 && b == 34 ) ||
- ( a == 6 && b == 36 ) ||
- ( a == 6 && b == 42 ) ||
- ( a == 6 && b == 43 ) ||
- ( a == 7 && b == 22 ) ||
- ( a == 7 && b == 23 ) ||
- ( a == 7 && b == 32 ) ||
- ( a == 7 && b == 37 ) ||
- ( a == 7 && b == 42 ) ||
- ( a == 7 && b == 43 ) ||
- ( a == 8 && b == 22 ) ||
- ( a == 8 && b == 23 ) ||
- ( a == 8 && b == 28 ) ||
- ( a == 8 && b == 29 ) ||
- ( a == 8 && b == 33 ) ||
- ( a == 8 && b == 35 ) ||
- ( a == 9 && b == 30 ) ||
- ( a == 9 && b == 31 ) ||
- ( a == 9 && b == 36 ) ||
- ( a == 9 && b == 37 ) ||
- ( a == 9 && b == 40 ) ||
- ( a == 9 && b == 42 ) ||
- ( a == 10 && b == 24 ) ||
- ( a == 10 && b == 25 ) ||
- ( a == 10 && b == 36 ) ||
- ( a == 10 && b == 37 ) ||
- ( a == 10 && b == 38 ) ||
- ( a == 10 && b == 43 ) ||
- ( a == 11 && b == 24 ) ||
- ( a == 11 && b == 25 ) ||
- ( a == 11 && b == 30 ) ||
- ( a == 11 && b == 31 ) ||
- ( a == 11 && b == 39 ) ||
- ( a == 11 && b == 41 ) ||
- ( a == 12 && b == 21 ) ||
- ( a == 12 && b == 24 ) ||
- ( a == 12 && b == 29 ) ||
- ( a == 12 && b == 31 ) ||
- ( a == 12 && b == 33 ) ||
- ( a == 12 && b == 36 ) ||
- ( a == 13 && b == 20 ) ||
- ( a == 13 && b == 22 ) ||
- ( a == 13 && b == 29 ) ||
- ( a == 13 && b == 31 ) ||
- ( a == 13 && b == 39 ) ||
- ( a == 13 && b == 42 ) ||
- ( a == 14 && b == 23 ) ||
- ( a == 14 && b == 25 ) ||
- ( a == 14 && b == 27 ) ||
- ( a == 14 && b == 30 ) ||
- ( a == 14 && b == 35 ) ||
- ( a == 14 && b == 37 ) ||
- ( a == 15 && b == 20 ) ||
- ( a == 15 && b == 22 ) ||
- ( a == 15 && b == 35 ) ||
- ( a == 15 && b == 37 ) ||
- ( a == 15 && b == 38 ) ||
- ( a == 15 && b == 40 ) ||
- ( a == 16 && b == 23 ) ||
- ( a == 16 && b == 25 ) ||
- ( a == 16 && b == 26 ) ||
- ( a == 16 && b == 28 ) ||
- ( a == 16 && b == 41 ) ||
- ( a == 16 && b == 43 ) ||
- ( a == 17 && b == 21 ) ||
- ( a == 17 && b == 24 ) ||
- ( a == 17 && b == 32 ) ||
- ( a == 17 && b == 34 ) ||
- ( a == 17 && b == 41 ) ||
- ( a == 17 && b == 43 ) ||
- ( a == 18 && b == 26 ) ||
- ( a == 18 && b == 28 ) ||
- ( a == 18 && b == 33 ) ||
- ( a == 18 && b == 36 ) ||
- ( a == 18 && b == 38 ) ||
- ( a == 18 && b == 40 ) ||
- ( a == 19 && b == 27 ) ||
- ( a == 19 && b == 30 ) ||
- ( a == 19 && b == 32 ) ||
- ( a == 19 && b == 34 ) ||
- ( a == 19 && b == 39 ) ||
- ( a == 19 && b == 42 ) )
- return -(2 - 3*Nc2 + Nc4)/(32.*Nc2);
- if( ( a == 0 && b == 26 ) ||
- ( a == 0 && b == 27 ) ||
- ( a == 0 && b == 29 ) ||
- ( a == 0 && b == 31 ) ||
- ( a == 0 && b == 37 ) ||
- ( a == 0 && b == 43 ) ||
- ( a == 1 && b == 31 ) ||
- ( a == 1 && b == 32 ) ||
- ( a == 1 && b == 33 ) ||
- ( a == 1 && b == 35 ) ||
- ( a == 1 && b == 37 ) ||
- ( a == 1 && b == 41 ) ||
- ( a == 2 && b == 29 ) ||
- ( a == 2 && b == 35 ) ||
- ( a == 2 && b == 38 ) ||
- ( a == 2 && b == 39 ) ||
- ( a == 2 && b == 41 ) ||
- ( a == 2 && b == 43 ) ||
- ( a == 3 && b == 20 ) ||
- ( a == 3 && b == 21 ) ||
- ( a == 3 && b == 23 ) ||
- ( a == 3 && b == 25 ) ||
- ( a == 3 && b == 36 ) ||
- ( a == 3 && b == 42 ) ||
- ( a == 4 && b == 25 ) ||
- ( a == 4 && b == 33 ) ||
- ( a == 4 && b == 34 ) ||
- ( a == 4 && b == 35 ) ||
- ( a == 4 && b == 36 ) ||
- ( a == 4 && b == 39 ) ||
- ( a == 5 && b == 23 ) ||
- ( a == 5 && b == 33 ) ||
- ( a == 5 && b == 39 ) ||
- ( a == 5 && b == 40 ) ||
- ( a == 5 && b == 41 ) ||
- ( a == 5 && b == 42 ) ||
- ( a == 6 && b == 21 ) ||
- ( a == 6 && b == 22 ) ||
- ( a == 6 && b == 23 ) ||
- ( a == 6 && b == 24 ) ||
- ( a == 6 && b == 30 ) ||
- ( a == 6 && b == 40 ) ||
- ( a == 7 && b == 24 ) ||
- ( a == 7 && b == 27 ) ||
- ( a == 7 && b == 28 ) ||
- ( a == 7 && b == 29 ) ||
- ( a == 7 && b == 30 ) ||
- ( a == 7 && b == 38 ) ||
- ( a == 8 && b == 21 ) ||
- ( a == 8 && b == 27 ) ||
- ( a == 8 && b == 38 ) ||
- ( a == 8 && b == 40 ) ||
- ( a == 8 && b == 42 ) ||
- ( a == 8 && b == 43 ) ||
- ( a == 9 && b == 20 ) ||
- ( a == 9 && b == 22 ) ||
- ( a == 9 && b == 24 ) ||
- ( a == 9 && b == 25 ) ||
- ( a == 9 && b == 28 ) ||
- ( a == 9 && b == 34 ) ||
- ( a == 10 && b == 22 ) ||
- ( a == 10 && b == 26 ) ||
- ( a == 10 && b == 28 ) ||
- ( a == 10 && b == 30 ) ||
- ( a == 10 && b == 31 ) ||
- ( a == 10 && b == 32 ) ||
- ( a == 11 && b == 20 ) ||
- ( a == 11 && b == 26 ) ||
- ( a == 11 && b == 32 ) ||
- ( a == 11 && b == 34 ) ||
- ( a == 11 && b == 36 ) ||
- ( a == 11 && b == 37 ) ||
- ( a == 12 && b == 22 ) ||
- ( a == 12 && b == 26 ) ||
- ( a == 12 && b == 34 ) ||
- ( a == 12 && b == 39 ) ||
- ( a == 12 && b == 40 ) ||
- ( a == 12 && b == 43 ) ||
- ( a == 13 && b == 24 ) ||
- ( a == 13 && b == 27 ) ||
- ( a == 13 && b == 33 ) ||
- ( a == 13 && b == 34 ) ||
- ( a == 13 && b == 37 ) ||
- ( a == 13 && b == 40 ) ||
- ( a == 14 && b == 20 ) ||
- ( a == 14 && b == 28 ) ||
- ( a == 14 && b == 32 ) ||
- ( a == 14 && b == 38 ) ||
- ( a == 14 && b == 41 ) ||
- ( a == 14 && b == 42 ) ||
- ( a == 15 && b == 25 ) ||
- ( a == 15 && b == 27 ) ||
- ( a == 15 && b == 28 ) ||
- ( a == 15 && b == 31 ) ||
- ( a == 15 && b == 33 ) ||
- ( a == 15 && b == 42 ) ||
- ( a == 16 && b == 21 ) ||
- ( a == 16 && b == 30 ) ||
- ( a == 16 && b == 32 ) ||
- ( a == 16 && b == 35 ) ||
- ( a == 16 && b == 36 ) ||
- ( a == 16 && b == 38 ) ||
- ( a == 17 && b == 23 ) ||
- ( a == 17 && b == 26 ) ||
- ( a == 17 && b == 29 ) ||
- ( a == 17 && b == 30 ) ||
- ( a == 17 && b == 36 ) ||
- ( a == 17 && b == 39 ) ||
- ( a == 18 && b == 21 ) ||
- ( a == 18 && b == 22 ) ||
- ( a == 18 && b == 25 ) ||
- ( a == 18 && b == 31 ) ||
- ( a == 18 && b == 35 ) ||
- ( a == 18 && b == 43 ) ||
- ( a == 19 && b == 20 ) ||
- ( a == 19 && b == 23 ) ||
- ( a == 19 && b == 24 ) ||
- ( a == 19 && b == 29 ) ||
- ( a == 19 && b == 37 ) ||
- ( a == 19 && b == 41 ) )
- return -sqr(-1 + Nc2)/(16.*Nc2);
- if( ( a == 0 && b == 28 ) ||
- ( a == 0 && b == 30 ) ||
- ( a == 0 && b == 34 ) ||
- ( a == 0 && b == 35 ) ||
- ( a == 0 && b == 40 ) ||
- ( a == 0 && b == 41 ) ||
- ( a == 1 && b == 28 ) ||
- ( a == 1 && b == 29 ) ||
- ( a == 1 && b == 34 ) ||
- ( a == 1 && b == 36 ) ||
- ( a == 1 && b == 42 ) ||
- ( a == 1 && b == 43 ) ||
- ( a == 2 && b == 30 ) ||
- ( a == 2 && b == 31 ) ||
- ( a == 2 && b == 36 ) ||
- ( a == 2 && b == 37 ) ||
- ( a == 2 && b == 40 ) ||
- ( a == 2 && b == 42 ) ||
- ( a == 3 && b == 22 ) ||
- ( a == 3 && b == 24 ) ||
- ( a == 3 && b == 32 ) ||
- ( a == 3 && b == 33 ) ||
- ( a == 3 && b == 38 ) ||
- ( a == 3 && b == 39 ) ||
- ( a == 4 && b == 22 ) ||
- ( a == 4 && b == 23 ) ||
- ( a == 4 && b == 32 ) ||
- ( a == 4 && b == 37 ) ||
- ( a == 4 && b == 42 ) ||
- ( a == 4 && b == 43 ) ||
- ( a == 5 && b == 24 ) ||
- ( a == 5 && b == 25 ) ||
- ( a == 5 && b == 36 ) ||
- ( a == 5 && b == 37 ) ||
- ( a == 5 && b == 38 ) ||
- ( a == 5 && b == 43 ) ||
- ( a == 6 && b == 20 ) ||
- ( a == 6 && b == 25 ) ||
- ( a == 6 && b == 26 ) ||
- ( a == 6 && b == 27 ) ||
- ( a == 6 && b == 38 ) ||
- ( a == 6 && b == 39 ) ||
- ( a == 7 && b == 20 ) ||
- ( a == 7 && b == 21 ) ||
- ( a == 7 && b == 26 ) ||
- ( a == 7 && b == 31 ) ||
- ( a == 7 && b == 40 ) ||
- ( a == 7 && b == 41 ) ||
- ( a == 8 && b == 24 ) ||
- ( a == 8 && b == 25 ) ||
- ( a == 8 && b == 30 ) ||
- ( a == 8 && b == 31 ) ||
- ( a == 8 && b == 39 ) ||
- ( a == 8 && b == 41 ) ||
- ( a == 9 && b == 21 ) ||
- ( a == 9 && b == 23 ) ||
- ( a == 9 && b == 26 ) ||
- ( a == 9 && b == 27 ) ||
- ( a == 9 && b == 32 ) ||
- ( a == 9 && b == 33 ) ||
- ( a == 10 && b == 20 ) ||
- ( a == 10 && b == 21 ) ||
- ( a == 10 && b == 27 ) ||
- ( a == 10 && b == 29 ) ||
- ( a == 10 && b == 34 ) ||
- ( a == 10 && b == 35 ) ||
- ( a == 11 && b == 22 ) ||
- ( a == 11 && b == 23 ) ||
- ( a == 11 && b == 28 ) ||
- ( a == 11 && b == 29 ) ||
- ( a == 11 && b == 33 ) ||
- ( a == 11 && b == 35 ) ||
- ( a == 12 && b == 23 ) ||
- ( a == 12 && b == 25 ) ||
- ( a == 12 && b == 27 ) ||
- ( a == 12 && b == 30 ) ||
- ( a == 12 && b == 35 ) ||
- ( a == 12 && b == 37 ) ||
- ( a == 13 && b == 23 ) ||
- ( a == 13 && b == 25 ) ||
- ( a == 13 && b == 26 ) ||
- ( a == 13 && b == 28 ) ||
- ( a == 13 && b == 41 ) ||
- ( a == 13 && b == 43 ) ||
- ( a == 14 && b == 21 ) ||
- ( a == 14 && b == 24 ) ||
- ( a == 14 && b == 29 ) ||
- ( a == 14 && b == 31 ) ||
- ( a == 14 && b == 33 ) ||
- ( a == 14 && b == 36 ) ||
- ( a == 15 && b == 21 ) ||
- ( a == 15 && b == 24 ) ||
- ( a == 15 && b == 32 ) ||
- ( a == 15 && b == 34 ) ||
- ( a == 15 && b == 41 ) ||
- ( a == 15 && b == 43 ) ||
- ( a == 16 && b == 20 ) ||
- ( a == 16 && b == 22 ) ||
- ( a == 16 && b == 29 ) ||
- ( a == 16 && b == 31 ) ||
- ( a == 16 && b == 39 ) ||
- ( a == 16 && b == 42 ) ||
- ( a == 17 && b == 20 ) ||
- ( a == 17 && b == 22 ) ||
- ( a == 17 && b == 35 ) ||
- ( a == 17 && b == 37 ) ||
- ( a == 17 && b == 38 ) ||
- ( a == 17 && b == 40 ) ||
- ( a == 18 && b == 27 ) ||
- ( a == 18 && b == 30 ) ||
- ( a == 18 && b == 32 ) ||
- ( a == 18 && b == 34 ) ||
- ( a == 18 && b == 39 ) ||
- ( a == 18 && b == 42 ) ||
- ( a == 19 && b == 26 ) ||
- ( a == 19 && b == 28 ) ||
- ( a == 19 && b == 33 ) ||
- ( a == 19 && b == 36 ) ||
- ( a == 19 && b == 38 ) ||
- ( a == 19 && b == 40 ) )
- return (1 - 1/Nc2)/16.;
- if( ( a == 20 && b == 20 ) ||
- ( a == 21 && b == 21 ) ||
- ( a == 22 && b == 22 ) ||
- ( a == 23 && b == 23 ) ||
- ( a == 24 && b == 24 ) ||
- ( a == 25 && b == 25 ) ||
- ( a == 26 && b == 26 ) ||
- ( a == 27 && b == 27 ) ||
- ( a == 28 && b == 28 ) ||
- ( a == 29 && b == 29 ) ||
- ( a == 30 && b == 30 ) ||
- ( a == 31 && b == 31 ) ||
- ( a == 32 && b == 32 ) ||
- ( a == 33 && b == 33 ) ||
- ( a == 34 && b == 34 ) ||
- ( a == 35 && b == 35 ) ||
- ( a == 36 && b == 36 ) ||
- ( a == 37 && b == 37 ) ||
- ( a == 38 && b == 38 ) ||
- ( a == 39 && b == 39 ) ||
- ( a == 40 && b == 40 ) ||
- ( a == 41 && b == 41 ) ||
- ( a == 42 && b == 42 ) ||
- ( a == 43 && b == 43 ) )
- return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3);
- if( ( a == 20 && b == 21 ) ||
- ( a == 20 && b == 22 ) ||
- ( a == 20 && b == 26 ) ||
- ( a == 20 && b == 29 ) ||
- ( a == 20 && b == 38 ) ||
- ( a == 21 && b == 24 ) ||
- ( a == 21 && b == 27 ) ||
- ( a == 21 && b == 31 ) ||
- ( a == 21 && b == 32 ) ||
- ( a == 22 && b == 23 ) ||
- ( a == 22 && b == 32 ) ||
- ( a == 22 && b == 35 ) ||
- ( a == 22 && b == 39 ) ||
- ( a == 23 && b == 25 ) ||
- ( a == 23 && b == 26 ) ||
- ( a == 23 && b == 33 ) ||
- ( a == 23 && b == 37 ) ||
- ( a == 24 && b == 25 ) ||
- ( a == 24 && b == 33 ) ||
- ( a == 24 && b == 38 ) ||
- ( a == 24 && b == 41 ) ||
- ( a == 25 && b == 27 ) ||
- ( a == 25 && b == 39 ) ||
- ( a == 25 && b == 43 ) ||
- ( a == 26 && b == 27 ) ||
- ( a == 26 && b == 28 ) ||
- ( a == 26 && b == 40 ) ||
- ( a == 27 && b == 30 ) ||
- ( a == 27 && b == 34 ) ||
- ( a == 28 && b == 29 ) ||
- ( a == 28 && b == 33 ) ||
- ( a == 28 && b == 34 ) ||
- ( a == 28 && b == 41 ) ||
- ( a == 29 && b == 31 ) ||
- ( a == 29 && b == 35 ) ||
- ( a == 29 && b == 36 ) ||
- ( a == 30 && b == 31 ) ||
- ( a == 30 && b == 35 ) ||
- ( a == 30 && b == 39 ) ||
- ( a == 30 && b == 40 ) ||
- ( a == 31 && b == 41 ) ||
- ( a == 31 && b == 42 ) ||
- ( a == 32 && b == 33 ) ||
- ( a == 32 && b == 34 ) ||
- ( a == 32 && b == 42 ) ||
- ( a == 33 && b == 36 ) ||
- ( a == 34 && b == 35 ) ||
- ( a == 34 && b == 43 ) ||
- ( a == 35 && b == 37 ) ||
- ( a == 36 && b == 37 ) ||
- ( a == 36 && b == 38 ) ||
- ( a == 36 && b == 42 ) ||
- ( a == 37 && b == 40 ) ||
- ( a == 37 && b == 43 ) ||
- ( a == 38 && b == 39 ) ||
- ( a == 38 && b == 40 ) ||
- ( a == 39 && b == 42 ) ||
- ( a == 40 && b == 41 ) ||
- ( a == 41 && b == 43 ) ||
- ( a == 42 && b == 43 ) )
- return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3);
- if( ( a == 20 && b == 23 ) ||
- ( a == 20 && b == 24 ) ||
- ( a == 20 && b == 28 ) ||
- ( a == 20 && b == 32 ) ||
- ( a == 20 && b == 36 ) ||
- ( a == 21 && b == 22 ) ||
- ( a == 21 && b == 25 ) ||
- ( a == 21 && b == 30 ) ||
- ( a == 21 && b == 38 ) ||
- ( a == 21 && b == 42 ) ||
- ( a == 22 && b == 25 ) ||
- ( a == 22 && b == 26 ) ||
- ( a == 22 && b == 30 ) ||
- ( a == 22 && b == 34 ) ||
- ( a == 23 && b == 24 ) ||
- ( a == 23 && b == 36 ) ||
- ( a == 23 && b == 39 ) ||
- ( a == 23 && b == 40 ) ||
- ( a == 24 && b == 27 ) ||
- ( a == 24 && b == 28 ) ||
- ( a == 24 && b == 40 ) ||
- ( a == 25 && b == 33 ) ||
- ( a == 25 && b == 34 ) ||
- ( a == 25 && b == 42 ) ||
- ( a == 26 && b == 29 ) ||
- ( a == 26 && b == 30 ) ||
- ( a == 26 && b == 34 ) ||
- ( a == 26 && b == 37 ) ||
- ( a == 27 && b == 28 ) ||
- ( a == 27 && b == 31 ) ||
- ( a == 27 && b == 40 ) ||
- ( a == 27 && b == 43 ) ||
- ( a == 28 && b == 31 ) ||
- ( a == 28 && b == 32 ) ||
- ( a == 29 && b == 30 ) ||
- ( a == 29 && b == 37 ) ||
- ( a == 29 && b == 38 ) ||
- ( a == 29 && b == 41 ) ||
- ( a == 30 && b == 38 ) ||
- ( a == 31 && b == 32 ) ||
- ( a == 31 && b == 35 ) ||
- ( a == 31 && b == 43 ) ||
- ( a == 32 && b == 35 ) ||
- ( a == 32 && b == 36 ) ||
- ( a == 33 && b == 34 ) ||
- ( a == 33 && b == 37 ) ||
- ( a == 33 && b == 41 ) ||
- ( a == 33 && b == 42 ) ||
- ( a == 34 && b == 37 ) ||
- ( a == 35 && b == 36 ) ||
- ( a == 35 && b == 39 ) ||
- ( a == 35 && b == 43 ) ||
- ( a == 36 && b == 39 ) ||
- ( a == 37 && b == 41 ) ||
- ( a == 38 && b == 41 ) ||
- ( a == 38 && b == 42 ) ||
- ( a == 39 && b == 40 ) ||
- ( a == 39 && b == 43 ) ||
- ( a == 40 && b == 43 ) ||
- ( a == 41 && b == 42 ) )
- return (2 - 3*Nc2 + Nc4)/(16.*Nc3);
- if( ( a == 20 && b == 25 ) ||
- ( a == 20 && b == 34 ) ||
- ( a == 20 && b == 37 ) ||
- ( a == 20 && b == 41 ) ||
- ( a == 20 && b == 42 ) ||
- ( a == 21 && b == 23 ) ||
- ( a == 21 && b == 35 ) ||
- ( a == 21 && b == 36 ) ||
- ( a == 21 && b == 40 ) ||
- ( a == 21 && b == 43 ) ||
- ( a == 22 && b == 24 ) ||
- ( a == 22 && b == 28 ) ||
- ( a == 22 && b == 31 ) ||
- ( a == 22 && b == 40 ) ||
- ( a == 22 && b == 43 ) ||
- ( a == 23 && b == 29 ) ||
- ( a == 23 && b == 30 ) ||
- ( a == 23 && b == 41 ) ||
- ( a == 23 && b == 42 ) ||
- ( a == 24 && b == 29 ) ||
- ( a == 24 && b == 30 ) ||
- ( a == 24 && b == 34 ) ||
- ( a == 24 && b == 37 ) ||
- ( a == 25 && b == 28 ) ||
- ( a == 25 && b == 31 ) ||
- ( a == 25 && b == 35 ) ||
- ( a == 25 && b == 36 ) ||
- ( a == 26 && b == 31 ) ||
- ( a == 26 && b == 32 ) ||
- ( a == 26 && b == 36 ) ||
- ( a == 26 && b == 39 ) ||
- ( a == 26 && b == 43 ) ||
- ( a == 27 && b == 29 ) ||
- ( a == 27 && b == 33 ) ||
- ( a == 27 && b == 37 ) ||
- ( a == 27 && b == 38 ) ||
- ( a == 27 && b == 42 ) ||
- ( a == 28 && b == 30 ) ||
- ( a == 28 && b == 38 ) ||
- ( a == 28 && b == 42 ) ||
- ( a == 29 && b == 39 ) ||
- ( a == 29 && b == 43 ) ||
- ( a == 30 && b == 32 ) ||
- ( a == 30 && b == 36 ) ||
- ( a == 31 && b == 33 ) ||
- ( a == 31 && b == 37 ) ||
- ( a == 32 && b == 37 ) ||
- ( a == 32 && b == 38 ) ||
- ( a == 32 && b == 41 ) ||
- ( a == 33 && b == 35 ) ||
- ( a == 33 && b == 39 ) ||
- ( a == 33 && b == 40 ) ||
- ( a == 34 && b == 36 ) ||
- ( a == 34 && b == 39 ) ||
- ( a == 34 && b == 40 ) ||
- ( a == 35 && b == 38 ) ||
- ( a == 35 && b == 41 ) ||
- ( a == 38 && b == 43 ) ||
- ( a == 39 && b == 41 ) ||
- ( a == 40 && b == 42 ) )
- return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3);
- if( ( a == 20 && b == 27 ) ||
- ( a == 20 && b == 31 ) ||
- ( a == 20 && b == 35 ) ||
- ( a == 20 && b == 39 ) ||
- ( a == 20 && b == 40 ) ||
- ( a == 21 && b == 26 ) ||
- ( a == 21 && b == 29 ) ||
- ( a == 21 && b == 33 ) ||
- ( a == 21 && b == 34 ) ||
- ( a == 21 && b == 41 ) ||
- ( a == 22 && b == 29 ) ||
- ( a == 22 && b == 33 ) ||
- ( a == 22 && b == 37 ) ||
- ( a == 22 && b == 38 ) ||
- ( a == 22 && b == 42 ) ||
- ( a == 23 && b == 27 ) ||
- ( a == 23 && b == 28 ) ||
- ( a == 23 && b == 32 ) ||
- ( a == 23 && b == 35 ) ||
- ( a == 23 && b == 43 ) ||
- ( a == 24 && b == 31 ) ||
- ( a == 24 && b == 32 ) ||
- ( a == 24 && b == 36 ) ||
- ( a == 24 && b == 39 ) ||
- ( a == 24 && b == 43 ) ||
- ( a == 25 && b == 26 ) ||
- ( a == 25 && b == 30 ) ||
- ( a == 25 && b == 37 ) ||
- ( a == 25 && b == 38 ) ||
- ( a == 25 && b == 41 ) ||
- ( a == 26 && b == 33 ) ||
- ( a == 26 && b == 38 ) ||
- ( a == 26 && b == 41 ) ||
- ( a == 27 && b == 32 ) ||
- ( a == 27 && b == 35 ) ||
- ( a == 27 && b == 39 ) ||
- ( a == 28 && b == 35 ) ||
- ( a == 28 && b == 36 ) ||
- ( a == 28 && b == 40 ) ||
- ( a == 28 && b == 43 ) ||
- ( a == 29 && b == 33 ) ||
- ( a == 29 && b == 34 ) ||
- ( a == 29 && b == 42 ) ||
- ( a == 30 && b == 34 ) ||
- ( a == 30 && b == 37 ) ||
- ( a == 30 && b == 41 ) ||
- ( a == 30 && b == 42 ) ||
- ( a == 31 && b == 36 ) ||
- ( a == 31 && b == 39 ) ||
- ( a == 31 && b == 40 ) ||
- ( a == 32 && b == 39 ) ||
- ( a == 32 && b == 43 ) ||
- ( a == 33 && b == 38 ) ||
- ( a == 34 && b == 41 ) ||
- ( a == 34 && b == 42 ) ||
- ( a == 35 && b == 40 ) ||
- ( a == 36 && b == 40 ) ||
- ( a == 36 && b == 43 ) ||
- ( a == 37 && b == 38 ) ||
- ( a == 37 && b == 42 ) )
- return -(-1 + Nc2)/(8.*Nc3);
- if( ( a == 20 && b == 30 ) ||
- ( a == 20 && b == 33 ) ||
- ( a == 21 && b == 28 ) ||
- ( a == 21 && b == 39 ) ||
- ( a == 22 && b == 27 ) ||
- ( a == 22 && b == 36 ) ||
- ( a == 23 && b == 34 ) ||
- ( a == 23 && b == 38 ) ||
- ( a == 24 && b == 26 ) ||
- ( a == 24 && b == 42 ) ||
- ( a == 25 && b == 32 ) ||
- ( a == 25 && b == 40 ) ||
- ( a == 26 && b == 35 ) ||
- ( a == 27 && b == 41 ) ||
- ( a == 28 && b == 37 ) ||
- ( a == 29 && b == 32 ) ||
- ( a == 29 && b == 40 ) ||
- ( a == 30 && b == 43 ) ||
- ( a == 31 && b == 34 ) ||
- ( a == 31 && b == 38 ) ||
- ( a == 33 && b == 43 ) ||
- ( a == 35 && b == 42 ) ||
- ( a == 36 && b == 41 ) ||
- ( a == 37 && b == 39 ) )
- return (4 - 5*Nc2 + Nc4)/(32.*Nc3);
- if( ( a == 20 && b == 43 ) ||
- ( a == 21 && b == 37 ) ||
- ( a == 22 && b == 41 ) ||
- ( a == 23 && b == 31 ) ||
- ( a == 24 && b == 35 ) ||
- ( a == 25 && b == 29 ) ||
- ( a == 26 && b == 42 ) ||
- ( a == 27 && b == 36 ) ||
- ( a == 28 && b == 39 ) ||
- ( a == 30 && b == 33 ) ||
- ( a == 32 && b == 40 ) ||
- ( a == 34 && b == 38 ) )
- return -(-1 + Nc4)/(8.*Nc3);
- }
+ if ( basis == id88888 ) {
+ return Nc5/32.;
+ }
- if ( basis == id33bar888 ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) )
- return (2 - 3*Nc2 + Nc4)/8.;
- if( ( a == 0 ) ||
- ( b == 1 ) )
- return (1 - Nc2)/4.;
- if( ( a == 0 && b == 2 ) ||
- ( a == 0 && b == 3 ) ||
- ( a == 0 && b == 4 ) ||
- ( a == 1 && b == 2 ) ||
- ( a == 1 && b == 3 ) ||
- ( a == 1 && b == 4 ) )
- return 0;
- if( ( a == 0 && b == 5 ) ||
- ( a == 0 && b == 8 ) ||
- ( a == 0 && b == 9 ) ||
- ( a == 1 && b == 6 ) ||
- ( a == 1 && b == 7 ) ||
- ( a == 1 && b == 10 ) )
- return (2 - 3*Nc2 + Nc4)/(8.*Nc);
- if( ( a == 0 && b == 6 ) ||
- ( a == 0 && b == 7 ) ||
- ( a == 0 && b == 10 ) ||
- ( a == 1 && b == 5 ) ||
- ( a == 1 && b == 8 ) ||
- ( a == 1 && b == 9 ) )
- return -(-1 + Nc2)/(4.*Nc);
- if( ( a == 2 && b == 2 ) ||
- ( a == 3 && b == 3 ) ||
- ( a == 4 && b == 4 ) )
- return sqr(-1 + Nc2)/8.;
- if( ( a == 2 && b == 3 ) ||
- ( a == 2 && b == 4 ) ||
- ( a == 3 && b == 4 ) )
- return (-1 + Nc2)/8.;
- if( ( a == 2 && b == 5 ) ||
- ( a == 2 && b == 6 ) ||
- ( a == 2 && b == 8 ) ||
- ( a == 2 && b == 10 ) ||
- ( a == 3 && b == 6 ) ||
- ( a == 3 && b == 7 ) ||
- ( a == 3 && b == 8 ) ||
- ( a == 3 && b == 9 ) ||
- ( a == 4 && b == 5 ) ||
- ( a == 4 && b == 7 ) ||
- ( a == 4 && b == 9 ) ||
- ( a == 4 && b == 10 ) )
- return sqr(-1 + Nc2)/(8.*Nc);
- if( ( a == 2 && b == 7 ) ||
- ( a == 2 && b == 9 ) ||
- ( a == 3 && b == 5 ) ||
- ( a == 3 && b == 10 ) ||
- ( a == 4 && b == 6 ) ||
- ( a == 4 && b == 8 ) )
- return -(-1 + Nc2)/(8.*Nc);
- if( ( a == 5 && b == 5 ) ||
- ( a == 6 && b == 6 ) ||
- ( a == 7 && b == 7 ) ||
- ( a == 8 && b == 8 ) ||
- ( a == 9 && b == 9 ) ||
- ( a == 10 && b == 10 ) )
- return pow(-1 + Nc2,3.)/(8.*Nc2);
- if( ( a == 5 && b == 6 ) ||
- ( a == 5 && b == 7 ) ||
- ( a == 6 && b == 9 ) ||
- ( a == 7 && b == 8 ) ||
- ( a == 8 && b == 10 ) ||
- ( a == 9 && b == 10 ) )
- return -sqr(-1 + Nc2)/(8.*Nc2);
- if( ( a == 5 && b == 8 ) ||
- ( a == 5 && b == 9 ) ||
- ( a == 6 && b == 7 ) ||
- ( a == 6 && b == 10 ) ||
- ( a == 7 && b == 10 ) ||
- ( a == 8 && b == 9 ) )
- return 0.125 - 1/(8.*Nc2);
- if( ( a == 5 && b == 10 ) ||
- ( a == 6 && b == 8 ) ||
- ( a == 7 && b == 9 ) )
- return (-1 + Nc4)/(8.*Nc2);
- }
+ if ( basis == id33bar888 ) {
+ return Nc4/8.;
+ }
- if ( basis == id33bar33bar8 ) {
- if( ( a == 0 && b == 0 ) ||
- ( a == 1 && b == 1 ) ||
- ( a == 2 && b == 2 ) ||
- ( a == 3 && b == 3 ) )
- return (Nc*(-1 + Nc2))/2.;
- if( ( a == 0 && b == 1 ) ||
- ( a == 0 && b == 3 ) ||
- ( a == 1 && b == 2 ) ||
- ( a == 2 && b == 3 ) )
- return (-1 + Nc2)/2.;
- if( ( a == 0 && b == 2 ) ||
- ( a == 1 && b == 3 ) )
- return 0;
+ if ( basis == id33bar33bar8 ) {
+ return Nc3/2.;
+ }
+
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
}
double SimpleColourBasis2::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
if(i == 0 && a == 0 && b == 0) return -1;
if(i == 0 && a == 1 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
return 0.;
}
if ( basis == id33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return -1;
return 0.;
}
if ( basis == id888 ) {
if(i == 0 && a == 3 && b == 0) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 7 && b == 0) return 1;
if(i == 0 && a == 8 && b == 1) return 1;
if(i == 1 && a == 4 && b == 0) return 1;
if(i == 1 && a == 5 && b == 1) return 1;
if(i == 1 && a == 6 && b == 1) return -1;
if(i == 1 && a == 7 && b == 0) return -1;
if(i == 2 && a == 3 && b == 0) return 1;
if(i == 2 && a == 4 && b == 0) return -1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 8 && b == 1) return -1;
return 0.;
}
if ( basis == id33bar8 ) {
if(i == 0 && a == 2 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 2 && b == 0) return -1;
return 0.;
}
if ( basis == id8888 ) {
if(i == 0 && a == 2 && b == 2) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 8 && b == 0) return -1;
if(i == 0 && a == 9 && b == 2) return 1;
if(i == 0 && a == 10 && b == 1) return 1;
if(i == 0 && a == 11 && b == 0) return 1;
if(i == 0 && a == 20 && b == 3) return -1;
if(i == 0 && a == 22 && b == 4) return -1;
if(i == 0 && a == 26 && b == 5) return -1;
if(i == 0 && a == 28 && b == 6) return -1;
if(i == 0 && a == 32 && b == 7) return -1;
if(i == 0 && a == 34 && b == 8) return -1;
if(i == 0 && a == 38 && b == 3) return 1;
if(i == 0 && a == 39 && b == 4) return 1;
if(i == 0 && a == 40 && b == 5) return 1;
if(i == 0 && a == 41 && b == 6) return 1;
if(i == 0 && a == 42 && b == 7) return 1;
if(i == 0 && a == 43 && b == 8) return 1;
if(i == 1 && a == 2 && b == 2) return 1;
if(i == 1 && a == 9 && b == 2) return -1;
if(i == 1 && a == 13 && b == 0) return -1;
if(i == 1 && a == 15 && b == 1) return -1;
if(i == 1 && a == 16 && b == 0) return 1;
if(i == 1 && a == 17 && b == 1) return 1;
if(i == 1 && a == 24 && b == 3) return 1;
if(i == 1 && a == 25 && b == 4) return 1;
if(i == 1 && a == 27 && b == 5) return 1;
if(i == 1 && a == 28 && b == 6) return 1;
if(i == 1 && a == 29 && b == 6) return -1;
if(i == 1 && a == 30 && b == 5) return -1;
if(i == 1 && a == 33 && b == 7) return 1;
if(i == 1 && a == 34 && b == 8) return 1;
if(i == 1 && a == 35 && b == 8) return -1;
if(i == 1 && a == 36 && b == 7) return -1;
if(i == 1 && a == 38 && b == 3) return -1;
if(i == 1 && a == 39 && b == 4) return -1;
if(i == 2 && a == 5 && b == 1) return 1;
if(i == 2 && a == 10 && b == 1) return -1;
if(i == 2 && a == 13 && b == 0) return 1;
if(i == 2 && a == 16 && b == 0) return -1;
if(i == 2 && a == 18 && b == 2) return -1;
if(i == 2 && a == 19 && b == 2) return 1;
if(i == 2 && a == 21 && b == 3) return 1;
if(i == 2 && a == 22 && b == 4) return 1;
if(i == 2 && a == 23 && b == 4) return -1;
if(i == 2 && a == 24 && b == 3) return -1;
if(i == 2 && a == 30 && b == 5) return 1;
if(i == 2 && a == 31 && b == 6) return 1;
if(i == 2 && a == 32 && b == 7) return 1;
if(i == 2 && a == 33 && b == 7) return -1;
if(i == 2 && a == 35 && b == 8) return 1;
if(i == 2 && a == 37 && b == 8) return -1;
if(i == 2 && a == 40 && b == 5) return -1;
if(i == 2 && a == 41 && b == 6) return -1;
if(i == 3 && a == 8 && b == 0) return 1;
if(i == 3 && a == 11 && b == 0) return -1;
if(i == 3 && a == 15 && b == 1) return 1;
if(i == 3 && a == 17 && b == 1) return -1;
if(i == 3 && a == 18 && b == 2) return 1;
if(i == 3 && a == 19 && b == 2) return -1;
if(i == 3 && a == 20 && b == 3) return 1;
if(i == 3 && a == 21 && b == 3) return -1;
if(i == 3 && a == 23 && b == 4) return 1;
if(i == 3 && a == 25 && b == 4) return -1;
if(i == 3 && a == 26 && b == 5) return 1;
if(i == 3 && a == 27 && b == 5) return -1;
if(i == 3 && a == 29 && b == 6) return 1;
if(i == 3 && a == 31 && b == 6) return -1;
if(i == 3 && a == 36 && b == 7) return 1;
if(i == 3 && a == 37 && b == 8) return 1;
if(i == 3 && a == 42 && b == 7) return -1;
if(i == 3 && a == 43 && b == 8) return -1;
return 0.;
}
if ( basis == id33bar88 ) {
if(i == 0 && a == 4 && b == 0) return 1;
if(i == 0 && a == 9 && b == 1) return 1;
if(i == 0 && a == 10 && b == 2) return 1;
if(i == 1 && a == 4 && b == 0) return -1;
if(i == 1 && a == 5 && b == 1) return -1;
if(i == 1 && a == 7 && b == 2) return -1;
if(i == 2 && a == 0 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 7 && b == 2) return 1;
if(i == 2 && a == 8 && b == 2) return -1;
if(i == 2 && a == 9 && b == 1) return -1;
if(i == 3 && a == 0 && b == 0) return 1;
if(i == 3 && a == 1 && b == 0) return -1;
if(i == 3 && a == 5 && b == 1) return 1;
if(i == 3 && a == 6 && b == 1) return -1;
if(i == 3 && a == 8 && b == 2) return 1;
if(i == 3 && a == 10 && b == 2) return -1;
return 0.;
}
if ( basis == id33bar33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 0 && a == 1 && b == 1) return 1;
if(i == 1 && a == 1 && b == 1) return -1;
if(i == 1 && a == 2 && b == 0) return -1;
if(i == 2 && a == 2 && b == 0) return 1;
if(i == 2 && a == 3 && b == 1) return 1;
if(i == 3 && a == 0 && b == 0) return -1;
if(i == 3 && a == 3 && b == 1) return -1;
return 0.;
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return 0.;
}
bool SimpleColourBasis2::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0));
}
if ( basis == id33bar ) {
return
a == 0 &&
(idColoured == 0 && idAntiColoured == 1);
}
if ( basis == id888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar8 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1));
}
if ( basis == id8888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar88 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3)));
}
if ( basis == id88888 ) {
return
(a == 0 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 2 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 3 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 9 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 10 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 11 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 12 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 13 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 14 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 15 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 16 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 17 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 18 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 19 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 20 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 21 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 22 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 23 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 24 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 25 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 26 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 27 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 28 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 29 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 30 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 31 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 32 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 33 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 34 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 35 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 36 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 37 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 38 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 39 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 40 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 41 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 42 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 43 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar888 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 4 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 9 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 10 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar8 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3)));
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return false;
}
map<size_t,vector<vector<size_t> > > SimpleColourBasis2::basisList(const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
map<size_t,vector<vector<size_t> > > blist;
vector<vector<size_t> > structures;
vector<size_t> structure;
if ( basis == id88 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id8888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
return blist;
}
if ( basis == id33bar88 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
return blist;
}
if ( basis == id33bar33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id88888 ) {
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[10] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[11] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[12] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[13] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[14] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[15] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[16] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[17] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[18] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[19] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[20] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[21] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[22] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[23] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[24] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[25] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[26] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[27] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[28] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[29] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[30] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[31] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[32] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[33] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[34] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[35] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[36] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[37] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[38] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[39] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[40] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[41] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[42] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[43] = structures;
return blist;
}
if ( basis == id33bar888 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[10] = structures;
return blist;
}
if ( basis == id33bar33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
return blist;
}
throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
return blist;
}
void SimpleColourBasis2::makeIds() const {
id88 = vector<PDT::Colour>(2,PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888 = vector<PDT::Colour>(3,PDT::Colour8);
id33bar8 = id33bar;
id33bar8.push_back(PDT::Colour8);
id8888 = vector<PDT::Colour>(4,PDT::Colour8);
id33bar88 = id33bar8;
id33bar88.push_back(PDT::Colour8);
id33bar33bar = id33bar;
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id88888 = vector<PDT::Colour>(5,PDT::Colour8);
id33bar888 = id33bar88;
id33bar888.push_back(PDT::Colour8);
id33bar33bar8 = id33bar33bar;
id33bar33bar8.push_back(PDT::Colour8);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis2::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis2::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<SimpleColourBasis2,ColourBasis>
describeHerwigSimpleColourBasis2("Herwig::SimpleColourBasis2", "HwMatchbox.so");
void SimpleColourBasis2::Init() {
static ClassDocumentation<SimpleColourBasis2> documentation
("SimpleColourBasis2 implements the colour algebra needed for "
"processes with four coloured legs at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Feb 23, 2:35 PM (22 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4486651
Default Alt Text
(285 KB)

Event Timeline