【问题标题】:Is log(a*b) always faster in Matlab than log(a) + log(b)?在 Matlab 中 log(a*b) 总是比 log(a) + log(b) 快吗?
【发布时间】:2013-08-22 16:48:32
【问题描述】:

在 Matlab 中 log(a*b) 总是比 log(a) + log(b) 快吗?

我测试了几个输入,似乎 log(a*b) 更快。 有经验的大侠能不能给点意见? 也许警告这可能并非总是如此,或者什么 否则我应该小心吗?所以在第一种情况下,我们有 1 个日志操作 和 1 个乘法,在第二种情况下,我们有两个对数运算和一个求和。

编辑:

要添加到我的原始帖子中,更一般的问题是:

log (a*b*...*z) 总是比 log(a) + log(b) + ... + log(z) 快吗?

谢谢

【问题讨论】:

  • 我认为 log 时间 >> multiply time > add time。所以这个观察是有道理的。

标签: matlab math numerical-methods


【解决方案1】:

log(a*b) 应该总是更快,因为计算对数很昂贵。在log(a*b) 你只做一次,在log(a)+log(b) 你做两次。

与对数、指数等相比,计算乘积和求和是微不足道的。就处理器周期而言,求和和乘积通常都小于 5,而对于某些架构,指数和对数可以从 50 到 200 个周期。

log (a*b*...*z) 总是比 log(a) + log(b) + ... + log(z) 快吗

是的。确实。尽可能避免计算对数。

这是一个小实验:

a=rand(5000000,1);

% log(a(1)*a(2)...)
tic
for ii=1:100
    res=log(prod(a));
end
toc
% Elapsed time is 0.649393 seconds.  

% log(a(1))+log(a(2))+...
tic
for ii=1:100
    res=sum(log(a));
end
toc
% Elapsed time is 6.894769 seconds.

在某个时间点,时间比率会饱和。饱和的位置取决于您的处理器架构,但差异至少是一个数量级。

【讨论】:

  • 在复杂对数的情况下差异更加显着,例如,a 是一个复杂随机值的向量。
  • 这里要小心,将[0,1]范围内的很多小值相乘会很快变为零。现实生活中使用probabilities时经常会出现这类问题...所以速度不是一切,在使用浮点数时还应该关注数值稳定性。
  • 为了说明它有多糟糕,在上面的示例中,仅在大约 700 个元素(500 万个中)之后产品变为零:sum(cumprod(a) > 0) 给了我 729
【解决方案2】:

请注意,虽然计算产品的log 速度更快,但由于机器精度,有时可能会出现错误。

有问题的情况之一是使用大量整数操作数或大数作为操作数。在这种情况下,乘积a_1 * a_2 * ... a_n 将导致溢出,而​​计算对数之和则不会。

另一个有问题的情况是使用小数字,这样它们的乘积由于机器精度而变为零(正如 Amro 所提到的)。

【讨论】:

  • 好的,在这种情况下,我们可以创建部分乘积,在溢出之前相乘,然后记录该结果。然后继续做同样的事情,继续将术语收集到产品中,在溢出之前获取日志。同意吗?
  • 是的,听起来可行。
  • +1 对已经给出答案的问题进行了很好的观察。
  • @user2381422 Nein,来自巴西。 Soll ich auf meine schlechte Deutsch hier sprechen?我来自巴西(我更喜欢它写成巴西,在葡萄牙语中,它看起来更漂亮)x)
【解决方案3】:

尽管执行log(a*b) 而不是log(a) + log(b) 通常会更快,但如果难以评估a*b,则不成立。在这种情况下,实际上可能是使用第二种方法更快。

例子:

a = 0;
b = Inf;
tic,for t = 1:1e6 log(a*b); end,toc
tic,for t = 1:1e6 log(a)+log(b); end,toc

当然,在这两种情况下它都会评估为NaN,但第二个比第一个快得多。

【讨论】:

  • 0*Inf 在现代处理器上得到快速处理;没有什么“难以评估”的。 (过去,一些处理器在使用 Infinities 和 NaN 进行算术运算时会遇到停顿,但这不再是一个真正的问题)
  • @StephenCanon 很好的时机表明它仍然很慢。也许缓慢的部分是对log(NaN) 的评估,而不是通过将零乘以无穷大来创建NaN。当然慢是相对的,“正常”情况只快 2 倍左右。
  • 在您的系统上,log(nan) 肯定比 log(0) 和 log(inf) 慢,但这可能是一个数学库实现的怪癖,而不是普遍适用的发现。
  • @StephenCanon 是的,但问题确实有 matlab 标签。
猜你喜欢
  • 2015-03-22
  • 1970-01-01
  • 2021-03-26
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
相关资源
最近更新 更多