【问题标题】:Why is random number generation from a kernel distribution up to 1000x slower if truncated?如果截断,为什么内核分发的随机数生成速度会慢 1000 倍?
【发布时间】:2018-09-23 16:12:13
【问题描述】:

我宁愿截断我的分布,但目前考虑到时间损失,这是不可能的。

标准内核分布:

expectation=fitdist(BTS,'kernel');

结果:

tic;expectation.random(10000,1);toc;
Elapsed time is 0.000745 seconds.

截断代码:

Exp{i,j}=truncate(expectation,min(BTS)-1,max(BTS)+1);

结果:

tic;random(Exp{i,j},1,10000);toc
Elapsed time is 0.772295 seconds.

【问题讨论】:

  • 你确定调用的是同一个random函数吗?
  • 是的,与 tic 运行时的速度相同;random(expectation,10000,1);toc;
  • 我可以在 MATLAB R2017b,Mac 版本上重现相同的问题。很想知道这个问题的答案。
  • 我没有统计工具箱,但我猜truncate 是一个更复杂的分布对象,需要更长的时间来评估。似乎random 为每个生成的数字评估对象。您应该考虑将此作为错误提交给 MathWorks。

标签: matlab random truncate


【解决方案1】:

作为替代方案,您可以尝试从未截断的分布中抽取随机数并自己进行截断。

我没有统计工具箱,所以这里用randn来抽取随机数:

function M = truncated_normal(n)
M = randn(n,1);
I = M < -2 | M > 2;
n = nnz(I);
if n>0
   M(I) = truncated_normal(n);
end

此函数从给定分布中抽取n 随机数,然后查找所选区间 (M &lt; -2 | M &gt; 2) 之外的任何值,并通过递归调用自身来为这些值绘制新值。

如果您愿意,也可以使用 while 循环编写该函数。但只要随机值出现在尾部的概率很小,就需要很少的迭代。

【讨论】:

    【解决方案2】:

    注意:这更像是一个评论,但它太长了,不适合 cmets 部分。

    Matlab 不一定提供生成随机数的最快方法。一种极端情况是二项式随机变量,matlab 通过绘制n伯努利数并将它们相加来生成。您的示例只是另一种情况。

    我建议你要么

    • 自行实施采样,因此您可以根据需要对其进行调整,

    • 或者使用肖邦的那个,参见论文here,你可以得到here,这是(据我所知)最新的此类算法

    请注意,尽管“截断”听起来像是让事情变得更容易/更快,但事实并非如此。尤其是现在存在非常快速的正态分布生成器。另一方面,与更好的方法相比,x1000 的惩罚太大了。

    【讨论】:

      猜你喜欢
      • 2017-11-13
      • 2021-05-29
      • 1970-01-01
      • 2021-07-17
      • 2021-09-01
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      相关资源
      最近更新 更多