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
36extern "C" {
37#include "form3.h"
38}
39
40#include "gentopo.h"
41
42//using namespace std;
43
44#define MAXPOINTS 120
45
46typedef 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
72int 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
123WORD 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//
179void 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
WORD Generator(PHEAD WORD *, WORD)
Definition proces.c:3101