Raw File
gamma.R
##
##  g a m m a z . R
##


gammaz <- function(z) {
    if (!is.numeric(z) && !is.complex(z))
        stop("Argument 'z' must be a numeric or complex vector.")

    z  <- c(z); zz <- z
    f  <- complex(length(z))

    p  <- which(Re(z) < 0)
    if (length(p) > 0) z[p] <- -z[p]

    # Lanczos approximation
    g  <- 607/128

    cc <- c(  0.99999999999999709182,     57.156235665862923517,
            -59.597960355475491248,       14.136097974741747174,
             -0.49191381609762019978,      0.33994649984811888699e-4,
              0.46523628927048575665e-4,  -0.98374475304879564677e-4,
              0.15808870322491248884e-3,  -0.21026444172410488319e-3,
              0.21743961811521264320e-3,  -0.16431810653676389022e-3,
              0.84418223983852743293e-4,  -0.26190838401581408670e-4,
              0.36899182659531622704e-5)

    z <- z - 1
    zh <- z + 0.5
    zgh <- zh + g
    # trick for avoiding FP overflow above z=141
    zp <- zgh^(zh*0.5)

    ss <- 0.0
    for (k in (length(cc)-1):1)
        ss <- ss + cc[k+1] / (z + k)

    # sqrt(2Pi)
    sq2pi <- 2.5066282746310005024157652848110;
    f <- (sq2pi * (cc[1]+ss)) * ((zp * exp(-zgh)) * zp);

    f[z == 0 | z == 1] <- 1.0

    # adjust for negative real parts
    if (length(p) > 0)
        f[p] <- -pi/(zz[p] * f[p] * sin(pi*zz[p]))

    # adjust for negative poles
    p <- which(round(zz) == zz & Im(zz) == 0 & Re(zz) <= 0)
    if (length(p) > 0)
        f[p] <- Inf

    return(f)
}


# lgammaz <- function(z) {
#     if (!is.numeric(z) && !is.complex(z))
#         stop("Argument 'z' must be a numeric or complex vector.")
# 
#     dimz <- dim(z)
#     z  <- c(z) + 0i
#     zz <- z
#     f  <- complex(length(z))
# 
#     p  <- which(Re(z) < 0)
#     if (length(p) > 0) z[p] <- -z[p]
# 
#     # Lanczos approximation
#     g  <- 607/128
# 
#     cc <- c(  0.99999999999999709182,     57.156235665862923517,
#             -59.597960355475491248,       14.136097974741747174,
#              -0.49191381609762019978,      0.33994649984811888699e-4,
#               0.46523628927048575665e-4,  -0.98374475304879564677e-4,
#               0.15808870322491248884e-3,  -0.21026444172410488319e-3,
#               0.21743961811521264320e-3,  -0.16431810653676389022e-3,
#               0.84418223983852743293e-4,  -0.26190838401581408670e-4,
#               0.36899182659531622704e-5)
# 
#     s <- 0
#     for (k in length(cc):2)
#         s <- s + cc[k]/(z + (k-2))
# 
#     zg <- z + g - 0.5
#     s2pi <- 0.9189385332046727417803297
#     f <- (s2pi + log(cc[1]+s)) - zg + (z-0.5) * log(zg)
# 
#     f[z == 1 | z == 2] <- 0.0
# 
#     if (length(p) > 0) {
#         lpi <- 1.14472988584940017414342735 + pi*1i
#         f[p] <- lpi - log(zz[p]) - f[p] - log(sin(pi*zz[p]))
#     }
# 
#     p <- which(round(zz) == zz & Im(zz) == 0 & Re(zz) <= 0)
#     if (length(p) > 0)
#         f[p] <- Inf
# 
#     dim(f) <- dimz
#     return(f)
# }

back to top