1
c $Id: nwpw_gamma_function.F 21411 2011-11-05 06:41:27Z d3y133 $
3
! *************************************************************************
5
! This is a modified version of Log(Gamma) function
6
! program from Num. Rec.
7
! Serves as backup if intrinic Gamma function
9
! ************************************************************************
11
DOUBLE PRECISION FUNCTION nwpw_LN_GAMMA (XX)
1
* ******************************************************
3
* * nwpw_SpecialKummer *
5
* ******************************************************
7
* Calculates a special case of the Kummer confluent hypergeometric
8
* function, M(n+1/2,l+3/2,z) for z .LE. 0
10
* This function was created by Marat Valiev, and modified by Eric Bylaska.
11
* See Abramowitz and Stegun for the formulas used in this function.
13
real*8 function nwpw_SpecialKummer(n,l,z)
18
* *** local variables ***
20
parameter (eps=1.0d-16)
25
* **** external functions ****
26
real*8 nwpw_gamma,nwpw_gammp
27
external nwpw_gamma,nwpw_gammp
29
nwpw_SpecialKummer = 0.0d0
31
* *** cannot handle positive z ***
33
call errquit('nwpw_SpecialKummer:invalid parameter, z>0',0,1)
37
* *** solution for z==0 ***
39
nwpw_SpecialKummer = 1.0d0
43
* ***** M(a,a+1,z) = a * (-z)**(-a) * igamma(a,-z) = a * (-z)**(-a) * P(a,-z) *Gamma(a) where z is real and a = (n+0.5) ****
45
nwpw_SpecialKummer = nwpw_gammp(n+0.5d0,(-z))
47
> *((-z)**((-n)- 0.5d0))
48
> *nwpw_gamma(n+0.5d0)
51
* ***** M(a,a,z) = exp(z) where a = (n+0.5) ****
52
else if (n.eq.(l+1)) then
53
nwpw_SpecialKummer = dexp(z)
57
! *** do inifinite series for small z
58
if (dabs(z).le.1.0d0) then
60
nwpw_SpecialKummer = 1.0d0
65
s = s*(a+i-1)*z/((b+i-1)*i)
66
nwpw_SpecialKummer = nwpw_SpecialKummer + s
67
if (dabs(s).lt.eps) return
69
call errquit("nwpw_SpecialKummer:cannot converge",0,1)
75
!*** starting point n=l or b=a+1***
79
!*** m1 = M(a,b-1) ***
80
!*** m2 = M(a,b,z) ***
82
nwpw_SpecialKummer = nwpw_gammp(a,(-z))*a/(-z)**a*nwpw_gamma(a)
84
!**********************************************
85
! using recursion formula
86
! z(a-b)M(a,b+1,z)=b(b-1)M(a,b-1,z)+b(1-b-z)M(a,b,z)
87
! obtain M(1/2,3/2+l ,z) --> m2
88
! M(1/2,3/2+l-1,z) --> m2
89
!**********************************************
91
m3=(b*(b-1.0d0)*m1+b*(1.0d0-b-z)*nwpw_SpecialKummer)
94
m1 = nwpw_SpecialKummer
95
nwpw_SpecialKummer = m3
98
else if (n.gt.(l+1)) then
100
!*** starting point n=l+1 or b=a ***
104
!*** m1 = M(a-1,b) ***
105
!*** m2 = M(a,a,z) ***
106
m1 = nwpw_gammp(a-1.0d0,(-z))*(a-1.0d0)/(-z)**(a-1.0d0)*
107
> nwpw_gamma(a-1.0d0)
108
nwpw_SpecialKummer = dexp(z)
110
!**********************************************
111
! using recursion formula
112
! aM(a+1,b,z)=(b-a)M(a-1,b,z)+(2a-b+z)M(a,b,z)
113
! obtain M(n+1/2-1,3/2,z) --> m1
114
! M(n+1/2 ,3/2,z) --> m2
115
!**********************************************
117
m3 = ((b-a)*m1+(2*a-b+z)*nwpw_SpecialKummer)/a
118
m1 = nwpw_SpecialKummer
119
nwpw_SpecialKummer = m3
127
* ***************************************
131
* ***************************************
133
* This function computes the Log(Gamma) function
134
* Serves as backup if intrinic Gamma function is not available
136
real*8 function nwpw_ln_gamma(XX)
19
144
DOUBLE PRECISION Y, COF(6)
21
DATA COF, STP/ 76.18009172947146D0, -86.50532032941677D0,
22
1 24.01409824083091D0, -1.231739572450155D0,
23
2 0.1208650973866179D-2, -.5395239384953D-5, 2.5066282746310005D0
146
DATA COF, STP/ 76.18009172947146d0, -86.50532032941677d0,
147
1 24.01409824083091d0, -1.231739572450155d0,
148
2 0.1208650973866179d-2, -.5395239384953d-5, 2.5066282746310005d0
28
TMP = (X + 0.5D0)*DLOG(TMP) - TMP
29
SER = 1.000000000190015D0
153
TMP = (X + 0.5d0)*dlog(TMP) - TMP
154
SER = 1.000000000190015d0
32
157
SER = SER + COF(J)/Y
35
nwpw_LN_GAMMA = TMP + DLOG(STP*SER/X)
40
! *************************************************
50
! *************************************************
51
DOUBLE PRECISION FUNCTION nwpw_GAMMA(X)
159
nwpw_ln_gamma = TMP + dlog(STP*SER/X)
163
* **********************************************
167
* **********************************************
169
* This function computes the Gamma function
171
real*8 function nwpw_gamma(X)
56
DOUBLE PRECISION nwpw_LN_GAMMA
177
external nwpw_ln_gamma
59
nwpw_GAMMA = DEXP(nwpw_LN_GAMMA(XX))
66
! *************************************************
76
! *************************************************
77
DOUBLE PRECISION FUNCTION nwpw_GAMMP (A, X)
81
DOUBLE PRECISION GAMMCF, GAMSER, GLN
83
IF (X .LT. A+1.0D0) THEN
85
CALL nwpw_GSER(GAMSER, A, X, GLN)
90
CALL nwpw_GCF(GAMMCF, A, X, GLN)
91
nwpw_GAMMP = 1.0D0 - GAMMCF
98
! *************************************************
108
! *************************************************
109
SUBROUTINE nwpw_GCF(GAMMCF, A, X, GLN)
112
DOUBLE PRECISION A, GAMMCF, GLN, X, EPS, FPMIN
113
PARAMETER (ITMAX = 100, EPS = 3.D-16, FPMIN = 1.D-30)
114
DOUBLE PRECISION AN, B, C, D, DEL, H
180
nwpw_gamma = dexp(nwpw_ln_gamma(XX))
184
* **********************************************
188
* **********************************************
190
* This function computes the incomplete gamma function P(a,x) = igamma(a,x)/Gamma(a)
193
* P(a,x) = 1/Gamma(a) * | exp(-t) * t**(a-1) dt
196
real*8 function nwpw_gammp(A, X)
199
real*8 gammcf,gamser,gln
201
if (x.lt. (a+1.0d0)) then
202
call nwpw_gser(gamser, a, x, gln)
205
call nwpw_gcf(gammcf,a,x,gln)
206
nwpw_gammp = 1.0d0 - gammcf
211
* **********************************************
215
* **********************************************
216
subroutine nwpw_gcf(GAMMCF, A, X, GLN)
219
real*8 A,GAMMCF,GLN,X,EPS,FPMIN
220
parameter (ITMAX = 100, EPS = 3.0d-16, FPMIN = 1.0d-30)
221
real*8 AN,B,C,D,DEL,H
117
DOUBLE PRECISION nwpw_LN_GAMMA
118
EXTERNAL nwpw_LN_GAMMA
225
external nwpw_ln_gamma
120
GLN = nwpw_LN_GAMMA(A)
227
GLN = nwpw_ln_gamma(A)
129
IF (DABS(D) .LT. 1.D-30) D = 1.D-30
236
IF (dabs(D) .LT. 1.0d-30) D = 1.0d-30
131
IF (DABS(C) .LT. 1.D-30) C = 1.D-30
238
IF (dabs(C) .LT. 1.0d-30) C = 1.0d-30
135
IF (DABS(DEL - 1.0D0) .LT. 3.D-16) GO TO 1
242
IF (dabs(DEL-1.0d0) .LT. 3.0d-16) GO TO 1
137
PAUSE 'a too large, ITMAX too small in gcf'
139
GAMMCF = DEXP((-X) + A*DLOG(X) - GLN)*H
244
call errquit('a too large, ITMAX too small in nwpw_gcf',0,0)
247
GAMMCF = dexp((-X) + A*dlog(X) - GLN)*H
144
! *************************************************
154
! *************************************************
155
SUBROUTINE nwpw_GSER(GAMSER, A, X, GLN)
251
* **********************************************
255
* **********************************************
256
subroutine nwpw_gser(GAMSER, A, X, GLN)
157
DOUBLE PRECISION A, X
158
DOUBLE PRECISION GAMSER, GLN
160
261
! *** local variables ***
162
PARAMETER (ITMAX = 100)
164
PARAMETER (EPS = 3.0D-16)
166
DOUBLE PRECISION AP, DEL, SUM
263
parameter (ITMAX = 100)
265
parameter (EPS = 3.0d-16)
168
DOUBLE PRECISION nwpw_LN_GAMMA
169
EXTERNAL nwpw_LN_GAMMA
172
GLN = nwpw_LN_GAMMA(A)
174
IF (X .LE. 0.0D0) THEN
175
IF(X.lt.0.0d0) CALL errquit("x < 0 in nwpw_GSER",0,1)
270
external nwpw_ln_gamma
272
GLN = nwpw_ln_gamma(A)
274
if (X .le. 0.0d0) then
275
if (X.lt.0.0d0) call errquit("x < 0 in nwpw_gser",0,1)
187
IF (DABS(DEL) .LT. DABS(SUM)*3.0D-16) GO TO 1
192
> ("a too large,ITMAX too small in nwpw_GSER",0,1)
195
GAMSER = SUM*DEXP((-X) + A*DLOG(X) - GLN)
287
if (dabs(DEL) .lt. dabs(SUM)*3.0d-16) GO TO 1
292
> ("a too large,ITMAX too small in nwpw_gser",0,1)
295
GAMSER = SUM*dexp((-X) + A*dlog(X) - GLN)