Most math libraries have a number of versions of logarithm functions. Most of the time we assume them to be perfect, but actually quite a lot of them just offer a certain number of digits of precision.
For some functions, there are numerically more stable variants. For example Fortran, R, Java and C both have Math.log1p
, for computing log(1.0+x)
(which offers higher precision for small values of x), and the counterpart expm1
. Here the numeric problems arise from a loss in precision - if x
is really small, 1.0 + x
loses digits in order to preserve the 1 at the beginning.
I've seen such functions for increased precision in a number of situations. This seems to be quite common whenever you are implementing distribution functions (Gamma, Beta, Poisson etc.) with high numeric precision. For example the Gamma function seems to be most of the time used as logGamma
. In general, going to "logspace" can improve precision a lot, and so R seems to have a "logspace" flag on most functions.
Another example, in R, there exists log1mexp
for log(1 - exp(p))
:
http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
I've been playing around with entropy and information theoretic measures. A very common term there is
p * -log(p)
where usually, one would want the base of the logarithm to be 2, not e; but just as often this is only a linear factor, and you can as well use the natural logarithm (so this is not of key importance to me). Anyway, do you know if there is a faster / more direct / more precise way of computing this term? I'm having it all over the place, so it could really pay off to make it a bit more precise and fast (save me the usual "premature optimization" stuff, thanks).
I don't see any obvious reason that would cause a loss in precision. So I'm mostly interested if there is any nice trick to speed up this computation. That maybe even saves me treating the p=0
corner case (which sensibly is 0
, although log(0)
does not exist) or gives me base 2 for free (although a single multiplication with a constant obviously is not killer expensive). Thanks.
log2
function which depending on your OS can be a simple wrapper aroundlog/log(2)
or make use of the fact that C99 added alog2
function. $\endgroup$