从对数正态分布生成随机数

时间:2013-07-28 03:26:28

标签: c++ random random-sample

这应该不会太困难,但由于某种原因,这个分布中的抽样随机数实际上是在绊倒我。

我知道从分发中生成随机数的最佳选择是boost / C ++ 11库...遗憾的是,我无法使用c ++ 0x编译此代码,无论如何,我最好保留兼容我正在使用的服务器,运行gcc 4.1.2 - 古代,我知道,不支持更新的C ++。挫折。和往常一样,时间紧迫意味着我需要尽快做到最好。快速修复。

从框muller方程中取一个随机数的指数是我的下一个选项,但是我没有得到具有我指定参数的对数正态分布。我不明白为什么这不起作用。

非常感谢任何帮助!

void testRNG(){

    int mean = 5000;
    int std = 50;

    ofstream out("./Output/normal_samples.out");

    RunningStats normal;
    for (int i=0;i<2000;++i){
        double sample = randomSample(mean, std, NORMAL);//call function with box muller transformation to return a number from a normal distriubtion
        out<<sample<<endl;
        normal.Push(sample);//keep a running average of sampled numbers
    }
    cout<<"Normal Mean = "<<normal.Mean()<<endl;
    cout<<"Normal Std = "<<normal.StandardDeviation()<<endl;

    RunningStats lognormal;
    for (int i=0;i<2000;++i){
        double sample = randomSample(mean, std, LOGNORMAL);
        out<<sample<<endl;
        lognormal.Push(sample);
    }
    cout<<"Lognormal Mean = "<<lognormal.Mean()<<endl;
    cout<<"Lognormal Std = "<<lognormal.StandardDeviation()<<endl;
}

我没有写的采样函数首先从randomSample()开始,然后调用:

编辑 - 我注意到它实际上调用了函数来查找对数正态参数。添加。

double randNormal(double mean, double stdev) {
static long numSamples = 0;
static double Z2;
if ((numSamples++ & 1) == 0) {
    double Z1, U1, U2;
    do { U1 = randUniform(0, 1); } while (U1 <= 0 || U1 >= 1);
    do { U2 = randUniform(0, 1); } while (U1 <= 0 || U1 >= 1);
    Z1 = sqrt(-2 * log(U1)) * cos(6.28318531 * U2);
    Z2 = sqrt(-2 * log(U1)) * sin(6.28318531 * U2);
    return mean + stdev * Z1;
} else {
    return mean + stdev * Z2;
}
}

double randLognormal(double mu, double sigma) {
return exp(randNormal(mu, sigma));
}

double randLognormalMeanStdev(double mean, double stdev) {
return randLognormal( log(mean) - 0.5 * log(1 + (stdev * stdev) / (mean * mean)) , log(1 + (stdev * stdev) / (mean * mean)));
}

所以我得到的输出是:

Normal Mean = 4998.72 //I said 5000
Normal Std = 49.7054 //I said 50
Lognormal Mean = 4999.74
Lognormal Std = 0.492766 //this is the part that is not working

我想让lognormal std成为我想要的是什么?

其他选项也会受到赞赏 - 也许还有其他我想念的东西。

提前致谢!

编辑 - 我意识到我应该明确表示我需要从对数正态分布中进行采样

0 个答案:

没有答案