[R] integration problem with gamma function

Leo Gürtler leog at anicca-vijja.de
Fri Sep 1 17:02:54 CEST 2006


Dear R-list members,

I have a problem with translating a mathematica script into R. The whole 
script is at the end of the email (with initial values for easy 
reproduction) and can be pasted directly into R. The problematic part 
(which is included below of course) is

<--- Original Mathematica --->
(* p_svbar *)
UiA  = Ni (Dsi - 2Di A + A^2)/2;
UiiA = Nii (Dsii - 2Dii A + A^2)/2;
psvbar = NIntegrate[1/(UiA^(Ni/2)) 1/(UiiA^(Nii/2))
    Gamma[Ni/2,UiA/(sH^2),UiA/(sL^2)]
    Gamma[Nii/2,UiiA/(sH^2),UiiA/(sL^2)],{A,L,H},
    MinRecursion->3];
PSVbar = psvbar/(4 Log[sH/sL]);
Print["p(sÂv|D_1D_2I)  = const. ",N[PSVbar,6]];
</--->

<--- translation to R --->
integpsvbar <- function(A)
{
# Mathematica: gamma[a,z0,z1] = gamma[a,z1] - gamma[a,z0]
 UiA <- Ni*(Dsi-2*Di*A+A^2)/2
 UiiA <- Nii*(Dsii-2*Dii*A+A^2)/2
 1/UiA^(Ni/2) *
 1/UiiA^(Nii/2) *
 ( pgamma(UiA/(sL^2), Ni/2) - pgamma(UiA/(sH^2), Ni/2) ) *
 ( pgamma(UiiA/(sL^2), Nii/2) - pgamma(UiiA/(sH^2), Nii/2) )
}

psvbar <- integrate(integpsvbar, lower=L, upper=H)
psvbar$value
PSVbar <- psvbar$value / (4*log(sH/sL))
PSVbar <- PSVbar * sqrt(pi) * sqrt(pi)      #note: two times pgamma in 
integration function above... correct it with two times multiplied by 
'sqrt(pi)' due to differences in defining incomplete gamma function 
between R and mathematica
print(paste("p(sÂv|D_1D_2I)  = const. ",PSVbar,sep=""))
</--->

According to Mathematica

psvbar ~ 1.72026 * 10^20
PSVbar ~ 5.24827 * 10^19

The R part produces

psvbar ~ 1.824023 * 10^13
PSVbar ~ 17482463305549.6



The script produces proper results untill the problematic part, so it 
seems quite reasonable that no other error before is responsible for the 
difference of the results.
I assume that I did something wrong with the Gamma function.

The "generalized incomplete gamma function" in Mathematica (Wolfram, 
p.363f.) is defined as

Gamma[a, z0, z1] := Gamma[a, z1] - Gamma[a, z0]

with

Gamma[a, z0, z1] := integral_z0^z1 t^(a-1) exp(-t) dt

Please note: I asked a quite similar question (thread from 07-August/ 
08-August 2006) for which Martin Mächler (08-08-2006 13:53) pointed out, 
that the result has to be multiplied by "sqrt(pi)" because of (-> 
manpage pgamma) differences in formulating the incomplete gamma function 
between Mathematica and R. However, I tried this in various ways and - 
at least for me - it does not help. Thus, I assume it is another issue.

Thank you very much,

best wishes
leo gürtler

now the R script to reproduce (can be pasted directly into R):

####################
# R-Portierung aus Mathematica (Urban Studer, 90er)
# Ursprung: G.L. Bretthorst "On the difference of means"
# zuerst: 12-06-05
# zuletzt: 21-06-06

# --------------------------------------------------
# Success rates and integration bounds in the case
# of the (conservative) Bayes-Laplace prior
# --------------------------------------------------





