RandStream класс позволяет создать поток случайных чисел. Это полезно по нескольким причинам:
Можно создавать случайные значения, не влияя на состояние глобального потока.
В моделировании можно разделить источники случайности.
Можно использовать генератор, настроенный иначе, чем тот, который используется программным обеспечением MATLAB ® при запуске.
С помощью RandStream можно создать собственный поток, задать доступные для записи свойства и использовать поток для создания случайных чисел. Можно управлять создаваемым потоком так же, как и глобальным потоком. Можно даже заменить глобальный поток созданным потоком.
Чтобы создать поток, используйте RandStream функция.
myStream = RandStream('mlfg6331_64');
rand(myStream,1,5)ans =
0.6986 0.7413 0.4239 0.6914 0.7255Случайный поток myStream действует отдельно от глобального потока. Если вы вызываете rand, randn, randi, и randperm функции с myStream в качестве первого аргумента они черпают из созданного вами потока. При звонке rand, randn, randi, и randperm без myStreamони черпают из глобального потока.
Вы можете сделать myStream глобальный поток с использованием RandStream.setGlobalStream способ.
RandStream.setGlobalStream(myStream) RandStream.getGlobalStream
ans =
mlfg6331_64 random stream (current global stream)
Seed: 0
NormalTransform: Ziggurat
RandStream.getGlobalStream == myStream
ans =
1Субпотоки можно использовать для получения различных результатов, статистически независимых от потока. В отличие от начальных чисел, где местоположения вдоль последовательности случайных чисел точно не известны, расстояние между субпотоками известно, поэтому любая вероятность перекрытия может быть исключена. Короче говоря, субпотоки - это более контролируемый способ сделать то же самое, для чего традиционно использовались семена. Субпотоки также являются более легким решением, чем параллельные потоки.
Субпотоки обеспечивают быстрый и простой способ получения различных результатов из одного и того же кода в разное время. Для использования Substream свойство RandStream создайте поток с помощью генератора, поддерживающего субпотоки. Список алгоритмов генератора, поддерживающих субпотоки, и их свойства см. в таблице в следующем разделе. Например, создать несколько случайных чисел в цикле.
myStream = RandStream('mlfg6331_64'); RandStream.setGlobalStream(myStream) for i = 1:5 myStream.Substream = i; z = rand(1,i) end
z =
0.6986
z =
0.9230 0.2489
z =
0.0261 0.2530 0.0737
z =
0.3220 0.7405 0.1983 0.1052
z =
0.2067 0.2417 0.9777 0.5970 0.4187В другом цикле можно создать случайные значения, которые не зависят от первого набора из 5 итераций.
for i = 6:10 myStream.Substream = i; z = rand(1,11-i) end
z =
0.2650 0.8229 0.2479 0.0247 0.4581
z =
0.3963 0.7445 0.7734 0.9113
z =
0.2758 0.3662 0.7979
z =
0.6814 0.5150
z =
0.5247Субпотоки полезны при последовательном вычислении. Субпотоки могут воссоздавать все или часть моделирования, возвращаясь к определенной контрольной точке в потоке. Например, можно вернуться к 6-му подпотоку в цикле. Результат содержит те же значения, что и 6-й выход выше.
myStream.Substream = 6; z = rand(1,5)
z =
0.2650 0.8229 0.2479 0.0247 0.4581MATLAB предлагает несколько вариантов алгоритмов генератора. Таблица суммирует ключевые свойства доступных алгоритмов генератора и ключевые слова, используемые для их создания. Чтобы вернуть список всех доступных алгоритмов генератора, используйте RandStream.list способ.
| Ключевое слово | Генератор | Поддержка нескольких потоков и субпотоков | Приблизительный период с полной точностью |
|---|---|---|---|
mt19937ar | Мерсенн твистер (используется по умолчанию при запуске MATLAB) | Нет | 219937-1 |
dsfmt19937 | SIMD-ориентированный быстрый мерсеннский твистер | Нет | 219937-1 |
mcg16807 | Мультипликативный конгруэнтный генератор | Нет | 231-2 |
mlfg6331_64 | Мультипликативный отставший генератор Фибоначчи | Да | 2124 (251 поток длиной 272) |
mrg32k3a | Комбинированный множественный рекурсивный генератор | Да | 2191 (263 потока длиной 2127) |
philox4x32_10 | Генератор Philox 4x32 с 10 патронами | Да | 2193 (264 потока длиной 2129) |
threefry4x64_20 | Три генератора 4x64 с 20 патронами | Да | 2514 (2256 потоков длиной 2258) |
shr3cong | Генератор регистра сдвига, суммированный с линейным конгруэнтным генератором | Нет | 264 |
swb2712 | Модифицированное вычитание с помощью генератора заимствований | Нет | 21492 |
Генераторы mcg16807, shr3cong, и swb2712 обеспечивают обратную совместимость с более ранними версиями MATLAB. mt19937ar и dsfmt19937 предназначены главным образом для последовательного применения. Остальные генераторы обеспечивают явную поддержку генерации параллельных случайных чисел.
В зависимости от применения некоторые генераторы могут быть более быстрыми или возвращать значения с большей точностью. Все генераторы псевдослучайных чисел основаны на детерминированных алгоритмах, и все генераторы проходят достаточно специфический статистический тест на случайность. Одним из способов проверки результатов моделирования Монте-Карло является повторный запуск моделирования с помощью двух или более различных алгоритмов генератора, и выбор генераторов в MATLAB предоставляет средства для этого. Хотя маловероятно, что ваши результаты будут отличаться больше, чем ошибка выборки Монте-Карло при использовании различных генераторов, в литературе есть примеры, где такой вид проверки выявил недостатки в конкретном алгоритме генератора. (Пример см. в [13].)
mt19937arТвистер Мерсенна, как описано в [11], имеет период 1 и каждое значение U (0,1) создается с помощью двух 32-битных целых чисел. Возможные значения кратны − 53 в интервале (0, 1). Этот генератор не поддерживает несколько потоков или субпотоков . randn алгоритм, используемый по умолчанию для mt19937ar потоки - это алгоритм зиггурата [7], но с mt19937ar генератор внизу.
Примечание
Этот генератор идентичен генератору, используемому rand начиная с версии 7 MATLAB, активируется rand('twister',s).
dsfmt19937SIMD-ориентированный Fast Mersenne Twister с двойной точностью, как описано в [12], является более быстрой реализацией алгоритма Mersenne Twister. Период равен 1 и возможные значения кратны − 52 в интервале (0, 1). Генератор производит значения двойной точности в [1, 2) нативно, которые преобразуются для создания значений U (0,1). Этот генератор не поддерживает несколько потоков или субпотоков.
mcg1680732-битный мультипликативный конгруэнтный генератор, как описано в [14], с умножителем 75, 231 − 1. Этот генератор имеет 231 − 2 и не поддерживает несколько потоков или субпотоков. Каждое значение U (0,1) создается с использованием одного 32-разрядного целого числа из генератора; все возможные значения (231 − 1) − 1 строго в пределах интервала (0, 1). Дляmcg16807 streams, алгоритм по умолчанию, используемый randn - полярный алгоритм (описан в [1]).
Примечание
Этот генератор идентичен генератору, используемому начиная с MATLAB версии 4 обоими rand и randn функции, активированные с помощью rand('seed',s) или randn('seed',s).
mlfg6331_6464-битный мультипликативный генератор Фибоначчи, как описано в [10], с лагами 63= 31. Этот генератор аналогичен MLFG, реализованному в пакете SPRNG. Он имеет период 2124 года. Он поддерживает до 261 параллельного потока через параметризацию 251 субпоток длиной 272. Каждое значение U (0,1) создается с использованием одного 64-разрядного целого числа из генератора; все возможные значения 2 − 64 строго в пределах интервала (0, 1). randn алгоритм, используемый по умолчанию для mlfg6331_64 потоки - это алгоритм зиггурата [7], но с mlfg6331_64 генератор внизу.
mrg32k3a32-битный комбинированный множественный рекурсивный генератор, как описано в [2]. Этот генератор аналогичен CMRG, реализованному в пакете RngStreams в C. Он имеет период и поддерживает до параллельных потоков посредством разделения последовательностей, каждый длиной . Он также поддерживает субпоток, каждый длиной . Каждое значение U (0,1) создается с использованием двух 32-разрядных целых чисел из генератора; возможные значения кратны 53 строго в пределах интервала (0, 1). randn алгоритм, используемый по умолчанию для mrg32k3a потоки - это алгоритм зиггурата [7], но с mrg32k3a генератор внизу.
philox4x32_10Генератор 4x32 с 10 патронами, как описано в [15]. Этот генератор использует сеть Фейстеля и целочисленное умножение. Генератор специально разработан для высокопроизводительных систем с высокой параллельностью, таких как GPU. Имеет период 2193 (264 потока длиной 2129).
threefry4x64_20Генератор 4x64 с 20 патронами, как описано в [15]. Этот генератор представляет собой не криптографическую адаптацию блочного шифра Threefish из хеш-функции Скейна. Имеет период 2514 (2256 потоков длиной 2258).
shr3congSHR3 генератор регистра сдвига Марсальи суммировался с линейным конгруэнтным генератором с умножителем 69069, 1234567 и 2 − 32. SHR3 - генератор 3-сдвиговых регистров, I + R17) (I + L5), где I - оператор идентификации, L - оператор левого сдвига, а R - оператор правого сдвига. Комбинированный генератор (SHR3 часть описана в [7]) имеет период приблизительно 264. Этот генератор не поддерживает несколько потоков или субпотоков. Каждое значение U (0,1) создается с использованием одного 32-разрядного целого числа из генератора; все возможные значения кратны 2 − 32 строго в пределах интервала (0, 1). randn алгоритм, используемый по умолчанию для shr3cong потоки - это ранняя форма алгоритма зиггурата [9], но с shr3cong генератор внизу. Этот генератор идентичен генератору, используемому randn функция, начинающаяся в MATLAB версии 5, активируется с помощью randn('state',s).
swb2712Модифицированный генератор вычитания с заимствованием, как описано в [8]. Этот генератор подобен аддитивно-запаздывающему генератору Фибоначчи с лагами 27 и 12, но он модифицирован, чтобы иметь гораздо более длительный период приблизительно . Генератор работает с двойной точностью для создания значений U (0,1), и все значения в открытом интервале (0, 1) возможны. randn алгоритм, используемый по умолчанию для swb2712 потоки - это алгоритм зиггурата [7], но с swb2712 генератор внизу.
Примечание
Этот генератор идентичен генератору, используемому rand функция, начинающаяся в MATLAB версии 5, активируется с помощью rand('state',s).
InversionВычисляет нормальную случайную переменную, применяя стандартную нормальную функцию обратного кумулятивного распределения к однородной случайной вариации. На нормальное значение расходуется ровно одно однородное значение.
PolarАлгоритм полярного отклонения, как описано в [1]. В среднем на нормальное значение расходуется примерно 1,27 однородных значений.
ZigguratАлгоритм зиггурата, как описано в [7]. Приблизительно 2,02 однородных значения расходуются на нормальное значение в среднем.
Поток случайных чисел s имеет свойства, управляющие его поведением. Для доступа к свойству или его изменения используйте синтаксис p = s.Property и s.Property = p.
Например, можно настроить алгоритм преобразования для генерации нормально распределенных псевдослучайных значений при использовании randn. Создание нормально распределенных псевдослучайных значений по умолчанию Ziggurat алгоритм преобразования.
s1 = RandStream('mt19937ar');
s1.NormalTransformans = 'Ziggurat'
r1 = randn(s1,1,10);
Сконфигурируйте поток для использования Polar алгоритм преобразования для генерации нормально распределенных псевдослучайных значений.
s1.NormalTransform = 'Polar's1 =
mt19937ar random stream
Seed: 0
NormalTransform: Polarr2 = randn(s1,1,10);
При генерации случайных чисел с равномерным распределением с использованием rand, также можно настроить поток для генерации антитетических псевдослучайных значений, то есть обычных значений, вычитаемых из 1 для однородных значений.
Создайте 6 случайных чисел с равномерным распределением из потока s.
s2 = RandStream('mt19937ar');
r1 = rand(s2,1,6)r1 =
0.8147 0.9058 0.1270 0.9134 0.6324 0.0975Восстановите исходное состояние потока. Создайте еще 6 случайных чисел с помощью Antithetic свойство имеет значение true. Проверьте, что эти 6 случайных чисел равны ранее сгенерированным случайным числам, вычитаемым из 1.
reset(s2) s2.Antithetic = true; r2 = rand(s2,1,6)
r2 =
0.1853 0.0942 0.8730 0.0866 0.3676 0.9025isequal(r1,1 - r2)
ans = 1
Вместо настройки свойств потока поочередно можно сохранить и восстановить все свойства потока. s с помощью A = get(s) и set(s,A)соответственно. Например, настройте все свойства потока s2 быть таким же, как поток s1.
A = get(s1)
A =
Type: 'mt19937ar'
NumStreams: 1
StreamIndex: 1
Substream: 1
Seed: 0
State: [625x1 uint32]
NormalTransform: 'Polar'
Antithetic: 0
FullPrecision: 1set(s2,A)
Type: 'mt19937ar'
NumStreams: 1
StreamIndex: 1
Substream: 1
Seed: 0
State: [625x1 uint32]
NormalTransform: 'Polar'
Antithetic: 0
FullPrecision: 1 get и set функции позволяют сохранять и восстанавливать всю конфигурацию потока так, чтобы результаты были точно воспроизводимы позже.
State свойство - внутреннее состояние генератора случайных чисел. Состояние глобального потока можно сохранить в определенный момент моделирования при генерации случайных чисел для последующего воспроизведения результатов.
Использовать RandStream.getGlobalStream для возврата дескриптора к глобальному потоку, то есть текущему глобальному потоку, rand генерирует случайные числа из. Сохраните состояние глобального потока.
globalStream = RandStream.getGlobalStream; myState = globalStream.State;
Используя myState, можно восстановить состояние globalStream и воспроизводят предыдущие результаты.
A = rand(1,100); globalStream.State = myState; B = rand(1,100); isequal(A,B)
ans = logical 1
rand, randi, randn, и randperm получить доступ к глобальному потоку. Поскольку все эти функции имеют доступ к одному и тому же базовому потоку, вызов одной из них влияет на значения, создаваемые другими при последующих вызовах.
globalStream.State = myState; A = rand(1,100); globalStream.State = myState; C = randi(100); B = rand(1,100); isequal(A,B)
ans = logical 0
Также можно сбросить начальные настройки потока с помощью reset функция.
reset(globalStream) A = rand(1,100); reset(globalStream) B = rand(1,100); isequal(A,B)
ans = logical 1
[1] Девройе, L. Поколение неоднородных случайных вариаций, Springer-Verlag, 1986.
[2] L'Ecuyer, P «Хорошие наборы параметров для комбинированных множественных генераторов рекурсивных случайных чисел», Operations Research, 47 (1): 159-164. 1999.
[3] Л'Эквадер, П. и С. Коте. «Реализация пакета случайных чисел с разделительными средствами», ACM Transactions on Mathematical Software, 17: 98-111. 1991.
[4] Л'Эквадер, П. и Р. Симард. «TestU01: Библиотека C для эмпирического тестирования генераторов случайных чисел», ACM Transactions on Mathematical Software, 33 (4): Article 22. 2007.
[5] Л'Эквадер, П., Р. Симард, Э. Дж. Чен и У. Д. Келтон. «Объектно-ориентированный пакет случайных чисел с множеством длинных потоков и субпотоков». Исследование операций, 50 (6): 1073-1075. 2002.
[6] Марсалья, Г. «Случайные числа для C: The END?» Публикация Usenet на sci.stat.math. 1999. Доступно в Интернете по адресу https://groups.google.com/group/sci.crypt/browse_thread/.
thread/ca8682a4658a124d/
[7] Марсалья Г., и У. В. Цанг. «Метод зиггурата для генерации случайных величин». Журнал статистического программного обеспечения, 5: 1-7. 2000. Доступно в Интернете по адресуhttps://www.jstatsoft.org/v05/i08.
[8] Марсалья, Г. и А. Заман. «Новый класс генераторов случайных чисел». Анналы прикладной вероятности 1 (3): 462-480. 1991.
[9] Марсалья, Г. и В. В. Цанг. «Быстрый, легко реализуемый метод выборки из убывающих или симметричных унимодальных функций плотности». SIAM J. Sci. Stat. Comput. 5(2):349–359. 1984.
[10] Масканьи, М. и А. Шринивасан. «Параметризация параллельных мультипликативных генераторов с отставанием Фибоначчи». Параллельные вычисления, 30: 899-916. 2004.
[11] Мацумото, М., и Т. Нисимура. «Mersenne Twister: A 623-Dimensionally Equiddisted Uniform Pseudorandom Number Generator». Транзакции ACM по моделированию и компьютерному моделированию, 8 (1): 3-30. 1998.
[12] Мацумото, М. и М. Сайто. «PRNG, специализированный на двойных точных числах с плавающей запятой с использованием аффинного перехода». Методы Монте-Карло и Квази-Монте-Карло 2008, 10.1007/978-3-642-04107-5_38. 2009.
[13] Молер, С.Б. Численные вычисления с MATLAB. СИАМ, 2004. Доступно в Интернете по адресу https://www.mathworks.com/moler
[14] Парк, С.К. и К.В. Миллер. «Генераторы случайных чисел: Хорошие трудно найти». Связь ACM, 31 (10): 1192-1201. 1998.
[15] Лосось, Дж. К., М. А. Мораес, Р. О. Дрор и Д. Э. Шоу. «Параллельные случайные числа: так легко, как 1, 2, 3». В трудах Международной конференции по высокопроизводительным вычислениям, сетям, хранению и анализу (SC11). Нью-Йорк, Нью-Йорк: ACM, 2011.