【问题标题】:problem with arithmetic using logarthms to avoid numerical underflow使用对数避免数值下溢的算术问题
【发布时间】:2010-02-18 10:17:52
【问题描述】:

我有两个分数列表;

A = [ 1/212, 5/212, 3/212, ... ]

B = [ 4/143, 7/143, 2/143, ... ]

如果我们定义A' = a[0] * a[1] * a[2] * ...B' = b[0] * b[1] * b[2] * ...

我要计算A' / B'的值,

我的问题是 A 和 B 都很长,每个值都很小,所以计算乘积会很快导致数值下溢......

我知道通过对数将乘积转化为和可以帮助我确定 A' 或 B' 中哪个更大

max( log(a[0])+log(a[1])+..., log(b[0])+log(b[1])+... )

但我需要实际比例....

迄今为止,我最好的选择是将数字表示形式保留为分数,即A = [ [1,212], [5,212], [3,212], ... ] 并实现我自己的算术,但它变得笨拙,我觉得我只是缺少一种(简单的)对数方式。 ...

A 和 B 的分子不是来自序列。出于这个问题的目的,它们也可能是随机的。如果它有助于 A 中所有值的分母相同,那么 B 中的所有分母也相同。

欢迎提出任何想法!

垫子

【问题讨论】:

    标签: logarithm numerical-methods


    【解决方案1】:

    你可以用稍微不同的顺序来计算它:

    A' / B' = a[0] / b[0] * a[1] / b[1] * a[2] / b[2] * ...
    

    【讨论】:

    • 太棒了!这应该可以正常工作。只见树木不见森林。
    • 不错的答案。你打败了我:)
    【解决方案2】:

    如果要保持对数形式,请记住 A/B 对应于 log A - log B,因此在将 A 和 B 的对数相加后,您可以找到较大与较小的比率用 max(logsumA, logsumB)-min(logsumA,logsumB) 对日志基数求幂。

    【讨论】:

    • 感谢这个。出于其他原因(因为这是更大图景的一部分),我有动力保留日志。干杯!
    【解决方案3】:

    去掉分子和分母,因为它们在整个序列中是相同的。逐个元素计算分子的比率(就像@Mark 建议的那样),最后将结果乘以 B 分母/A 分母的右幂。

    或者,如果在计算分子或分母幂的乘积时会出现整数溢出,则类似于:

    A'/B' = (numerator(A[0])/numerator(b[0]))*(denominator(B)/denominator(A) * ...
    

    我可能把一些分数颠倒了,但我想你能弄清楚吗?

    【讨论】:

      猜你喜欢
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      相关资源
      最近更新 更多