Skip to content

Commit 81522af

Browse files
committed
feat(grcc): implment qgraf-compatible keywords in FORM
These pass a large number of comparisons with qgraf, using @tueda's "qgraf.frm" comparison procedures.
1 parent 0bee367 commit 81522af

File tree

4 files changed

+145
-86
lines changed

4 files changed

+145
-86
lines changed

sources/diawrap.cc

Lines changed: 83 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ void ProcessDiagram(EGraph *eg, void *ti)
245245
//
246246
// Now get the nodes
247247
//
248-
if ( ( info->flags & NONODES ) == 0 ) {
248+
if ( ( info->flags & WITHOUTNODES ) == 0 ) {
249249
for ( i = 0; i < eg->nNodes; i++ ) {
250250
//
251251
// node_(number,coupling,particle_1(momentum_1),...,particle_n(momentum_n))
@@ -395,7 +395,7 @@ void ProcessDiagram(EGraph *eg, void *ti)
395395
startfill[1] = fill-startfill;
396396
}
397397
}
398-
if ( ( info->flags & WITHONEPI ) == WITHONEPI ) {
398+
if ( ( info->flags & WITHONEPISETS ) == WITHONEPISETS ) {
399399
for ( i = 0; i < eg->econn->nopic; i++ ) {
400400
startfill = fill;
401401
*fill++ = ONEPI;
@@ -452,8 +452,6 @@ void ProcessDiagram(EGraph *eg, void *ti)
452452
*newterm = fill - newterm;
453453
AT.WorkPointer = fill;
454454

455-
// MesPrint("<> %a",newterm[0],newterm);
456-
457455
Generator(BHEAD newterm,info->level);
458456
AT.WorkPointer = oldworkpointer;
459457
}
@@ -479,6 +477,9 @@ Bool ProcessTopology(EGraph *eg, void *ti)
479477
// return False; skip diagram generation (when asked for).
480478
//
481479
TERMINFO *info = (TERMINFO *)ti;
480+
481+
// This seems to work properly. It was disabled before.
482+
#define WITHEARLYVETO
482483
#ifdef WITHEARLYVETO
483484
if ( ( ( info->flags & CHECKEXTERN ) == CHECKEXTERN ) && info->currentMODEL != NULL ) {
484485
int i, j;
@@ -500,6 +501,7 @@ Bool ProcessTopology(EGraph *eg, void *ti)
500501
}
501502
}
502503
#endif
504+
503505
if ( ( info->flags & TOPOLOGIESONLY ) == 0 ) {
504506
info->numtopo++;
505507
return True;
@@ -664,7 +666,7 @@ Bool ProcessTopology(EGraph *eg, void *ti)
664666
// startfill[1] = fill-startfill;
665667
// }
666668
}
667-
if ( ( info->flags & WITHONEPI ) == WITHONEPI ) {
669+
if ( ( info->flags & WITHONEPISETS ) == WITHONEPISETS ) {
668670
for ( i = 0; i < eg->econn->nopic; i++ ) {
669671
startfill = fill;
670672
*fill++ = ONEPI;
@@ -718,15 +720,39 @@ Bool ProcessTopology(EGraph *eg, void *ti)
718720
*newterm = fill - newterm;
719721
AT.WorkPointer = fill;
720722

721-
//MesPrint("<> %a",*newterm,newterm);
722-
723723
Generator(BHEAD newterm,info->level);
724724
AT.WorkPointer = oldworkpointer;
725725
info->numtopo++;
726726
return False;
727727
}
728728

729729
// #] ProcessTopology :
730+
// #[ SetDualOpts :
731+
void SetDualOpts(int *opt, const WORD num, const int key, const char* key_name,
732+
const int dual, const char* dual_name, const int val, const int dval) {
733+
734+
if ( ( num & key ) == key ) {
735+
if ( ( num & dual ) == dual ) {
736+
MLOCK(ErrorMessageLock);
737+
MesPrint("&Conflicting diagram filters: %s and %s.", key_name, dual_name);
738+
MUNLOCK(ErrorMessageLock);
739+
Terminate(-1);
740+
}
741+
else {
742+
*opt = val;
743+
}
744+
}
745+
else {
746+
if ( ( num & dual ) == dual ) {
747+
*opt = dval;
748+
}
749+
else {
750+
// The default value is always 0.
751+
*opt = 0;
752+
}
753+
}
754+
}
755+
// #] SetDualOpts :
730756
// #[ GenDiagrams :
731757

732758
int GenDiagrams(PHEAD WORD *term, WORD level)
@@ -780,48 +806,47 @@ int GenDiagrams(PHEAD WORD *term, WORD level)
780806

781807
opt->setOutAG(ProcessDiagram, &info);
782808
opt->setOutMG(ProcessTopology, &info);
783-
// opt->setEndMG(fendMG, &info);
784809

785-
opt->values[GRCC_OPT_1PI] = ( optionnumber & ONEPARTICLEIRREDUCIBLE ) == ONEPARTICLEIRREDUCIBLE;
786-
opt->values[GRCC_OPT_NoTadpole] = ( optionnumber & NOTADPOLES ) == NOTADPOLES;
787-
//
788-
// Next are snails:
789-
//
790-
opt->values[GRCC_OPT_No1PtBlock] = ( optionnumber & NOTADPOLES ) == NOTADPOLES;
791-
//
792-
if ( ( optionnumber & WITHINSERTIONS ) == WITHINSERTIONS ) {
793-
opt->values[GRCC_OPT_No2PtL1PI] = True;
794-
opt->values[GRCC_OPT_NoAdj2PtV] = True;
795-
opt->values[GRCC_OPT_No2PtL1PI] = True;
796-
}
797-
else {
798-
opt->values[GRCC_OPT_NoAdj2PtV] = True;
799-
}
800-
opt->values[GRCC_OPT_SymmInitial] = ( optionnumber & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
801-
opt->values[GRCC_OPT_SymmFinal] = ( optionnumber & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
802-
803-
// opt->values[GRCC_OPT_Block] = ( optionnumber & WITHBLOCKS ) == WITHBLOCKS;
810+
opt->values[GRCC_OPT_SymmInitial] = ( optionnumber & WITHSYMMETRIZEI ) == WITHSYMMETRIZEI;
811+
opt->values[GRCC_OPT_SymmFinal] = ( optionnumber & WITHSYMMETRIZEF ) == WITHSYMMETRIZEF;
812+
813+
// WITHBLOCKS controls output formatting. We could introduce an extra filtering option
814+
// corresponding to GRCC_OPT_Block, which is somewhat like Qgraf "onevi" but not quite
815+
// the same currently.
816+
//opt->values[GRCC_OPT_Block] = ;
817+
818+
// Now the "qgraf-compatible filtering options":
819+
int qgopt[GRCC_QGRAF_OPT_Size];
820+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_ONEPI], optionnumber,ONEPARTI, "ONEPI_", ONEPARTR, "ONEPR_", 1,-1);
821+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_ONSHELL], optionnumber,ONSHELL, "ONSHELL_", OFFSHELL, "OFFSHELL_", 1,-1);
822+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_NOSIGMA], optionnumber,NOSIGMA, "NOSIGMA_", SIGMA, "SIGMA_", 1,-1);
823+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_NOSNAIL], optionnumber,NOSNAIL, "NOSNAIL_", SNAIL, "SNAIL_", 1,-1);
824+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_NOTADPOLE],optionnumber,NOTADPOLE,"NOTADPOLE_",TADPOLE , "TADPOLE_", 1,-1);
825+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_SIMPLE], optionnumber,SIMPLE, "SIMPLE_", NOTSIMPLE,"NOTSIMPLE_",1,-1);
826+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_BIPART], optionnumber,BIPART, "BIPART_", NONBIPART,"NONBIPART_",1,-1);
827+
SetDualOpts(&qgopt[GRCC_QGRAF_OPT_CYCLI], optionnumber,CYCLI, "CYCLI_", CYCLR, "CYCLR_", 1,-1);
828+
// Qgraf has a "notfloop" which we could also add, with a small modification to grcc.cc.
829+
qgopt[GRCC_QGRAF_OPT_FLOOP] = ( optionnumber & FLOOP ) == FLOOP;
830+
// Now set the options internally:
831+
opt->setQGrafOpt(qgopt);
804832

