stringtranslate.com

Xorshift

Пример случайного распределения Xorshift128

Генераторы случайных чисел Xorshift , также называемые генераторами сдвиговых регистров , представляют собой класс генераторов псевдослучайных чисел , которые были изобретены Джорджем Марсальей . [1] Они являются подмножеством регистров сдвига с линейной обратной связью (LFSR), которые позволяют особенно эффективно реализовать их в программном обеспечении без чрезмерного использования разреженных полиномов . [2] Они генерируют следующее число в своей последовательности, многократно принимая исключающее или числа с его версией, сдвинутой по битам . Это делает выполнение чрезвычайно эффективным на современных компьютерных архитектурах, но не повышает эффективность в аппаратной реализации. Как и все LFSR, параметры должны быть выбраны очень тщательно, чтобы достичь длительного периода. [3]

Для выполнения в программном обеспечении генераторы xorshift являются одними из самых быстрых PRNG, требуя очень небольшого кода и состояния. Однако они не проходят все статистические тесты без дальнейшей доработки. Эта слабость устраняется путем объединения их с нелинейной функцией, как описано в оригинальной статье. Поскольку простые генераторы xorshift (без нелинейного шага) не проходят некоторые статистические тесты, их обвиняют в ненадежности. [3] : 360 

Пример реализации

Здесь приведена версия C [a] трех алгоритмов xorshift [1] : 4,5. Первый имеет одно 32-битное слово состояния и период 2 32 −1 . Второй имеет одно  64 - битное слово состояния и период 2 64 −1. Последний имеет четыре 32-битных слова состояния и период 2 128 −1. 128-битный алгоритм проходит самые сложные тесты . Однако он не проходит тесты MatrixRank и LinearComp тестового набора BigCrush из фреймворка TestU01 .

Все используют три сдвига и три или четыре операции «исключающее ИЛИ»:

#include <stdint.h> struct xorshift32_state { uint32_t a ; };    /* Состояние должно быть инициализировано ненулевым значением */ uint32_t xorshift32 ( struct xorshift32_state * state ) { /* Алгоритм "xor" со стр. 4 книги Марсальи "Xorshift RNGs" */ uint32_t x = state -> a ; x ^= x << 13 ; x ^= x >> 17 ; x ^= x << 5 ; return state -> a = x ; }                     struct xorshift64_state { uint64_t a ; };    uint64_t xorshift64 ( struct xorshift64_state * state ) { uint64_t x = state -> a ; x ^= x << 13 ; x ^ = x >> 7 ; x ^= x << 17 ; return state -> a = x ; }                     /* struct xorshift128_state может быть альтернативно определена как пара  uint64_t или uint128_t, где поддерживается */ struct xorshift128_state { uint32_t x [ 4 ]; };    /* Состояние должно быть инициализировано ненулевым значением */ uint32_t xorshift128 ( struct xorshift128_state * state ) { /* Алгоритм "xor128" со стр. 5 книги Марсалья "Xorshift RNGs" */ uint32_t t = state -> x [ 3 ]; uint32_t s = state -> x [ 0 ]; /* Выполнить искусственный 32-битный сдвиг. */ state -> x [ 3 ] = state -> x [ 2 ]; state -> x [ 2 ] = state -> x [ 1 ]; state -> x [ 1 ] = s ;                  t ^= t << 11 ; t ^= t >> 8 ; вернуть состояние -> x [ 0 ] = t ^ s ^ ( s >> 19 ); }                 

В случае одного 64-битного слова состояния существуют параметры, которые содержат период 2 64 −1 с двумя парами исключающего ИЛИ и сдвига. [4]

#include <stdint.h> struct xorshift64_state { uint64_t a ; };    uint64_t xorshift64 ( struct xorshift64_state * state ) { uint64_t x = state -> a ; x ^= x << 7 ; x ^= x >> 9 ; return state -> a = x ; }                 

Нелинейные вариации

