我正在用非常大的数字做一些数学运算(我使用的是 Python,但这个问题不是 Python 特有的)。对于一个值,我有一个公式可以给我f(t) = Pr(X < t)
. 我想用这个公式得到Pr(X >= t) = 1 - f(t)
. 因为f(t)
返回值非常接近于零,所以我一直在使用对数转换和存储log( f(t) )
而不是f(t)
. 我log( f(t) )
的顺序是-1e5 左右。
对于乘法,这非常有效。log( f(t) * g ) = log( f(t) ) + log(g)
.
但是,log( 1 - f(t) )
仅使用; 来计算非常困难log( f(t) )
;当然,我可以暂时对我存储和计算的值求幂log( 1 - exp( log( f(t) ) )
,但这会返回,log( 1 - 0.0 ) = 0.0
因为log( f(t) )
它非常接近于零。
你可能会问,“你为什么在乎?如果它接近于零,那么 1 减去它就非常接近于 1。” 嗯,这是一个很好的观点。你是个聪明的饼干。
问题是我想用它来对值进行排名,所以我真的很关心一个是log(0.999)
,另一个是log(0.9999)
。你也可能会问,“好吧,你为什么不给 排名log( f(t) )
,然后颠倒顺序来获得排名log( 1 - f(t) )
。” 再一次,我不得不指出你的问题有多棒。与您交谈真的很愉快。
但问题是:我不只是想按1 - f(t)
; 我实际上想根据 排名Pr(X >= t) * g(t) = (1 - f(t)) g(t)
。记录日志后,我得到log( 1 - f(t) ) + log( g(t) )
; 仅基于排名f(t)
不会给出正确答案。
过去我写了一个小 Python 函数来计算log(a + b)
和:log(a)
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
它有助于首先将它们归一化,使它们靠近在一起,然后在它们靠近在一起时取幂。
不幸的是,我无法使用相同的技巧来进行减法运算,因为没有归一化因子可以将它们log(1)
结合log( f(t) )
在一起,因为它们相距甚远。
有谁知道如何解决这个问题?这似乎是一个经典的问题;我真的希望/希望/祈祷有一个聪明的功能可以在位级别上运行,可以log(1-x)
从log(x)
. 另外,如果你知道它是如何工作的,我真的很想知道。
干杯! 奥利弗