statistics – 日志的数字精度(1-exp(x))

我正在做一些非常大的数学计算(我使用的是
Python,但这个问题不是
Python特有的).对于一个值,我有一个公式,给出f(t)= Pr(X

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).另外,如果你知道它是如何工作的,我真的很想知道.

干杯!
奥利弗

最佳答案 如果log(f(t))确实是-1e5(或类似的数量级),那么0.0是log(1-f(t))的最佳浮点表示.实际上,f(t)= exp(-1e5)所以,通过dmuir提到的泰勒级数,log(1-f(t))= – exp(-1e5)(这实际上不是完全相等,但它是一个非常好的近似值).现在,-exp(-1e5)= -3.56e-43430,但在0和-4e-324之间没有浮点数,因此最佳浮点表示为0.0.

因此,标准浮点数不可能实现您想做的事情.

这有关系吗?你说想要根据Pr(X> = t)* g(t)=(1 – f(t))g(t)排名,相当于按log(1 – f(t)排名) log(g(t)).我们在上面发现log(1-f(t))= -3.56e-43430,所以如果log(g(t))的不同值相差不超过这个微小的数字,这个术语只会产生差异.如果你的计算足够准确,它可以通过这些微小数字来区分(如果你使用标准的浮点数,那么你的计算将永远不够准确).换句话说,如果log(f(t))确实是-1e5或类似,那么你可以按g(t)排序.

然而,log(f(t))可能是-1e5的数量级,但它有时会使值接近零,如-10或-1.在这种情况下,你不能忽略它,你必须确实按log(1-f(t))log(g(t))排名.你应该使用math.log1p函数来写这个:按log1p(-f(t))log(g(t))排名.原因是如果f(t)接近零,则log(1-f(t))是不准确的,但log1p(-f(t))是准确的.如果f(t)非常接近于零,例如当log(f(t))= -1e5时,则log1p(-f(t))= 0.0,因为这是使用标准浮点数可以做到的最佳值.

我使用表达式“标准浮点数”是有原因的.可以使用更精确的浮点数,如果你真的想捕捉-3.56e-43430之类的微小数字,那就是你应该做的.一种可能性是在Python中是mpmath(不幸的是,它似乎不支持log1p函数).请注意,这比标准浮点数慢得多,正如我所说,我认为你不需要它.但是,如果你想更好地理解这些问题,那就值得一试.

点赞