805833
opt->setOutputF(False,"");
806834
opt->setOutputP(False,"");
807835
opt->printLevel(babble);
808836

809-
// opt->values[GRCC_OPT_Step] = GRCC_AGraph;
810-
811837
// Load the various arrays.
812-
813-
ninitl = Sets[inset].last - Sets[inset].first;
814-
for ( i = 0; i < ninitl; i++ ) {
815-
x = SetElements[Sets[inset].first+i];
816-
initlPart[i] = ConvertParticle(model,x);
838+
ninitl = Sets[inset].last - Sets[inset].first;
839+
for ( i = 0; i < ninitl; i++ ) {
840+
x = SetElements[Sets[inset].first+i];
841+
initlPart[i] = ConvertParticle(model,x);
817842
info.legcouple[i] = m->vertices[numParticle(m,x)]->couplings;
818-
}
819-
nfinal = Sets[outset].last - Sets[outset].first;
820-
for ( i = 0; i < nfinal; i++ ) {
821-
x = SetElements[Sets[outset].first+i];
822-
finalPart[i] = ConvertParticle(model,x);
843+
}
844+
nfinal = Sets[outset].last - Sets[outset].first;
845+
for ( i = 0; i < nfinal; i++ ) {
846+
x = SetElements[Sets[outset].first+i];
847+
finalPart[i] = ConvertParticle(model,x);
823848
info.legcouple[i+ninitl] = m->vertices[numParticle(m,x)]->couplings;
824-
}
849+
}
825850
info.numextern = ninitl + nfinal;
826851
for ( i = 2; i <= MAXLEGS; i++ ) {
827852
if ( m->legcouple[i] == 1 ) {
@@ -850,16 +875,14 @@ Go_on:;
850875

851876
if ( ( info.flags & TOPOLOGIESONLY ) == 0 ) {
852877
while ( DistrN(nc,cpl,m->ncouplings,scratch) ) {
853-
proc = new Process(pid, model, opt,
854-
ninitl, initlPart, nfinal, finalPart, cpl);
878+
proc = new Process(pid, model, opt, ninitl, initlPart, nfinal, finalPart, cpl);
855879
delete proc;
856880
info.numtopo = 1;
857881
}
858882
}
859883
else {
860884
cpl[0] = nc;
861-
proc = new Process(pid, model, opt,
862-
ninitl, initlPart, nfinal, finalPart, cpl);
885+
proc = new Process(pid, model, opt, ninitl, initlPart, nfinal, finalPart, cpl);
863886
delete proc;
864887
}
865888
M_free(scratch,"DistrN");
@@ -892,8 +915,7 @@ Go_on:;
892915
/*
893916
And now the generation:
894917
*/
895-
proc = new Process(pid, model, opt,
896-
ninitl, initlPart, nfinal, finalPart, cpl);
918+
proc = new Process(pid, model, opt, ninitl, initlPart, nfinal, finalPart, cpl);
897919
opt->end();
898920
delete proc;
899921
delete opt;
@@ -1000,22 +1022,23 @@ int GenTopologies(PHEAD WORD *term, WORD level)
10001022

10011023
info.flags |= TOPOLOGIESONLY; // this is the topologies_ function after all.
10021024
if ( t1 < tstop && t1[0] == -SNUMBER ) {
1003-
if ( ( t1[1] & NONODES ) == NONODES ) info.flags |= NONODES;
1025+
if ( ( t1[1] & WITHOUTNODES ) == WITHOUTNODES ) info.flags |= WITHOUTNODES;
10041026
if ( ( t1[1] & WITHEDGES ) == WITHEDGES ) info.flags |= WITHEDGES;
10051027
if ( ( t1[1] & WITHBLOCKS ) == WITHBLOCKS ) info.flags |= WITHBLOCKS;
1006-
if ( ( t1[1] & WITHONEPI ) == WITHONEPI ) info.flags |= WITHONEPI;
1007-
opt->values[GRCC_OPT_1PI] = ( t1[1] & ONEPARTICLEIRREDUCIBLE ) == ONEPARTICLEIRREDUCIBLE;
1008-
// opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOTADPOLES ) == NOTADPOLES;
1009-
opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOSNAILS ) == NOSNAILS;
1010-
opt->values[GRCC_OPT_No1PtBlock] = ( t1[1] & NOTADPOLES ) == NOTADPOLES;
1011-
opt->values[GRCC_OPT_NoExtSelf] = ( t1[1] & NOEXTSELF ) == NOEXTSELF;
1012-
1013-
if ( ( t1[1] & WITHINSERTIONS ) == WITHINSERTIONS ) {
1014-
opt->values[GRCC_OPT_No2PtL1PI] = True;
1015-
opt->values[GRCC_OPT_NoAdj2PtV] = True;
1016-
opt->values[GRCC_OPT_No2PtL1PI] = True;
1017-
}
1018-
opt->values[GRCC_OPT_SymmInitial] = ( t1[1] & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
1028+
if ( ( t1[1] & WITHONEPISETS ) == WITHONEPISETS ) info.flags |= WITHONEPISETS;
1029+
opt->values[GRCC_OPT_1PI] = ( t1[1] & ONEPARTI ) == ONEPARTI;
1030+
// opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOTADPOLE ) == NOTADPOLE;
1031+
opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOSNAIL ) == NOSNAIL;
1032+
opt->values[GRCC_OPT_No1PtBlock] = ( t1[1] & NOTADPOLE ) == NOTADPOLE;
1033+
// opt->values[GRCC_OPT_NoExtSelf] = ( t1[1] & NOEXTSELF ) == NOEXTSELF;
1034+
1035+
// if ( ( t1[1] & WITHINSERTIONS ) == WITHINSERTIONS ) {
1036+
// opt->values[GRCC_OPT_No2PtL1PI] = True;
1037+
// opt->values[GRCC_OPT_NoAdj2PtV] = True;
1038+
// opt->values[GRCC_OPT_No2PtL1PI] = True;
1039+
// }
1040+
opt->values[GRCC_OPT_SymmInitial] = ( t1[1] & WITHSYMMETRIZEI ) == WITHSYMMETRIZEI;
1041+
opt->values[GRCC_OPT_SymmFinal] = ( t1[1] & WITHSYMMETRIZEF ) == WITHSYMMETRIZEF;
10191042
}
10201043

10211044
info.numdia = 0;

sources/ftypes.h

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,16 +1102,35 @@ typedef int (*TFUN1)();
11021102
#define DENSETABLE 1
11031103
#define SPARSETABLE 0
11041104

1105-
#define ONEPARTICLEIRREDUCIBLE 1
1106-
#define WITHINSERTIONS 2
1107-
#define NOTADPOLES 4
1108-
#define WITHSYMMETRIZE 8
1109-
#define TOPOLOGIESONLY 16
1110-
#define NONODES 32
1111-
#define WITHEDGES 64
1112-
#define CHECKEXTERN 128
1113-
#define WITHBLOCKS 256
1114-
#define WITHONEPI 512
1115-
#define NOSNAILS 1024
1116-
#define NOEXTSELF 2048
1105+
// Diagram generator flags. They should be powers of two, since they are added
1106+
// to pass to diagrams and masked in diawrap.cc to check the flags.
1107+
// We use a "stringified" version of these when defining the FORM preprocessor
1108+
// variables, so can't neatly use "1<<10" etc here.
1109+
#define TOPOLOGIESONLY 1
1110+
#define WITHOUTNODES 2
1111+
#define WITHEDGES 4
1112+
#define WITHBLOCKS 8
1113+
#define WITHONEPISETS 16
1114+
#define WITHSYMMETRIZEI 32
1115+
#define WITHSYMMETRIZEF 64
1116+
// This is not an "option" preprocessor var but is set by "external" particle definitions
1117+
#define CHECKEXTERN 128
1118+
// The "qgraf compatible" filtering flags:
1119+
#define ONEPARTI 256
1120+
#define ONEPARTR 512
1121+
#define ONSHELL 1024
1122+
#define OFFSHELL 2048
1123+
#define NOSIGMA 4096
1124+
#define SIGMA 8192
1125+
#define NOSNAIL 16384
1126+
#define SNAIL 32768
1127+
#define NOTADPOLE 65536
1128+
#define TADPOLE 131072
1129+
#define SIMPLE 262144
1130+
#define NOTSIMPLE 524288
1131+
#define BIPART 1048576
1132+
#define NONBIPART 2097152
1133+
#define CYCLI 4194304
1134+
#define CYCLR 8388608
1135+
#define FLOOP 16777216
11171136

sources/grccparam.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ typedef struct {
129129
#define GRCC_QGRAF_OPT_BIPART 6
130130
#define GRCC_QGRAF_OPT_CYCLI 7
131131
#define GRCC_QGRAF_OPT_FLOOP 8
132-
#define GRCC_QGRAF_OPT_TOPOL 9
132+
//TODO what does this do? Does it work?
133+
//#define GRCC_QGRAF_OPT_TOPOL 9
133134

134135
#ifdef GRCC_QGRAF_OPT_TOPOL
135136
#define GRCC_QGRAF_OPT_Size 10

sources/startup.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,20 +1205,36 @@ void StartVariables(void)
12051205
PutPreVar((UBYTE *)"keepright_",(UBYTE *)("0"),0,0);
12061206
PutPreVar((UBYTE *)"SYSTEMERROR_",(UBYTE *)("0"),0,0);
12071207
/*
1208-
Next are a few 'constants' for diagram generation
1208+
Next are the flags to control diagram generation filters
12091209
*/
1210-
PutPreVar((UBYTE *)"ONEPI_",(UBYTE *)("1"),0,0);
1211-
PutPreVar((UBYTE *)"WITHOUTINSERTIONS_",(UBYTE *)("2"),0,0);
1212-
PutPreVar((UBYTE *)"NOTADPOLES_",(UBYTE *)("4"),0,0);
1213-
PutPreVar((UBYTE *)"SYMMETRIZE_",(UBYTE *)("8"),0,0);
1214-
PutPreVar((UBYTE *)"TOPOLOGIESONLY_",(UBYTE *)("16"),0,0);
1215-
PutPreVar((UBYTE *)"NONODES_",(UBYTE *)("32"),0,0);
1216-
PutPreVar((UBYTE *)"WITHEDGES_",(UBYTE *)("64"),0,0);
1217-
/* Note that CHECKEXTERN is 128 */
1218-
PutPreVar((UBYTE *)"WITHBLOCKS_",(UBYTE *)("256"),0,0);
1219-
PutPreVar((UBYTE *)"WITHONEPISETS_",(UBYTE *)("512"),0,0);
1220-
PutPreVar((UBYTE *)"NOSNAILS_",(UBYTE *)("1024"),0,0);
1221-
PutPreVar((UBYTE *)"NOEXTSELF_",(UBYTE *)("2048"),0,0);
1210+
#define STR2(x) #x
1211+
#define STR(x) STR2(x)
1212+
PutPreVar((UBYTE *)"TOPOLOGIESONLY_" ,(UBYTE*)(STR(TOPOLOGIESONLY)) ,0,0);
1213+
PutPreVar((UBYTE *)"WITHOUTNODES_" ,(UBYTE*)(STR(WITHOUTNODES)) ,0,0);
1214+
PutPreVar((UBYTE *)"WITHEDGES_" ,(UBYTE*)(STR(WITHEDGES)) ,0,0);
1215+
PutPreVar((UBYTE *)"WITHBLOCKS_" ,(UBYTE*)(STR(WITHBLOCKS)) ,0,0);
1216+
PutPreVar((UBYTE *)"WITHONEPISETS_" ,(UBYTE*)(STR(WITHONEPISETS)) ,0,0);
1217+
PutPreVar((UBYTE *)"WITHSYMMETRIZEI_",(UBYTE*)(STR(WITHSYMMETRIZEI)),0,0);
1218+
PutPreVar((UBYTE *)"WITHSYMMETRIZEF_",(UBYTE*)(STR(WITHSYMMETRIZEF)),0,0);
1219+
// This is not an "option" preprocessor var but is set by "external" particle definitions
1220+
// PutPreVar((UBYTE *)"CHECKEXTERN_" ,(UBYTE*)(STR(CHECKEXTERN)) ,0,0);
1221+
PutPreVar((UBYTE *)"ONEPI_" ,(UBYTE*)(STR(ONEPARTI)) ,0,0);
1222+
PutPreVar((UBYTE *)"ONEPR_" ,(UBYTE*)(STR(ONEPARTR)) ,0,0);
1223+
PutPreVar((UBYTE *)"ONSHELL_" ,(UBYTE*)(STR(ONSHELL)) ,0,0);
1224+
PutPreVar((UBYTE *)"OFFSHELL_" ,(UBYTE*)(STR(OFFSHELL)) ,0,0);
1225+
PutPreVar((UBYTE *)"NOSIGMA_" ,(UBYTE*)(STR(NOSIGMA)) ,0,0);
1226+
PutPreVar((UBYTE *)"SIGMA_" ,(UBYTE*)(STR(SIGMA)) ,0,0);
1227+
PutPreVar((UBYTE *)"NOSNAIL_" ,(UBYTE*)(STR(NOSNAIL)) ,0,0);
1228+
PutPreVar((UBYTE *)"SNAIL_" ,(UBYTE*)(STR(SNAIL)) ,0,0);
1229+
PutPreVar((UBYTE *)"NOTADPOLE_" ,(UBYTE*)(STR(NOTADPOLE)) ,0,0);
1230+
PutPreVar((UBYTE *)"TADPOLE_" ,(UBYTE*)(STR(TADPOLE)) ,0,0);
1231+
PutPreVar((UBYTE *)"SIMPLE_" ,(UBYTE*)(STR(SIMPLE)) ,0,0);
1232+
PutPreVar((UBYTE *)"NOTSIMPLE_" ,(UBYTE*)(STR(NOTSIMPLE)) ,0,0);
1233+
PutPreVar((UBYTE *)"BIPART_" ,(UBYTE*)(STR(BIPART)) ,0,0);
1234+
PutPreVar((UBYTE *)"NONBIPART_" ,(UBYTE*)(STR(NONBIPART)) ,0,0);
1235+
PutPreVar((UBYTE *)"CYCLI_" ,(UBYTE*)(STR(CYCLI)) ,0,0);
1236+
PutPreVar((UBYTE *)"CYCLR_" ,(UBYTE*)(STR(CYCLR)) ,0,0);
1237+
PutPreVar((UBYTE *)"FLOOP_" ,(UBYTE*)(STR(FLOOP)) ,0,0);
12221238

12231239
{
12241240
char buf[41]; /* up to 128-bit */

0 commit comments

Comments
 (0)