| dltgammaInc | R Documentation |
This is the deltagammainc algorithm as described in Abergel and
Moisan (2020).
It uses one of three different algorithms to compute G(p,x), their
conveniently scaled generalization of the (upper and lower)
incomplete Gamma functions,
G(p,x) = e^{x - p\log x} \times \gamma(p,x) \ \textrm{if} x \le p or \Gamma(p,x) \textrm{otherwise},
for \gamma(p,x) and \Gamma(p,x) the
lower and upper incomplete gamma functions, and for all
x \ge 0 and p > 0.
dltgammaInc(x,y, mu, p) := I_{x,y}^{\mu,p}
computes their (generalized incomplete gamma) integral
I_{x,y}^{\mu,p} := \int_x^y s^{p-1} e^{-\mu s} \; ds.
Current explorations (via package Rmpfr's
igamma()) show that this algorithm is less
accurate than R's own pgamma() at least for small p.
dltgammaInc(x, y, mu = 1, p)
x, y, p |
numeric vectors, typically of the same length; otherwise recycled to common length. |
mu |
a number different from 0; must be finite; |
a list with three components
rho, sigma |
numeric vectors of same length (the common length of
|
method |
integer code indicating the algorithm used for the
computation of |
C source from Remy Abergel and Lionel Moisan, see the reference; original is in ‘1006.zip’ at https://calgo.acm.org/.
Interface to R in DPQ: Martin Maechler
Rémy Abergel and Lionel Moisan (2020) Algorithm 1006: Fast and accurate evaluation of a generalized incomplete gamma function, ACM Transactions on Mathematical Software 46(1): 1–24. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1145/3365983")}
Rmpfr's igamma(), R's pgamma().
p <- pi
x <- y <- seq(0, 10, by = 1/8)
dltg1 <- dltgammaInc(0, y, mu = 1, p = pi); r1 <- with(dltg1, rho * exp(sigma)) ##
dltg2 <- dltgammaInc(x, Inf, mu = 1, p = pi); r2 <- with(dltg2, rho * exp(sigma))
str(dltg1)
stopifnot(identical(c(rho = "double", sigma = "double", method = "integer"),
sapply(dltg1, typeof)))
summary(as.data.frame(dltg1))
pg1 <- pgamma(q = y, shape = pi, lower.tail=TRUE)
pg2 <- pgamma(q = x, shape = pi, lower.tail=FALSE)
stopifnot(all.equal(r1 / gamma(pi), pg1, tolerance = 1e-14)) # seen 5.26e-15
stopifnot(all.equal(r2 / gamma(pi), pg2, tolerance = 1e-14)) # " 5.48e-15
if(requireNamespace("Rmpfr")) withAutoprint({
asN <- Rmpfr::asNumeric
mpfr <- Rmpfr::mpfr
iGam <- Rmpfr::igamma(a= mpfr(pi, 128),
x= mpfr(y, 128))
relErrV <- sfsmisc::relErrV
relE <- asN(relErrV(target = iGam, current = r2))
summary(relE)
plot(x, relE, type = "b", col=2, # not very good: at x ~= 3, goes up to 1e-14 !
main = "rel.Error(incGamma(pi, x)) vs x")
abline(h = 0, col = adjustcolor("gray", 0.75), lty = 2)
lines(x, asN(relErrV(iGam, pg2 * gamma(pi))), col = adjustcolor(4, 1/2), lwd=2)
## ## ==> R's pgamma() is *much* more accurate !! ==> how embarrassing for TOMS 1006 !?!?
legend("topright", expression(dltgammaInc(x, Inf, mu == 1, p == pi),
pgamma(x, pi, lower.tail== F) %*% Gamma(pi)),
col = c(palette()[2], adjustcolor(4, 1/2)), lwd = c(1, 2), pch = c(1, NA), bty = "n")
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.