Все генераторы xorshift не проходят некоторые тесты в тестовом наборе BigCrush . Это справедливо для всех генераторов, основанных на линейных рекуррентах, таких как Mersenne Twister или WELL . Однако легко перепутать выходные данные таких генераторов, чтобы улучшить их качество.

Скремблеры, известные как + и *, по-прежнему оставляют слабость в младших битах, [5] поэтому они предназначены для использования с плавающей точкой, где младшие биты чисел с плавающей точкой оказывают меньшее влияние на интерпретируемое значение. [6] Для общего назначения скремблер ** (произносится как старстар ) заставляет генераторы LFSR передавать все биты.

xorwow

Марсалья предложил скремблировать вывод, объединив его с простым аддитивным счетчиком по модулю 2 32 (который он называет « последовательностью Вейля » в честь теоремы Вейля о равнораспределении ). Это также увеличивает период в 2 32 раза , до 2 192 −2 32 :

#include <stdint.h> struct xorwow_state { uint32_t x [ 5 ]; uint32_t счетчик ; };      /* Массив состояний должен быть инициализирован так, чтобы в первых четырех словах не было всех нулей */ uint32_t xorwow ( struct xorwow_state * state ) { /* Алгоритм "xorwow" со стр. 5 книги Марсальи "Xorshift RNGs" */ uint32_t t = state -> x [ 4 ]; uint32_t s = state -> x [ 0 ]; /* Выполнить искусственный 32-битный поворот. */ state -> x [ 4 ] = state -> x [ 3 ]; state -> x [ 3 ] = state -> x [ 2 ]; state -> x [ 2 ] = state -> x [ 1 ]; state -> x [ 1 ] = s ; t ^= t >> 2 ; t ^ = t << 1 ; t ^= s ^ ( s << 4 ); состояние -> x [ 0 ] = t ; состояние -> счетчик += 362437 ; возврат t + состояние -> счетчик ; }                                                      

Это работает хорошо, но не проходит несколько тестов в BigCrush. [7] Этот генератор используется по умолчанию в наборе инструментов CUDA от Nvidia . [8]

xorshift*

Генератор xorshift* применяет обратимое умножение (по модулю размера слова) в качестве нелинейного преобразования к выходным данным генератора xorshift , как предложил Марсалья. [1] Все генераторы xorshift* выдают последовательность значений, которая равномерно распределена в максимально возможном измерении (за исключением того, что они никогда не выведут ноль для 16 вызовов, т. е. 128 байтов подряд). [9]

Следующий 64-битный генератор имеет максимальный период 2 64 −1. [9]

#include <stdint.h> /* xorshift64s, вариант A_1(12,25,27) с множителем M_32 из строки 3 таблицы 5 */ uint64_t xorshift64star ( void ) { /* начальное семя должно быть ненулевым, не используйте статическую переменную для состояния, если многопоточность */ static uint64_t x = 1 ; x ^= x >> 12 ; x ^= x << 25 ; x ^= x >> 27 ; return x * 0x2545F4914F6CDD1DULL ; }                           

Генератор не проходит только тест MatrixRank BigCrush, однако если генератор модифицировать так, чтобы он возвращал только старшие 32 бита, то он проходит BigCrush без сбоев. [10] : 7  Фактически, сокращенная версия, имеющая только 40 бит внутреннего состояния, проходит тест, что предполагает большой запас прочности. [10] : 19  Похожий генератор, предложенный в Numerical Recipes [11] , также RanQ1не проходит тест BirthdaySpacings .

Вигна [9] предлагает следующий генератор xorshift1024* с 1024 битами состояния и максимальным периодом 2 1024 −1; однако он не всегда проходит BigCrush. [5] Поэтому xoshiro256** является гораздо лучшим вариантом.

#include <stdint.h> /* Состояние должно быть инициализировано так, чтобы в массиве был хотя бы один ненулевой элемент */ struct xorshift1024s_state { uint64_t x [ 16 ]; int index ; };    uint64_t xorshift1024s ( struct xorshift1024s_state * state ) { int index = state -> index ; uint64_t const s = state -> x [ index ++ ]; uint64_t t = state -> x [ index &= 15 ]; t ^= t << 31 ; // a t ^= t >> 11 ; // b -- Опять же, сдвиги и множители настраиваются t ^= s ^ ( s >> 30 ); // c state -> x [ index ] = t ; state -> index = index ; return t * 1181783497276652981ULL ; }                                    

