C ++ TR1: как использовать нормальный_распределение? - PullRequest
9 голосов
/ 13 июля 2009

Я пытаюсь использовать расширения 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 ! Если я использую дистрибутив, который я закомментировал, он прекращается, поэтому мне интересно, что я делаю неправильно. Есть идеи?

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

Ответы [ 4 ]

7 голосов
/ 24 ноября 2010

У меня была такая же проблема с кодом, первоначально размещенным и исследованным 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();
3 голосов
/ 13 июля 2009

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

 #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 голосов
/ 04 сентября 2009

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

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

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

1 голос
/ 13 июля 2009

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

...