SucRatesIntBounds <- function(Ni, Si, Nii, Sii, smin)
{
# BEGIN BLOCK
# necessary variables:
# {Nmax, Nmin}

### defintion of constants
Di <- (Si + 1) / (Ni + 2)
si <- sqrt(Di * (1 - Di) / (Ni + 3))
Dii <- (Sii + 1) / (Nii + 2)
sii <- sqrt(Dii * (1 - Dii) / (Nii + 3))

Nmax <- max(Ni, Nii)
Nmin <- min(Ni, Nii)
sL <- floor(1000 * sqrt((Nmax+1) / (Nmax+3)) / (Nmax + 2)) / 1000
sH <- ceiling(1000 / (2 * sqrt(Nmin + 3))) / 1000
L <- floor(100 * (smin + 1) / (Nmax + 2)) / 100
H <- 1 - L

return(c(Di, si, Dii, sii, sL, sH, L, H))
}
#END BLOCK
# --------------------------------------------------


Si <- 11
Ni <- 15
Sii <- 10
Nii <- 16
smin <- 0
res1 <- SucRatesIntBounds(Ni, Si, Nii, Sii, smin)
res1
#return(c(Di, si, Dii, sii, sL, sH, L, H))

names(res1) <- c("Di","si","Dii","sii","sL","sH","L","H")
res1

Di <- res1[1]
si <- res1[2]
Dii <- res1[3]
sii <- res1[4]
sL <- res1[5]
sH <- res1[6]
L <- res1[7]
H <- res1[8]


# --------------------------------------------------
# Begin: ON THE DIFFERENCE IN MEANS
# --------------------------------------------------

#DiffinMeans <- function(Ni, Di, si, Nii, Dii, sii, L, H, sL, sH)
## BEGIN BLOCK
#{

# necessary variables in the function
#{ NN, DD, Dsi, Dsii, DsD, ss,
#  dd, lownum, upnum, low, up, psv, PSV,
#  zz, lowinum, upinum, lowiinum, upiinum, psbarv, PSbarV,
#  psvbar, PSVbar, psbarvbar, PSbarVbar, cc,
#  sv, sbarv, svbar, sbarvbar,
#  samemeans, diffmeans, samevars, diffvars, diffsets },



### defintion of constants
NN <- Ni+Nii
DD <- (Ni * Di + Nii * Dii) / NN
Dsi <- (Ni-1) / Ni * si^2 + Di^2
Dsii <- (Nii-1) / Nii * sii^2 + Dii^2
DsD <- (Ni * Dsi + Nii * Dsii) / NN
ss <- sqrt(NN * (DsD - DD^2) / (NN-1))


