MATLAB ® включает алгоритмы генератора, которые позволяют вам создавать несколько независимых потоков случайных чисел. Для примера четыре типа генераторов, которые поддерживают несколько независимых потоков, являются Комбинированными Несколькими Рекурсивными ('mrg32k3a'
), мультипликативный Lagged Fibonacci ('mlfg6331_64'
), Philox 4x32 ('philox4x32_10
'), и трехфазный 4x64 (' threefry4x64_20
') генераторы. Можно создать несколько независимых потоков, которые гарантированно не перекрываются, и для которых были проведены тесты, которые демонстрируют (псевдослучайную) независимость значений между потоками. Для получения дополнительной информации об алгоритмах генератора, которые поддерживают несколько потоков, смотрите таблицу алгоритмов генератора в Создании и управлении потоком случайных чисел .
The RandStream.create
функция позволяет вам создавать потоки, которые имеют один и тот же алгоритм генератора и начальное значение, но являются статистически независимыми.
[s1,s2,s3] = RandStream.create('mlfg6331_64','NumStreams',3)
s1 = mlfg6331_64 random stream StreamIndex: 1 NumStreams: 3 Seed: 0 NormalTransform: Ziggurat
s2 = mlfg6331_64 random stream StreamIndex: 2 NumStreams: 3 Seed: 0 NormalTransform: Ziggurat
s3 = mlfg6331_64 random stream StreamIndex: 3 NumStreams: 3 Seed: 0 NormalTransform: Ziggurat
Как свидетельство независимости, можно увидеть, что эти потоки в значительной степени некоррелированы.
r1 = rand(s1,100000,1); r2 = rand(s2,100000,1); r3 = rand(s3,100000,1); corrcoef([r1,r2,r3])
ans = 3×3
1.0000 0.0007 0.0052
0.0007 1.0000 0.0000
0.0052 0.0000 1.0000
В зависимости от приложения, создание только некоторых потоков в наборе независимых потоков может быть полезным, если нужно симулировать некоторые события. Задайте StreamIndices
параметр для создания только некоторых потоков из набора из нескольких потоков. The StreamIndex
свойство возвращает индекс каждого создаваемого вами потока.
numLabs = 256; labIndex = 4; s4 = RandStream.create('mlfg6331_64','NumStreams',numLabs,'StreamIndices',labIndex)
s4 = mlfg6331_64 random stream StreamIndex: 4 NumStreams: 256 Seed: 0 NormalTransform: Ziggurat
Несколько потоков, поскольку они являются статистически независимыми, могут использоваться, чтобы проверить точность симуляции. Например, набор независимых потоков может использоваться, чтобы повторить симуляцию Монте-Карло несколько раз в различных сеансах работы с MATLAB или на разных процессорах и определить отклонение в результатах. Это делает несколько потоков полезными в крупномасштабных параллельных симуляциях.
Для типов генераторов, которые явно не поддерживают независимые потоки, различные начальные значения обеспечивают метод для создания нескольких потоков. При помощи различных семян можно создать потоки, которые возвращают различные значения и действуют отдельно друг от друга. Однако использование генератора, специально разработанного для нескольких независимых потоков, является лучшей опцией, поскольку статистические свойства между потоками были тщательно проверены.
Создайте два потока с различными семенами с помощью генератора случайных чисел Вихрь Мерсенна.
s1 = RandStream('mt19937ar','Seed',1)
s1 = mt19937ar random stream Seed: 1 NormalTransform: Ziggurat
s2 = RandStream('mt19937ar','Seed',2)
s2 = mt19937ar random stream Seed: 2 NormalTransform: Ziggurat
Используйте первый поток в одном сеансе работы с MATLAB, чтобы сгенерировать случайные числа.
r1 = rand(s1,100000,1);
Используйте второй поток в другом сеансе работы с MATLAB, чтобы сгенерировать случайные числа.
r2 = rand(s2,100000,1);
С различными семенами потоки обычно возвращают значения, которые являются некоррелированными.
corrcoef([r1,r2])
ans = 2×2
1.0000 0.0030
0.0030 1.0000
Два потока с различными семенами могут показаться некоррелированными, поскольку пространство состояний Вихря Мерсенна намного больше ( элементы), чем количество возможных семян (). Шансы перекрытия в различных запусках симуляции довольно отдалены, если вы не используете большое количество различных семян. Использование широко расставленных семян не увеличивает уровень случайности. Фактически, приведение этой стратегии к крайнему значению и повторная подача генератора перед каждым вызовом может привести к последовательности значений, которые не являются статистически независимыми и идентично распределенными.
Посев потока наиболее полезен, если вы используете его как шаг инициализации, возможно, при запуске MATLAB или перед запуском симуляции.
Другой метод получения различных результатов от потока - это использование субпотоков. В отличие от семян, где местоположения вдоль последовательности случайных чисел точно не известны, интервал между субпотоками известен, поэтому любая вероятность перекрытия может быть исключена. Как и независимые параллельные потоки, исследования были проведены, чтобы продемонстрировать статистическую независимость между субпотоками. Короче говоря, субпотоки являются более контролируемым способом сделать многие из тех же вещей, для которых традиционно использовались семена, и более легким решением, чем параллельные потоки.
Субпотоки обеспечивают быстрый и легкий способ гарантировать, что вы получаете различные результаты от одного и того же кода в разное время. Для примера сгенерируйте несколько случайных чисел в цикле.
defaultStream = RandStream('mlfg6331_64'); RandStream.setGlobalStream(defaultStream) for i = 1:5 defaultStream.Substream = i; z = rand(1,i) end
z = 0.6986
z = 1×2
0.9230 0.2489
z = 1×3
0.0261 0.2530 0.0737
z = 1×4
0.3220 0.7405 0.1983 0.1052
z = 1×5
0.2067 0.2417 0.9777 0.5970 0.4187
В другом цикле можно сгенерировать случайные значения, которые не зависят от первого набора из 5 итераций.
for i = 6:10 defaultStream.Substream = i; z = rand(1,11-i) end
z = 1×5
0.2650 0.8229 0.2479 0.0247 0.4581
z = 1×4
0.3963 0.7445 0.7734 0.9113
z = 1×3
0.2758 0.3662 0.7979
z = 1×2
0.6814 0.5150
z = 0.5247
Каждый из этих субпотоков может воспроизводить свои итерации цикла. Для примера можно вернуться к 6-му субпотоку в цикле.
defaultStream.Substream = 6; z = rand(1,5)
z = 1×5
0.2650 0.8229 0.2479 0.0247 0.4581