Этот пример показывает, как использовать функцию rng
, которая обеспечивает управление генерацией случайных чисел.
(Псевдо) Случайные числа в MATLAB прибывают из rand
, randi
и функций randn
. Много других функций вызывают те три, но те - основные стандартные блоки. Все три зависят от единственного разделяемого генератора случайных чисел, что можно управлять использованием rng
.
Важно понять, что "случайные" числа в MATLAB весьма предсказуемы вообще, но сгенерированы детерминированным алгоритмом. Алгоритм разработан, чтобы быть достаточно сложным так, чтобы его вывод, казалось, был независимой случайной последовательностью кому-то, кто не знает алгоритм и может пройти различные статистические тесты случайности. Функция, которая представлена здесь, обеспечивает способы использовать в своих интересах детерминизм к
повторите вычисления, которые включают случайные числа и получают те же результаты, или
гарантируйте, что различные случайные числа используются в повторных вычислениях
и использовать в своих интересах очевидную случайность, чтобы выровнять по ширине объединяющиеся результаты отдельных вычислений.
Если вы посмотрите на вывод от rand
, randi
или randn
в новом сеансе работы с MATLAB, вы заметите, что они возвращают те же последовательности чисел каждый раз, когда вы перезапускаете MATLAB. Часто полезно смочь сбросить генератор случайных чисел к тому состоянию запуска, на самом деле не перезапуская MATLAB. Например, вы можете хотеть повторить вычисление, которое включает случайные числа, и получите тот же результат.
rng
обеспечивает очень простой способ отложить генератор случайных чисел к его настройкам по умолчанию.
rng default rand % returns the same value as at startup
ans = 0.8147
Каковы настройки случайных чисел "по умолчанию", которые MATLAB запускает с, или который rng default
дает вам? Если вы вызываете rng
без входных параметров, вы видите, что это - алгоритм Генератора случайных чисел Вихрь Мерсенна, отобранный с 0.
rng
ans = struct with fields:
Type: 'twister'
Seed: 0
State: [625x1 uint32]
Вы будете видеть более подробно ниже, как использовать вышеупомянутый вывод, включая поле State
, чтобы управлять и измениться, как MATLAB генерирует случайные числа. На данный момент это служит способом видеть, какой генератор rand
, randi
и randn
в настоящее время используют.
Каждый раз, когда вы вызываете rand
, randi
или randn
, они чертят новое значение от своего разделяемого генератора случайных чисел, и последовательные значения могут быть обработаны как статистически независимые. Но, как упомянуто выше, каждый раз, когда вы перезапускаете MATLAB, те функции сбрасываются и возвращают те же последовательности чисел. Очевидно, вычисления, которые используют те же "случайные" числа, не могут думаться как статистически независимые. Таким образом, когда необходимо объединить вычисления, сделанные в двух или больше сеансах работы с MATLAB, как будто они были статистически независимы, вы не можете использовать настройки генератора по умолчанию.
Один простой способ постараться не повторять те же случайные числа в новом сеансе работы с MATLAB состоит в том, чтобы выбрать различный seed для генератора случайных чисел. rng
дает вам простой способ сделать это путем создания seed на основе текущего времени.
rng shuffle
rand
ans = 0.0424
Каждый раз, когда вы используете 'shuffle'
, он пересевает генератор с различным seed. Можно вызвать rng
без входных параметров, чтобы видеть то, что отбирает его на самом деле используемый.
rng
ans = struct with fields:
Type: 'twister'
Seed: 781479910
State: [625x1 uint32]
rng shuffle % creates a different seed each time rng
ans = struct with fields:
Type: 'twister'
Seed: 781479913
State: [625x1 uint32]
rand
ans = 0.6495
'shuffle'
является очень простым способом пересеять генератор случайных чисел. Вы можете думать, что это - хорошая идея, или даже необходимый, чтобы использовать его, чтобы получить "истинную" случайность в MATLAB. В большинстве целей, тем не менее, не необходимо использовать 'shuffle'
вообще. Выбор seed на основе текущего времени не улучшает статистические свойства значений, которые вы получите от rand
, randi
и randn
, и не делаете их "более случайными" ни в каком действительном смысле. В то время как это прекрасно подходит, чтобы пересеять генератор каждый раз, когда вы запускаете MATLAB, или прежде чем вы выполните некоторое большое вычисление, включающее случайные числа, это - на самом деле не хорошая идея пересевать генератор слишком часто в сеансе, потому что это может влиять на статистические свойства ваших случайных чисел.
То, что действительно обеспечивает 'shuffle'
, является способом постараться не повторять те же последовательности значений. Иногда это очень важно, иногда это просто "хорошо", но часто это не важно вообще. Примите во внимание, что, если вы используете 'shuffle'
, можно хотеть сохранить seed, который создал rng
так, чтобы можно было повторить вычисления позже. Вы будете видеть, как сделать это ниже.
До сих пор вы видели, как сбросить генератор случайных чисел к его настройкам по умолчанию и пересеять его с помощью seed, который создается с помощью текущего времени. rng
также обеспечивает способ пересеять его с помощью определенного seed.
Можно несколько раз использовать тот же seed, чтобы повторить те же вычисления. Например, если вы запускаете этот код дважды...
rng(1) % the seed is any non-negative integer < 2^32
x = randn(1,5)
x = 1×5
-0.6490 1.1812 -0.7585 -1.1096 -0.8456
rng(1) x = randn(1,5)
x = 1×5
-0.6490 1.1812 -0.7585 -1.1096 -0.8456
... вы получаете точно те же результаты. Вы можете сделать это, чтобы воссоздать x
, очистив его, так, чтобы можно было повторить то, что происходит в последующих вычислениях, которые зависят от x
, с помощью тех определенных значений.
С другой стороны, вы можете хотеть выбрать различные seed, чтобы гарантировать, чтобы вы не повторяли те же вычисления. Например, если вы запускаете этот код в одном сеансе работы с MATLAB...
rng(2)
x2 = sum(randn(50,1000),1); % 1000 trials of a random walk
и этот код в другом...
rng(3) x3 = sum(randn(50,1000),1);
... вы могли объединить два результата и быть уверены, что они не просто те же результаты, повторенные дважды.
x = [x2 x3];
Как с 'shuffle'
существует протест при пересеве генератора случайных чисел MATLAB, потому что это влияет на весь последующий вывод от rand
, randi
и randn
. Если вам не нужны воспроизводимость или уникальность, обычно желательно просто сгенерировать случайные значения, не пересевая генератор. Если действительно необходимо пересеять генератор, который обычно лучше всего делается в командной строке, или в месте в коде, который легко не пропущен.
Мало того, что можно пересеять генератор случайных чисел как показано выше, можно также выбрать тип генератора случайных чисел, который вы хотите использовать. Различные типы генератора производят различные последовательности случайных чисел, и вы можете, например, выбрать определенный тип из-за его статистических свойств. Или вы можете должны быть воссоздать результаты более старой версии MATLAB, который использовал различный тип генератора по умолчанию.
Еще одна общая причина выбора типа генератора состоит в том, что вы пишете тест валидации, который генерирует "случайные" входные данные, и необходимо гарантировать, что тест может всегда ожидать точно тот же предсказуемый результат. Если вы вызываете rng
с seed прежде, чем создать входные данные, он пересевает генератор случайных чисел. Но если тип генератора был изменен по некоторым причинам, то вывод от rand
, randi
и randn
не будет тем, что вы ожидаете от того seed. Поэтому, чтобы быть на 100% уверенными в воспроизводимости, можно также задать тип генератора.
Например,
rng(0,'twister')
причины rand
, randi
и randn
, чтобы использовать алгоритм Генератора случайных чисел Вихрь Мерсенна, после отбора это с 0.
Используя 'combRecursive'
rng(0,'combRecursive')
выбирает Объединенный Мультипликативный Рекурсивный алгоритм генератора, который поддерживает некоторые параллельные функции, которые не делает Вихрь Мерсенна.
Эта команда
rng(0,'v4')
выбирает алгоритм генератора, который был значением по умолчанию в MATLAB 4.0.
И конечно, эта команда возвращает генератор случайных чисел в свои настройки по умолчанию.
rng default
Однако, потому что настройки генератора случайных чисел по умолчанию могут измениться между релизами MATLAB, использование 'default'
не гарантирует предсказуемые результаты по долгосрочному. 'default'
является удобным способом сбросить генератор случайных чисел, но еще для большей предсказуемости, задать тип генератора и seed.
С другой стороны, когда вы работаете в интерактивном режиме и нуждаетесь в воспроизводимости, это более просто, и обычно достаточно, чтобы вызвать rng
только с seed.
Вызов rng
без входных параметров возвращает скалярную структуру с полями, которые уже содержат два данные, описанные: тип генератора и целое число, с которым был в последний раз пересеян генератор.
s = rng
s = struct with fields:
Type: 'twister'
Seed: 0
State: [625x1 uint32]
Третье поле, State
, содержит копию вектора текущего состояния генератора. Этот вектор состояния является информацией, которую генератор поддерживает внутренне в порядке сгенерировать следующее значение в его последовательности случайных чисел. Каждый раз, когда вы вызываете rand
, randi
или randn
, генератор, который они совместно используют, обновляет свое внутреннее состояние. Таким образом вектор состояния в структуре настроек, возвращенной rng
, содержит информацию, необходимую, чтобы повторить последовательность, начинающуюся с точки, в которой было получено состояние.
В то время как просто способность видеть этот вывод информативна, rng
также принимает структуру настроек как входной параметр, так, чтобы можно было сохранить настройки, включая вектор состояния, и восстановить их позже, чтобы повторить вычисления. Поскольку настройки содержат тип генератора, вы будете знать точно, что вы получаете, и поэтому "более поздняя" сила означает что-либо от несколько моментов спустя в том же сеансе работы с MATLAB к годам (и несколько релизов MATLAB) позже. Можно повторить результаты любой точки в последовательности случайных чисел, в которой вы сохранили настройки генератора. Например,
x1 = randn(10,10); % move ahead in the random number sequence s = rng; % save the settings at this point x2 = randn(1,5)
x2 = 1×5
0.8404 -0.8880 0.1001 -0.5445 0.3035
x3 = randn(5,5); % move ahead in the random number sequence rng(s); % return the generator back to the saved state x2 = randn(1,5) % repeat the same numbers
x2 = 1×5
0.8404 -0.8880 0.1001 -0.5445 0.3035
Заметьте, что, в то время как пересев обеспечивает только крупную реинициализацию, сохраняя и восстанавливая состояние генератора, использование структуры настроек позволяет вам повторять любую часть последовательности случайных чисел.
Наиболее распространенный способ использовать структуру настроек состоит в том, чтобы восстановить состояние генератора. Однако, потому что структура содержит не только состояние, но также и тип генератора и seed, это - также удобный способ временно переключить типы генератора. Например, если необходимо создать стоимость с помощью одного из устаревших генераторов от MATLAB 5.0, можно сохранить текущие настройки в то же самое время, когда вы переключаетесь, чтобы использовать старый генератор...
previousSettings = rng(0,'v5uniform')
previousSettings = struct with fields:
Type: 'twister'
Seed: 0
State: [625x1 uint32]
... и затем восстановите исходные настройки позже.
rng(previousSettings)
Вы не должны изменять содержимое ни одного из полей в структуре настроек. В частности, вы не должны создавать свой собственный вектор состояния, или даже зависеть от формата состояния генератора.
rng
позволяет вам также
пересейте генератор случайных чисел, или
сохраните и восстановите настройки генератора случайных чисел
не имея необходимость знать то, что вводит его. Можно также возвратить генератор случайных чисел в его настройки по умолчанию, не имея необходимость знать, каковы те настройки. В то время как существуют ситуации, когда вы можете хотеть задать тип генератора, rng
предоставляет вам простоту не необходимости задать его.
Если вы сможете постараться не задавать тип генератора, ваш код автоматически адаптируется к случаям, где различный генератор должен использоваться и автоматически извлечет выгоду из улучшенных свойств в новом типе генератора случайных чисел по умолчанию.
Устаревший Режим и rng
В версиях MATLAB до 7,7, вы управляли внутренним состоянием генератора случайных чисел путем вызова rand
или randn
непосредственно с 'seed', 'состоянием' или входными параметрами 'обманщика'. Например,
rand('state',1234)
Тот синтаксис не рекомендуется и переключает MATLAB в "устаревший режим случайных чисел", где rand
и randn
используют отдельный и устаревший генераторы, ведя себя, как они сделали до MATLAB 7.7. Если возможно, необходимо обновить любой существующий код, который использует старый синтаксис, чтобы использовать rng
вместо этого. Чтобы сделать это, может потребоваться некоторая мысль, чтобы определить истинное намерение старого кода; смотрите Обновление Вашего Синтаксиса Генератора случайных чисел в Руководстве пользователя для предложений и примеров.
Если вы или некоторый код, который вы запустили, выполнили команду, такую как rand('state',1234)
, который помещает MATLAB в устаревший режим, можно использовать
rng default
сбежать из устаревшего режима и возвратиться к генератору запуска по умолчанию. Если существует код, который вы не можете или не разрешенные изменить, можно охранять вокруг того старого использования кода:
s = rng; % save current settings of the generator % call code using legacy random number generator syntaxes rng(s) % restore previous settings of the generator
убедиться, что никакой другой код не использует устаревшие генераторы случайных чисел.
rng и RandStream
rng
обеспечивает удобный способ управлять генерацией случайных чисел в MATLAB для наиболее распространенных потребностей. Однако более сложные ситуации, включающие несколько потоков случайных чисел и параллельной генерации случайных чисел, требуют более сложного инструмента. Класс RandStream
- то, что инструмент, и это обеспечивает самый мощный способ управлять генерацией случайных чисел. Эти два инструмента дополнительны с rng
, обеспечивающим намного более простой и краткий синтаксис, который создается сверху гибкости RandStream
.