C ++中的Marsaglia正态随机变量

时间:2012-02-03 04:38:03

标签: c++ random

我的查询非常简单。我更喜欢在Java中编写数值方法,但通常需要在C ++中做一些事情。我喜欢Java中的高斯随机变量,因为它使用Marsaglia算法并保留两个Normal随机变量。它在第一次调用时返回一个,在第二次调用时返回第二个,并且在第三次调用之前不再进行昂贵的计算。使用下面的oracle链接(在程序注释中)我试图用C ++实现这个代码,但不知道如何编写“同步”公共方法的C ++版本,这将允许我使用两个Normal随机变量。我不是一名专业的程序员,因此非常感谢任何指导。

简而言之,我想保留:

V2 *乘法器

// This function is Similar to the GNU 
// Java Implementation as seen on
// http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextGaussian%28%29
double nextGaussian() {

    double v1, v2, s, nextNextGaussian;
    do { 
        v1 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
        v2 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
        s = v1 * v1 + v2 * v2;
    } while (s >= 1 || s == 0);
    double multiplier = sqrt(-2 * log(s)/s);
    nextNextGaussian = v2 * multiplier;
    return v1 * multiplier;

}

3 个答案:

答案 0 :(得分:3)

只需将 nextGaussianVal 声明为 static ,即

static double nextGaussianVal;

然后,下次调用该方法时, nextGaussianVal 的值将可用。您可能还需要另一个静态变量来跟上当前计数,如下所示:

double nextGaussian()
{
    static int count = 0;
    static double nextGaussianVal;
    double firstGaussianVal, v1, v2, s;

    if (count == 0) {
       do { 
           v1 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
           v2 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
           s = v1 * v1 + v2 * v2;
        } while (s >= 1 || s == 0);
        double multiplier = sqrt(-2 * log(s)/s);
        nextGaussianVal = v2 * multiplier;
        firstGaussianVal = v1 * multiplier;
        count = 1;
        return firstGaussianVal;
    }

    count = 0;
    return nextGaussianVal;
}

编辑:更详细的解释 - 第一次调用该函数时,count初始化为零。根据 if 语句,执行相关计算,并假设 firstGaussianVal nextGaussianVal 被赋值, count 的值为1,并返回 firstGaussianVal 。下次调用该函数时, count 将使其先前指定的值为1,而 nextGaussianVal 将包含先前在第一次调用期间分配的值 - 即说,因为 count 现在是1,该函数将根据 if 语句将零指定给计数并返回 nextGaussianVal < / strong>即可。冲洗,重复......

答案 1 :(得分:1)

在更加面向对象的问题中,您应该将这些内容保存在“随机数生成器”对象中。查看此代码的实例: https://code.cor-lab.org/projects/nemomath/repository/entry/trunk/nemomath/src/nemo/Random.h “gaussian”这个类以算法的方式实现了你想要的东西。

答案 2 :(得分:-1)

上述建议的问题是COUNT变量应该是BOOLEAN而不是整数。此外,存储的高斯需要也是静态的。

我要感谢大家的帮助,帮助我找到我想要的正确解决方案。我知道这个片段属于一个对象。我有理由立即将其保存在一个文件中。

double nextGaussian() {

    // Static variables allow the function to make use of
    // both Gaussian Random variables.  Generated by the polar Marsaglia 
    // method This makes the function much more efficient with will 
    // pay off for simulations

    static bool hasNextGaussian = false;
    static double nextNextGaussian;
    double v1, v2, s;

    if (!hasNextGaussian) {

        do {

            v1 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
            v2 = 2 * nextUniform() - 1;   // between -1.0 and 1.0
            s = v1 * v1 + v2 * v2;

        } while (s >= 1 || s == 0);

        double multiplier = sqrt(-2 * log(s)/s);
        nextNextGaussian = v2 * multiplier;
        hasNextGaussian = true;
        return v1 * multiplier;

    } else {

        hasNextGaussian = false;
        return nextNextGaussian;

    }

}

double nextUniform(){

double Uniform = rand() / double(RAND_MAX);
return Uniform;

}