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.