xorshift+

Генератор xorshift+ может достигать на порядок меньшего количества сбоев, чем Mersenne Twister или WELL . Собственная реализация генератора xorshift+ на языке C, которая проходит все тесты из набора BigCrush, обычно может генерировать случайное число менее чем за 10 тактов на x86 благодаря конвейеризации инструкций . [12]

Вместо использования умножения можно использовать сложение как более быстрое нелинейное преобразование. Идея была впервые предложена Сайто и Мацумото (также ответственными за Mersenne Twister) в генераторе XSadd , который складывает два последовательных выхода базового генератора xorshift на основе 32-битных сдвигов. [13] Однако один из недостатков сложения последовательных выходов заключается в том, что, в то время как базовый генератор xorshift128 является 2-мерно равнораспределенным, генератор xorshift128+ является только 1-мерно равнораспределенным. [14]

XSadd имеет некоторые слабости в младших битах своего вывода; он не проходит несколько тестов BigCrush, когда выходные слова перевернуты. Чтобы исправить эту проблему, Vigna представила семейство xorshift+ , [14] основанное на 64-битных сдвигах. Генераторы xorshift+ , даже такие большие, как xorshift1024+ , демонстрируют некоторую обнаруживаемую линейность в младших битах своего вывода; [5] он проходит BigCrush, но не проходит, когда 32 младших бита используются в обратном порядке из каждого 64-битного слова. [5] Этот генератор является одним из самых быстрых генераторов, проходящих BigCrush. [12]

Следующий генератор xorshift128+ использует 128 бит состояния и имеет максимальный период 2 128 −1.

#include <stdint.h> struct xorshift128p_state { uint64_t x [ 2 ]; };    /* Состояние должно быть затравлено так, чтобы оно не было полностью равным нулю */ uint64_t xorshift128p ( struct xorshift128p_state * state ) { uint64_t t = state -> x [ 0 ]; uint64_t const s = state -> x [ 1 ]; state -> x [ 0 ] = s ; t ^= t << 23 ; // a t ^= t >> 18 ; // b -- Опять же, сдвиги и множители настраиваются t ^= s ^ ( s >> 5 ); // c state -> x [ 1 ] = t ; return t + s ; }                                

xorshiftr+

Генератор xorshiftr+ (r означает уменьшенный; читается как «xorshifter plus») в основном основан на xorshift+, но включает модификации, делающие его значительно быстрее (особенно на легких устройствах) и более успешным в тестах на случайность (включая набор TestU01 BigCrush) по сравнению с его предшественниками. [15] Это один из самых быстрых генераторов, прошедших все тесты в наборе TestU01 BigCrush. Как и xorshift+, собственная реализация генератора xorshiftr+ на языке C, которая проходит все тесты из набора BigCrush, обычно может генерировать случайное число менее чем за 10 тактов на x86 благодаря конвейеризации инструкций . [12] [15]

В отличие от xorshift+ , xorshiftr+ не возвращает сумму двух переменных, полученных из состояния с использованием шагов в стиле xorshift, а возвращает одну переменную с самой последней операцией в своем цикле; однако, он имеет сложение непосредственно перед возвратом значения, а именно в фазе корректировки начального числа для следующего цикла; отсюда и "+" в названии алгоритма. Размеры переменных, включая состояние, можно увеличивать без ущерба для оценок случайности, но на легких устройствах могут наблюдаться падения производительности.

Следующий генератор xorshiftr128+ использует 128 бит состояния (с двумя переменными) и имеет максимальный период 2 128 −1.