### descriptive statistics
print(" \n------------- Data ---------------------------------------\n")
print(paste("N_1 = ",Ni ," :     Mean_1 ± s_1    = ", Di," ± ",si, sep=""))
print(paste("N_2 = ",Nii," :     Mean_2 ± s_2    = ", Dii," ± ",sii, 
sep=""))
print(paste("N   = ", NN ," :  Mean_comb ± s_comb = ", DD," ± ",ss, sep=""))
print(" ")
print(paste("s_L = ",sL,", s_H = ",sH,";  L = ",L, ", H = ",H,"  (smin = 
",smin,")",sep=""))
if(L < DD)
  {
   print(paste("L - Mean_comb < 0 : ", (L<DD), "\n", "             (-> 
'+'-sign between Gamma-fcts o.k.)", sep=""))
  } else print(paste("L - Mean_comb < 0 : ", (L<DD), "\n", "             
(-> '+'-sign between Gamma-fcts false!)", sep=""))
print(paste(" \n ", sep=""))


#(* p_sv *)
dd <- NN * (DsD - DD^2)
lownum <- NN * (L-DD)^2
upnum  <- NN * (H-DD)^2

#low = lownum / (2*s^2)
#up  = upnum / (2*s^2)
integpsv <- function(s)
{ 1 / (s^NN) * exp(-dd / (2 * s^2)) *
  ( pgamma(upnum/(2*s^2), 1/2) + pgamma(lownum/(2*s^2), 1/2) )
}
psv <- integrate(integpsv, lower=sL, upper=sH)
#???    (* + if (L-DD) < 0 *)
PSV <- psv$value / sqrt(2*NN) * sqrt(pi)    # normalizing factor due to R
# Gamma(1/2)= sqrt(pi)
# psv ~ 1.39848 * 10^20
# ~ 3.44715 * 10 ^20
# ~ 5.24827 * 10 ^20
# ~ 1.52788 * 10 ^20
print("------------- Results ------------------------------------\n")
print(paste("p(sv|D_1D_2I)   = const. ",PSV, sep=""))


### p_sbarv
zz <- Ni * (Dsi - Di^2) + Nii * (Dsii - Dii^2)
lowinum <- Ni * (L - Di)^2
upinum <- Ni * (H - Di)^2
lowiinum <- Nii * (L - Dii)^2
upiinum <- Nii * (H - Dii)^2

#lowi <- lowinum / (2*s^2)
#upi  <- upinum / (2*s^2)
#lowii <- lowiinum / (2*s^2)
#upii <- upiinum / (2*s^2)
integpsbarv <- function(s)
{
 1/(s^(NN-1)) * exp(-zz/(2*s^2)) *
 ( pgamma(upinum/(2*s^2), 1/2) + pgamma(lowinum/(2*s^2), 1/2) ) *
 ( pgamma(upiinum/(2*s^2), 1/2) + pgamma(lowiinum/(2*s^2), 1/2) )
}
psbarv <- integrate(integpsbarv, lower=sL, upper=sH)
#??? (* + if (L-DD) < 0 *)
PSbarV <- psbarv$value / (2*(H-L) * sqrt(Ni*Nii)) * sqrt(pi) * sqrt(pi)
# 2mal mit sqrt(pi) mal nehmen = "* pi", weil zei pgamma-Ausdrücke 
enthalten sind in der Integration
print(paste("p(Âsv|D_1D_2I)  = const. ",PSbarV, sep=""))

###############ALL ABOVE PRODUCES PROPER RESULTS COMPARED TO
###############MATHEMATICA SCRIPT

###############PROBLEMATIC PART STARTS HERE#################  
### p_svbar
###
# Mathematica
#(* p_svbar *)
#UiA  = Ni (Dsi - 2Di A + A^2)/2;
#UiiA = Nii (Dsii - 2Dii A + A^2)/2;
#psvbar = NIntegrate[1/(UiA^(Ni/2)) 1/(UiiA^(Nii/2))
#   Gamma[Ni/2,UiA/(sH^2),UiA/(sL^2)]
#   Gamma[Nii/2,UiiA/(sH^2),UiiA/(sL^2)],{A,L,H},
#    MinRecursion->3];
#PSVbar = psvbar/(4 Log[sH/sL]);
#Print["p(sÂv|D_1D_2I)  = const. ",N[PSVbar,6]];

###R trial
integpsvbar <- function(A)
{
# Mathematica: gamma[a,z0,z1] = gamma[a,z1] - gamma[a,z0]
 UiA <- Ni*(Dsi-2*Di*A+A^2)/2
 UiiA <- Nii*(Dsii-2*Dii*A+A^2)/2
 1/UiA^(Ni/2) *
 1/UiiA^(Nii/2) *
 ( pgamma(UiA/(sL^2), Ni/2) - pgamma(UiA/(sH^2), Ni/2) ) *
 ( pgamma(UiiA/(sL^2), Nii/2) - pgamma(UiiA/(sH^2), Nii/2) )
}

psvbar <- integrate(integpsvbar, lower=L, upper=H)
psvbar$value
PSVbar <- psvbar$value / (4*log(sH/sL)) * sqrt(pi) * sqrt(pi) # two 
times sqrt(pi) to correct for differences between R and mathematica
print(paste("p(sÂv|D_1D_2I)  = const. ",PSVbar,sep=""))



More information about the R-help mailing list