C++中0到1之间的Box muller随机数

杰·科比

我目前正在尝试创建一个高斯随机数生成器,它会产生 0 到 1 之间的值。我一直在尝试使用下面的函数,平均值为 0,标准差为 1,但是当我通过这个函数生成随机数时循环,我最终生成的大部分值都超出了 [0,1] 的范围。我将如何调整我正在做的事情以将这些值带入该范围内?

float Network::box_muller(float m, float s) {                     
float x1, x2, w, y1;
static float y2;
static int use_last = 0;

if (use_last) {
    y1 = y2;
    use_last = 0;
}
else {
    do {
        x1 = 2.0 * ((double)rand() / (RAND_MAX)) - 1.0;
        x2 = 2.0 * ((double)rand() / (RAND_MAX)) - 1.0;
        w = x1 * x1 + x2 * x2;
    } while (w >= 1.0);

    w = sqrt((-2.0 * log(w)) / w);
    y1 = x1 * w;
    y2 = x2 * w;
    use_last = 1;
}

return(m + y1 * s);
}
贾拉·麦金太尔

对于生产代码:

如果您有权访问 C++11 功能,那么您应该使用std::normal_distribution( http://en.cppreference.com/w/cpp/numeric/random/normal_distribution ) 或其变体之一,而不是自己实现该功能。这应该给你一个健壮的(不使用rand())、线程安全的(你的不是)、经过良好测试的实现。

用于学习目的

维基百科在 C++ 中有一个该算法的示例实现。具体来说,我可以看到您的代码有两个问题。

  1. 您没有正确处理 的情况w==0log(0)和除以零是未定义的。

  2. 为您的更新功能y1y2不正确。正确的算法(在伪代码):y1 = sqrt(-2 * log(u1)) * cos(2*PI*u2)y2 = sqrt(-2 * log(u1)) * sin(2*PI*u2)其中显然u1必须在范围(0,1),而U2是不受约束的。

也在一个次要的句法点上。您的use_last变量应该是 a bool,而不是intC++ 中的an

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章