为什么这样实现 log_sum 会更有效率?
Why is it more efficient to implement log_sum like this?
根据这个帖子:To Compute log(a+b)
有时候log_sum是这样实现的:
log(a + b) = log(a * (1 + b/a)) = log a + log(1 + b/a)
我很困惑为什么这种方法更有效。有人对此有想法吗?
当 a
不变(至少对于某些 b
值)和 b<<a
(明显更小)时,此方法可能有用。在这种情况下 log(1 + b/a)
可以通过 Taylor series expansion fast and with good precision (log1p
function in some math libraries, another method)
来计算
我见过这种事情的一个地方是在处理高维空间的概率或可能性时。有时人们想计算像
这样的总和
p1 + p2 + ..
然而,此类概率通常太小而无法以双精度表示,因此人们通常使用概率的对数来代替。然后我们要计算
log( exp(l1) + exp( l2) + ..)
其中 l 是 p1 等的日志。
问题是,如果只对 exp 求值,很可能会得到 0,然后表达式变得不确定。但是你提到的技巧可以解决问题,我们可以评估
l1 + log( 1 + exp(l2-l1) + ...)
这将合理地评估(至少如果 l1 是 l 中最大的)。
所以这不是效率问题,而是绕过双精度的有限精度。
根据这个帖子:To Compute log(a+b)
有时候log_sum是这样实现的:
log(a + b) = log(a * (1 + b/a)) = log a + log(1 + b/a)
我很困惑为什么这种方法更有效。有人对此有想法吗?
当 a
不变(至少对于某些 b
值)和 b<<a
(明显更小)时,此方法可能有用。在这种情况下 log(1 + b/a)
可以通过 Taylor series expansion fast and with good precision (log1p
function in some math libraries, another method)
我见过这种事情的一个地方是在处理高维空间的概率或可能性时。有时人们想计算像
这样的总和p1 + p2 + ..
然而,此类概率通常太小而无法以双精度表示,因此人们通常使用概率的对数来代替。然后我们要计算
log( exp(l1) + exp( l2) + ..)
其中 l 是 p1 等的日志。 问题是,如果只对 exp 求值,很可能会得到 0,然后表达式变得不确定。但是你提到的技巧可以解决问题,我们可以评估
l1 + log( 1 + exp(l2-l1) + ...)
这将合理地评估(至少如果 l1 是 l 中最大的)。
所以这不是效率问题,而是绕过双精度的有限精度。