【问题标题】:Calculating log(sum of exp(terms) ) when "terms" are very small当“条款”非常小时计算日志(exp(条款)的总和)
【发布时间】:2014-10-18 04:12:30
【问题描述】:

我想计算 log(exp(A1) + exp(A2))。
下面的公式

 log(exp(A1) + exp(A2) ) = log[exp(A1)(1 + exp(A2)/exp(A1))] = A1 + log(1+exp(A2-A1)) 

在 A1 和 A2 很大并且数值为 exp(A1)=Inf(或 exp(A2)=Inf)时很有用。 (这个公式在这个线程中讨论-> How to calculate log(sum of terms) from its component log-terms)。当A1和A2的角色被替换时,公式为真。

我对这个公式的关注是当 A1 和 A2 非常小时。例如,当 A1 和 A2 是:

 A1 <- -40000
 A2 <- -45000

那么 log(exp(A1) + exp(A2) ) 的直接计算为:

 log(exp(A1) + exp(A2))
 [1] -Inf

使用上面的公式给出:

 A1 + log(1 + exp(A2-A1))
 [1] -40000

这是A1的值。 将上面的公式与 A1 和 A2 的翻转角色相结合,得到:

A2 + log(1 + exp(A1-A2))
[1] Inf

三个值中哪个最接近 log(exp(A1) + exp(A2)) 的真实值?是否有稳健的方法来计算 log(exp(A1) + exp(A2)) 可以在 A1、A2 较小且 A1、A2 较大时使用。

提前谢谢你

【问题讨论】:

    标签: math sum precision largenumber natural-logarithm


    【解决方案1】:

    你应该使用更准确的东西来进行直接计算。

    它“在 [它们] 很大时没有用”。当差异非常负时,它很有用。

    x 接近 0 时,log(1+x) 大约是 x。所以如果A1&gt;A2,我们可以取你的第一个公式:

    log(exp(A1) + exp(A2)) = A1 + log(1+exp(A2-A1))
    

    并通过A1 + exp(A2-A1) 对其进行近似(随着A2-A1 更负,近似值会变得更好)。由于A2-A1=-5000,这足以使近似值足够负。

    无论如何,如果y 离零太远(无论哪种方式)exp(y) 将(溢出|低于)双精度并导致 0 或无穷大(这是双精度,对吗?您使用什么语言? )。这解释了你的答案。但是由于exp(A2-A1)=exp(-5000) 接近于零,所以你的答案大约是-40000+exp(-5000),与-40000 无法区分,所以一个是正确的。

    【讨论】:

      【解决方案2】:

      在如此巨大的指数差异中,没有任意精度的最安全方法是

      • 选择最大的指数让它成为Am = max(A1,A2)
      • 所以:log(exp(A1)+exp(A2)) -&gt; log(exp(Am)) = Am
      • 对于这种情况,这是您可以得到的最接近的值
      • 所以在你的例子中结果是-40000+delta
      • delta 非常小

      如果你想使用第二个公式,那么一切都分解为计算log(1+exp(A))

      • 如果A 是肯定的,那么结果与真实情况相去甚远
      • 如果A 为负数,那么它将截断为log(1)=0,因此您会得到与上面相同的结果

      [备注]

      • 你的指数差是base^500
      • 单精度32位浮点数最多可存储(+/-)2^(+/-128)
      • 双精度64位浮点数最多可存储(+/-)2^(+/-1024)
      • 因此,当您的基数为 10 或 e 时,这远远不够您所需要的
      • 如果你有四倍的精度应该足够了,但是当你再次开始更改 exp 差异时,你将很快达到与现在相同的点

      [PS] 如果您需要更高的精度而不是任意精度

      • 您可以尝试创建自己的号码类
      • 内部存储诸如number=a^b 之类的数字
      • a,b 是浮点数
      • 但为此您需要编写所有基本功能
      • *,/ 很简单
      • +,- 是一场噩梦,但即使是这样也可能有一些方法/算法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多