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