!!
!! Copyright (C) 2018 Andreas van Hameren.
!!
!! This file is part of OneLOop-rolln.
!!
!! OneLOop-rolln is free software: you can redistribute it and/or modify
!! it under the terms of the GNU General Public License as published by
!! the Free Software Foundation, either version 3 of the License, or
!! (at your option) any later version.
!!
!! OneLOop-rolln is distributed in the hope that it will be useful,
!! but WITHOUT ANY WARRANTY; without even the implied warranty of
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
!! GNU General Public License for more details.
!!
!! You should have received a copy of the GNU General Public License
!! along with OneLOop-rolln. If not, see .
!!
module avh_olo_dilog
!***********************************************************************
! /1 ln(1-zz*t)
! dilog(xx,iph) = - | dt ----------
! /0 t
! with zz = 1 - xx*exp(imag*pi*iph) [pi, NOT 2*pi]
!
! dilog(x1,i1,x2,i2) = ( dilog(x1,i1)-dilog(x2,i2) )/( x1-x2 )
!
! Arguments xx,x1,x2, may be all real or all complex,
! arguments iph,i1,i2 must be all integer.
!***********************************************************************
use avh_olo_units
use avh_olo_prec
use avh_olo_print
use avh_olo_auxfun
use avh_olo_arrays
implicit none
private
public :: update_dilog,dilog
include 'avh_olo_real.h90'
,allocatable,save :: coeff(:)
include 'avh_olo_real.h90'
,allocatable,save :: thrs(:,:)
integer,allocatable,save :: ntrm(:,:)
integer,parameter :: nStp=6
include 'avh_olo_real.h90'
,allocatable :: bern(:),fact(:)
interface dilog
module procedure dilog_c,dilog_r,dilog2_c,dilog2_r
end interface
contains
subroutine update_dilog
!***********************************************************************
!***********************************************************************
include 'avh_olo_real.h90'
:: tt
integer :: nn,ii,jj
logical :: highestSoFar
! real(kind(1d0)) :: xx(6) !DEBUG
!
if (allocated(thrs)) then
call shift2( thrs ,prcpar )
call shift2( ntrm ,prcpar )
else
allocate(thrs(1:nStp,1:1))
allocate(ntrm(1:nStp,1:1))
if (prcpar.ne.1) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop update_dilog'
stop
endif
endif
!
highestSoFar = prcpar.eq.ubound(ntrm,2)
if (highestSoFar) then
if (allocated(coeff)) deallocate(coeff)
allocate(coeff(0:-1)) ! allocate at size=0
endif
!
if (prcpar.gt.1) then ;nn=ntrm(nStp,prcpar-1)-1
else ;nn=2
endif
!
do
nn = nn+1
if (nn.gt.ubound(coeff,1)) call update_coeff( 2*nn )
tt = 1
tt = (EPSN/abs(coeff(nn)))**(tt/(2*nn))
! expansion parameter is smaller than 1.05
if (100*tt.gt.105*RONE) exit
enddo
!
if (highestSoFar) call resize( coeff ,0,nn )
!
ntrm(nStp,prcpar) = nn
thrs(nStp,prcpar) = tt
nn = max(1,nint(nn*1d0/nStp))
do ii=nStp-1,1,-1
ntrm(ii,prcpar) = ntrm(ii+1,prcpar)-nn
if (ntrm(ii,prcpar).le.2) then
do jj=1,ii
ntrm(jj,prcpar) = max(2,ntrm(ii,prcpar))
thrs(jj,prcpar) = 0
enddo
exit
endif
jj = ntrm(ii,prcpar)
tt = 1
tt = (EPSN/abs(coeff(jj)))**(tt/(2*jj))
thrs(ii,prcpar) = tt
enddo
!
if (allocated(bern)) deallocate(bern)
if (allocated(fact)) deallocate(fact)
!
! do ii=lbound(thrs,2),ubound(thrs,2) !DEBUG
! do jj=1,nStp !DEBUG
! xx(jj) = thrs(jj,ii) !DEBUG
! enddo !DEBUG
! write(*,'(99e10.3)') xx(:) !DEBUG
! write(*,'(99i10)' ) ntrm(:,ii) !DEBUG
! enddo !DEBUG
end subroutine
subroutine update_coeff( ncf )
!*******************************************************************
! coeff(0)=-1/4
! coeff(n)=bern(2*n)/(2*n+1)
! bern(n)=bernoulli(n)/n!
! fact(n)=n!
! DO NOT SKIP THE ODD bern IN THE RECURSIVE LOOP
! DO NOT PUT THE ODD bern TO ZERO
!*******************************************************************
integer ,intent(in) :: ncf
integer :: ii,jj,nbern,nold
!
if (allocated(bern)) then ;nold=ubound(bern,1)
else ;nold=0
endif
!
nbern = 2*ncf
!
call enlarge( bern ,1,nbern )
call enlarge( fact ,0,nbern+1 )
call enlarge( coeff ,0,ncf )
!
fact(0) = 1
do ii=nold+1,nbern+1
fact(ii) = fact(ii-1)*ii
enddo
!
do ii=nold+1,nbern
bern(ii) = -1/fact(ii+1)
do jj=1,ii-1
bern(ii) = bern(ii) - bern(jj)/fact(ii+1-jj)
enddo
enddo
!
coeff(0) = 1
coeff(0) =-coeff(0)/4
do ii=nold+2,nbern,2
coeff(ii/2) = bern(ii)/(ii+1)
enddo
!
end subroutine
function dilog_c(xx,iph) result(rslt)
!*******************************************************************
!*******************************************************************
include 'avh_olo_complex.h90'
,intent(in) :: xx
integer ,intent(in) :: iph
include 'avh_olo_complex.h90'
:: rslt ,yy,lyy,loy,zz,z2
include 'avh_olo_real.h90'
:: rex,imx,az
integer :: ii,jj,ntwo,odd,nn
logical :: r_gt_1 , y_lt_h
!
rex = areal(xx)
imx = aimag(xx)
!
if (abs(imx).le.EPSN*abs(rex)) then
if (rex.ge.RZRO) then
rslt = dilog_r( rex, iph )
else
rslt = dilog_r(-rex, iph+sgnRe(imx) )
endif
return
endif
!
if (rex.gt.RZRO) then ;yy= xx ;jj=iph
else ;yy=-xx ;jj=iph+sgnRe(imx)
endif
!
odd = mod(jj,2)
ntwo = jj-odd
!
r_gt_1 = (rex*rex+imx*imx.gt.RONE)
lyy = log(yy)
if (odd.ne.0) yy = -yy
!
if (r_gt_1) then
yy = 1/yy
lyy =-lyy
ntwo =-ntwo
odd =-odd
endif
loy = log(1-yy)
!
y_lt_h = (2*areal(yy).lt.RONE)
if (y_lt_h) then ;zz=-loy
else ;zz=-lyy
endif
!
az = abs(zz)
! if (az.gt.thrs(6,prcpar)) ERROR az to big
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
else ;nn=ntrm(1,prcpar)
endif
z2 = zz*zz
rslt = coeff(nn)
do ii=nn,2,-1
rslt = coeff(ii-1) + z2*rslt
enddo
rslt = zz*( 1 + zz*( coeff(0) + zz*rslt ) )
!
if (y_lt_h) then
rslt = 4*PISQo24 - rslt - loy*(lyy+IPI*(ntwo+odd))
else
rslt = rslt - loy*IPI*ntwo
endif
!
if (r_gt_1) rslt = -rslt - (lyy+IPI*(ntwo+odd))**2/2
end function
function dilog_r(xx,iph) result(rslt)
!*******************************************************************
!*******************************************************************
include 'avh_olo_real.h90'
,intent(in) :: xx
integer ,intent(in) :: iph
include 'avh_olo_complex.h90'
:: rslt
include 'avh_olo_real.h90'
:: yy,lyy,loy,zz,z2,liox,az
integer :: jj,ii,ntwo,odd,nn
logical :: r_gt_1 , y_lt_h
!
if (xx.eq.RZRO) then
rslt = 4*PISQo24
return
elseif (xx.gt.RZRO) then ;yy= xx ;jj=iph
else ;yy=-xx ;jj=iph+1 ! log(-1)=i*pi
endif
!
odd = mod(jj,2)
ntwo = jj-odd
!
if (yy.eq.RONE.and.odd.eq.0) then
if (ntwo.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog_r: ' &
,'|x|,iph = ',trim(myprint(yy)),',',jj,', returning 0'
endif
rslt = 0
return
endif
!
r_gt_1 = (yy.gt.RONE)
lyy = log(yy)
if (odd.ne.0) yy = -yy
!
if (r_gt_1) then
yy = 1/yy
lyy =-lyy
ntwo =-ntwo
odd =-odd
endif
loy = log(1-yy) ! log(1-yy) is always real
!
y_lt_h = (2*yy.lt.RONE)
if (y_lt_h) then
zz = -loy ! log(1-yy) is real
else
zz = -lyy ! yy>0.5 => log(yy) is real
endif
!
az = abs(zz)
! if (az.gt.thrs(6,prcpar)) ERROR az to big
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
else ;nn=ntrm(1,prcpar)
endif
z2 = zz*zz
liox = coeff(nn)
do ii=nn,2,-1
liox = coeff(ii-1) + z2*liox
enddo
liox = zz*( 1 + zz*( coeff(0) + zz*liox ) )
!
rslt = acmplx(liox)
!
if (y_lt_h) then
rslt = 4*PISQo24 - rslt - acmplx(loy*lyy,loy*ONEPI*(ntwo+odd))
else
rslt = rslt + acmplx( 0 ,-loy*ONEPI*ntwo )
endif
!
if (r_gt_1) rslt = -rslt - acmplx(lyy,ONEPI*(ntwo+odd))**2/2
end function
function dilog2_c( x1,i1 ,x2,i2 ) result(rslt)
!*******************************************************************
!*******************************************************************
use avh_olo_olog
include 'avh_olo_complex.h90'
,intent(in) :: x1,x2
integer ,intent(in) :: i1,i2
include 'avh_olo_complex.h90'
:: rslt ,y1,y2 ,ff,gg,logr1,logr2,logo1,logo2,r1,r2,rr
include 'avh_olo_real.h90'
:: eps ,re1,im1,re2,im2,a1,a2,aa,ao1,ao2
integer :: j1,j2,ii,nn,oo
integer,parameter :: pp(-1:1,-1:1)=&
reshape((/-2,-2,2 ,-2,0,2 ,-2,2,2/),(/3,3/))
!
re1=areal(x1) ;re2=areal(x2)
im1=aimag(x1) ;im2=aimag(x2)
!
if (abs(im1).le.EPSN*abs(re1).and.abs(im2).le.EPSN*abs(re2)) then
if (re1.ge.RZRO) then
if (re2.ge.RZRO) then
rslt = dilog2_r( re1,i1 , re2,i2 )
else
rslt = dilog2_r( re1,i1 ,-re2,i2+sgnRe(im2) )
endif
elseif (re2.ge.RZRO) then
rslt = dilog2_r(-re1,i1+sgnRe(im1) , re2,i2 )
else
rslt = dilog2_r(-re1,i1+sgnRe(im1) ,-re2,i2+sgnRe(im2) )
endif
return
endif
!
if (re1.ge.RZRO) then ;r1= x1 ;j1=i1
else ;r1=-x1 ;j1=i1+sgnRe(im1,1)
endif
if (re2.ge.RZRO) then ;r2= x2 ;j2=i2
else ;r2=-x2 ;j2=i2+sgnRe(im2,1)
endif
!
a1=abs(r1) ;a2=abs(r2)
if (a1.gt.a2) then
aa=a1;a1=a2;a2=aa
rr=r1;r1=r2;r2=rr
ii=j1;j1=j2;j2=ii
endif
!
oo=mod(j1,2) ;nn=j1-oo ;y1=r1 ;if (oo.ne.0) y1=-y1
oo=mod(j2,2) ;nn=j2-oo ;y2=r2 ;if (oo.ne.0) y2=-y2
!
eps = 8*EPSN
!
if (j1.ne.j2) then
if (r1.eq.r2) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
,'j1,j2,r1-r2',j1,j2,',',trim(myprint(r1-r2)),', returning 0'
rslt = 0
! write(*,*) 'dilog2_c j1=/=j2,r1=r2' !DEBUG
return
else
rslt = ( dilog_c(r1,j1)-dilog_c(r2,j2) )/(y1-y2)
! write(*,*) 'dilog2_c j1=/=j2' !DEBUG
return
endif
endif
!
if (a1.lt.eps) then
if (a2.lt.eps) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
,'r1,r2 =',trim(myprint(r1)),',',trim(myprint(r2)),', returning 0'
rslt = 0
! write(*,*) 'dilog2_c r10.1' !DEBUG
return
elseif (oo.eq.0.and.ao1.lt.eps) then
if (nn.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
,'r1,oo,nn =',trim(myprint(r1)),',',oo,nn,', putting nn=0'
endif
if (ao2.lt.eps) then
rslt = -1
! write(*,*) 'dilog2_c |1-y1|' !DEBUG
return
else
y1=1-eps ;nn=0 ;logr1=0 ;r1=1-eps
endif
elseif (oo.eq.0.and.ao2.lt.eps) then
if (nn.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
,'r2,oo,nn =',trim(myprint(r2)),',',oo,nn,', putting nn=0'
endif
y2=1-eps ;nn=0 ;logr2=0 ;r2=1-eps
endif
else
aa = abs((logr1+oo*IPI)/(logr2+oo*IPI)-1)
if (10*aa.gt.RONE) then
rslt = (dilog_c(r1,j1)-dilog_c(r2,j2))/(y1-y2)
! write(*,*) 'dilog2_c |logr1/logr2-1|>0.1',logr1,logr2 !DEBUG
return
elseif (aa.lt.eps) then
ii = 0
if (a1.gt.RONE) ii = ii + (nn+pp(oo,sgnIm(y2)))
if (a2.gt.RONE) ii = ii - (nn+pp(oo,sgnIm(y2)))
ii = nn*ii
if (ii.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_c: ' &
,'r1,r2,nn =',trim(myprint(r1)),',',trim(myprint(r2)),',',nn &
,', putting nn=0'
endif
rslt = -olog1(y2,0)
! write(*,*) 'dilog2_c |logr1/lorg2|1/2' !DEBUG
rslt = ff*sumterms_c(-logr1,-logr2) - nn*IPI*gg
else
! write(*,*) 'dilog2_c re<1/2' !DEBUG
logo1 = log(1-y1)
logo2 = log(1-y2)
rslt = gg*( sumterms_c(-logo1,-logo2) - (nn+oo)*IPI - logr2 ) + ff*logo1
endif
!
if (a1.gt.RONE) then !implies also r2>1
! write(*,*) 'dilog2_c r1>1,r2>1' !DEBUG
rslt = y1*y2*( rslt - ff*((logr1+logr2)/2 + (nn+oo)*IPI) )
elseif (a2.gt.RONE.and.nn.ne.0) then
! write(*,*) 'dilog2_c r1<1,r2>1',oo,sgnIm(y2)!DEBUG
rslt = rslt - 12*nn*( nn + pp(oo,sgnIm(y2)) )*PISQo24/(y1-y2)
endif
!
end function
function dilog2_r( x1,i1 ,x2,i2 ) result(rslt)
!*******************************************************************
!*******************************************************************
use avh_olo_olog
include 'avh_olo_real.h90'
,intent(in) :: x1,x2
integer ,intent(in) :: i1,i2
include 'avh_olo_complex.h90'
:: rslt
include 'avh_olo_real.h90'
:: y1,y2 ,ff,gg,logr1,logr2,logo1,logo2
include 'avh_olo_real.h90'
:: eps,r1,r2,rr,ro1,ro2
integer :: j1,j2,ii,nn,oo
!
if (x1.ge.RZRO) then ;r1= x1 ;j1=i1
else ;r1=-x1 ;j1=i1+1 ! log(-1)=i*pi
endif
if (x2.ge.RZRO) then ;r2= x2 ;j2=i2
else ;r2=-x2 ;j2=i2+1 ! log(-1)=i*pi
endif
!
if (r1.gt.r2) then
rr=r1;r1=r2;r2=rr
ii=j1;j1=j2;j2=ii
endif
!
oo=mod(j1,2) ;nn=j1-oo ;y1=r1 ;if (oo.ne.0) y1=-y1
oo=mod(j2,2) ;nn=j2-oo ;y2=r2 ;if (oo.ne.0) y2=-y2
!
eps = 8*EPSN
!
if (j1.ne.j2) then
if (r1.eq.r2) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
,'j1,j2,r1-r2',j1,j2,',',trim(myprint(r1-r2)),', returning 0'
rslt = 0
! write(*,*) 'dilog2_r j1=/=j2,r1=r2' !DEBUG
return
else
rslt = ( dilog_r(r1,j1)-dilog_r(r2,j2) )/(y1-y2)
! write(*,*) 'dilog2_r j1=/=j2' !DEBUG
return
endif
endif
!
if (r1.lt.eps) then
if (r2.lt.eps) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
,'r1,r2 =',trim(myprint(r1)),',',trim(myprint(r2)),', returning 0'
rslt = 0
! write(*,*) 'dilog2_r r10.1' !DEBUG
return
elseif (oo.eq.0.and.ro1.lt.eps) then
if (nn.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
,'r1,oo,nn =',trim(myprint(r1)),',',oo,nn,', putting nn=0'
endif
if (ro2.lt.eps) then
rslt = -1
! write(*,*) 'dilog2_r |1-y1|' !DEBUG
return
else
y1=1-eps ;nn=0 ;logr1=0 ;r1=1-eps
endif
elseif (oo.eq.0.and.ro2.lt.eps) then
if (nn.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
,'r2,oo,nn =',trim(myprint(r2)),',',oo,nn,', putting nn=0'
endif
y2=1-eps ;nn=0 ;logr2=0 ;r2=1-eps
endif
else
rr = abs((logr1+oo*IPI)/(logr2+oo*IPI)-1)
if (10*rr.gt.RONE) then
rslt = (dilog_r(r1,j1)-dilog_r(r2,j2))/(y1-y2)
! write(*,*) 'dilog2_r |logr1/logr2-1|>0.1',logr1,logr2 !DEBUG
return
elseif (rr.lt.eps) then
ii = 0
if (r1.gt.RONE) ii = ii + (nn+2*oo)
if (r2.gt.RONE) ii = ii - (nn+2*oo)
ii = nn*ii
if (ii.ne.0) then
errorcode = errorcode+1
if (eunit.ge.0) write(eunit,*) 'ERROR in OneLOop dilog2_r: ' &
,'r1,r2,nn =',trim(myprint(r1)),',',trim(myprint(r2)),',',nn &
,', putting nn=0'
endif
rslt = -olog1(y2,2*oo)
! write(*,*) 'dilog2_r |logr1/lorg2|1/2' !DEBUG
rslt = ff*sumterms_r(-logr1,-logr2) - nn*IPI*gg
else
! write(*,*) 'dilog2_r re<1/2' !DEBUG
logo1 = log(1-y1)
logo2 = log(1-y2)
rslt = gg*( sumterms_r(-logo1,-logo2) - (nn+oo)*IPI - logr2 ) + ff*logo1
endif
!
if (r1.gt.RONE) then !implies also r2>1
! write(*,*) 'dilog2_r r1>1,r2>1' !DEBUG
rslt = y1*y2*( rslt - ff*((logr1+logr2)/2 + (nn+oo)*IPI) )
elseif (r2.gt.RONE.and.nn.ne.0) then
! write(*,*) 'dilog2_r r1<1,r2>1' !DEBUG
rslt = rslt - 12*nn*PISQo24*(nn+2*oo)/(y1-y2)
endif
!
end function
function sumterms_c( z1,z2 ) result(rslt)
!***********************************************************************
! ( f(z1)-f(z2) )/( z1-z2 ), where
! f(z)= z + c0*z^2 + c1*z^3 + c2*z^5 + c3*z^7 + ...
!***********************************************************************
include 'avh_olo_complex.h90'
,intent(in) :: z1,z2
include 'avh_olo_complex.h90'
:: rslt,yy,zz
include 'avh_olo_real.h90'
:: az
integer :: ii,nn
az = max(abs(z1),abs(z2))
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
else ;nn=ntrm(1,prcpar)
endif
! calculates all z(i)=(z1^i-z2^i)/(z1-z2) numerically stable
! zz(1) = 1
! yy = 1
! do ii=2,2*nn+1
! yy = z2*yy
! zz(ii) = z1*zz(ii-1) + yy
! enddo
zz = 1
yy = 1
rslt = zz
yy = z2*yy
zz = z1*zz+yy
rslt = rslt + coeff(0)*zz
do ii=1,nn
yy = z2*yy
zz = z1*zz+yy
rslt = rslt + coeff(ii)*zz
yy = z2*yy
zz = z1*zz+yy
enddo
end function
function sumterms_r( z1,z2 ) result(rslt)
!***********************************************************************
! ( f(z1)-f(z2) )/( z1-z2 ), where
! f(z)= z + c0*z^2 + c1*z^3 + c2*z^5 + c3*z^7 + ...
!***********************************************************************
include 'avh_olo_real.h90'
,intent(in) :: z1,z2
include 'avh_olo_real.h90'
:: rslt,yy,zz
include 'avh_olo_real.h90'
:: az
integer :: ii,nn
az = max(abs(z1),abs(z2))
if (az.ge.thrs(5,prcpar)) then ;nn=ntrm(6,prcpar)
elseif (az.ge.thrs(4,prcpar)) then ;nn=ntrm(5,prcpar)
elseif (az.ge.thrs(3,prcpar)) then ;nn=ntrm(4,prcpar)
elseif (az.ge.thrs(2,prcpar)) then ;nn=ntrm(3,prcpar)
elseif (az.ge.thrs(1,prcpar)) then ;nn=ntrm(2,prcpar)
else ;nn=ntrm(1,prcpar)
endif
zz = 1
yy = 1
rslt = zz
yy = z2*yy
zz = z1*zz+yy
rslt = rslt + coeff(0)*zz
do ii=1,nn
yy = z2*yy
zz = z1*zz+yy
rslt = rslt + coeff(ii)*zz
yy = z2*yy
zz = z1*zz+yy
enddo
end function
end module