I'm doing some math with really big numbers (I'm using Python, but this question isn't Python specific). For one value, I have a formula that gives me f(t) = Pr(X < t)
. I want to use this formula to get Pr(X >= t) = 1 - f(t)
. Because f(t)
returns values very close to zero, I've been using a log transform and storing log( f(t) )
instead of f(t)
. My log( f(t) )
is on the order of -1e5 or so.
For multiplying, this works quite well. log( f(t) * g ) = log( f(t) ) + log(g)
.
But, it's very difficult to compute log( 1 - f(t) )
using only log( f(t) )
; I could, of course, temporarily exponentiate the value I store and compute log( 1 - exp( log( f(t) ) )
, but that will return log( 1 - 0.0 ) = 0.0
because log( f(t) )
is so close to zero.
You might ask, "Why do you care? If it's close to zero, then 1 minus it is very close to 1." Well, that's a good point you've made. You're a smart cookie.
The trouble is I want to use this to rank values, so I really care if one is log(0.999)
and the other is log(0.9999)
. You might also ask, "Well, why don't you just rank the log( f(t) )
and then reverse the order to get the rankings for log( 1 - f(t) )
." Again, I cannot help but point out how great your questions are. It really has been a pleasure talking to you.
But here's the problem: I don't just want to rank by 1 - f(t)
; I actually want to rank based on Pr(X >= t) * g(t) = (1 - f(t)) g(t)
. After taking logs, I get log( 1 - f(t) ) + log( g(t) )
; ranking based on f(t)
alone won't give the correct answer.
In the past I wrote a little Python function to compute log(a + b)
from log(a)
and log(b)
:
def log_add(logA,logB):
if logA == log(0):
return logB
if logA<logB:
return log_add(logB,logA)
return log( 1 + math.exp(logB-logA) ) + logA
It helps by first normalizing them so that they're close together and then exponentiating when they're close together.
Unfortunately, I wasn't able to get the same trick to work for my subtraction because there is no normalization factor that will bring log(1)
and log( f(t) )
close together because they're so far apart.
Does anyone know how to solve this? It seems like such a classic kind of problem; I'd really expect/hope/pray that there is a clever function that operates on the bit level that can give me log(1-x)
from log(x)
. Also, if you know how it works, I'd really, really love to know.
Cheers! Oliver