From 89f286e7508d2cc18b87868d10ef9ec3c520d62a Mon Sep 17 00:00:00 2001 From: Takahiro Ueda Date: Fri, 27 Dec 2024 09:45:29 +0900 Subject: [PATCH 1/2] fix: resolve issues with the topologies_ function - Add NOTOPOS and NOSYMMETRYFACTOR flags to control the inclusion of topo_ and symmetry factors. - Set an appropriate default value for the optional last argument of the topologies_ function. - Fix missing/wrong initialization of info and TopoInf. - Avoid unnecessary heap allocation. --- sources/diawrap.cc | 147 ++++++++++++++++++++++++--------------------- sources/ftypes.h | 7 ++- 2 files changed, 83 insertions(+), 71 deletions(-) diff --git a/sources/diawrap.cc b/sources/diawrap.cc index 4c40e4ba..5163ee95 100644 --- a/sources/diawrap.cc +++ b/sources/diawrap.cc @@ -414,35 +414,39 @@ void ProcessDiagram(EGraph *eg, void *ti) // // Topology counter. We have exaggerated a bit with the eye on the far future. // - if ( info->numtopo-1 < MAXPOSITIVE ) { - *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill) - *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo-1); - } - else if ( info->numtopo-1 < FULLMAX-1 ) { - *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill) - *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill) - *fill++ = 4; - *fill++ = (WORD)((info->numtopo-1) & WORDMASK); - *fill++ = 1; *fill++ = 3; - } - else { // for now: science fiction - *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill) - *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill) - *fill++ = 6; *fill++ = (WORD)((info->numtopo-1) >> BITSINWORD); - *fill++ = (WORD)((info->numtopo-1) & WORDMASK); - *fill++ = 0; *fill++ = 1; *fill++ = 5; + if ( !(info->flags & NOTOPOS) ) { + if ( info->numtopo-1 < MAXPOSITIVE ) { + *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill) + *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo-1); + } + else if ( info->numtopo-1 < FULLMAX-1 ) { + *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill) + *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill) + *fill++ = 4; + *fill++ = (WORD)((info->numtopo-1) & WORDMASK); + *fill++ = 1; *fill++ = 3; + } + else { // for now: science fiction + *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill) + *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill) + *fill++ = 6; *fill++ = (WORD)((info->numtopo-1) >> BITSINWORD); + *fill++ = (WORD)((info->numtopo-1) & WORDMASK); + *fill++ = 0; *fill++ = 1; *fill++ = 5; + } } // // Symmetry factors. We let Normalize do the multiplication. // - if ( eg->nsym != 1 ) { - *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1; - } - if ( eg->esym != 1 ) { - *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1; - } - if ( eg->extperm != 1 ) { - *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->extperm; *fill++ = 1; + if ( !(info->flags & NOSYMMETRYFACTOR) ) { + if ( eg->nsym != 1 ) { + *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1; + } + if ( eg->esym != 1 ) { + *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1; + } + if ( eg->extperm != 1 ) { + *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->extperm; *fill++ = 1; + } } // // finish it off @@ -683,32 +687,36 @@ Bool ProcessTopology(EGraph *eg, void *ti) // // Topology counter. We have exaggerated a bit with the eye on the far future. // - if ( info->numtopo < MAXPOSITIVE ) { - *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill) - *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo); - } - else if ( info->numtopo < FULLMAX-1 ) { - *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill) - *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill) - *fill++ = 4; - *fill++ = (WORD)(info->numtopo & WORDMASK); - *fill++ = 1; *fill++ = 3; - } - else { // for now: science fiction - *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill) - *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill) - *fill++ = 6; *fill++ = (WORD)(info->numtopo >> BITSINWORD); - *fill++ = (WORD)(info->numtopo & WORDMASK); - *fill++ = 0; *fill++ = 1; *fill++ = 5; + if ( !(info->flags & NOTOPOS) ) { + if ( info->numtopo < MAXPOSITIVE ) { + *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill) + *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo); + } + else if ( info->numtopo < FULLMAX-1 ) { + *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill) + *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill) + *fill++ = 4; + *fill++ = (WORD)(info->numtopo & WORDMASK); + *fill++ = 1; *fill++ = 3; + } + else { // for now: science fiction + *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill) + *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill) + *fill++ = 6; *fill++ = (WORD)(info->numtopo >> BITSINWORD); + *fill++ = (WORD)(info->numtopo & WORDMASK); + *fill++ = 0; *fill++ = 1; *fill++ = 5; + } } // // Symmetry factors. We let Normalize do the multiplication. // - if ( eg->nsym != 1 ) { - *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1; - } - if ( eg->esym != 1 ) { - *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1; + if ( !(info->flags & NOSYMMETRYFACTOR) ) { + if ( eg->nsym != 1 ) { + *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1; + } + if ( eg->esym != 1 ) { + *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1; + } } // // finish it off @@ -961,7 +969,7 @@ int processVertex(TOPOTYPE *TopoInf, int pointsremaining, int level) WORD GenTopologies(PHEAD WORD *term, WORD level) { - Options *opt = new Options; + Options opt; int nlegs, nloops, i, identical; TERMINFO info; WORD *t, *t1, *tstop; @@ -972,6 +980,7 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) info.level = level; info.diaoffset = AR.funoffset; info.flags = 0; + info.currentModel = NULL; t = term + info.diaoffset; // the function t1 = t + FUNHEAD; // its arguments @@ -987,7 +996,7 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) nloops = t1[1]; nlegs = t1[3]; - info.numextern = nlegs; + info.numextern = ABS(nlegs); for ( i = 0; i <= MAXLEGS; i++ ) { TopoInf.cmind[i] = TopoInf.cmaxd[i] = 0; } @@ -998,31 +1007,29 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) } else TopoInf.vertmax = NULL; - info.flags |= TOPOLOGIESONLY; // this is the topologies_ function after all. if ( t1 < tstop && t1[0] == -SNUMBER ) { - if ( ( t1[1] & NONODES ) == NONODES ) info.flags |= NONODES; - if ( ( t1[1] & WITHEDGES ) == WITHEDGES ) info.flags |= WITHEDGES; - if ( ( t1[1] & WITHBLOCKS ) == WITHBLOCKS ) info.flags |= WITHBLOCKS; - if ( ( t1[1] & WITHONEPI ) == WITHONEPI ) info.flags |= WITHONEPI; - opt->values[GRCC_OPT_1PI] = ( t1[1] & ONEPARTICLEIRREDUCIBLE ) == ONEPARTICLEIRREDUCIBLE; -// opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOTADPOLES ) == NOTADPOLES; - opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOSNAILS ) == NOSNAILS; - opt->values[GRCC_OPT_No1PtBlock] = ( t1[1] & NOTADPOLES ) == NOTADPOLES; - opt->values[GRCC_OPT_NoExtSelf] = ( t1[1] & NOEXTSELF ) == NOEXTSELF; - - if ( ( t1[1] & WITHINSERTIONS ) == WITHINSERTIONS ) { - opt->values[GRCC_OPT_No2PtL1PI] = True; - opt->values[GRCC_OPT_NoAdj2PtV] = True; - opt->values[GRCC_OPT_No2PtL1PI] = True; - } - opt->values[GRCC_OPT_SymmInitial] = ( t1[1] & WITHSYMMETRIZE ) == WITHSYMMETRIZE; + info.flags = t1[1]; } + else { + info.flags = ONEPARTICLEIRREDUCIBLE | NOEXTSELF | NOTOPOS | NOSYMMETRYFACTOR; + } + info.flags |= TOPOLOGIESONLY; // this is the topologies_ function after all. + opt.values[GRCC_OPT_Step] = GRCC_AGraph; + opt.values[GRCC_OPT_1PI] = !!(info.flags & ONEPARTICLEIRREDUCIBLE); + opt.values[GRCC_OPT_NoSelfLoop] = !!(info.flags & NOSNAILS); + opt.values[GRCC_OPT_NoTadpole] = !!(info.flags & (NOSNAILS | NOTADPOLES)); + opt.values[GRCC_OPT_No1PtBlock] = !!(info.flags & (NOSNAILS | NOTADPOLES)); + opt.values[GRCC_OPT_No2PtL1PI] = !!(info.flags & WITHINSERTIONS); + opt.values[GRCC_OPT_NoExtSelf] = !!(info.flags & NOEXTSELF); + opt.values[GRCC_OPT_NoAdj2PtV] = !!(info.flags & WITHINSERTIONS); + opt.values[GRCC_OPT_Block] = False; + opt.values[GRCC_OPT_SymmInitial] = !!(info.flags & WITHSYMMETRIZE); + opt.values[GRCC_OPT_SymmFinal] = False; info.numdia = 0; info.numtopo = 1; - opt->setOutAG(ProcessDiagram, &info); - opt->setOutMG(ProcessTopology, &info); + opt.setOutMG(ProcessTopology, &info); // // Now we should sum over all possible vertices and run MGraph for // each combination. This is done by recursion in the processVertex routine @@ -1031,6 +1038,7 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) // First the external nodes. + identical = 0; if ( nlegs == -2 ) { nlegs = 2; identical = 1; @@ -1045,7 +1053,7 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) TopoInf.clnum[0] = 2; } TopoInf.ncl = nlegs; - TopoInf.opt = opt; + TopoInf.opt = &opt; if ( points >= MAXPOINTS ) { MLOCK(ErrorMessageLock); @@ -1059,7 +1067,6 @@ WORD GenTopologies(PHEAD WORD *term, WORD level) MUNLOCK(ErrorMessageLock); Terminate(-1); } - delete opt; return(0); } diff --git a/sources/ftypes.h b/sources/ftypes.h index 4ae77506..b37a919f 100644 --- a/sources/ftypes.h +++ b/sources/ftypes.h @@ -1104,6 +1104,10 @@ typedef int (*TFUN1)(); #define DENSETABLE 1 #define SPARSETABLE 0 +/* + Flags for TERMINFO +*/ + #define ONEPARTICLEIRREDUCIBLE 1 #define WITHINSERTIONS 2 #define NOTADPOLES 4 @@ -1116,4 +1120,5 @@ typedef int (*TFUN1)(); #define WITHONEPI 512 #define NOSNAILS 1024 #define NOEXTSELF 2048 - +#define NOTOPOS 4096 +#define NOSYMMETRYFACTOR 8192 From e76def6d076e23644631d7e8faabf58c019dcb7b Mon Sep 17 00:00:00 2001 From: Takahiro Ueda Date: Fri, 27 Dec 2024 11:23:56 +0900 Subject: [PATCH 2/2] test: reenable test cases for topologies_ The expected result for the Diagrams_3 test case is updated while remaining consistent with the old result because of the symmetry of interchanging the external legs. For now, the node IDs are decremented in the test code to reproduce the old results. --- check/examples.frm | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/check/examples.frm b/check/examples.frm index 6533690a..237121aa 100644 --- a/check/examples.frm +++ b/check/examples.frm @@ -1830,10 +1830,9 @@ Print; Set PP:p1,...,p8; #define LOOPS "2" Local F = topologies_(`LOOPS',2,{3,},QQ,PP); + id node_(i_?,?a) = node_(i_-1,?a); * for compatibility Print +f +s; .end -# TODO: enable it -#pend_if true assert succeeded? assert result("F") =~ expr(" + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,-p1,-p2)*node_(3,Q2,p1,-p3)* @@ -1848,10 +1847,9 @@ Print; Set PP:p1,...,p8; #define LOOPS "2" Local F = topologies_(`LOOPS',2,{3,4},QQ,PP); + id node_(i_?,?a) = node_(i_-1,?a); * for compatibility Print +f +s; .end -# TODO: enable it -#pend_if true assert succeeded? assert result("F") =~ expr(" + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,Q2,-p1,-p2)*node_(3,p1,p2,-p3,p3 @@ -1880,10 +1878,9 @@ Print; Set PP:p1,...,p8; #define LOOPS "2" Local F = topologies_(`LOOPS',-2,{3,4},QQ,PP); + id node_(i_?,?a) = node_(i_-1,?a); * for compatibility Print +f +s; .end -# TODO: enable it -#pend_if true assert succeeded? assert result("F") =~ expr(" + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,Q2,-p1,-p2)*node_(3,p1,p2,-p3,p3 @@ -1896,10 +1893,10 @@ Print; node_(4,p1,p2,p3,p4) + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,-p1,-p2)*node_(3,Q2,-p3,-p4)* node_(4,p1,p3,-p5)*node_(5,p2,p4,p5) - + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,-p1,-p2)*node_(3,p1,-p3,-p4)* - node_(4,Q2,p2,p3,p4) + node_(0,-Q1)*node_(1,-Q2)*node_(2,Q1,-p1,-p2,-p3)*node_(3,Q2,p1,p2,p3 ) + + node_(0,-Q1)*node_(1,-Q2)*node_(2,-p1,-p2,-p3)*node_(3,Q2,p1,-p4)* + node_(4,Q1,p2,p3,p4) + node_(0,-Q1)*node_(1,-Q2)*node_(2,-p1,-p2,-p3)*node_(3,p1,p2,-p4)* node_(4,Q1,Q2,p3,p4) ") @@ -1910,9 +1907,8 @@ Print; Set PP:p1,...,p17; #define LOOPS "6" Local F = topologies_(`LOOPS',-2,{3,},QQ,PP); + id node_(i_?,?a) = node_(i_-1,?a); * for compatibility .end -# TODO: enable it -#pend_if true #time_dilation 2.0 assert succeeded? assert nterms("F") == 2793