Качество линейных конгруэнтных генераторов для случайных чисел

14

Я делаю некоторые моделирования уравнения Ланжевена для различных внешних сил. Мне сказали, что C's rand()from stdlib.hможет внести в мои результаты смещение, я использую Twister Mersenne.

Тем не менее, я хотел бы знать (и посмотреть), какие именно ошибки линейный конгруэнтный генератор может внести в мое моделирование. Это то, что я пробовал:

  • Генерация трехмерных кортежей случайностей, чтобы попытаться увидеть гиперплоскости. Я ничего не вижу.
  • Делаем БПФ из большого вектора случайных чисел. Это почти одинаково и для Mersenne Twister, и для rand().
  • Проверка принципа равенства для частицы в броуновском движении. Оба интеграторы согласны в ожидаемой стоимости с таким же количеством значащих цифр.KE=12kBT
  • Видя, как хорошо они складывают в несколько корзин, это не степень два. Оба дают одинаковые качественные результаты, никто не бывает лучше.
  • Глядя на броуновских путях , чтобы увидеть явные расхождения с . Опять не повезло.x=0
  • Распределение точек по кругу. Заполнено и только по периметру. Между всеми ними и между ближайшими соседями (ответ Шора ниже в комментариях). Доступный в этом списке , просто запустите его с Julia 0.5.0 после установки необходимых библиотек (см. Инструкции в этом разделе).

Я хотел бы подчеркнуть, что я ищу внесенный уклон в контексте физического моделирования. Например, я видел, как с rand()треском проваливаются тесты жестких дисков, в то время как тестер Мерсенна нет, но на данный момент это не так много значит для меня.

Есть ли у вас физические конкретные примеры того, как плохой генератор случайных чисел разрушает симуляцию Монте-Карло?

Примечание: я видел, как PRNG RANDUможет быть ужасным. Меня интересуют неочевидные примеры генераторов, которые выглядят невинно, но в конечном итоге вносят предвзятость.

RedPointyJackson
источник
1
У вас нет запрошенных примеров, но я использовал drand48 () / srand48 () вместо rand () / srand () в моих собственных программах на Си. Их соответствующие справочные страницы описывают различные используемые алгоритмы prng (см. Man random для алгоритма rand), и я считаю, что drand48, как правило, предпочтительнее, хотя мое детальное понимание исчезающе мало. Когда мне нужна гарантированная портативная воспроизводимость на разных платформах, я закодировал run1 () из Numeric Recipes in C, 2nd Edition, WHPress и др., Cambridge UP 1992, ISBN 0-521-43108-5, стр. 280. Отлично работает, поскольку Я могу сказать, но не проверял количественно.
Используйте random () или drand48 () / lrand48 () (я всегда использую последний для молекулярной динамики и моделирования Монте-Карло, и это довольно хорошо). Также попробуйте использовать случайное семя. Этого должно быть более чем достаточно для моделирования одночастичного уравнения Ланжевена.
Валерио
Мы использовали окружность, а не круг.
@PeterShor Спасибо за исправление. Я обновил ответ, до сих пор не повезло, я боюсь.
RedPointyJackson
1
@DanielShapero random и urandom должны быть криптографически безопасным ГСЧ, предназначенным для криптографических целей, таких как генерация ключей. Аппаратный аспект этого является то , что на Linux, они используют экологическую энтропию, это не то же самое , как аппаратное ускорение. Они на самом деле не предназначены для моделирования Монте-Карло.
Кирилл

Ответы:

3

Одна интересная ссылка, которая описывает сбой моделирования Монте-Карло физической системы из-за неадекватного RNG (хотя они не использовали LCG):

А. Ферренберг и Д. П. Ландау. Моделирование Монте-Карло: Скрытые ошибки от «хороших» генераторов случайных чисел. Physical Review Letters 63 (23): 3382-3384, 1992.

Модели Изинга, которые изучали Ферренберг и Ландуа, являются хорошими тестами ГСЧ, потому что вы можете сравнить с точным решением (для двумерной задачи) и найти ошибки в цифрах. Эти модели должны показывать ошибки в старомодной 32-битной арифметической PMMLCG без особых затруднений.

Еще одна интересная ссылка:

Х. Бауке и Стефан Мертенс. Псевдо случайные монеты показывают больше голов, чем хвостов. arXiv: cond-mat / 0307138 [cond-mat.stat-mech]

Бауке и Мертенс приводят веские аргументы против двоичных генераторов случайных чисел в стиле линейного регистра обратной связи. У Бьюка и Мертенса есть еще несколько документов, связанных с этим.

Может быть трудно найти плоскости Марсальи на трехмерном графике рассеяния. Вы можете попытаться повернуть сюжет, чтобы лучше видеть, и иногда они просто выскочат на вас. Вы также можете выполнить 3D-тесты статистической однородности - для более старых 32-битных LCG они не пройдут при довольно небольшом количестве бинов. Например, теста на однородность с сеткой ячеек 20x20x20 в 3 измерениях достаточно, чтобы обнаружить отсутствие однородности для широко используемого (и хорошо известного ранее) PMMLCG с m = 2 ^ 31-1, a = 7 ^ 5.

Брайан Борхерс
источник
1

Можно использовать набор тестов PRNG TestU01 , чтобы выяснить, какой из этих тестов randне пройден . (См. TestU01: Библиотека AC для эмпирического тестирования генераторов случайных чисел для обзора набора тестов.) Это проще, чем придумывать собственные моделирования Монте-Карло. В некотором смысле, это также вопрос о возможности компоновки программного обеспечения (и правильности программного обеспечения): если учесть, что PRNG хорошо работает в небольших простых тестах, откуда вы знаете, что его патологическое поведение не будет вызвано большой программой?

Вот код:

#include "TestU01.h"

int main() {
  // Same as rand() on my machine
  unif01_Gen* gen = ulcg_CreateLCG(2147483647, 16807, 0, 12345);

  bbattery_SmallCrush(gen);
  bbattery_Crush(gen);

  return 0;
}

Для набора SmallCrush есть 3 теста, не прошедших 15 испытаний ( подробные описания и все ссылки см. В guidelongtestu01.pdf в TestU01; это 15 статистик из 10 тестов).

  • n tdtdtI1,{Ij+1Ij} следует приблизительно за известным распределением.

  • n t[0,1)tdt равных гиперкубов и подсчитывает количество столкновений.

  • nt[0,1)XnP(X<x)=xtn=2×106t=6χ2<10300

Предполагая, что это все «типичные» симуляции Монте-Карло (хотя они могут не соответствовать тем проблемам, которые вы имели в виду), можно сделать вывод, что они randне соответствуют некоторому неизвестному их подмножеству. Я не знаю, почему именно это подмножество, поэтому я не могу сказать, сработает ли это над вашей собственной проблемой или нет.

MaxOft кажется особенно подозрительным, учитывая, насколько простое описание.

Среди тестов в наборе Crushrand не удается 51 из 140 (140 статистики в 96 тестах). Некоторые из неудачных тестов (например, Fourier3 ) выполняются на битовых строках, поэтому, возможно, они не будут иметь отношения к вам. Еще один любопытный тест, который не проходит , GCD , который проверяет распределение GCD из двух случайных целых чисел. (Опять же, я не знаю, почему этот конкретный тест не пройден или ваша симуляция пострадает от этого.)

PS : еще одна вещь, на которую следует обратить внимание, это то, что rand()она на самом деле медленнее, чем некоторые PRNG, которые успешно проходят все тесты SmallCrush , Crush , BigCrush , такие как MRG32k3a (см. Выше статью L'Ecuyer & Simard).

Кирилл
источник