#include <stdint.h> struct xorshiftr128plus_state { uint64_t s [ 2 ]; // семена };     /* Состояние должно быть заполнено так, чтобы оно не было полностью равным нулю */ uint64_t xorshiftr128plus ( struct xorshiftr128plus_state * state ) { uint64_t x = state -> s [ 0 ]; uint64_t const y = state -> s [ 1 ]; state -> s [ 0 ] = y ; x ^= x << 23 ; // shift & xor x ^= x >> 17 ; // shift & xor x ^= y ; // xor state -> s [ 1 ] = x + y ; return x ; }                               

хоширо

xoshiro (сокращение от "xor, shift, rotate") и xoroshiro (сокращение от "xor, rotate, shift, rotate") используют вращения в дополнение к сдвигам. По словам Виньи, они быстрее и производят более качественный вывод, чем xorshift. [16] [17]

Этот класс генераторов имеет варианты для 32- и 64-битного целочисленного и плавающего вывода; для плавающей точки берутся верхние 53 бита (для binary64 ) или верхние 23 бита (для binary32 ), поскольку верхние биты имеют лучшее качество, чем нижние биты в генераторах с плавающей точкой. Алгоритмы также включают jumpфункцию, которая устанавливает состояние вперед на некоторое количество шагов — обычно степень двойки, что позволяет многим потокам выполнения начинаться с различных начальных состояний.

Для 32-битного вывода xoshiro128** и xoshiro128+ полностью эквивалентны xoshiro256** и xoshiro256+, с uint32_t вместо uint64_t и с другими константами сдвига/вращения.

Совсем недавно генераторы xoshiro++ были созданы как альтернатива генераторам xoshiro** . Они используются в некоторых реализациях компиляторов Fortran, таких как GNU Fortran, Java и Julia . [18]

xoshiro256++

xoshiro256++ — это универсальный генератор случайных 64-битных чисел.

/* Адаптировано из кода, размещенного на сайте Себастьяно Виньи */#include <stdint.h> uint64_t rol64 ( uint64_t x , int k ) { return ( x << k ) | ( x >> ( 64 - k )); }              структура xoshiro256pp_state { uint64_t s [ 4 ]; };   uint64_t xoshiro256pp ( struct xoshiro256pp_state * state ) { uint64_t * s = state -> s ; uint64_t const result = rol64 ( s [ 0 ] + s [ 3 ], 23 ) + s [ 0 ]; uint64_t const t = s [ 1 ] << 17 ;                      с [ 2 ] ^= с [ 0 ]; с [ 3 ] ^= с [ 1 ]; с [ 1 ] ^= с [ 2 ]; с [ 0 ] ^= с [ 3 ];        с [ 2 ] ^= т ; с [ 3 ] = рол64 ( с [ 3 ], 45 );     вернуть результат ; } 

xoshiro256**

xoshiro256** использует умножение, а не сложение в своей выходной функции. Однако стоит отметить, что выходная функция обратима, что позволяет тривиально раскрыть базовое состояние. [19] Она используется в компиляторе GNU Fortran , Lua (начиная с Lua 5.4) и .NET Framework (начиная с .NET 6.0). [18]

/* Адаптировано из кода, размещенного на сайте Себастьяно Виньи */#include <stdint.h> uint64_t rol64 ( uint64_t x , int k ) { return ( x << k ) | ( x >> ( 64 - k )); }              структура xoshiro256ss_state { uint64_t s [ 4 ]; };   uint64_t xoshiro256ss ( struct xoshiro256ss_state * state ) { uint64_t * s = state -> s ; uint64_t const result = rol64 ( s [ 1 ] * 5 , 7 ) * 9 ; uint64_t const t = s [ 1 ] << 17 ;                      с [ 2 ] ^= с [ 0 ]; с [ 3 ] ^= с [ 1 ]; с [ 1 ] ^= с [ 2 ]; с [ 0 ] ^= с [ 3 ];        с [ 2 ] ^= т ; с [ 3 ] = рол64 ( с [ 3 ], 45 );     вернуть результат ; } 

xoshiro256+

xoshiro256+ примерно на 15% быстрее, чем xoshiro256**, но три младших бита имеют низкую линейную сложность; поэтому его следует использовать только для результатов с плавающей точкой, извлекая старшие 53 бита.

