1 import array
2 import copy
3 import math
6
8 """ Returns the number of independent coefficients there is in a
9 fully symmetric tensor of rank r """
10 return sum([((3+ri)*(2+ri)*(1+ri))/6 for ri in range(0,r+1)])
11
13 """ A class to represent a polynomial in the loop momentum (4-vector) q
14 and how the symmetrized coefficients are ordered. The ordering rule
15 correspond to what is presented in Eq. C.15 of arxiv:hep-ph/1405.0301"""
16
18
19 assert rank > -1, "The rank of a q-polynomial should be 0 or positive"
20 self.rank=rank
21 self.init_coef_list()
22
24 """ Creates a list whose elements are arrays being the coefficient
25 indices. We order this list according to the algorithm in
26 get_coef_position. This coef_list can then be used for the function
27 get_coef_at_position()
28 """
29
30 self.coef_list=[None,]*get_number_of_coefs_for_rank(self.rank)
31
32 PNO = Polynomial_naive_ordering(self.rank)
33
34 for coef in PNO.coef_list:
35 self.coef_list[self.get_coef_position(list(coef))]=coef
36
38 """ Returns the canonical position for a coefficient characterized
39 by the value of the indices of the loop momentum q it multiplies,
40 that is for example C_01032 multiplying q_0*q_1*q_0*q_3*q_2.
41 We assume that the explicit construction of the position below is
42 faster than a lookup in a table"""
43
44 fact = math.factorial
45
46 if len(indices_list)==0:
47 return 0
48
49 res = get_number_of_coefs_for_rank(len(indices_list)-1)
50
51 new_indices_list = copy.copy(indices_list)
52 new_indices_list.sort()
53
54 for i, ind in enumerate(new_indices_list):
55 if ind>0:
56 res = res + (fact(ind+i)/(fact(i+1)*fact(ind - 1)))
57
58 return res
59
61 """ Returns the coefficient at position pos in the one dimensional
62 vector """
63 return list(self.coef_list[pos])
64
66 """ A class to represent a polynomial in the loop momentum (4-vector) q"""
67
69
70 assert rank > -1, "The rank of a q-polynomial should be 0 or positive"
71 self.rank=rank
72 self.init_coef_list()
73
75 """ Creates a list whose elements are arrays being the coefficient
76 indices sorted in growing order and the value is their position in a
77 one-dimensional vector. For example the position of the coefficient
78 C_01032 will be placed in the list under array.array('i',(0,0,1,3,2)).
79 """
80 self.coef_list=[]
81 self.coef_list.append(array.array('i',()))
82
83 if self.rank==0:
84 return
85
86 tmp_coef_list=[array.array('i',(0,)),array.array('i',(1,)),
87 array.array('i',(2,)),array.array('i',(3,))]
88 self.coef_list.extend(tmp_coef_list)
89
90 for i in range(1,self.rank):
91 new_tmp_coef_list=[]
92 for coef in tmp_coef_list:
93 for val in range(coef[-1],4):
94 new_coef=copy.copy(coef)
95 new_coef.append(val)
96 new_tmp_coef_list.append(new_coef)
97 tmp_coef_list=new_tmp_coef_list
98 self.coef_list.extend(tmp_coef_list)
99
101 """ Returns the canonical position for a coefficient characterized
102 by the value of the indices of the loop momentum q it multiplies,
103 that is for example C_01032 multiplying q_0*q_1*q_0*q_3*q_2 """
104
105 new_indices_list=copy.copy(indices_list)
106 new_indices_list.sort()
107 try:
108 return self.coef_list.index(array.array('i',new_indices_list))
109 except ValueError:
110 raise PolynomialError,\
111 "The index %s looked for could not be found"%str(indices_list)
112
114 """ Returns the coefficient at position pos in the one dimensional
115 vector """
116 return list(self.coef_list[pos])
117
119 """ The mother class to output the polynomial subroutines """
120
121 - def __init__(self, max_rank, coef_format='complex*16', sub_prefix=''
122 ,line_split=30):
123 self.coef_format=coef_format
124 self.sub_prefix=sub_prefix
125 if coef_format=='complex*16':
126 self.rzero='0.0d0'
127 self.czero='(0.0d0,0.0d0)'
128 elif coef_format=='complex*32':
129 self.rzero='0.0e0_16'
130 self.czero='CMPLX(0.0e0_16,0.0e0_16,KIND=16)'
131 else:
132 self.rzero='0.0e0'
133 self.czero='(0.0e0,0.0e0)'
134 self.line_split=line_split
135 if max_rank<0:
136 raise PolynomialError, \
137 "The rank of a q-polynomial should be 0 or positive"
138 self.max_rank=max_rank
139 self.pq=Polynomial(max_rank)
140
142 """ A daughter class to output the subroutine in the fortran format"""
143
144
146 """ Returns a fortran subroutine which fills in the array of integral reduction
147 coefficients following MadLoop standards using pjfry++ coefficients."""
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 def format_power(pow):
163 b, e = pow
164
165 if e == 1:
166 return str(b)
167 else:
168 return "%s^%d" % (b, e)
169
170
171 def get_coef_position(indices_list):
172 new_indices_list=copy.copy(indices_list)
173 new_indices_list.sort()
174 r=len(new_indices_list)
175 if r == 0:
176 pos=0
177 else:
178 pos=get_number_of_coefs_for_rank(r-1)
179 for i,mu in enumerate(new_indices_list):
180 num = mu
181 den = 1
182 if mu > 0 and i > 0:
183 for j in range(2,i+2):
184 num *= (mu+j-1)
185 den *= j
186 pos += num/den
187 return pos
188
189 lines = []
190 lines.append(
191 """SUBROUTINE %(sub_prefix)sCONVERT_PJFRY_COEFFS(RANK,PJCOEFS,TIRCOEFS)
192 C GLOABLE VARIABLES
193 include 'coef_specs.inc'
194 C ARGUMENTS
195 INTEGER RANK
196 %(coef_format)s PJCOEFS(0:LOOP_MAXCOEFS-1,3)
197 %(coef_format)s TIRCOEFS(0:LOOP_MAXCOEFS-1,3)"""
198 %{'sub_prefix':self.sub_prefix,'coef_format':self.coef_format})
199
200 for R in range(self.max_rank+1):
201 Ncoeff=((3+R)*(2+R)*(1+R))/6
202 if R == 0:
203 offset=0
204 else:
205 offset=get_number_of_coefs_for_rank(R-1)
206 for i in range(offset,Ncoeff+offset):
207 indices_list=self.pq.get_coef_at_position(i)
208 sindices = map(lambda i: "q(%d)" % i, indices_list)
209 coeff_list = []
210 for j in range(4):
211 qvalue = "q(%d)"%j
212 qpow = sindices.count(qvalue)
213 if qpow > 0:
214 coeff_list.append(format_power([qvalue,qpow]))
215
216 if not coeff_list:
217 coeff_str = "1"
218 else:
219 coeff_str = "*".join(coeff_list)
220
221 pjpos = get_coef_position(indices_list)
222 lines.append("c Reduction Coefficient %s"%coeff_str)
223 lines.append('TIRCOEFS(%d,1:3)=PJCOEFS(%d,1:3)'%(i,pjpos))
224 lines.append('IF(RANK.LE.%d)RETURN'%R)
225
226 lines.append('end')
227
228 return '\n'.join(lines)
229
231 """ Returns a fortran subroutine which fills in the array of integral reduction
232 coefficients following MadLoop standards using IREGI coefficients."""
233
234
235
236
237
238
239
240
241 def format_power(pow):
242 b, e = pow
243
244 if e == 1:
245 return str(b)
246 else:
247 return "%s^%d" % (b, e)
248
249 lines = []
250 lines.append(
251 """SUBROUTINE %(sub_prefix)sCONVERT_IREGI_COEFFS(RANK,IREGICOEFS,TIRCOEFS)
252 C GLOABLE VARIABLES
253 include 'coef_specs.inc'
254 C ARGUMENTS
255 INTEGER RANK
256 %(coef_format)s IREGICOEFS(0:LOOP_MAXCOEFS-1,3)
257 %(coef_format)s TIRCOEFS(0:LOOP_MAXCOEFS-1,3)"""
258 %{'sub_prefix':self.sub_prefix,'coef_format':self.coef_format})
259
260 iregi_gen = FromIREGIFortranCodeGenerator(self.max_rank)
261 for R in range(self.max_rank+1):
262 Ncoeff=((3+R)*(2+R)*(1+R))/6
263 if R == 0:
264 offset=0
265 else:
266 offset=get_number_of_coefs_for_rank(R-1)
267 for i in range(offset,Ncoeff+offset):
268 indices_list=self.pq.get_coef_at_position(i)
269 sindices = map(lambda i: "q(%d)" % i, indices_list)
270 coeff_list = []
271 for j in range(4):
272 qvalue = "q(%d)"%j
273 qpow = sindices.count(qvalue)
274 if qpow > 0:
275 coeff_list.append(format_power([qvalue,qpow]))
276
277 if not coeff_list:
278 coeff_str = "1"
279 else:
280 coeff_str = "*".join(coeff_list)
281
282 iregipos = iregi_gen.get_coef_position(indices_list)
283 lines.append("c Reduction Coefficient %s"%coeff_str)
284 lines.append('TIRCOEFS(%d,1:3)=IREGICOEFS(%d,1:3)'%(i,iregipos))
285 lines.append('IF(RANK.LE.%d)RETURN'%R)
286 lines.append('end')
287
288 return '\n'.join(lines)
289
291 """ Returns a fortran subroutine which fills in the array of tensorial
292 coefficients following golem95 standards using MadLoop coefficients."""
293
294 subroutines = []
295
296
297 d = 4
298 golem_max_rank = 6
299
300
301
302 block_info = {}
303 for R in range(1,self.max_rank+1):
304 for k in range(1,min(R,d)+1):
305 LHS, RHS, lst, dic = \
306 FromGolem95FortranCodeGenerator.generate_equations(R, k)
307 block_info[(R,k)] = (lst, dic)
308
309
310 def format_power(pow):
311 b, e = pow
312
313 if e == 1:
314 return str(b)
315 else:
316 return "%s^%d" % (b, e)
317
318
319 for R in range(golem_max_rank+1):
320
321 lines=[]
322
323 if R==0:
324 lines.append(
325 """SUBROUTINE %(sub_prefix)sFILL_GOLEM_COEFFS_0(ML_COEFS,GOLEM_COEFS)
326 use precision_golem, only: ki
327 include 'coef_specs.inc'
328 %(coef_format)s ML_COEFS(0:LOOP_MAXCOEFS-1)
329 complex(ki) GOLEM_COEFS"""
330 %{'sub_prefix':self.sub_prefix,'coef_format':self.coef_format})
331 lines.append("GOLEM_COEFS=ML_COEFS(0)")
332 lines.append("end")
333 subroutines.append('\n'.join(lines))
334 continue
335
336
337 lines.append(
338 """SUBROUTINE %(sub_prefix)sFILL_GOLEM_COEFFS_%(rank)d(ML_COEFS,GOLEM_COEFS)
339 use tens_rec, only: coeff_type_%(rank)d
340 include 'coef_specs.inc'
341 %(coef_format)s ML_COEFS(0:LOOP_MAXCOEFS-1)
342 type(coeff_type_%(rank)d) GOLEM_COEFS"""
343 %{'sub_prefix':self.sub_prefix,'rank':R,
344 'coef_format':self.coef_format})
345
346 if R > self.max_rank:
347 lines.append('C Dummy routine for %(sub_prefix)sFILL_GOLEM_COEFS_%(rank)d'\
348 %{'sub_prefix':self.sub_prefix,'rank':R,
349 'coef_format':self.coef_format})
350 lines.append("STOP 'ERROR: %d > %d'"%(R,self.max_rank))
351 lines.append('end')
352 subroutines.append('\n'.join(lines))
353 continue
354
355
356 lines.append("c Constant coefficient ")
357 lines.append("GOLEM_COEFS%%c0=ML_COEFS(%d)"\
358 %self.pq.get_coef_position([]))
359
360
361 for k in range(1,min(R,d)+1):
362 lst, dic = block_info[(R,k)]
363 dim = len(lst)
364 lab = 0
365 for indices in FromGolem95FortranCodeGenerator.select(range(d), k):
366 lab += 1
367 sindices = map(lambda i: "q(%d)" % i, indices)
368 for i in range(dim):
369 coeff_str = "*".join(map(format_power,zip(sindices, lst[i])))
370 ML_indices = sum(
371 [[ind]*lst[i][j] for j, ind in enumerate(indices)],[])
372 ML_coef_pos = self.pq.get_coef_position(ML_indices)
373 ML_sign_convention = ' ' if len(ML_indices)%2==0 else '-'
374 lines.append("c Coefficient %s"%coeff_str)
375 lines.append("GOLEM_COEFS%%c%d(%d,%d)=%sML_COEFS(%d)"\
376 % (k, lab, i+1, ML_sign_convention, ML_coef_pos))
377
378 subroutines.append('\n'.join(lines+['end']))
379
380 return '\n\n'.join(subroutines)
381
383 """ Give out the subroutine to update a polynomial of rank r_1 with
384 one of rank r_2 """
385
386
387
388
389
390
391
392
393
394
395 lines=[]
396
397
398 lines.append(
399 """SUBROUTINE %(sub_prefix)sUPDATE_WL_%(r_1)d_%(r_2)d(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT)
400 include 'coef_specs.inc'
401 INTEGER I,J,K
402 %(coef_format)s A(MAXLWFSIZE,0:LOOP_MAXCOEFS-1,MAXLWFSIZE)
403 %(coef_format)s B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE)
404 %(coef_format)s OUT(MAXLWFSIZE,0:LOOP_MAXCOEFS-1,MAXLWFSIZE)
405 INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE
406 """%{'sub_prefix':self.sub_prefix,'r_1':r_1,'r_2':r_2,
407 'coef_format':self.coef_format})
408
409
410 lines.append("DO I=1,LCUT_SIZE")
411 lines.append(" DO J=1,OUT_SIZE")
412 lines.append(" DO K=0,%d"%(get_number_of_coefs_for_rank(r_2+r_1)-1))
413 lines.append(" OUT(J,K,I)=%s"%self.czero)
414 lines.append(" ENDDO")
415 lines.append(" DO K=1,IN_SIZE")
416
417
418
419
420
421
422 coef_expressions={}
423 for coef_a in range(0,get_number_of_coefs_for_rank(r_1)):
424 for coef_b in range(0,get_number_of_coefs_for_rank(r_2)):
425 ind_list=self.pq.get_coef_at_position(coef_a)+\
426 self.pq.get_coef_at_position(coef_b)
427 new_term="A(K,%d,I)*B(J,%d,K)"%(coef_a,coef_b)
428 new_position=self.pq.get_coef_position(ind_list)
429 try:
430 coef_expressions[new_position].append(new_term)
431 except KeyError:
432 coef_expressions[new_position]=[new_term,]
433 for coef, value in coef_expressions.items():
434 split=0
435 while split<len(value):
436 lines.append("OUT(J,%d,I)=OUT(J,%d,I)+"%(coef,coef)+\
437 '+'.join(value[split:split+self.line_split]))
438 split=split+self.line_split
439
440
441 lines.append(" ENDDO")
442 lines.append(" ENDDO")
443 lines.append("ENDDO")
444 lines.append("END")
445
446
447 return '\n'.join(lines)
448
450 """ Give out the subroutine to evaluate a polynomial of a rank up to
451 the maximal one specified when initializing the FortranPolynomialRoutines
452 object. """
453 lines=[]
454
455
456 lines.append("""SUBROUTINE %(sub_prefix)sEVAL_POLY(C,R,Q,OUT)
457 include 'coef_specs.inc'
458 %(coef_format)s C(0:LOOP_MAXCOEFS-1)
459 INTEGER R
460 %(coef_format)s Q(0:3)
461 %(coef_format)s OUT
462 """%{'sub_prefix':self.sub_prefix,
463 'coef_format':self.coef_format})
464
465
466 lines.append("OUT=C(0)")
467
468 for r in range(1,self.max_rank+1):
469 lines.append("IF (R.GE.%d) then"%r)
470 terms=[]
471 for coef_num in range(get_number_of_coefs_for_rank(r-1)
472 ,get_number_of_coefs_for_rank(r)):
473 coef_inds=self.pq.get_coef_at_position(coef_num)
474 terms.append('*'.join(['C(%d)'%coef_num,]+
475 ['Q(%d)'%ind for ind in coef_inds]))
476 split=0
477 while split<len(terms):
478 lines.append("OUT=OUT+"+\
479 '+'.join(terms[split:split+self.line_split]))
480 split=split+self.line_split
481 lines.append("ENDIF")
482 lines.append("END")
483
484 return '\n'.join(lines)
485
487 """ Give out the subroutine to merge the components of a final loop
488 wavefunction of a loop to create the coefficients of the polynomial
489 representing the numerator, while multiplying each of them by 'const'."""
490 lines=[]
491
492
493 lines.append("""SUBROUTINE %(sub_prefix)sMERGE_WL(WL,R,LCUT_SIZE,CONST,OUT)
494 include 'coef_specs.inc'
495 INTEGER I,J
496 %(coef_format)s WL(MAXLWFSIZE,0:LOOP_MAXCOEFS-1,MAXLWFSIZE)
497 INTEGER R,LCUT_SIZE
498 %(coef_format)s CONST
499 %(coef_format)s OUT(0:LOOP_MAXCOEFS-1)
500 """%{'sub_prefix':self.sub_prefix,
501 'coef_format':self.coef_format})
502
503
504 lines.append("""INTEGER NCOEF_R(0:%(max_rank)d)
505 DATA NCOEF_R/%(ranks)s/
506 """%{'max_rank':self.max_rank,'ranks':','.join([
507 str(get_number_of_coefs_for_rank(r)) for r in
508 range(0,self.max_rank+1)])})
509
510
511 lines.append("DO I=1,LCUT_SIZE")
512 lines.append(" DO J=0,NCOEF_R(R)-1")
513 lines.append(" OUT(J)=OUT(J)+WL(I,J,I)*CONST")
514 lines.append(" ENDDO")
515 lines.append("ENDDO")
516 lines.append("END")
517
518 return '\n'.join(lines)
519
521 """ Give out the subroutine to simply add together the coefficients
522 of two loop polynomials of rank R1 and R2 storing the result in the
523 first polynomial given in the arguments."""
524 lines=[]
525
526
527 lines.append("""SUBROUTINE %(sub_prefix)sADD_COEFS(A,RA,B,RB)
528 include 'coef_specs.inc'
529 INTEGER I
530 %(coef_format)s A(0:LOOP_MAXCOEFS-1),B(0:LOOP_MAXCOEFS-1)
531 INTEGER RA,RB
532 """%{'sub_prefix':self.sub_prefix,
533 'coef_format':self.coef_format})
534
535
536 lines.append("""INTEGER NCOEF_R(0:%(max_rank)d)
537 DATA NCOEF_R/%(ranks)s/
538 """%{'max_rank':self.max_rank,'ranks':','.join([
539 str(get_number_of_coefs_for_rank(r)) for r in
540 range(0,self.max_rank+1)])})
541
542
543 lines.append("DO I=0,NCOEF_R(RB)-1")
544 lines.append(" A(I)=A(I)+B(I)")
545 lines.append("ENDDO")
546 lines.append("END")
547
548 return '\n'.join(lines)
549
551 """ Back up of the class Polynomial, which uses the same coefficeints orders with IREGI.
552 It is useful in the case that the order of MadLoop coefficients changes in the future."""
553
555
556 assert rank > -1, "The rank of a q-polynomial should be 0 or positive"
557 self.rank=rank
558 self.init_coef_list()
559
561 """ Creates a list whose elements are arrays being the coefficient
562 indices sorted in growing order and the value is their position in a
563 one-dimensional vector. For example the position of the coefficient
564 C_01032 will be placed in the list under array.array('i',(0,0,1,3,2)).
565 """
566 self.coef_list=[]
567 self.coef_list.append(array.array('i',()))
568
569 if self.rank==0:
570 return
571
572 tmp_coef_list=[array.array('i',(0,)),array.array('i',(1,)),
573 array.array('i',(2,)),array.array('i',(3,))]
574 self.coef_list.extend(tmp_coef_list)
575
576 for i in range(1,self.rank):
577 new_tmp_coef_list=[]
578 for coef in tmp_coef_list:
579 for val in range(coef[-1],4):
580 new_coef=copy.copy(coef)
581 new_coef.append(val)
582 new_tmp_coef_list.append(new_coef)
583 tmp_coef_list=new_tmp_coef_list
584 self.coef_list.extend(tmp_coef_list)
585
587 """ Returns the canonical position for a coefficient characterized
588 by the value of the indices of the loop momentum q it multiplies,
589 that is for example C_01032 multiplying q_0*q_1*q_0*q_3*q_2 """
590
591 new_indices_list=copy.copy(indices_list)
592 new_indices_list.sort()
593 try:
594 return self.coef_list.index(array.array('i',new_indices_list))
595 except ValueError:
596 raise PolynomialError,\
597 "The index %s looked for could not be found"%str(indices_list)
598
600 """ Returns the coefficient at position pos in the one dimensional
601 vector """
602 return list(self.coef_list[pos])
603
606 """ Just a container class with helper functions taken from the script
607 tens.py of golem which generates most of the golem95 tens_rec.f fortran
608 code."""
609
610 PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
611 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
612 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
613 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
614 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
615 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
616 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
617 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
618 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
619 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
620 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
621 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
622 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
623 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
624 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
625 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
626 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
627 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
628 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
629 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
630 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
631 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373]
632
633 @classmethod
635 """
636 Calculates the binomial coefficient (n atop k).
637 """
638 if k < 0 or k > n:
639 return 0
640 else:
641 num = 1
642 den = 1
643 for i in range(1, k+1):
644 num *= n-i+1
645 den *= i
646 return num/den
647
648 @classmethod
650 """
651 Generates a mapping from tensor components \hat{C}(a_1, ..., a_k)
652 into a one dimensional array.
653
654 PARAMETER
655
656 R -- rank
657 k -- number of non-zero components of q
658
659 RETURN
660
661 (lst, dic)
662
663 lst -- list of (a_1, ..., a_k)
664 dic -- mapping from (a_1, ..., a_k) -> int
665
666 lst[dic[X]] = X if X in dic
667 """
668
669 def rec_generator(k, R):
670 if k == 0:
671 yield []
672 elif k <= R:
673 for a_1 in range(1, R - (k - 1) + 1):
674 if k > 1:
675 for tail in rec_generator(k - 1, R - a_1):
676 yield [a_1] + tail
677 else:
678 yield [a_1]
679
680 lst = []
681 dic = {}
682 i = 0
683 for indices in rec_generator(k, R):
684 t = tuple(indices)
685 lst.append(t)
686 dic[t] = i
687 i += 1
688
689 assert i == cls.combinat(R, k), \
690 "len(%s) != %d, R=%d,k=%d" % (lst,cls.combinat(R, k),R,k)
691 return lst, dic
692
693 @classmethod
695 """
696 Generates a set of equations for a given number of non-zero
697 components and fixed maximum rank.
698
699 PARAMETER
700
701 R -- rank
702 k -- number of non-zero components of q
703
704 RETURN
705
706 (LHS, RHS)
707
708 LHS -- a matrix (i.e. list of lists) of coefficients
709 RHS -- a list of values of q
710 """
711
712 lst, dic = cls.generate_mapping(R, k)
713 l = len(lst)
714 LHS = []
715 RHS = []
716 for num_eq in range(l):
717 q = map(lambda i: cls.PRIMES[i], lst[num_eq])
718 coeffs = [
719 reduce(lambda x,y: x*y, map(lambda (b,e): b**e, zip(q, term)), 1)
720 for term in lst]
721 LHS.append(coeffs)
722 RHS.append(q)
723
724 return LHS, RHS, lst, dic
725
726 @classmethod
728 """
729 Iterator over all selections of k elements from a given list.
730
731 PARAMETER
732
733 items -- list of elements to choose from (no repetitions)
734 k -- number of elements to select.
735 """
736 n = len(items)
737
738
739 if k == n:
740 yield items[:]
741 elif k == 0:
742 yield []
743 elif 0 < k and k < n:
744 head = items[0:1]
745 tail = items[1:]
746 for result in cls.select(tail, k-1):
747 yield head + result
748 for result in cls.select(tail, k):
749 yield result
750
751 if __name__ == '__main__':
752 """I test here the write_golem95_mapping function"""
753
754 max_rank=6
755 FPR=FortranPolynomialRoutines(max_rank)
756 print "Output of write_golem95_mapping function for max_rank=%d:\n\n"%max_rank
757
758 import os
759 import sys
760 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
761 sys.path.insert(0, os.path.join(root_path,os.path.pardir))
762 import madgraph.iolibs.file_writers as writers
763 FWriter = writers.FortranWriter("GOLEM95_interface.f")
764 FWriter.writelines(FPR.write_golem95_mapping())
765