2
!! Copyright (C) 2014 Andreas van Hameren.
4
!! This file is part of OneLOop-3.4.
6
!! OneLOop-3.4 is free software: you can redistribute it and/or modify
7
!! it under the terms of the GNU General Public License as published by
8
!! the Free Software Foundation, either version 3 of the License, or
9
!! (at your option) any later version.
11
!! OneLOop-3.4 is distributed in the hope that it will be useful,
12
!! but WITHOUT ANY WARRANTY; without even the implied warranty of
13
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
!! GNU General Public License for more details.
16
!! You should have received a copy of the GNU General Public License
17
!! along with OneLOop-3.4. If not, see <http://www.gnu.org/licenses/>.
21
module avh_olo_forIREGI_dilog
22
!***********************************************************************
24
! dilog(xx,iph) = - | dt ----------
26
! with zz = 1 - xx*exp(imag*pi*iph) [pi, NOT 2*pi]
28
! dilog(x1,i1,x2,i2) = ( dilog(x1,i1)-dilog(x2,i2) )/( x1-x2 )
30
! Arguments xx,x1,x2, may be all real or all complex,
31
! arguments iph,i1,i2 must be all integer.
32
!***********************************************************************
33
use avh_olo_forIREGI_units
34
use avh_olo_forIREGI_prec
35
use avh_olo_forIREGI_print
36
use avh_olo_forIREGI_auxfun
37
use avh_olo_forIREGI_arrays
40
public :: update_dilog,dilog
42
include 'avh_olo_real.h90'
43
,allocatable,save :: coeff(:)
44
include 'avh_olo_real.h90'
45
,allocatable,save :: thrs(:,:)
46
integer,allocatable,save :: ntrm(:,:)
47
integer,parameter :: nStp=6
49
include 'avh_olo_real.h90'
50
,allocatable :: bern(:),fact(:)
53
module procedure dilog_c,dilog_r,dilog2_c,dilog2_r
58
subroutine update_dilog
59
!***********************************************************************
60
!***********************************************************************
61
include 'avh_olo_real.h90'
64
logical :: highestSoFar
65
! real(kind(1d0)) :: xx(6) !DEBUG
67
if (allocated(thrs)) then
68
call shift2( thrs ,prcpar )
69
call shift2( ntrm ,prcpar )
71
allocate(thrs(1:nStp,1:1))
72
allocate(ntrm(1:nStp,1:1))
74
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop update_dilog'
79
highestSoFar = prcpar.eq.ubound(ntrm,2)
80
if (highestSoFar) then
81
if (allocated(coeff)) deallocate(coeff)
82
allocate(coeff(0:-1)) ! allocate at size=0
85
if (prcpar.gt.1) then ;nn=ntrm(nStp,prcpar-1)-1
91
if (nn.gt.ubound(coeff,1)) call update_coeff( 2*nn )
93
tt = (EPSN/abs(coeff(nn)))**(tt/(2*nn))
94
! expansion parameter is smaller than 1.05
95
if (100*tt.gt.105*RONE) exit
98
if (highestSoFar) call resize( coeff ,0,nn )
100
ntrm(nStp,prcpar) = nn
101
thrs(nStp,prcpar) = tt
102
nn = max(1,nint(nn*1d0/nStp))
104
ntrm(ii,prcpar) = ntrm(ii+1,prcpar)-nn
105
if (ntrm(ii,prcpar).le.2) then
107
ntrm(jj,prcpar) = max(2,ntrm(ii,prcpar))
114
tt = (EPSN/abs(coeff(jj)))**(tt/(2*jj))
118
if (allocated(bern)) deallocate(bern)
119
if (allocated(fact)) deallocate(fact)
121
! do ii=lbound(thrs,2),ubound(thrs,2) !DEBUG
122
! do jj=1,nStp !DEBUG
123
! xx(jj) = thrs(jj,ii) !DEBUG
125
! write(*,'(99e10.3)') xx(:) !DEBUG
126
! write(*,'(99i10)' ) ntrm(:,ii) !DEBUG
131
subroutine update_coeff( ncf )
132
!*******************************************************************
134
! coeff(n)=bern(2*n)/(2*n+1)
135
! bern(n)=bernoulli(n)/n!
137
! DO NOT SKIP THE ODD bern IN THE RECURSIVE LOOP
138
! DO NOT PUT THE ODD bern TO ZERO
139
!*******************************************************************
140
integer ,intent(in) :: ncf
141
integer :: ii,jj,nbern,nold
143
if (allocated(bern)) then ;nold=ubound(bern,1)
149
call enlarge( bern ,1,nbern )
150
call enlarge( fact ,0,nbern+1 )
151
call enlarge( coeff ,0,ncf )
155
fact(ii) = fact(ii-1)*ii
159
bern(ii) = -1/fact(ii+1)
161
bern(ii) = bern(ii) - bern(jj)/fact(ii+1-jj)
166
coeff(0) =-coeff(0)/4
168
coeff(ii/2) = bern(ii)/(ii+1)
174
function dilog_c(xx,iph) result(rslt)
175
!*******************************************************************
176
!*******************************************************************
177
include 'avh_olo_complex.h90'
179
integer ,intent(in) :: iph
180
include 'avh_olo_complex.h90'
181
:: rslt ,yy,lyy,loy,zz,z2
182
include 'avh_olo_real.h90'
184
integer :: ii,jj,ntwo,odd,nn
185
logical :: r_gt_1 , y_lt_h
190
if (abs(imx).le.EPSN*abs(rex)) then
191
if (rex.ge.RZRO) then
192
rslt = dilog_r( rex, iph )
194
rslt = dilog_r(-rex, iph+sgnRe(imx) )
199
if (rex.gt.RZRO) then ;yy= xx ;jj=iph
200
else ;yy=-xx ;jj=iph+sgnRe(imx)
206
r_gt_1 = (rex*rex+imx*imx.gt.RONE)
208
if (odd.ne.0) yy = -yy
218
y_lt_h = (2*areal(yy).lt.RONE)
219
if (y_lt_h) then ;zz=-loy
224
! if (az.gt.thrs(6,prcpar)) ERROR az to big
225
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
226
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
227
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
228
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
229
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
230
else ;nn=ntrm(1,prcpar)
235
rslt = coeff(ii-1) + z2*rslt
237
rslt = zz*( 1 + zz*( coeff(0) + zz*rslt ) )
240
rslt = 4*PISQo24 - rslt - loy*(lyy+IPI*(ntwo+odd))
242
rslt = rslt - loy*IPI*ntwo
245
if (r_gt_1) rslt = -rslt - (lyy+IPI*(ntwo+odd))**2/2
250
function dilog_r(xx,iph) result(rslt)
251
!*******************************************************************
252
!*******************************************************************
253
include 'avh_olo_real.h90'
255
integer ,intent(in) :: iph
256
include 'avh_olo_complex.h90'
258
include 'avh_olo_real.h90'
259
:: yy,lyy,loy,zz,z2,liox,az
260
integer :: jj,ii,ntwo,odd,nn
261
logical :: r_gt_1 , y_lt_h
266
elseif (xx.gt.RZRO) then ;yy= xx ;jj=iph
267
else ;yy=-xx ;jj=iph+1 ! log(-1)=i*pi
273
if (yy.eq.RONE.and.odd.eq.0) then
275
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog_r: ' &
276
,'|x|,iph = ',trim(myprint(yy)),',',jj,', returning 0'
282
r_gt_1 = (yy.gt.RONE)
284
if (odd.ne.0) yy = -yy
292
loy = log(1-yy) ! log(1-yy) is always real
294
y_lt_h = (2*yy.lt.RONE)
296
zz = -loy ! log(1-yy) is real
298
zz = -lyy ! yy>0.5 => log(yy) is real
302
! if (az.gt.thrs(6,prcpar)) ERROR az to big
303
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
304
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
305
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
306
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
307
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
308
else ;nn=ntrm(1,prcpar)
313
liox = coeff(ii-1) + z2*liox
315
liox = zz*( 1 + zz*( coeff(0) + zz*liox ) )
320
rslt = 4*PISQo24 - rslt - acmplx(loy*lyy,loy*ONEPI*(ntwo+odd))
322
rslt = rslt + acmplx( 0 ,-loy*ONEPI*ntwo )
325
if (r_gt_1) rslt = -rslt - acmplx(lyy,ONEPI*(ntwo+odd))**2/2
329
function dilog2_c( x1,i1 ,x2,i2 ) result(rslt)
330
!*******************************************************************
331
!*******************************************************************
332
use avh_olo_forIREGI_olog
333
include 'avh_olo_complex.h90'
335
integer ,intent(in) :: i1,i2
336
include 'avh_olo_complex.h90'
337
:: rslt ,y1,y2 ,ff,gg,logr1,logr2,logo1,logo2,r1,r2,rr
338
include 'avh_olo_real.h90'
339
:: eps ,re1,im1,re2,im2,a1,a2,aa,ao1,ao2
340
integer :: j1,j2,ii,nn,oo
341
integer,parameter :: pp(-1:1,-1:1)=&
342
reshape((/-2,-2,2 ,-2,0,2 ,-2,2,2/),(/3,3/))
344
re1=areal(x1) ;re2=areal(x2)
345
im1=aimag(x1) ;im2=aimag(x2)
347
if (abs(im1).le.EPSN*abs(re1).and.abs(im2).le.EPSN*abs(re2)) then
348
if (re1.ge.RZRO) then
349
if (re2.ge.RZRO) then
350
rslt = dilog2_r( re1,i1 , re2,i2 )
352
rslt = dilog2_r( re1,i1 ,-re2,i2+sgnRe(im2) )
354
elseif (re2.ge.RZRO) then
355
rslt = dilog2_r(-re1,i1+sgnRe(im1) , re2,i2 )
357
rslt = dilog2_r(-re1,i1+sgnRe(im1) ,-re2,i2+sgnRe(im2) )
362
if (re1.ge.RZRO) then ;r1= x1 ;j1=i1
363
else ;r1=-x1 ;j1=i1+sgnRe(im1,1)
365
if (re2.ge.RZRO) then ;r2= x2 ;j2=i2
366
else ;r2=-x2 ;j2=i2+sgnRe(im2,1)
369
a1=abs(r1) ;a2=abs(r2)
376
oo=mod(j1,2) ;nn=j1-oo ;y1=r1 ;if (oo.ne.0) y1=-y1
377
oo=mod(j2,2) ;nn=j2-oo ;y2=r2 ;if (oo.ne.0) y2=-y2
383
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
384
,'j1,j2,r1-r2',j1,j2,',',trim(myprint(r1-r2)),', returning 0'
386
! write(*,*) 'dilog2_c j1=/=j2,r1=r2' !DEBUG
389
rslt = ( dilog_c(r1,j1)-dilog_c(r2,j2) )/(y1-y2)
390
! write(*,*) 'dilog2_c j1=/=j2' !DEBUG
397
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
398
,'r1,r2 =',trim(myprint(r1)),',',trim(myprint(r2)),', returning 0'
400
! write(*,*) 'dilog2_c r1<eps,r2<eps' !DEBUG
403
rslt = (dilog_c(r2,j2)-4*PISQo24)/y2
404
! write(*,*) 'dilog2_c r1<eps' !DEBUG
409
logr1=log(r1) ;logr2=log(r2)
411
ao1=abs(1-y1) ;ao2=abs(1-y2)
412
if (10*ao1.lt.RONE.or.10*ao2.lt.RONE) then
414
if (10*aa.gt.RONE) then
415
rslt = (dilog_c(r1,j1)-dilog_c(r2,j2))/(y1-y2)
416
! write(*,*) 'dilog2_c ||1-y1|/|1-y2|-1|>0.1' !DEBUG
418
elseif (oo.eq.0.and.ao1.lt.eps) then
419
if (nn.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
420
,'r1,oo,nn =',trim(myprint(r1)),',',oo,nn,', putting nn=0'
423
! write(*,*) 'dilog2_c |1-y1|' !DEBUG
426
y1=1-eps ;nn=0 ;logr1=0 ;r1=1-eps
428
elseif (oo.eq.0.and.ao2.lt.eps) then
429
if (nn.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
430
,'r2,oo,nn =',trim(myprint(r2)),',',oo,nn,', putting nn=0'
431
y2=1-eps ;nn=0 ;logr2=0 ;r2=1-eps
434
aa = abs((logr1+oo*IPI)/(logr2+oo*IPI)-1)
435
if (10*aa.gt.RONE) then
436
rslt = (dilog_c(r1,j1)-dilog_c(r2,j2))/(y1-y2)
437
! write(*,*) 'dilog2_c |logr1/logr2-1|>0.1',logr1,logr2 !DEBUG
439
elseif (aa.lt.eps) then
441
if (a1.gt.RONE) ii = ii + (nn+pp(oo,sgnIm(y2)))
442
if (a2.gt.RONE) ii = ii - (nn+pp(oo,sgnIm(y2)))
444
if (ii.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
445
,'r1,r2,nn =',trim(myprint(r1)),',',trim(myprint(r2)),',',nn &
448
! write(*,*) 'dilog2_c |logr1/lorg2|<eps' !DEBUG
454
y1=1/y1 ;logr1=-logr1
455
y2=1/y2 ;logr2=-logr2
459
ff=y1/y2 ;ff=-olog2(ff,0)/y2
460
gg=(1-y1)/(1-y2) ;gg=-olog2(gg,0)/(1-y2)
462
if (2*areal(y1).ge.RONE) then
463
! write(*,*) 'dilog2_c re>1/2' !DEBUG
464
rslt = ff*sumterms_c(-logr1,-logr2) - nn*IPI*gg
466
! write(*,*) 'dilog2_c re<1/2' !DEBUG
469
rslt = gg*( sumterms_c(-logo1,-logo2) - (nn+oo)*IPI - logr2 ) + ff*logo1
472
if (a1.gt.RONE) then !implies also r2>1
473
! write(*,*) 'dilog2_c r1>1,r2>1' !DEBUG
474
rslt = y1*y2*( rslt - ff*((logr1+logr2)/2 + (nn+oo)*IPI) )
475
elseif (a2.gt.RONE.and.nn.ne.0) then
476
! write(*,*) 'dilog2_c r1<1,r2>1',oo,sgnIm(y2)!DEBUG
477
rslt = rslt - 12*nn*( nn + pp(oo,sgnIm(y2)) )*PISQo24/(y1-y2)
483
function dilog2_r( x1,i1 ,x2,i2 ) result(rslt)
484
!*******************************************************************
485
!*******************************************************************
486
use avh_olo_forIREGI_olog
487
include 'avh_olo_real.h90'
489
integer ,intent(in) :: i1,i2
490
include 'avh_olo_complex.h90'
492
include 'avh_olo_real.h90'
493
:: y1,y2 ,ff,gg,logr1,logr2,logo1,logo2
494
include 'avh_olo_real.h90'
495
:: eps,r1,r2,rr,ro1,ro2
496
integer :: j1,j2,ii,nn,oo
498
if (x1.ge.RZRO) then ;r1= x1 ;j1=i1
499
else ;r1=-x1 ;j1=i1+1 ! log(-1)=i*pi
501
if (x2.ge.RZRO) then ;r2= x2 ;j2=i2
502
else ;r2=-x2 ;j2=i2+1 ! log(-1)=i*pi
510
oo=mod(j1,2) ;nn=j1-oo ;y1=r1 ;if (oo.ne.0) y1=-y1
511
oo=mod(j2,2) ;nn=j2-oo ;y2=r2 ;if (oo.ne.0) y2=-y2
517
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
518
,'j1,j2,r1-r2',j1,j2,',',trim(myprint(r1-r2)),', returning 0'
520
! write(*,*) 'dilog2_r j1=/=j2,r1=r2' !DEBUG
523
rslt = ( dilog_r(r1,j1)-dilog_r(r2,j2) )/(y1-y2)
524
! write(*,*) 'dilog2_r j1=/=j2' !DEBUG
531
if (eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
532
,'r1,r2 =',trim(myprint(r1)),',',trim(myprint(r2)),', returning 0'
534
! write(*,*) 'dilog2_r r1<eps,r2<eps' !DEBUG
537
rslt = (dilog_r(r2,j2)-4*PISQo24)/y2
538
! write(*,*) 'dilog2_r r1<eps' !DEBUG
543
logr1=log(r1) ;logr2=log(r2)
545
ro1=abs(1-y1) ;ro2=abs(1-y2)
546
if (10*ro1.lt.RONE.or.10*ro2.lt.RONE) then
548
if (10*rr.gt.RONE) then
549
rslt = (dilog_r(r1,j1)-dilog_r(r2,j2))/(y1-y2)
550
! write(*,*) 'dilog2_r ||1-y1|/|1-y2|-1|>0.1' !DEBUG
552
elseif (oo.eq.0.and.ro1.lt.eps) then
553
if (nn.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
554
,'r1,oo,nn =',trim(myprint(r1)),',',oo,nn,', putting nn=0'
557
! write(*,*) 'dilog2_r |1-y1|' !DEBUG
560
y1=1-eps ;nn=0 ;logr1=0 ;r1=1-eps
562
elseif (oo.eq.0.and.ro2.lt.eps) then
563
if (nn.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
564
,'r2,oo,nn =',trim(myprint(r2)),',',oo,nn,', putting nn=0'
565
y2=1-eps ;nn=0 ;logr2=0 ;r2=1-eps
568
rr = abs((logr1+oo*IPI)/(logr2+oo*IPI)-1)
569
if (10*rr.gt.RONE) then
570
rslt = (dilog_r(r1,j1)-dilog_r(r2,j2))/(y1-y2)
571
! write(*,*) 'dilog2_r |logr1/logr2-1|>0.1',logr1,logr2 !DEBUG
573
elseif (rr.lt.eps) then
575
if (r1.gt.RONE) ii = ii + (nn+2*oo)
576
if (r2.gt.RONE) ii = ii - (nn+2*oo)
578
if (ii.ne.0.and.eunit.gt.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
579
,'r1,r2,nn =',trim(myprint(r1)),',',trim(myprint(r2)),',',nn &
582
! write(*,*) 'dilog2_r |logr1/lorg2|<eps' !DEBUG
588
y1=1/y1 ;logr1=-logr1
589
y2=1/y2 ;logr2=-logr2
593
ff=y1/y2 ;ff=-olog2(ff,0)/y2
594
gg=(1-y1)/(1-y2) ;gg=-olog2(gg,0)/(1-y2)
596
if (2*y1.ge.RONE) then
597
! write(*,*) 'dilog2_r re>1/2' !DEBUG
598
rslt = ff*sumterms_r(-logr1,-logr2) - nn*IPI*gg
600
! write(*,*) 'dilog2_r re<1/2' !DEBUG
603
rslt = gg*( sumterms_r(-logo1,-logo2) - (nn+oo)*IPI - logr2 ) + ff*logo1
606
if (r1.gt.RONE) then !implies also r2>1
607
! write(*,*) 'dilog2_r r1>1,r2>1' !DEBUG
608
rslt = y1*y2*( rslt - ff*((logr1+logr2)/2 + (nn+oo)*IPI) )
609
elseif (r2.gt.RONE.and.nn.ne.0) then
610
! write(*,*) 'dilog2_r r1<1,r2>1' !DEBUG
611
rslt = rslt - 12*nn*PISQo24*(nn+2*oo)/(y1-y2)
617
function sumterms_c( z1,z2 ) result(rslt)
618
!***********************************************************************
619
! ( f(z1)-f(z2) )/( z1-z2 ), where
620
! f(z)= z + c0*z^2 + c1*z^3 + c2*z^5 + c3*z^7 + ...
621
!***********************************************************************
622
include 'avh_olo_complex.h90'
624
include 'avh_olo_complex.h90'
626
include 'avh_olo_real.h90'
629
az = max(abs(z1),abs(z2))
630
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
631
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
632
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
633
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
634
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
635
else ;nn=ntrm(1,prcpar)
637
! calculates all z(i)=(z1^i-z2^i)/(z1-z2) numerically stable
642
! zz(ii) = z1*zz(ii-1) + yy
649
rslt = rslt + coeff(0)*zz
653
rslt = rslt + coeff(ii)*zz
660
function sumterms_r( z1,z2 ) result(rslt)
661
!***********************************************************************
662
! ( f(z1)-f(z2) )/( z1-z2 ), where
663
! f(z)= z + c0*z^2 + c1*z^3 + c2*z^5 + c3*z^7 + ...
664
!***********************************************************************
665
include 'avh_olo_real.h90'
667
include 'avh_olo_real.h90'
669
include 'avh_olo_real.h90'
672
az = max(abs(z1),abs(z2))
673
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
674
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
675
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
676
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
677
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
678
else ;nn=ntrm(1,prcpar)
685
rslt = rslt + coeff(0)*zz
689
rslt = rslt + coeff(ii)*zz