FORM  4.3
topowrap.cc
Go to the documentation of this file.
1 
6 /* #[ License : */
7 /*
8  * Copyright (C) 1984-2022 J.A.M. Vermaseren
9  * When using this file you are requested to refer to the publication
10  * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
11  * This is considered a matter of courtesy as the development was paid
12  * for by FOM the Dutch physics granting agency and we would like to
13  * be able to track its scientific use to convince FOM of its value
14  * for the community.
15  *
16  * This file is part of FORM.
17  *
18  * FORM is free software: you can redistribute it and/or modify it under the
19  * terms of the GNU General Public License as published by the Free Software
20  * Foundation, either version 3 of the License, or (at your option) any later
21  * version.
22  *
23  * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
24  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
26  * details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with FORM. If not, see <http://www.gnu.org/licenses/>.
30  */
31 /*
32  #] License :
33  #[ includes :
34 */
35 
36 extern "C" {
37 #include "form3.h"
38 }
39 
40 #include "gentopo.h"
41 
42 //using namespace std;
43 
44 #define MAXPOINTS 120
45 
46 typedef struct ToPoTyPe {
47  int cldeg[MAXPOINTS], clnum[MAXPOINTS], clext[MAXPOINTS];
48  int ncl, nloops, nlegs, npadding;
49  WORD *vert;
50  WORD *vertmax;
51  WORD nvert;
52  WORD sopi;
53 } TOPOTYPE;
54 
55 /*
56  #] includes :
57  #[ GenerateVertices :
58 
59  Routine is to be used recursively to work its way through a list
60  of possible vertices. The array of vertices is in TopoInf->vert
61  with TopoInf->nvert the number of possible vertices.
62  Currently we allow in TopoInf->vert only vertices with 3 or more edges.
63 
64  We work with a point system. Each n-point vertex contributes n-2 points.
65  When all points are assigned, we can call mgraph->generate().
66 
67  The number of vertices of a given number of edges is stored in
68  TopoInf->clnum[..] but the loop that determines how many there are
69  may be limited by the corresponding element in TopoInf->vertmax[level]
70 */
71 
72 int GenerateVertices(TOPOTYPE *TopoInf, int pointsremaining, int level)
73 {
74  int i, j;
75 
76  for ( i = pointsremaining, j = 0; i >= 0; i -= TopoInf->vert[level]-2, j++ ) {
77  if ( TopoInf->vertmax && TopoInf->vertmax[level] >= 0
78  && j > TopoInf->vertmax[level] ) break;
79  if ( i == 0 ) { // We got one!
80  MGraph *mgraph;
81  TopoInf->cldeg[TopoInf->ncl] = TopoInf->vert[level];
82  TopoInf->clnum[TopoInf->ncl] = j;
83  TopoInf->clext[TopoInf->ncl] = 0;
84  TopoInf->ncl++;
85 
86  mgraph = new MGraph(0, TopoInf->ncl, TopoInf->cldeg,
87  TopoInf->clnum, TopoInf->clext, TopoInf->sopi);
88 
89  mgraph->generate();
90 
91  delete mgraph;
92 
93  TopoInf->ncl--;
94 
95  break;
96  }
97  if ( level < TopoInf->nvert-1 ) {
98  if ( j > 0 ) {
99  TopoInf->cldeg[TopoInf->ncl] = TopoInf->vert[level];
100  TopoInf->clnum[TopoInf->ncl] = j;
101  TopoInf->clext[TopoInf->ncl] = 0;
102  TopoInf->ncl++;
103  }
104  if ( GenerateVertices(TopoInf,i,level+1) < 0 ) return(-1);
105  if ( j > 0 ) { TopoInf->ncl--; }
106  }
107  }
108  return(0);
109 }
110 
111 /*
112  #] GenerateVertices :
113  #[ GenerateTopologies :
114 
115  Note that setmax, option1 and option2 are optional.
116  Default values are -1,0,0
117 
118  vert is a pointer to a set of numbers indicating the types of vertices
119  that are allowed.
120  nvert is the number of elements in vert.
121 */
122 
123 WORD GenerateTopologies(PHEAD WORD nloops, WORD nlegs, WORD setvert, WORD setmax)
124 {
125  TOPOTYPE TopoInf;
126  int i, points, identical = 0;
127  DUMMYUSE(AT.nfac);
128 
129  if ( nlegs == -2 ) {
130  nlegs = 2;
131  identical = 1;
132  }
133  TopoInf.vert = &(SetElements[Sets[setvert].first]);
134  TopoInf.nvert = Sets[setvert].last-Sets[setvert].first;
135 
136  if ( setmax >= 0 ) TopoInf.vertmax = &(SetElements[Sets[setmax].first]);
137  else TopoInf.vertmax = 0;
138 
139 // point counting: an n-point vertex counts for n-2 points.
140 
141  points = 2*nloops-2+nlegs;
142  if ( points >= MAXPOINTS ) {
143  MLOCK(ErrorMessageLock);
144  MesPrint("GenerateTopologies: %d loops and %d legs considered excessive",nloops,nlegs);
145  MUNLOCK(ErrorMessageLock);
146  Terminate(-1);
147  }
148 
149 // First the external nodes.
150 
151  for ( i = 0; i < nlegs; i++ ) {
152  TopoInf.cldeg[i] = 1; TopoInf.clnum[i] = 1; TopoInf.clext[i] = 1;
153  }
154  if ( identical == 1 ) { /* Only propagator topologies..... */
155  nlegs = 1;
156  TopoInf.clnum[0] = 2;
157  }
158  TopoInf.ncl = nlegs;
159  TopoInf.sopi = 1; // For now
160 
161  if ( GenerateVertices(&TopoInf,points,0) != 0 ) {
162  MLOCK(ErrorMessageLock);
163  MesPrint("Called from GenerateTopologies with %d loops and %d legs considered excessive",nloops,nlegs);
164  MUNLOCK(ErrorMessageLock);
165  Terminate(-1);
166  }
167  return(0);
168 }
169 
170 /*
171  #] GenerateTopologies :
172  #[ toForm :
173 */
174 
175 //==============================================================
176 // Output for FROM called by genTopo each time a new graph is
177 // generated
178 //
179 void toForm(EGraph *egraph)
180 {
181  GETIDENTITY;
182 //
183 // skipext : boolean; whether to skip external node/line in the output.
184 //
185 // const int skipext = 1;
186 
187  int n, lg, ed, i, fromset;
188 
189  WORD *termout = AT.WorkPointer;
190  WORD *t, *tt, *ttstop, *ttend, *ttail;
191 
192  t = termout+1;
193 
194 // First pick up part of the original term
195 
196  tt = AT.TopologiesTerm + 1;
197  i = AT.TopologiesStart - tt;
198  NCOPY(t,tt,i)
199  ttail = tt+tt[1];
200 
201 // Now the vertices/nodes
202 // Options are in AT.TopologiesOptions[]
203 
204  for ( n = 0; n < egraph->nNodes; n++ ) {
205  if ( ( AT.TopologiesOptions[1] &1 ) == 1 && egraph->nodes[n].ext ) continue;
206  tt = t;
207  *t++ = VERTEX; t++; FILLFUN(t);
208  *t++ = -SNUMBER; *t++ = n;
209  for ( lg = 0; lg < egraph->nodes[n].deg; lg++ ) {
210  ed = egraph->nodes[n].edges[lg];
211  if ( ed >= 0 ) { *t++ = -VECTOR; }
212  else { ed = -ed; *t++ = -MINVECTOR; }
213 
214 // Now we need to pick up the proper set element.
215 
216  fromset = egraph->edges[ed].ext ? AT.setexterntopo : AT.setinterntopo;
217  *t++ = SetElements[Sets[fromset].first+egraph->edges[ed].momn-1];
218  }
219  tt[1] = t-tt;
220  }
221 
222  if ( ( AT.TopologiesOptions[0] & 1 ) == 1 ) {
223 // Note that the edges count from 1.
224  for ( n = 1; n <= egraph->nEdges; n++ ) {
225  if ( ( AT.TopologiesOptions[1] & 1 ) == 1 && egraph->edges[n].ext ) continue;
226  tt = t;
227  *t++ = EDGE; t++; FILLFUN(t);
228  *t++ = -SNUMBER; *t++ = egraph->edges[n].nodes[0];
229  *t++ = -SNUMBER; *t++ = egraph->edges[n].nodes[1];
230  *t++ = -VECTOR;
231  fromset = egraph->edges[n].ext ? AT.setexterntopo : AT.setinterntopo;
232  *t++ = SetElements[Sets[fromset].first+egraph->edges[n].momn-1];
233  tt[1] = t-tt;
234  }
235  }
236 
237 // Now the tail end
238 
239  ttend = AT.TopologiesTerm; ttend = ttend+ttend[0];
240  ttstop = ttend - ABS(ttend[-1]);
241  i = ttstop - ttail;
242  NCOPY(t,ttail,i)
243 
244 // Finally the coefficient
245 // The topological coefficient should be in egraph->wsum, egraph->nwsum
246 // as a FORM Long number
247 
248 #ifdef WITHFACTOR
249  if ( egraph->nwsum == 1 && egraph->wsum[0] == 1 ) {
250  while (ttstop < ttend ) *t++ = *ttstop++;
251  }
252  else {
253  WORD newsize;
254  newsize = ttend[-1];
255  newsize = REDLENG(newsize);
256  if ( Divvy(BHEAD (UWORD *)ttstop,&newsize,egraph->wsum,egraph->nwsum) )
257  goto OnError;
258  newsize = INCLENG(newsize);
259  i = ABS(newsize)-1;
260  NCOPY(t,ttstop,i)
261  *t++ = newsize;
262  }
263 #else
264  while (ttstop < ttend ) *t++ = *ttstop++;
265 #endif
266  *termout = t - termout;
267 
268  AT.WorkPointer = t;
269 
270  if ( Generator(BHEAD termout,AT.TopologiesLevel) < 0 ) {
271 // OnError:
272  MLOCK(ErrorMessageLock);
273  MesPrint("Called from the topologies routine toForm");
274  MUNLOCK(ErrorMessageLock);
275  Terminate(-1);
276  }
277 
278  AT.WorkPointer = termout;
279 }
280 
281 /*
282  #] toForm :
283 */
284 
Definition: gentopo.h:34
WORD Generator(PHEAD WORD *, WORD)
Definition: proces.c:3101
Definition: gentopo.h:84