[英]C++ TR1: how to use the normal_distribution?
我正在嘗試使用C ++ STD TechnicalReport1擴展來生成正常分布后的數字,但是這段代碼(改編自本文 ):
mt19937 eng;
eng.seed(SEED);
normal_distribution<double> dist;
// XXX if I use the one below it exits the for loop
// uniform_int<int> dist(1, 52);
for (unsigned int i = 0; i < 1000; ++i) {
cout << "Generating " << i << "-th value" << endl;
cout << dist(eng) << endl;
}
只打印1“Generating ...”日志消息,然后永遠不會退出for循環 ! 如果我使用我注釋掉的發行版,它會終止,所以我想知道我做錯了什么。 任何的想法?
非常感謝!
我最初發布的代碼遇到了同樣的問題並調查了GNU的實現
首先是一些觀察結果:使用g ++ - 4.4並使用代碼掛起,使用g ++ - 4.5並使用-std = c ++ 0x(即不是TR1但是真實的東西)上面的代碼可以工作
恕我直言,TR1和c ++ 0x之間有關於隨機數生成和隨機數消耗之間的適配器的變化 - mt19937產生整數,normal_distribution消耗雙精度
c ++ 0x自動使用自適應,g ++ TR1代碼沒有
為了讓您的代碼使用g ++ - 4.4和TR1,請執行以下操作
std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();
這肯定不會掛起程序。 但是,不確定它是否真的滿足您的需求。
#include <random>
#include <iostream>
using namespace std;
typedef std::tr1::ranlux64_base_01 Myeng;
typedef std::tr1::normal_distribution<double> Mydist;
int main()
{
Myeng eng;
eng.seed(1000);
Mydist dist(1,10);
dist.reset(); // discard any cached values
for (int i = 0; i < 10; i++)
{
std::cout << "a random value == " << (int)dist(eng) << std::endl;
}
return (0);
}
如果您的TR1隨機數生成實現有問題,您可以通過編寫自己的普通生成器來避免TR1,如下所示。
使用您信任的任何隨機生成器生成兩個均勻(0,1)隨機樣本u和v。 然后讓r = sqrt(-2 log(u))並返回x = r sin(2 pi v)。 (這被稱為Box-Mueller方法。)
如果您需要具有平均μ和標准偏差西格瑪的正常樣品樣品,則返回sigma * x + mu而不是x。
雖然這似乎是一個錯誤,但快速確認將傳遞默認的0.0,1.0參數。 normal_distribution<double>::normal_distribution()
應該等於normal_distribution<double>::normal_distribution(0.0, 1.0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.