5
RECURSIVE FUNCTION factorial(i) RESULT(fac)
10
LOGICAL,DIMENSION(12)::lfacsave
11
INTEGER,DIMENSION(12)::facsave
12
SAVE facsave,init,lfacsave
14
lfacsave(1:12)=.FALSE.
18
WRITE(*,*)"ERROR: i<0 in factorial with i=",i
22
WRITE(*,*)"ERROR: i > 12, please take long type (KIND=LINT) integer"
36
END FUNCTION factorial
38
SUBROUTINE PCL2PE(NLOOPLINE,PCL,PE)
39
! transfer the loop momenta q,q+p1,q+p1+p2,q+p1+p2+p3,...
42
INTEGER,INTENT(IN)::NLOOPLINE
43
REAL(KIND(1d0)),DIMENSION(NLOOPLINE,0:3),INTENT(IN)::PCL
44
REAL(KIND(1d0)),DIMENSION(NLOOPLINE,0:3),INTENT(OUT)::PE
47
PE(i,0:3)=PCL(i+1,0:3)-PCL(i,0:3)
49
PE(NLOOPLINE,0:3)=PCL(1,0:3)-PCL(NLOOPLINE,0:3)
53
RECURSIVE SUBROUTINE calc_all_integers(n,ntot,i,sol)
54
! finds all the non-negative solutions to x1,...,xn
55
! that x1+x2+...+xn==i
56
! the number of solutions should be ntot=C(i+n-1)^(n-1)=(i+n-1)!/(n-1)!/i!
57
! it can be recycled for all phase space point
59
INTEGER,INTENT(IN)::n,ntot,i
60
INTEGER,DIMENSION(ntot,n),INTENT(OUT)::sol
72
k=xiarray_arg1(i-j,n-1)
74
CALL calc_all_integers(n-1,k,i-j,sol(k0+1:k0+k,2:n))
78
END SUBROUTINE calc_all_integers
80
SUBROUTINE all_Integers(n,ntot,i,sol,factor)
81
! finds all the non-negative solutions to x1,...,xn
82
! that x1+x2+...+xn==i
83
! the number of solutions should be ntot=C(i+n-1)^(n-1)=(i+n-1)!/(n-1)!/i!
84
! it can be recycled for all phase space point
86
INTEGER,INTENT(IN)::n,ntot,i
87
INTEGER,DIMENSION(ntot,n),INTENT(OUT)::sol
88
REAL(KIND(1d0)),DIMENSION(ntot),INTENT(OUT)::factor
89
INTEGER::ifirst=0,j,jk,k,ntemptot
90
INTEGER::maxxiarray,inum,nnum,maxxiarray1,maxxiarray2
91
INTEGER::maxfactor_xiarray
93
! calculate xiarray_i_n first
95
maxxiarray=(MAXRANK_IREGI+1)*(MAXNLOOP_IREGI-1)
96
IF(.NOT.ALLOCATED(xiarray))THEN
97
ALLOCATE(xiarray(maxxiarray))
99
maxfactor_xiarray=(MAXRANK_IREGI+1)*(MAXNLOOP_IREGI-2)
100
IF(.NOT.ALLOCATED(factor_xiarray))THEN
101
ALLOCATE(factor_xiarray(MAXRANK_IREGI+2:maxfactor_xiarray+MAXRANK_IREGI+1))
104
! C(i+n-1)^(n-1)=(i+n-1)!/(n-1)!/i!
106
inum=MOD(j-1,MAXRANK_IREGI+1) ! i
107
nnum=(j-1)/(MAXRANK_IREGI+1)+1 ! n
108
maxxiarray1=xiarray_arg1(inum,nnum)
110
IF(.NOT.ALLOCATED(xiarray(j)%xiarray_i_n))THEN
111
ALLOCATE(xiarray(j)%xiarray_i_n(maxxiarray1,maxxiarray2))
114
xiarray(j)%xiarray_i_n(1,1)=j-1
117
CALL calc_all_integers(nnum,maxxiarray1,inum,&
118
xiarray(j)%xiarray_i_n(1:maxxiarray1,1:maxxiarray2))
119
IF(.NOT.ALLOCATED(factor_xiarray(j)%factor_xiarray_i_n))THEN
120
ALLOCATE(factor_xiarray(j)%factor_xiarray_i_n(maxxiarray1))
123
factor_xiarray(j)%factor_xiarray_i_n(jk)=DBLE(factorial(inum))
125
factor_xiarray(j)%factor_xiarray_i_n(jk)=factor_xiarray(j)%factor_xiarray_i_n(jk)/&
126
DBLE(factorial(xiarray(j)%xiarray_i_n(jk,k)))
129
ntot_xiarray(inum,nnum)=maxxiarray1
133
IF(n.GT.MAXNLOOP_IREGI-1.OR.n.LT.1)THEN
134
WRITE(*,100)"ERROR: n is out of range 1<=n<=",MAXNLOOP_IREGI-1," in all_integers"
137
IF(i.GT.MAXRANK_IREGI.OR.i.LT.0)THEN
138
WRITE(*,100)"ERROR: r is out of range 0<=r<=",MAXRANK_IREGI," in all_integers"
141
IF(n.EQ.1.AND.ntot.NE.1)THEN
142
WRITE(*,*)"ERROR:ntot should be 1 when n=1 in all_integers"
145
IF(n.GE.2.AND.n.LE.MAXNLOOP_IREGI-1)THEN
146
! Make it work in MadLoop, otherwise it is wrong
147
IF(ntot.NE.ntot_xiarray(i,n))THEN
148
WRITE(*,*)"ERROR: ntot is not correct in all_integers"
152
j=(n-1)*(MAXRANK_IREGI+1)+i+1
155
sol(1:ntot,1:n)=xiarray(j)%xiarray_i_n(1:1,1:n)
158
sol(1:ntot,1:n)=xiarray(j)%xiarray_i_n(1:ntot,1:n)
159
factor(1:ntot)=factor_xiarray(j)%factor_xiarray_i_n(1:ntot)
162
100 FORMAT(2X,A31,I2,A16)
163
END SUBROUTINE all_Integers
165
SUBROUTINE calc_factorial_pair
168
factorial_pair(1:MAXINDICES_IREGI,0)=1d0
169
DO i=1,MAXINDICES_IREGI
171
factorial_pair(i,j)=DBLE(factorial(i+j-1))&
172
/DBLE(factorial(i-1))/DBLE(factorial(j))
176
END SUBROUTINE calc_factorial_pair
178
FUNCTION number_coefs_for_rank(rank) RESULT(res)
180
INTEGER,INTENT(IN)::rank
185
res=res+((3+i)*(2+i)*(1+i))/6
188
END FUNCTION number_coefs_for_rank
192
CHARACTER(len=8)::ampm
197
CHARACTER( len = 9 ),PARAMETER,DIMENSION(12) :: month = (/ &
198
'January ', 'February ', 'March ', 'April ', &
199
'May ', 'June ', 'July ', 'August ', &
200
'September', 'October ', 'November ', 'December ' /)
203
INTEGER,DIMENSION(8)::values
205
CALL date_and_time(values=values)
215
ELSEIF( h.EQ.12 )THEN
216
IF( n.EQ.0 .AND. s.EQ.0 )THEN
225
ELSEIF( h.EQ.12 )THEN
226
IF(n.EQ.0.AND.s.EQ.0)THEN
233
WRITE( *, '(i2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) &
234
d, TRIM( month(m) ), y, h, ':', n, ':', s, '.', mm, TRIM( ampm )
236
END SUBROUTINE timestamp
237
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
239
! FOLLOWING SUBROUTINES/FUNCTIONS ARE ONLY FOR THE REORDERING THE TIR COEFS !
241
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
242
SUBROUTINE SORT_IREGICOEFS(RANK,NLOOPCOEFS,OLDCOEFS,NEWCOEFS)
244
! CONVERT THE OUTPUT OF IREGI TO THAT OF (NEW) MADLOOP
246
! THE NEW OUTPUT OF COEFS FROM MADLOOP IS
248
! RANK=1: (0,),(1,),(2,),(3,)
249
! RANK=2: (0,0),(0,1),(1,1),(0,2),(1,2),(2,2),(0,3),(1,3),(2,3),(3,3)
251
! THE OLD OUTPUT OF COEFS FROM MADLOOP IS
253
! RANK=1: (0,),(1,),(2,),(3,)
254
! RANK=2: (0,0),(0,1),(0,2),(0,3),(1,1),(2,1),(3,1),(2,2),(2,3),(3,3)
259
INTEGER,INTENT(IN)::RANK,NLOOPCOEFS
260
COMPLEX(KIND(1d0)),DIMENSION(0:NLOOPCOEFS-1,3),INTENT(IN)::OLDCOEFS
261
COMPLEX(KIND(1d0)),DIMENSION(0:NLOOPCOEFS-1,3),INTENT(OUT)::NEWCOEFS
267
! Sum((3+r)*(2+r)*(1+r)/6,{r,0,10})=1001
268
INTEGER,PARAMETER::LOOPMAXCOEFS_IREGI=1001
269
INTEGER,DIMENSION(0:LOOPMAXCOEFS_IREGI-1)::POS
278
IF(NLOOPCOEFS.GT.LOOPMAXCOEFS_IREGI)&
279
STOP "ERROR:LOOPMAXCOEFS_IREGI IS TOO SMALL!!!"
281
! ASSIGN THE POSITION OF POS FOR SWAP
282
CALL ASSIGN_PJPOS(POS)
286
! NEWCOEFS(I,1:3)=OLDCOEFS(POS(I),1:3)
287
NEWCOEFS(POS(I),1:3)=OLDCOEFS(I,1:3)
290
END SUBROUTINE SORT_IREGICOEFS
292
SUBROUTINE ASSIGN_PJPOS(POS)
294
! ASSIGN THE POSITION OF POS FOR SWAP
302
! Sum((3+r)*(2+r)*(1+r)/6,{r,0,10})=1001
303
INTEGER,PARAMETER::LOOPMAXCOEFS_IREGI=1001,MAXRANK=10
307
INTEGER,DIMENSION(0:LOOPMAXCOEFS_IREGI-1),INTENT(OUT)::POS
311
INTEGER::I,J,K,SHIFT,DN
312
INTEGER,DIMENSION(MAXRANK)::POSINDEX,PJPOSINDEX
322
DN=(J+3)*(J+2)*(J+1)/6
323
POSINDEX(1:MAXRANK)=0
324
PJPOSINDEX(1:MAXRANK)=0
326
IF(I.GT.1)CALL NEXTINDEX(J,POSINDEX)
327
CALL CONVERT_PJPOSINDEX(J,POSINDEX,PJPOSINDEX)
328
K=DN-QPOLYPOS(J,PJPOSINDEX)+1+SHIFT
335
END SUBROUTINE ASSIGN_PJPOS
337
SUBROUTINE NEXTINDEX(RANK,POSINDEX)
339
! CALL FOR THE NEXT INDEX
345
INTEGER,PARAMETER::MAXRANK=10
349
INTEGER,INTENT(IN)::RANK
350
INTEGER,DIMENSION(MAXRANK),INTENT(INOUT)::POSINDEX
359
POSINDEX(I)=POSINDEX(I)+1
360
IF(POSINDEX(I).GT.3)THEN
367
POSINDEX(1:I-1)=POSINDEX(I)
373
END SUBROUTINE NEXTINDEX
375
SUBROUTINE CONVERT_PJPOSINDEX(RANK,POSINDEX,PJPOSINDEX)
377
! CONVERT POSINDEX TO PJPOSINDEX
383
INTEGER,PARAMETER::MAXRANK=10
387
INTEGER,INTENT(IN)::RANK
388
INTEGER,DIMENSION(MAXRANK),INTENT(IN)::POSINDEX
389
INTEGER,DIMENSION(MAXRANK),INTENT(OUT)::PJPOSINDEX
398
PJPOSINDEX(RANK+1-I)=3-POSINDEX(I)
401
END SUBROUTINE CONVERT_PJPOSINDEX
403
FUNCTION QPOLYPOS(RANK,POSINDEX)
405
! COMPUTATION THE RELATIVE POSITION OF INDEX WITH RANK
406
! IN THE *OLD* MADLOOP CONVENTION
412
INTEGER,PARAMETER::MAXRANK=10
416
INTEGER,INTENT(IN)::RANK
417
INTEGER,DIMENSION(MAXRANK),INTENT(IN)::POSINDEX
433
QPOLYPOS=POSINDEX(1)+1
437
QPOLYPOS=POSINDEX(1)-POSINDEX(2)+1
444
DO J=IMIN,POSINDEX(I)-1
445
QPOLYPOS=QPOLYPOS+QPOLYNUMBER(J,I-1)
449
END FUNCTION QPOLYPOS
451
FUNCTION NEWQPOLYPOS(RANK,POSINDEX)
453
! COMPUTATION THE RELATIVE POSITION OF INDEX WITH RANK
454
! IN THE *NEW* MADLOOP CONVENTION
460
INTEGER,PARAMETER::MAXRANK=10
464
INTEGER,INTENT(IN)::RANK
465
INTEGER,DIMENSION(MAXRANK),INTENT(IN)::POSINDEX
481
NEWQPOLYPOS=POSINDEX(1)+1
487
IF(POSINDEX(RANK-I+1).EQ.0)THEN
490
! Eq.(3.4.6) in Valentin's PhD Thesis
491
IMIN=factorial(POSINDEX(RANK-I+1)+I-1)/factorial(I)&
492
/factorial(POSINDEX(RANK-I+1)-1)
494
NEWQPOLYPOS=NEWQPOLYPOS+IMIN
497
END FUNCTION NEWQPOLYPOS
499
FUNCTION QPOLYNUMBER(I,RANK)
501
! THE INDEPENDENT NUMBER OF Q POLY WITH \MU=I,...,3 AND RANK
510
INTEGER,INTENT(IN)::I,RANK
520
QPOLYNUMBER=(3+RANK)*(2+RANK)*(1+RANK)/6
522
QPOLYNUMBER=(2+RANK)*(1+RANK)/2
528
STOP 'I must be >= 0 and <=3 in QPOLYNUMBER.'
531
END FUNCTION QPOLYNUMBER
533
FUNCTION POS2RANK(ipos)
535
INTEGER,INTENT(IN)::ipos
538
! NOW ITS MAX RANK IS 10
539
INTEGER,PARAMETER::MAXRANK=10
540
INTEGER,DIMENSION(0:MAXRANK)::IRANGE
546
IRANGE(I)=IRANGE(I-1)+(I+3)*(I+2)*(I+1)/6
555
IF(ipos.LE.IRANGE(I))THEN
560
WRITE(*,*)"ERROR in POS2RANK,ipos=",ipos
562
END FUNCTION POS2RANK
564
FUNCTION RANK_NUM(MAXRANK)
567
INTEGER,INTENT(IN)::MAXRANK
570
IF(MAXRANK.LT.0)RETURN
572
RANK_NUM=RANK_NUM+(I+3)*(I+2)*(I+1)/6
575
END FUNCTION RANK_NUM
577
SUBROUTINE SHIFT_MOM(MOM,NCOEFS,TICOEFS_SAVE,TICOEFS)
584
! Sum((3+r)*(2+r)*(1+r)/6,{r,0,10})=1001 --> LOOPMAXCOEFS_IREGI
585
! MAX OF (i1+1)*(i2+1)*(i3+1)*(i4+1) with i1+i2+i3+i4<=MAXRANK = 144 --> MAXSPLIT
586
INTEGER,PARAMETER::LOOPMAXCOEFS_IREGI=1001,MAXRANK=10,MAXSPLIT=144
587
REAL(KIND(1d0)),DIMENSION(0:3),INTENT(IN)::MOM
588
INTEGER,INTENT(IN)::NCOEFS
589
COMPLEX(KIND(1d0)),DIMENSION(0:NCOEFS-1,1:4),INTENT(IN)::TICOEFS_SAVE
590
COMPLEX(KIND(1d0)),DIMENSION(0:NCOEFS-1,1:4),INTENT(OUT)::TICOEFS
592
INTEGER,DIMENSION(0:LOOPMAXCOEFS_IREGI-1)::NTERM
593
REAL(KIND(1d0)),DIMENSION(0:LOOPMAXCOEFS_IREGI-1,MAXSPLIT)::SPLIT_FACTOR
594
! i=0-3 -> number of lorentz indices =i
595
! i=4 -> the position of TICOEFS that should be multiplied
596
! e.g. (q+MOM)^mu1(q+MOM)^mu2...(q+MOM)^muk
597
! it can be splitted into q^mu1...q^muk+q^mu1...q^mui Mom^mui+1 ...q^muk ...
598
! for some specific term configurateion mu1=0,mu2=0,...muk=3
599
! NTERM stores the total number of terms
600
! SPLIT_FACTOR is the factor for each term
601
! SPLIT_INFO(J,K,0-3) is the number of 0,1,2,3 with MOM^mu
602
! SPLIT_INFO(J,K,4) is the corresponding q^mu (remaining lorentz indices)
603
INTEGER,DIMENSION(0:LOOPMAXCOEFS_IREGI-1,MAXSPLIT,0:4)::SPLIT_INFO
604
SAVE INIT,NTERM,SPLIT_FACTOR,SPLIT_INFO
605
INTEGER::I,J,K,L,NINDEX,r,incr
606
INTEGER::i1,i2,i3,i4,nsplit,itit,rte,ND
607
REAL(KIND(1d0))::temp
608
INTEGER,DIMENSION(MAXRANK)::POSINDEX
617
! exhaust all of the subsets
619
NTERM(incr)=(I+1)*(J+1)*(K+1)*(L+1)
629
!DO itit=i1+i2+1,i1+i2+i3
633
!DO itit=i1+i2+i3+1,i1+i2+i3+i4
639
POSINDEX(rte-itit+1)=0
642
POSINDEX(rte-itit+1)=1
644
DO itit=i1+i2+1,i1+i2+i3
645
POSINDEX(rte-itit+1)=2
647
DO itit=i1+i2+i3+1,i1+i2+i3+i4
648
POSINDEX(rte-itit+1)=3
650
SPLIT_INFO(incr,nsplit,4)=QPOLYPOS(rte,POSINDEX)+RANK_NUM(rte-1)-1
651
SPLIT_INFO(incr,nsplit,0)=I-i1
652
SPLIT_INFO(incr,nsplit,1)=J-i2
653
SPLIT_INFO(incr,nsplit,2)=K-i3
654
SPLIT_INFO(incr,nsplit,3)=L-i4
655
SPLIT_FACTOR(incr,nsplit)=DBLE(factorial(I))&
656
/DBLE(factorial(i1)*factorial(I-i1))
657
SPLIT_FACTOR(incr,nsplit)=SPLIT_FACTOR(incr,nsplit)*&
658
DBLE(factorial(J))/DBLE(factorial(i2)*factorial(J-i2))
659
SPLIT_FACTOR(incr,nsplit)=SPLIT_FACTOR(incr,nsplit)*&
660
DBLE(factorial(K))/DBLE(factorial(i3)*factorial(K-i3))
661
SPLIT_FACTOR(incr,nsplit)=SPLIT_FACTOR(incr,nsplit)*&
662
DBLE(factorial(L))/DBLE(factorial(i4)*factorial(L-i4))
663
IF(.NOT.ML5_CONVENTION)THEN
664
SPLIT_FACTOR(incr,nsplit)=SPLIT_FACTOR(incr,nsplit)*&
665
DBLE(factorial(r))/DBLE(factorial(I)*factorial(J))&
666
/DBLE(factorial(K)*factorial(L))
667
SPLIT_FACTOR(incr,nsplit)=SPLIT_FACTOR(incr,nsplit)/&
668
DBLE(factorial(rte))*DBLE(factorial(i1))*DBLE(factorial(i2))*&
669
DBLE(factorial(i3))*DBLE(factorial(i4))
679
ND=ND+(3+r)*(2+r)*(1+r)/6
684
TICOEFS(I,1:4)=DCMPLX(0d0)
686
temp=SPLIT_FACTOR(I,J)
688
NINDEX=SPLIT_INFO(I,J,K)
690
temp=temp*MOM(K)**NINDEX
693
TICOEFS(I,1:4)=TICOEFS(I,1:4)&
694
+TICOEFS_SAVE(SPLIT_INFO(I,J,4),1:4)*temp
698
END SUBROUTINE SHIFT_MOM
700
FUNCTION xiarray_arg1(i,n)
702
INTEGER,INTENT(IN)::i,n
703
INTEGER::xiarray_arg1
705
!INTEGER(KIND=LINT)::itemp
711
xiarray_arg1=xiarray_arg1*j
714
xiarray_arg1=xiarray_arg1/factorial(imin)
717
xiarray_arg1=xiarray_arg1/j
721
xiarray_arg1=factorial(i+n-1)/factorial(n-1)/factorial(i)
724
END FUNCTION xiarray_arg1