mt19937 и uniform_real_distribution

Я пытаюсь найти эффективный способ реализовать равномерное (0,1) распределение. Поскольку мне нужно сгенерировать очень большое количество семплов, в качестве движка я выбрал mt19937. Я использую версию из библиотеки boost. Мой вопрос: в чем разница между использованием вывода самого движка и uniform_real_distribution?

Вариант №1

std::random_device rd;
boost::mt19937 gen(rd());
boost::random::uniform_real_distribution<double> urand(0, 1);

for ( int i = 0; i < 1E8; i++ ) {
    u = urand(gen);
}

Вариант 2

std::random_device rd;
boost::mt19937 gen(rd());

for ( int i = 0; i < 1E8; i++ ) {
    u = (double) gen()/gen.max();
}

Судя по моим тестам, вариант №2 значительно лучше, чем вариант №1, с точки зрения времени выполнения. Есть ли причина, по которой я должен выбрать вариант №1 вместо варианта №2?


person user3278488    schedule 09.12.2014    source источник
comment
Не глядя на саму реализацию, невозможно узнать наверняка, но я бы предположил, что uniform_real_distribution использует больше битов, чтобы гарантировать, что каждый возможный результат с плавающей запятой в диапазоне может быть возвращен. Вариант № 2 будет иметь отверстия, которые 1/gen.max() друг от друга.   -  person Mark Ransom    schedule 10.12.2014


Ответы (2)


Я не знаю, какова реализация urand(), но использование результата деления может привести к смещению младших битов в качестве эффекта квантования. Если gen.max() не велик, то «младшие биты» могут составлять очень много или большую часть битов результата.

Несоответствие производительности может происходить из-за правильного распределения случайных чисел. Если double слишком точен для ваших нужд, возможно, использование float позволит ему работать более эффективно.

person sh1    schedule 10.12.2014

Мой вопрос: в чем разница между использованием вывода самого движка и uniform_real_distribution?

В вашем первом варианте urand() имеет диапазон [0,1), тогда как ваш второй вариант имеет диапазон [0,1] (если boost::mt19937::min() == 0, что обычно имеет место).

person Zeta    schedule 09.12.2014
comment
Спасибо! Разницы в дальности не заметил. Получается, что второй вариант лучше и по производительности, и по качеству генератора случайных чисел? - person user3278488; 09.12.2014