Box-Muller尝试生成随机数有什么问题?

时间:2019-04-03 23:44:17

标签: random kdb

我正在尝试使用Box-Muller方法从高斯分布中生成一个随机数。但是,我的结果与事实相去甚远。

你能告诉我我在做什么错吗?

.stat.GetOneGaussianByBoxMuller:{ 
sq:{
    a:2.0*rand[abs[system"S"]]%abs[system"S"]-1;
    b:2.0*rand[abs[system"S"]]%abs[system"S"]-1;
    sq:(a*a)+(b*b);
    x:sq
   }/[{x>=1};1]; 

  :(2.0*rand[abs[system"S"]]%abs[system"S"]-1)*sqrt[(neg[2]*log[sq])%sq]
 };

1 个答案:

答案 0 :(得分:3)

您的答案中存在三个问题:q中的操作优先级,如何在[-1; 1]中生成随机变量以及变量sq的条件。

操作优先级:

请注意下面的a1a2不同:

u:rand[1f];
a1:-1+2.0*u;
a2:2.0*u-1;

u:0.5
a1:0f
a2:-1f

u:0
a1:-1f
a2:-2f

在[-1; 1]中生成随机变量:

使用以下内容:

a:-1+2.0*rand[1.0];
b:-1+2.0*rand[1.0];

sq上的条件:

您确实考虑了sq >= 1条件,但是如果sq = 0在最后一步中必须除以sq,也会遇到问题。

此外,在您的实现中,您两次计算a,其中1)并不是最优的,而2)与方法学不一致,因为在{{ 1}},在最后一步中,后者产生了很大的数量。我从wikipedia page获得了一些启发,他们建议如果不满足上述条件,则重新生成a。因此,在以下实现中的函数中进行递归调用:

sq

您现在可以查看通过绘制以下数据集的直方图生成的数据:

sq

编辑:

实际上,您可以通过每个函数调用生成2个随机数来实现更有效的实现,如下所示:

.stat.GetOneGaussianByBoxMuller:{ 
    a:-1+2.0*rand[1.0];
    b:-1+2.0*rand[1.0];
    sq:(a*a)+(b*b);
    if[(sq>=1)|(sq=0);
        :.stat.GetOneGaussianByBoxMuller[];
    ];
    :a*sqrt[(neg[2]*log[sq])%sq];
 };

此实现需要150毫秒才能生成100000正态分布的随机数,而上面的一个需要245毫秒。

相关问题