С++ TR1: как использовать normal_distribution?

Я пытаюсь использовать расширения С++ 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;
}

печатает только сообщение журнала "Generating...", а затем никогда не выходит из цикла for! Если я использую дистрибутив, я прокомментировал это, он заканчивается, поэтому мне интересно, что я делаю неправильно. Любая идея?

Спасибо большое!

Ответ 1

Это определенно не повесило бы программу. Но, не уверен, действительно ли это соответствует вашим потребностям.

 #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); 
 }

Ответ 2

У меня была такая же проблема с первоначально опубликованным кодом и была изучена реализация GNU

сначала некоторые наблюдения: с g++ - 4.4 и с использованием кода зависает, с g++ - 4.5 и с использованием -std = С++ 0x (т.е. не TR1, а реальная вещь) над кодом работает

IMHO произошло изменение между TR1 и С++ 0x в отношении адаптеров между генерированием случайных чисел и потреблением случайных чисел - mt19937 производит целые числа, normal_distribution потребляет удвоения

С++ 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();

Ответ 3

Если ваша реализация генерации случайных чисел TR1 ошибочна, вы можете избежать TR1, написав свой собственный обычный генератор следующим образом.

Создайте два равномерных (0, 1) случайных выборка u и v, используя любой случайный генератор, которому вы доверяете. Тогда пусть r = sqrt (-2 log (u)) и возвращает x = r sin (2 pi v). (Это называется методом Box-Mueller.)

Если вам нужны обычные образцы образцов со средним значением mu и сигма стандартного отклонения, верните sigma * x + mu вместо просто x.

Ответ 4

В то время как это кажется ошибкой, быстрым подтверждением было бы передать параметры 0.0, 1.0 по умолчанию. normal_distribution<double>::normal_distribution() должен равняться normal_distribution<double>::normal_distribution(0.0, 1.0)