lgammaP11 | R Documentation |
p
by Pugh's Method (11 Terms)Computes \log(\Gamma(p))
for p > 0
,
where \Gamma(p) = \int_0^\infty s^{p-1} e^{-s}\; ds
.
The evaluation hapenss via Pugh's method (approximation with 11 terms), which is a refinement of the Lanczos method (with 6 terms).
This implementation has been used in and for Abergel and Moisan (2020)'s
TOMS 1006 algorithm, see the reference and our dltgammaInc()
.
Given the examples below and example(dltgammaInc)
, their use of
“accurate” does not apply to R's “standard” accuracy.
lgammaP11(x)
x |
a numeric vector |
a numeric vector "as" x
(with no attributes, currently).
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")}
dltgammaInc()
partly uses (the underly C code of) lgammaP11()
;
DPQ's lgamma1p
, R's lgamma()
.
(r <- lgammaP11(1:20))
stopifnot(all.equal(r, lgamma(1:20)))
summary(rE <- sfsmisc::relErrV(r, lgamma(1:20)))
cbind(x=1:20, r, lgamma(1:20))
## at x=1 and 2 it is *not* fully accurate but gives -4.44e-16 (= - 2*EPS )
if(requireNamespace("Rmpfr")) withAutoprint({
asN <- Rmpfr::asNumeric
mpfr <- Rmpfr::mpfr
x <- seq(1, 20, by = 1/8)
lgamM <- lgamma(x = mpfr(x, 128)) # uses Rmpfr::Math(.) -> Rmpfr:::.Math.codes
lgam <- lgammaP11(x)
relErrV <- sfsmisc::relErrV
relE <- asN(relErrV(target = lgamM, current = lgam))
summary(relE)
summary(relE.R <- asN(relErrV(lgamM, base::lgamma(x))))
plot(x, relE, type = "b", col=2, # not very good: at x ~= 3, goes up to 1e-14 !
main = "rel.Error(lgammaP11(x)) vs x")
abline(h = 0, col = adjustcolor("gray", 0.75), lty = 2)
lines(x, relE.R, col = adjustcolor(4, 1/2), lwd=2)
## ## ==> R's lgamma() is much more accurate
legend("topright", expression(lgammaP11(x), lgamma(x)),
col = c(palette()[2], adjustcolor(4, 1/2)), lwd = c(1, 2), pch = c(1, NA), bty = "n")
## |absolute rel.Err| on log-scale:
cEps <- 2^-52 ; lc <- adjustcolor("gray", 0.75)
plot(x, abs(relE), type = "b", col=2, log = "y", ylim = cEps * c(2^-4, 2^6), yaxt = "n",
main = "|rel.Error(lgammaP11(x))| vs x -- log-scale")
sfsmisc::eaxis(2, cex.axis = 3/4, col.axis = adjustcolor(1, 3/4))
abline(h= cEps, col = lc, lty = 2); axis(4, at=cEps, quote(epsilon[C]), las=1, col.axis=lc)
lines(x, pmax(2^-6*cEps, abs(relE.R)), col = adjustcolor(4, 1/2), lwd=2)
## ## ==> R's lgamma() is *much* more accurate
legend("topright", expression(lgammaP11(x), lgamma(x)), bg = adjustcolor("gray", 1/4),
col = c(palette()[2], adjustcolor(4, 1/2)), lwd = c(1, 2), pch = c(1, NA), bty = "n")
mtext(sfsmisc::shortRversion(), cex = .75, adj = 1)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.