BGexpand: More performance improvements
[BGap.git] / BGap.h
bloba0d126c56717e0cdd07b05a42c5b8d2ce76536a4
1 * This file implements the Berends-Giele recursion to compute the
2 * alpha' expansion of disk integrals using the method described in the
3 * paper arXiv:1609.07078
5 * Non-abelian Z-theory: Berends-Giele recursion for the alpha' expansion
6 * of disk integrals
7 *
8 * by Carlos R. Mafra and Oliver Schlotterer.
10 * You can use this file as you wish, as long as you cite the
11 * paper arXiv:1609.07078 afterwards. In addition, consider citing
12 * the paper arXiv:1603.09731 as well, as it is very closely related
14 * Copyright (c) 2016 Carlos R. Mafra
16 Indices a,b,c,d,e,f,g,h,i,j,k,l;
17 Indices m,n,p,q,r,ss,t,u,v,x;
18 Indices <m1,n1>,...,<m20,n20>;
19 Indices i1,...,i20;
20 Indices j1,...,j20;
22 Symbols [p],[c];
23 Symbol x1;
24 Symbols <zeta2>,...,<zeta10>;
26 * Mandelstam s(i,j), Is(i,j)=1/s(i,j), KK(i,[c],j) = ki.kj
27 CFunction s(s), Is(s), KK;
29 CFunction phi, Zint;
30 CFunction nargs;
32 CFunction ctmpF1,countL,countR;
33 Function tmpF, tmpF1;
35 * phi(i1,i2,i3|j1,j2,j3) = ML(i1)*ML(i2)*ML(i3)*MR(j1)*MR(j2)*MR(j3)
36 Function ML,MR,L,R;
37 Function KKL,KKR;
39 Autodeclare Function Jpt;
41 #procedure DeconcatenateN(F,n)
43 * Deconcatenate function F into n-partitions or all partitions when n==0
45 * n==0: F(1,2,3) --> F(1)*F(2)*F(3) + F(1,2)*F(3) + F(1)*F(2,3)
46 * n==2: F(1,2,3) --> F(1,2)*F(3) + F(1)*F(2,3)
48 if (match(tmpF1(?m)));
49 print "Error: temp function already present: %t";
50 exit;
51 endif;
53 if ((count('F',1) <= -1) || (count('F',1) >= 2));
54 print "Error: Deconc does not work for : %t";
55 exit;
56 endif;
58 chainout 'F';
60 repeat id once 'F'(?m)*'F'(?n) =
61 + 'F'(?m,?n)
62 + tmpF1(?m)*'F'(?n)
65 id tmpF1(?m) = 'F'(?m);
67 #if 'n' == 0
68 * do nothing, keep all partitions
69 #else
70 * keep only n-partitions (or up to n-partitions)
71 * if ((match('F'(?m))) && (count('F',1) != 'n'));
72 if ((match('F'(?m))) && (count('F',1) > 'n'));
73 discard;
74 endif;
75 #endif
77 * remove trivial partition F(1,2,3) -> F(1,2,3)
78 if ((count('F',1) == 1));
79 discard;
80 endif;
82 #endprocedure
85 #procedure BiDeconcatenate(phi,n)
87 * phi(A,[p],B) --> all deconcatenations of A and B, separated by [c]
89 * s(1,2,3)*phi(1,2,3,[p],4,5,6) = phi(1,[c],2,3,[p],4,[c],5,6) + phi(1,2,[c],3,[p],4,[c],5,6) + ...
91 * A and B cannot be composed of smaller words, so no [c]s allowed
92 if (match(phi(?m,[c],?n)));
93 print "Bug: cannot deconcatenate multiple slots %t";
94 exit;
95 endif;
97 id once 'phi'(?m1,[p],?m2) = Is(?m1)*ML(?m1)*MR(?m2);
98 #call DeconcatenateN(ML,'n')
99 #call DeconcatenateN(MR,'n')
101 * keep only the same depth of deconcatenation on both sides
102 if (count(ML,1) != count(MR,1));
103 discard;
104 endif;
106 * Kill deconcatenations where there is no matching number of slots
107 * between ML() and MR(). Recall that ML() gives rise to the A-slots
108 * in the various BGphiN.h files and MR() the B-slots. These slots
109 * refer to the definition (3.13) of arXiv:1609.07078v1, namely
110 * T_{A1 A2...}^{B1 B2...}. If |Ai| != |Bj| for all i,j it means
111 * that all resulting factors phi(Ai|Bj) vanish by the initial
112 * condition from eq.(3.3).
113 id ML(?m) = ML(?m)*countL(nargs_(?m));
114 id MR(?m) = MR(?m)*countR(nargs_(?m));
115 id countL(i?)*countR(i?) = 1;
116 * if any countL() remains, it means there was no matching countR(),
117 * so kill the term
118 id countL(i?) = 0;
120 .sort:bideconc'n';
121 #endprocedure
124 #procedure tLalphaExpand(n,w)
126 #if ({'$Npts'-1-'n'} >= 9 && 'w' >= 7)
127 #include- BGphiN/BGphi9-Jreg.h
128 bracket L,R;
129 .sort:brack9;
130 keep brackets;
131 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*L(?a8)*L(?a9)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)*R(?b8)*R(?b9) =
132 + phi(?a9,[p],?b9)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*L(?a8)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)*R(?b8)
133 - phi(?a9,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*L(?a8)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)*R(?b8)*R(?b9)
135 #call MultiparticleConstraint(9)
136 #endif
138 #if ({'$Npts'-1-'n'} >= 8 && 'w' >= 6)
139 #include- BGphiN/BGphi8-Jreg.h
140 bracket L,R;
141 .sort:brack8;
142 keep brackets;
143 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*L(?a8)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)*R(?b8) =
144 + phi(?a8,[p],?b8)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)
145 - phi(?a8,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)*R(?b8)
147 #call MultiparticleConstraint(8)
148 #endif
150 #if ({'$Npts'-1-'n'} >= 7 && 'w' >= 5)
151 #include- BGphiN/BGphi7-Jreg.h
152 bracket L,R;
153 .sort:brack7;
154 keep brackets;
155 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*L(?a7)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7) =
156 + phi(?a7,[p],?b7)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)
157 - phi(?a7,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)*R(?b7)
159 #call MultiparticleConstraint(7)
160 #endif
162 #if ({'$Npts'-1-'n'} >= 6 && 'w' >= 4)
163 #include- BGphiN/BGphi6-Jreg.h
164 bracket L,R;
165 .sort:brack6;
166 keep brackets;
167 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*L(?a6)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6) =
168 + phi(?a6,[p],?b6)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5)
169 - phi(?a6,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*R(?b2)*R(?b3)*R(?b4)*R(?b5)*R(?b6)
171 #call MultiparticleConstraint(6)
172 #endif
174 #if ({'$Npts'-1-'n'} >= 5 && 'w' >= 3)
175 #include- BGphiN/BGphi5-Jreg.h
176 bracket L,R;
177 .sort:brack5;
178 keep brackets;
179 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*L(?a5)*R(?b1)*R(?b2)*R(?b3)*R(?b4)*R(?b5) =
180 + phi(?a5,[p],?b5)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*R(?b1)*R(?b2)*R(?b3)*R(?b4)
181 - phi(?a5,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*L(?a4)*R(?b2)*R(?b3)*R(?b4)*R(?b5)
183 #call MultiparticleConstraint(5)
184 #endif
186 #if {'$Npts'-1-'n'} >= 4
187 #include- BGphiN/BGphi4-Jreg.h
188 bracket L,R;
189 .sort:brack4;
190 keep brackets;
191 id L(?a1)*L(?a2)*L(?a3)*L(?a4)*R(?b1)*R(?b2)*R(?b3)*R(?b4) =
192 + phi(?a4,[p],?b4)*L(?a1)*L(?a2)*L(?a3)*R(?b1)*R(?b2)*R(?b3)
193 - phi(?a4,[p],?b1)*L(?a1)*L(?a2)*L(?a3)*R(?b2)*R(?b3)*R(?b4)
195 #call MultiparticleConstraint(4)
196 #endif
198 #if {'$Npts'-1-'n'} >= 3
199 #include- BGphiN/BGphi3-Jreg.h
200 bracket L,R;
201 .sort:brack3;
202 keep brackets;
203 id L(?a1)*L(?a2)*L(?a3)*R(?b1)*R(?b2)*R(?b3) =
204 + phi(?a3,[p],?b3)*L(?a1)*L(?a2)*R(?b1)*R(?b2)
205 - phi(?a3,[p],?b1)*L(?a1)*L(?a2)*R(?b2)*R(?b3)
207 #call MultiparticleConstraint(3)
208 #endif
210 bracket L,R;
211 .sort:brack2;
212 keep brackets;
213 id L(?a1)*L(?a2)*R(?b1)*R(?b2) =
214 + phi(?a2,[p],?b2)*phi(?a1,[p],?b1)
215 - phi(?a2,[p],?b1)*phi(?a1,[p],?b2)
217 #call MultiparticleConstraint(2)
219 id ML(?m1)*ML(?m2)*MR(?n1)*MR(?n2) =
220 + phi(?m1,[p],?n1)*phi(?m2,[p],?n2)
221 - phi(?m2,[p],?n1)*phi(?m1,[p],?n2)
224 bracket phi;
225 .sort:brackphi;
226 keep brackets;
228 #call MultiparticleConstraint(1)
230 #endprocedure
233 #procedure MultiparticleConstraint(n)
235 if (match(phi(?m,[c],?n)));
236 print "bug: no subwords in phi %t";
237 exit;
238 endif;
240 id phi(i?,[p],j?) = delta_(i,j);
241 id phi(i?,j?,[p],i?,j?) = Is(i,j);
242 id phi(i?,j?,[p],j?,i?) = - Is(i,j);
244 * remove phi(A|B) where length(A) != length(B)
245 id phi(?m,[p],?n) = phi(?m,[p],?n)*delta_(nargs_(?m),nargs_(?n));
247 * remove phi(A|B) when letters in A and B are not the same
248 if (match(ctmpF1(?m))==0);
249 id phi(?m,[p],?n) = phi(?m,[p],?n)*ctmpF1(?m,[p],?n);
250 repeat id ctmpF1(?m1,i?,?m2,[p],?m3,i?,?m4) = ctmpF1(?m1,?m2,[p],?m3,?m4);
251 id ctmpF1([p]) = 1;
252 id ctmpF1(?m) = 0;
253 endif;
255 .sort: MulCtrnt'n';
257 #endprocedure
259 #procedure BGexpand(w)
261 .sort:AlphapWeight'w';
262 Symbol zwgt(:'w');
264 #if 'w' > 7
265 print "Error: order higher than alpha^7 not implemented!";
266 exit;
267 #endif
269 * Sanity check: number of arguments on both sides must be equal
270 id Zint(?m,[p],?n) = Zint(?m,[p],?n)*nargs(nargs_(?m) - nargs_(?n));
271 id nargs(0) = 1;
272 if (match(nargs(i?)));
273 print "Error: unequal number of labels in domain and integrand: %t";
274 exit;
275 endif;
277 if (match(Zint(?m,[p],?n)) == 0);
278 print "Error: specify the domain P and integrand Q as Zint(P,[p],Q)";
279 exit;
280 endif;
282 * Get the number of points
283 id once Zint(?m,[p],?n) = Zint(?m,[p],?n)*nargs(nargs_(?n));
284 id once nargs(x1?$Npts) = 1;
286 #define Npts "$Npts"
288 * Exploit cyclic symmetry of Zint(P|Q) in Q to match last label
289 id once Zint(?m,i?,[p],?n,i?,?p) = s(?n,?p)*phi(?m,[p],?p,?n);
290 .sort
292 * TODO: the number of calls to BiDeconcatenate(phi,i) should vary according to w
293 #call BiDeconcatenate(phi,{'w'+2})
294 #call CancelMandelstams('Npts')
296 #call tLalphaExpand(0,'w')
297 #call BiDeconcatenate(phi,{'w'+2})
298 #call tLalphaExpand(1,'w')
299 #call BiDeconcatenate(phi,{'w'+2})
300 #call tLalphaExpand(2,'w')
301 #call BiDeconcatenate(phi,{'w'+2})
302 #call tLalphaExpand(3,'w')
303 #call BiDeconcatenate(phi,{'w'+2})
304 #call tLalphaExpand(4,'w')
305 #call BiDeconcatenate(phi,{'w'+2})
306 #call tLalphaExpand(5,'w')
307 #call BiDeconcatenate(phi,{'w'+2})
308 #call tLalphaExpand(6,'w')
309 #call BiDeconcatenate(phi,{'w'+2})
310 #call tLalphaExpand(7,'w')
312 if (match(phi(?m)));
313 print "Bug: cannot have phi() at the end of recursion: %t";
314 print "Add more calls to tLalphaExpand()";
315 exit;
316 endif;
318 #if ('w' >= 7 && '$Npts' >= 10)
319 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
320 .sort:abrack10;
321 keep brackets;
322 #include- NptJregs/10ptJregs.h
323 #endif
325 #if ('w' >= 6 && '$Npts' >= 9)
326 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
327 .sort:abrack9;
328 keep brackets;
329 #include- NptJregs/9ptJregs.h
330 #endif
332 #if ('w' >= 5 && '$Npts' >= 8)
333 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
334 .sort:abrack8;
335 keep brackets;
336 #include- NptJregs/8ptJregs.h
337 #endif
339 #if ('w' >= 4 && '$Npts' >= 7)
340 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
341 .sort:abrack7;
342 keep brackets;
343 #include- NptJregs/7ptJregs.h
344 #endif
346 #if ('w' >= 3 && '$Npts' >= 6)
347 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
348 .sort:abrack6;
349 keep brackets;
350 #include- NptJregs/6ptJregs.h
351 #endif
353 #if ('w' >= 2 && '$Npts' >= 5)
354 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
355 .sort:abrack5;
356 keep brackets;
357 #include- NptJregs/5ptJregs.h
358 #endif
360 #if ('w' >= 1 && '$Npts' >= 4)
361 abracket phi,Is,KK,zeta2,zeta3,zeta5,zeta7;
362 .sort:abrack4;
363 keep brackets;
364 #include- NptJregs/4ptJregs.h
365 #endif
367 id zwgt = 1;
368 #call KKTos()
370 #endprocedure
372 #procedure KKTos()
374 bracket KK;
375 .sort:bracKK;
376 keep brackets;
378 repeat id KK(?n,i?,j?,[c],?m) = KK(?n,i,[c],?m) + KK(j,[c],?m);
380 id KK(i?,[c],i1?) = s(i,i1);
381 id KK(i?,[c],i1?,i2?) = s(i,i1) + s(i,i2);
382 id KK(i?,[c],i1?,i2?,i3?) = s(i,i1) + s(i,i2) + s(i,i3);
383 id KK(i?,[c],i1?,i2?,i3?,i4?) = s(i,i1) + s(i,i2) + s(i,i3) + s(i,i4);
384 id KK(i?,[c],i1?,i2?,i3?,i4?,i5?) = s(i,i1) + s(i,i2) + s(i,i3) + s(i,i4) + s(i,i5);
385 id KK(i?,[c],i1?,...,i6?) = s(i,i1) + s(i,i2) + s(i,i3) + s(i,i4) + s(i,i5) + s(i,i6);
386 id KK(i?,[c],i1?,...,i7?) = s(i,i1) + s(i,i2) + s(i,i3) + s(i,i4) + s(i,i5) + s(i,i6) + s(i,i7);
387 id KK(i?,[c],i1?,...,i8?) = s(i,i1) + s(i,i2) + s(i,i3) + s(i,i4) + s(i,i5) + s(i,i6) + s(i,i7) + s(i,i8);
389 .sort:KKTos;
390 * #call KNBasis('$Npts')
391 * #call MomentumConservationMandelstams('$Npts')
392 * #call NumericMandelstams('$Npts')
394 #endprocedure
397 #ifndef 'pss2mandelstams'
399 #procedure CancelMandelstams(N)
401 #do i=2,'N'
402 id s(i1?,...,i'i'?)^-1 = Is(i1,...,i'i');
403 id s(i1?,...,i'i'?)*Is(i1?,...,i'i'?) = 1;
404 #enddo
406 #endprocedure
408 #endif