#include <stdint.h> uint64_t rol64 ( uint64_t x , int k ) { return ( x << k ) | ( x >> ( 64 - k )); }              структура xoshiro256p_state { uint64_t s [ 4 ]; };   uint64_t xoshiro256p ( struct xoshiro256p_state * state ) { uint64_t * s = state -> s ; uint64_t const result = s [ 0 ] + s [ 3 ]; uint64_t const t = s [ 1 ] << 17 ;                   с [ 2 ] ^= с [ 0 ]; с [ 3 ] ^= с [ 1 ]; с [ 1 ] ^= с [ 2 ]; с [ 0 ] ^= с [ 3 ];        с [ 2 ] ^= т ; с [ 3 ] = рол64 ( с [ 3 ], 45 );     вернуть результат ; } 

ксороширо

Если пространство в дефиците, xoroshiro128** и xoroshiro128+ эквивалентны xoshiro256** и xoshiro256+. Они имеют меньшие пространства состояний и, таким образом, менее полезны для программ с массовым параллелизмом. xoroshiro128+ также демонстрирует слабую зависимость в подсчете популяции , генерируя сбой после5  ТБ вывода. Авторы не считают, что это может быть обнаружено в реальных программах. Вместо того, чтобы увековечить традицию Марсальиxorshiftкак основная операция,xoroshiro128+использует линейное преобразование на основе сдвига/вращения, разработанное Себастьяно Винья в сотрудничестве с Дэвидом Блэкманом. Результатом является значительное улучшение скорости и статистического качества. [20]

xoroshiro64** и xoroshiro64* эквивалентны xoroshiro128** и xoroshiro128+. В отличие от генераторов xoshiro, они не являются прямыми портами своих более точных аналогов.

Статистическое качество

Самые младшие биты выходных данных, сгенерированныхxoroshiro128+имеют низкое качество. Авторыxoroshiro128+признать, что он не проходит все статистические тесты, заявив,

