Вопрос по c++, tr1, normal-distribution – C ++ TR1: как использовать нормальный_распределение?

9

Я пытаюсь использовать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 & quot; Генерирование ... & quot; сообщение журнала, затемnever exits the for loop! Если я использую дистрибутив, который я закомментировал, вместо этого, он прекращается, поэтому мне интересно, что я делаю неправильно. Любая идея?

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

Ваш Ответ

4   ответа
1

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

он также не работает, он все еще застрял при выполнении первого вычисления .. puccio
7

первоначально опубликованным и исследованным GNU-реализацией

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

ИМХО, произошло изменение между 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

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

 #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); 
 }
Очевидно, единственное отличие состоит в том, что вы используете генератор чисел mt19937, тогда как Jagannath использует std :: tr1 :: ranlux64_base_01. Логически, я думаю, ошибка может быть в вашей реализации объекта mt19937 (алгоритма, о котором я никогда не слышал до того, как вы это сделали, спасибо за это :-)), который не является частью библиотеки std.
Можно ли векторизовать такой цикл for при рисовании случайных чисел? Напоминаю, что вы не можете векторизовать цикл, в котором есть вызов функции.
спасибо, мужик, это работает как шарм, но мне интересно, почему с этим двигателем он работает, а не с другим .. puccio
2

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

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

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

не используйте Box Muller.
Просто попробовал это. Он работает очень быстро - протестирован с 1М образцами и показал почти идеальную статистику для образцов в пределах 1-сигма, 2-сигма и т. Д.
Box M & # xFC; ller работает медленно

Похожие вопросы