#include "AMEGIC++/Amplitude/Amplitude_Group.H" #include "AMEGIC++/Amplitude/Super_Amplitude.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/My_MPI.H" #include "AMEGIC++/Amplitude/Zfunc.H" #include "AMEGIC++/Amplitude/Zfunctions/Basic_Sfuncs.H" #include using namespace AMEGIC; using namespace ATOOLS; using namespace std; // compare to graph_families class Compare_Graph_Families { public: int operator()(const Graph_Family * a, const Graph_Family * b) { if (a->znumberznumber) return 1; else if (a->znumber>b->znumber) return 0; else { if (a->permnumberpermnumber) return 1; else if (a->permnumber>b->permnumber) return 0; else { if (a->topnumbertopnumber) return 1; else return 0; } } } }; Amplitude_Group::~Amplitude_Group() { } void Amplitude_Group::PrintGraph() { if (!msg_LevelIsTracking()) return; msg_Out()<<"Group: "<PrintGraph(); } void Amplitude_Group::FillCoupling(String_Handler* shand) { for (size_t i=0;iFillCoupling(shand); } void Amplitude_Group::ClearCalcList() { for (size_t i=0;iClearCalcList(); } void Amplitude_Group::KillZList() { for (size_t i=0;iKillZList(); } void Amplitude_Group::SetStringOn() { buildstring=1; for (size_t i=0;iSetStringOn(); } void Amplitude_Group::SetStringOff() { buildstring=0; for (size_t i=0;iSetStringOff(); } void Amplitude_Group::SetNumber(int& n) { for (size_t i=0;iSetNumber(n); } void Amplitude_Group::Add(Amplitude_Base* ab, int sign) { if (sign==-1) ab->SetSign(sign*ab->GetSign()); graphs.push_back(ab); } int Amplitude_Group::Size() { return graphs.size(); } Amplitude_Base* Amplitude_Group::GetAmplitude(const int n) { for (size_t i=0;iGetAmplitude(n); if (help!=0) return help; } return 0; } Graph_Family * Amplitude_Group::FindFamily(int zn, int tn, int pn) { for (Graph_Families::iterator git=family_table.begin(); git!=family_table.end();++git) { if (((*git)->znumber==zn) && ((*git)->topnumber==tn) && ((*git)->permnumber==pn)) { return (*git); } } return 0; } void Amplitude_Group::BuildGlobalString(int* _b,int _n, Basic_Sfuncs* _BS, Flavour* _fl, String_Handler* _shand) { // fill map for (vector::iterator g=graphs.begin();g!=graphs.end();++g) { Zfunc_List* zl = (*g)->GetZlist(); for (Zfunc_Iterator zit=zl->begin();zit!=zl->end();++zit) { graph_table[(*zit)->m_str].push_back((*g)); } } // fill family table for (vector::iterator g=graphs.begin();g!=graphs.end();++g) { int zn = (*g)->GetZlist()->size(); int tn = (*g)->topnum; int pn = (*g)->permnum; Graph_Family * gf = FindFamily(zn,tn,pn); if (!gf) { gf = new Graph_Family; gf->was_clustered = 0; gf->znumber = zn; gf->topnumber = tn; gf->permnumber = pn; family_table.push_back(gf); } else { gf->banner += string("+"); } gf->graphs.push_back(*g); Zfunc_List * zl = (*g)->GetZlist(); for (Zfunc_Iterator zit=zl->begin();zit!=zl->end();++zit) { if (zit!=zl->begin()) gf->banner += string("*"); gf->banner += (*zit)->m_str; } } // sort family table acording to znumber, permnumber, and topnumber, sort(family_table.begin(), family_table.end(),Compare_Graph_Families()); // count zn int zncount=0, last_zn=0; for (Graph_Families::iterator git=family_table.begin(); git!=family_table.end();++git) { if ((*git)->znumber!=last_zn) { last_zn=(*git)->znumber; ++zncount; } } //using the Kabbala value of the Zfunc String_Tree st; string globalstr; list addend_list; int combine_step=0; for (;;) { // basic output int nsuper=0; int nampl=0; // nfamily nsuper // cluster each family for (Graph_Families::iterator git=family_table.begin(); git!=family_table.end();++git) { if ((*git)->banner==string("")) { cerr<<" Empty String for family = " <<(*git)->znumber<<" " <<(*git)->topnumber<<" " <<(*git)->permnumber<graphs.size()>1 ) { if ((*git)->was_clustered==0 ) {// has not been combined in last step, no need to try it again!!! sknot* sh = st.String2Tree((*git)->banner); st.DeleteMinus(sh); st.Cluster(sh,0,1); st.DeleteMinus(sh); st.Delete(sh,string("Z[0]")); (*git)->banner=st.Tree2String(sh,0); list local_addend_list; st.Addends(sh,local_addend_list); (*git)->was_clustered=local_addend_list.size(); } nsuper+=(*git)->was_clustered; nampl+=(*git)->graphs.size(); } else { ++nsuper; ++nampl; } } } // if only one family cluster finished if ((int)family_table.size()==zncount) break; // combine families if (combine_step==0) { // combine all perms Graph_Families::iterator agit=family_table.begin(); Graph_Families::iterator bgit=family_table.begin(); for (; agit!=family_table.end();) { if (agit!=bgit) { if ( (*agit)->znumber==(*bgit)->znumber && (*agit)->permnumber==(*bgit)->permnumber ) { //combine a to b (*bgit)->was_clustered=0; for (Amplitude_List::iterator g=(*agit)->graphs.begin();g!=(*agit)->graphs.end();++g) { (*bgit)->graphs.push_back((*g)); } (*bgit)->banner+=string("+")+(*agit)->banner; agit=family_table.erase(agit); } else { bgit=agit; ++agit; } } else ++agit; } } else { // combine neighbors Graph_Families::iterator agit=family_table.begin(); Graph_Families::iterator bgit=family_table.begin(); for (; agit!=family_table.end();) { if (agit!=bgit) { if ( (*agit)->znumber==(*bgit)->znumber) { //combine a to b (*bgit)->was_clustered=0; for (Amplitude_List::iterator g=(*agit)->graphs.begin();g!=(*agit)->graphs.end();++g) { (*bgit)->graphs.push_back((*g)); } (*bgit)->banner+=string("+")+(*agit)->banner; agit=family_table.erase(agit); bgit=agit; if (agit!=family_table.end()) ++agit; } else { bgit=agit; ++agit; } } else ++agit; } } ++combine_step; } globalstr=family_table.front()->banner; if (family_table.size()>1) { for (size_t i=1;ibanner; } sknot* sh = st.String2Tree(globalstr); st.Addends(sh,addend_list); for (list::iterator it=addend_list.begin();it!=addend_list.end();++it) { string newaddend = st.Tree2String(*it,0); st.Expand(*it); list superlist; st.Addends(*it,superlist); if (superlist.size()>1) { Super_Amplitude* sg = new Super_Amplitude(_b,_n,_BS,_fl,_shand); for (list::iterator sit=superlist.begin();sit!=superlist.end();++sit) { list zfunclist; st.Factors(*sit,zfunclist); sg->Add(GetSingleGraph(zfunclist)); } sg->Init(newaddend); graphs.push_back(sg); } } } Amplitude_Base* Amplitude_Group::GetSingleGraph(list& zfunclist) { String_Tree st; Amplitude_List & al=graph_table[st.Tree2String(zfunclist.front(),0)]; for (vector::iterator g=al.begin();g!=al.end();++g) { int hit = 1; for (list::iterator it=zfunclist.begin();it!=zfunclist.end();++it) { Zfunc_List* zl = (*g)->GetZlist(); if (zl==0) { //SuperGraph.... hit = 0; break; } int hit2 = 0; for (Zfunc_Iterator zit=zl->begin();zit!=zl->end();++zit) { if ((*zit)->m_str==st.Tree2String(*it,0)) { hit2 = 1; break; } } if (hit2==0) { hit = 0; break; } } if (hit) { Amplitude_Base* g2 = *g; al.erase(g); for (vector::iterator git=graphs.begin();git!=graphs.end();++git) { if (g2==(*git)) { graphs.erase(git); break; } } return g2; } } cerr<<"Error: No Amplitude found in Amplitude_Group::GetSingleGraph()!"<Zvalue(ihel); return M; } Complex Amplitude_Group::Zvalue(String_Handler * sh,int ihel) { Complex M(0.,0.); for (size_t i=0;iZvalue(sh, ihel); return M; } Complex Amplitude_Group::Zvalue(int ihel,int* signlist) { Complex mcm,M(0.,0.); double max = 0.; for (size_t i=0;iZvalue(ihel,signlist); M+=mcm; max = ATOOLS::Max(max,abs(mcm)); } return M; } const std::vector &Amplitude_Group::GetOrder() { return graphs.front()->GetOrder(); }