Это xoroshiro128+ 1.0, наш лучший и самый быстрый генератор малых состояний для чисел с плавающей точкой. Мы предлагаем использовать его верхние биты для генерации чисел с плавающей точкой, так как он немного быстрее, чем xoroshiro128**. Он проходит все известные нам тесты, за исключением четырех нижних битов, которые могут не пройти тесты на линейность (и только их), поэтому, если низкая линейная сложность не считается проблемой (как это обычно и бывает), его можно использовать для генерации 64-битных выходов; более того, этот генератор имеет очень слабую зависимость от веса Хэмминга, из-за чего наш тест (http://prng.di.unimi.it/hwd.php) терпит неудачу после 5 ТБ выходных данных; мы считаем, что это небольшое смещение не может повлиять ни на одно приложение. Если вас это беспокоит, используйте xoroshiro128** или xoshiro256+.

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

Состояние должно быть засеяно так, чтобы оно не было везде нулевым. Если у вас есть 64-битное засеивание, мы предлагаем засеять генератор splitmix64 и использовать его вывод для заполнения s.

ПРИМЕЧАНИЕ: параметры (a=24, b=16, c=37) этой версии немного отличаются

лучшие результаты в нашем тесте, чем в версии 2016 года (a=55, b=14, c=36). [21]

Эти утверждения о непрохождении тестов можно подтвердить, запустив PractRand на входе, что приведет к выводу, подобному показанному ниже:

RNG_test с использованием PractRand версии 0.93ГСЧ = RNG_stdin64, начальное число = 0xfac83126тестовый набор = нормальный, сворачивание = стандартный (64 бит)rng=RNG_stdin64, seed=0xfac83126длина= 128 мегабайт (2^27 байт), время= 2,1 секунды Название теста Оценка сырого обработанного [Low1/64]BRank(12):256(2) R= +3748 p~= 3e-1129 FAIL !!!!!!!!  [Low1/64]BRank(12):384(1) R= +5405 p~= 3e-1628 FAIL !!!!!!!!  ...и 146 результатов тестов без аномалий

Признавая это, авторы продолжают:

Мы предлагаем использовать знаковый тест для извлечения случайного булевого значения [21]

Таким образом, программисты должны предпочесть самые высокие биты (например, создание орла/решки путем записи, random_number < 0а не random_number & 1). Следует отметить, однако, что тот же тест не проходит некоторые экземпляры Mersenne Twister и WELL .

Статистические проблемы выходят далеко за рамки нескольких нижних битов, поскольку он не проходит тест PractRand даже при усечении [22] и не проходит несколько тестов в BigCrush даже при обратном порядке битов. [23]

Инициализация

В статье xoshiro рекомендуется инициализировать состояние генераторов с помощью генератора, который радикально отличается от инициализированных генераторов, а также генератора, который никогда не даст состояние «все нули»; для генераторов на основе сдвиговых регистров из этого состояния невозможно выйти. [17] [24] Авторы специально рекомендуют использовать генератор SplitMix64 из 64-битного начального числа следующим образом:

#include <stdint.h> struct splitmix64_state { uint64_t s ; };   uint64_t splitmix64 ( struct splitmix64_state * state ) { uint64_t result = ( state -> s += 0x9E3779B97f4A7C15 ); result = ( result ^ ( result >> 30 )) * 0xBF58476D1CE4E5B9 ; result = ( result ^ ( result >> 27 )) * 0x94D049BB133111EB ; return result ^ ( result >> 31 ); }                              struct xorshift128_state { uint32_t x [ 4 ]; };    // то же самое можно сделать для любого другого генератора void xorshift128_init ( struct xorshift128_state * state , uint64_t seed ) { struct splitmix64_state smstate = { seed };          uint64_t tmp = splitmix64 ( & smstate ); состояние -> x [ 0 ] = ( uint32_t ) tmp ; состояние -> x [ 1 ] = ( uint32_t )( tmp >> 32 );         tmp = splitmix64 ( & smstate ); состояние -> x [ 2 ] = ( uint32_t ) tmp ; состояние -> x [ 3 ] = ( uint32_t )( tmp >> 32 ); }        

Смотрите также

Примечания

  1. ^ В языке C и большинстве других языков на основе C ^представляет собой побитовое исключающее ИЛИ , а <<и >>представляет собой побитовые сдвиги .

Ссылки

  1. ^ abc Marsaglia, George (июль 2003 г.). "Xorshift RNGs". Журнал статистического программного обеспечения . 8 (14). doi : 10.18637/jss.v008.i14 .
  2. ^ Брент, Ричард П. (август 2004 г.). «Заметка о генераторах случайных чисел Xorshift Марсальи». Журнал статистического программного обеспечения . 11 (5). doi : 10.18637/jss.v011.i05 . hdl : 1885/34049 .
  3. ^ ab Panneton, François; L'Ecuyer, Pierre (октябрь 2005 г.). «О генераторах случайных чисел xorshift» (PDF) . ACM Transactions on Modeling and Computer Simulation . 15 (4): 346–361. doi :10.1145/1113316.1113319. S2CID  11136098.
  4. ^ 和田維作. "良い乱数・悪い乱数" . Проверено 28 августа 2023 г.Параметры только (7,9) и (9,7).
  5. ^ abcd Lemire, Daniel; O'Neill, Melissa E. (апрель 2019 г.). «Xorshift1024*, Xorshift1024+, Xorshift128+ и Xoroshiro128+ не проходят статистические тесты на линейность». Computational and Applied Mathematics . 350 : 139–142. arXiv : 1810.05313 . doi :10.1016/j.cam.2018.10.019. S2CID  52983294. Мы сообщаем, что эти скремблированные генераторы систематически не проходят Big Crush — в частности, тесты линейной сложности и ранга матрицы, которые обнаруживают линейность — при взятии 32 младших битов в обратном порядке из каждого 64-битного слова.
  6. ^ "ИСО/МЭК 60559:2020". ИСО .
  7. ^ Le Floc'h, Fabien (12 января 2011 г.). "Результаты XORWOW L'ecuyer TestU01". Chase The Devil (блог) . Получено 2017-11-02 .
  8. ^ "Тестирование cuRAND". Nvidia . Получено 2017-11-02 .
  9. ^ abc Винья, Себастьяно (июль 2016 г.). «Экспериментальное исследование генераторов ксоршифта Марсальи, скрамблированное» (PDF) . ACM Transactions on Mathematical Software . 42 (4): 30. arXiv : 1402.6246 . doi :10.1145/2845077. S2CID  13936073. Предлагает генераторы xorshift*, добавляющие конечное умножение на константу.
  10. ^ ab O'Neill, Melissa E. (5 сентября 2014 г.). PCG: Семейство простых быстрых и эффективных по объему статистически хороших алгоритмов для генерации случайных чисел (PDF) (Технический отчет). Harvey Mudd College . С. 6–8. HMC-CS-2014-0905.
  11. ^ Press, WH ; Teukolsky, SA ; Vetterling, WT; Flannery, BP (2007). "Раздел 7.1.2.A. 64-битный метод Xorshift". Numerical Recipes: The Art of Scientific Computing (3-е изд.). Нью-Йорк: Cambridge University Press. ISBN 978-0-521-88068-8.
  12. ^ abc Винья, Себастьяно. "xorshift*/xorshift+ генераторы и перестрелка PRNG" . Получено 25.10.2014 .
  13. ^ Сайто, Муцуо; Мацумото, Макото (2014). "XORSHIFT-ADD (XSadd): вариант XORSHIFT" . Получено 25 октября 2014 г.
  14. ^ ab Vigna, Sebastiano (май 2017 г.). «Дальнейшие скрамблинги генераторов ксоршифта Марсальи» (PDF) . Журнал вычислительной и прикладной математики . 315 (C): 175–181. arXiv : 1404.0390 . doi :10.1016/j.cam.2016.11.006. S2CID  6876444. Описывает генераторы xorshift+, обобщение XSadd.
  15. ^ аб Чабук, Умут Джан; Айдын, Омер; Далкилич, Гекхан (2017). «Генератор случайных чисел для облегченных протоколов аутентификации: xorshiftR+». Турецкий журнал электротехники и компьютерных наук . 25 : 4818–4828. дои : 10.3906/elk-1703-361.
  16. ^ Винья, Себастьяно. "генераторы xoshiro/xoroshiro и перестрелка PRNG" . Получено 07.07.2019 .
  17. ^ ab Блэкман, Дэвид; Винья, Себастьяно (2018). "Генератор псевдослучайных чисел с зашифрованными линейными числами". Структуры данных и алгоритмы . arXiv : 1805.01407 .
  18. ^ ab "xoshiro / xoroshiro generators and the PRNG shootout" . Получено 2023-09-07 .
  19. ^ О'Нил, ME (2018-05-05). "Быстрый взгляд на Xoshiro256**". PCG, Лучший генератор случайных чисел . Получено 2024-10-04 .
  20. ^ Блэкман, Дэвид; Винья, Себастьяно (2018). «Скремблированные линейные псевдослучайные генераторы». arXiv : 1805.01407 [cs.DS].
  21. ^ ab Blackman, David; Vigna, Sebastiano (2018). "Оригинальная реализация исходного кода C xoroshiro128+" . Получено 4 мая 2018 г. .
  22. ^ "xoroshiro не проходит PractRand при усечении". 2020 . Получено 30 декабря 2020 г.
  23. ^ "Генератор случайных чисел Xorshift128+ не справляется с BigCrush". 2020 . Получено 30 декабря 2020 г.
  24. ^ Мацумото, Макото; Вада, Исаку; Курамото, Ай; Ашихара, Хё (сентябрь 2007 г.). «Распространённые дефекты инициализации генераторов псевдослучайных чисел». Труды ACM по моделированию и компьютерному моделированию . 17 (4): 15–es. doi :10.1145/1276927.1276928. S2CID  1721554.

Дальнейшее чтение

Внешние ссылки