【发布时间】:2011-10-13 01:54:17
【问题描述】:
我正在用非常大的数字做一些数学运算(我使用的是 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( f(t) ) 来计算 log( 1 - 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(x) 给我log(1-x)。另外,如果您知道 它是如何工作的,我真的很想知道。
干杯! 奥利弗
【问题讨论】:
-
x->log(1-x) 的泰勒级数是 -(x + x^2/2 + .. x^n/n + ..)。有了 x 的范围,要将 -x 与 log(1-x) 区分开来,你需要使用 ~1.4e5 位,所以也许你可以通过 -x 来近似 log(1-x)。
标签: statistics probability numerical-methods