これはそれほど難しいことではありませんが、何らかの理由で、この分布からの乱数のサンプリングは本当に私をつまずかせます.
ディストリビューションから乱数を生成するための最良のオプションはブースト/C++11 ライブラリであることを知っています...残念ながら、このコードを c++0x でコンパイルすることはできません。 gcc 4.1.2 を実行している私も使用しているサーバー - 古代、私は知っていますが、新しい C++ をサポートしていません。フラストレーション。そしていつものように、時間の不足は、迅速な修正で最善を尽くす必要があることを意味します.
ボックス ミュラー方程式から乱数の指数を取得することが次のオプションですが、指定したパラメーターでは対数正規分布が得られません。これが機能しない理由がわかりません。
どんな助けでも大歓迎です!
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 を必要なものにするために何が欠けていますか?
他のオプションも高く評価されます-おそらく私が見逃しているものがあります。
前もって感謝します!
編集 - 対数正規分布からサンプリングする必要があることを明確にする必要があることに気付きました