curve(lgamma1p, -1.25, 5, n=1001, col=2, lwd=2)
abline(h=0, v=-1:0, lty=c(2,3,2), lwd=c(1, 1/2,1))
for(k in 1:15)
curve(lgamma1p_series(x, k=k), add=TRUE, col=adjustcolor(paste0("gray",25+k*4), 2/3), lty = 3)
curve(lgamma1p, -0.25, 1.25, n=1001, col=2, lwd=2)
abline(h=0, v=0, lty=2)
for(k in 1:15)
curve(lgamma1p_series(x, k=k), add=TRUE, col=adjustcolor("gray20", 2/3), lty = 3)
curve(-log(x*gamma(x)), 1e-30, .8, log="xy", col="gray50", lwd = 3,
axes = FALSE, ylim = c(1e-30,1)) # underflows to zero at x ~= 1e-16
eaxGrid <- function(at.x = 10^(1-4*(0:8)), at.y = at.x) {
sfsmisc::eaxis(1, sub10 = c(-2, 2), nintLog=16)
sfsmisc::eaxis(2, sub10 = 2, nintLog=16)
abline(h = at.y, v = at.x, col = "lightgray", lty = "dotted")
}
eaxGrid()
curve(-lgamma( 1+x), add=TRUE, col="red2", lwd=1/2)# underflows even earlier
curve(-lgamma1p (x), add=TRUE, col="blue") -> lgxy
curve(-lgamma1p.(x), add=TRUE, col=adjustcolor("forest green",1/4),
lwd = 5, lty = 2)
for(k in 1:15)
curve(-lgamma1p_series(x, k=k), add=TRUE, col=paste0("gray",80-k*4), lty = 3)
stopifnot(with(lgxy, all.equal(y, -lgamma1pC(x))))
if(requireNamespace("Rmpfr")) { # accuracy comparisons, originally from ../tests/qgamma-ex.R
x <- 2^(-(500:11)/8)
x. <- Rmpfr::mpfr(x, 200)
## versions of lgamma1p(x) := lgamma(1+x)
## lgamma1p(x) = log gamma(x+1) = log (x * gamma(x)) = log(x) + lgamma(x)
xct. <- log(x. * gamma(x.)) # using MPFR arithmetic .. no overflow/underflow ...
xc2. <- log(x.) + lgamma(x.) # (ditto)
AllEq <- function(target, current, ...)
Rmpfr::all.equal(target, current, ...,
formatFUN = function(x, ...) Rmpfr::format(x, digits = 9))
print(AllEq(xct., xc2., tol = 0)) # 2e-57
rr <- vapply(1:15, function(k) lgamma1p_series(x, k=k), x)
colnames(rr) <- paste0("k=",1:15)
relEr <- Rmpfr::asNumeric(sfsmisc::relErrV(xct., rr))
## rel.error of direct simple computation:
relE.D <- Rmpfr::asNumeric(sfsmisc::relErrV(xct., lgamma(1+x)))
matplot(x, abs(relEr), log="xy", type="l", axes = FALSE,
main = "|rel.Err(.)| for lgamma(1+x) =~= lgamma1p_series(x, k = 1:15)")
eaxGrid()
p2 <- -(53:52); twp <- 2^p2; labL <- lapply(p2, function(p) substitute(2^E, list(E=p)))
abline(h = twp, lty=3)
axis(4, at=twp, las=2, line=-1, labels=as.expression(labL), col=NA,col.ticks=NA)
legend("topleft", paste("k =", 1:15), ncol=3, col=1:6, lty=1:5, bty="n")
lines(x, abs(relE.D), col = adjustcolor(2, 2/3), lwd=2)
legend("top", "lgamma(1+x)", col=2, lwd=2)
## zoom in:
matplot(x, abs(relEr), log="xy", type="l", axes = FALSE,
xlim = c(1e-5, 0.1), ylim = c(1e-17, 1e-10),
main = "|rel.Err(.)| for lgamma(1+x) =~= lgamma1p_series(x, k = 1:15)")
eaxGrid(10^(-5:1), 10^-(17:10))
abline(h = twp, lty=3)
axis(4, at=twp, las=2, line=-1, labels=as.expression(labL), col=NA,col.ticks=NA)
legend("topleft", paste("k =", 1:15), ncol=3, col=1:6, lty=1:5, bty="n")
lines(x, abs(relE.D), col = adjustcolor(2, 2/3), lwd=2)
legend("right", "lgamma(1+x)", col=2, lwd=2)
} # Rmpfr only
Run the code above in your browser using DataLab