Controlling Random Number Generation
This example shows how to use the
rng function, which provides control over random number generation.
(Pseudo)Random numbers in MATLAB® come from the
randn functions. Many other functions call those three, but those are the fundamental building blocks. All three depend on a single shared random number generator that you can control using
It's important to realize that "random" numbers in MATLAB are not unpredictable at all, but are generated by a deterministic algorithm. The algorithm is designed to be sufficiently complicated so that its output appears to be an independent random sequence to someone who does not know the algorithm, and can pass various statistical tests of randomness. The function that is introduced here provides ways to take advantage of the determinism to
repeat calculations that involve random numbers, and get the same results, or
guarantee that different random numbers are used in repeated calculations
and to take advantage of the apparent randomness to justify combining results from separate calculations.
If you look at the output from
randn in a new MATLAB session, you'll notice that they return the same sequences of numbers each time you restart MATLAB. It's often useful to be able to reset the random number generator to that startup state, without actually restarting MATLAB. For example, you might want to repeat a calculation that involves random numbers, and get the same result.
When you first start a MATLAB session or call
rng("default"), MATLAB initializes the random number generator using the default algorithm and seed. Starting in R2023b, you can set the default algorithm and seed in MATLAB preferences. If you do not change these preferences, then
rng uses the factory value of
"twister" for the Mersenne Twister generator with seed 0, as in previous releases. For more information, see Default Settings for Random Number Generator and Reproducibility for Random Number Generator.
rng("default") provides a very simple way to put the random number generator back to its default settings.
rng("default") rand % returns the same value as at startup
ans = 0.8147
What are the "default" random number settings that MATLAB starts up with, or that
rng("default") gives you? Before R2023b, if you call
rng with no inputs, you can see that it is the Mersenne Twister generator algorithm, seeded with 0.
ans = struct with fields: Type: 'twister' Seed: 0 State: [625x1 uint32]
You'll see in more detail below how to use the above output, including the
State field, to control and change how MATLAB generates random numbers. For now, it serves as a way to see what generator
randn are currently using.
Each time you call
randn, they draw a new value from their shared random number generator, and successive values can be treated as statistically independent. But as mentioned above, each time you restart MATLAB those functions are reset and return the same sequences of numbers. Obviously, calculations that use the same "random" numbers cannot be thought of as statistically independent. So when it's necessary to combine calculations done in two or more MATLAB sessions as if they were statistically independent, you cannot use the default generator settings.
One simple way to avoid repeating the same random numbers in a new MATLAB session is to choose a different seed for the random number generator.
rng gives you an easy way to do that, by creating a seed based on the current time.
ans = 0.6465
Each time you use
"shuffle", it reseeds the generator with a different seed. You can call
rng with no inputs to see what seed it actually used.
ans = struct with fields: Type: 'twister' Seed: 1507067353 State: [625x1 uint32]
rng("shuffle") % creates a different seed each time rng
ans = struct with fields: Type: 'twister' Seed: 1507067356 State: [625x1 uint32]
ans = 0.3008
"shuffle" is a very easy way to reseed the random number generator. You might think that it's a good idea, or even necessary, to use it to get "true" randomness in MATLAB. For most purposes, though, it is not necessary to use
"shuffle" at all. Choosing a seed based on the current time does not improve the statistical properties of the values you'll get from
randn, and does not make them "more random" in any real sense. While it is perfectly fine to reseed the generator each time you start up MATLAB, or before you run some kind of large calculation involving random numbers, it is actually not a good idea to reseed the generator too frequently within a session, because this can affect the statistical properties of your random numbers.
"shuffle" does provide is a way to avoid repeating the same sequences of values. Sometimes that is critical, sometimes it's just "nice", but often it is not important at all. Bear in mind that if you use
"shuffle", you may want to save the seed that
rng created so that you can repeat your calculations later on. You'll see how to do that below.
More Control over Repeatability and Non-Repeatability
So far, you've seen how to reset the random number generator to its default settings, and reseed it using a seed that is created using the current time.
rng also provides a way to reseed it using a specific seed.
You can use the same seed several times, to repeat the same calculations. For example, if you run this code twice ...
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
... you get exactly the same results. You might do this to recreate
x after having cleared it, so that you can repeat what happens in subsequent calculations that depend on
x, using those specific values.
On the other hand, you might want to choose different seeds to ensure that you don't repeat the same calculations. For example, if you run this code in one MATLAB session ...
rng(2) x2 = sum(randn(50,1000),1); % 1000 trials of a random walk
and this code in another ...
rng(3) x3 = sum(randn(50,1000),1);
... you could combine the two results and be confident that they are not simply the same results repeated twice.
x = [x2 x3];
As with "
shuffle" there is a caveat when reseeding MATLAB's random number generator, because it affects all subsequent output from
randn. Unless you need repeatability or uniqueness, it is usually advisable to simply generate random values without reseeding the generator. If you do need to reseed the generator, that is usually best done at the command line, or in a spot in your code that is not easily overlooked.
Choosing a Generator Type
Not only can you reseed the random number generator as shown above, you can also choose the type of random number generator that you want to use. Different generator types produce different sequences of random numbers, and you might, for example, choose a specific type because of its statistical properties. Or you might need to recreate results from an older version of MATLAB that used a different default generator type.
One other common reason for choosing the generator type is that you are writing a validation test that generates "random" input data, and you need to guarantee that your test can always expect exactly the same predictable result. If you call
rng with a seed before creating the input data, it reseeds the random number generator. But if the generator type has been changed for some reason, then the output from
randn will not be what you expect from that seed. Therefore, to be 100% certain of repeatability, you can also specify a generator type.
randn to use the Mersenne Twister generator algorithm, after seeding it with 0.
selects the Combined Multiple Recursive generator algorithm, which supports some parallel features that the Mersenne Twister does not.
selects the generator algorithm that was the default in MATLAB 4.0.
And of course, this command returns the random number generator to its default settings.
However, because the default random number generator settings may change between MATLAB releases, using
"default" does not guarantee predictable results over the long-term.
"default" is a convenient way to reset the random number generator, but for even more predictability, specify a generator type and a seed.
On the other hand, when you are working interactively and need repeatability, it is simpler, and usually sufficient, to call
rng with just a seed.
Saving and Restoring Random Number Generator Settings
rng with no inputs returns a scalar structure with fields that contain two pieces of information described already: the generator type, and the integer with which the generator was last reseeded.
s = rng
s = struct with fields: Type: 'twister' Seed: 0 State: [625x1 uint32]
The third field,
State, contains a copy of the generator's current state vector. This state vector is the information that the generator maintains internally in order to generate the next value in its sequence of random numbers. Each time you call
randn, the generator that they share updates its internal state. Thus, the state vector in the settings structure returned by
rng contains the information necessary to repeat the sequence, beginning from the point at which the state was captured.
While just being able to see this output is informative,
rng also accepts a settings structure as an input, so that you can save the settings, including the state vector, and restore them later to repeat calculations. Because the settings contain the generator type, you'll know exactly what you're getting, and so "later" might mean anything from moments later in the same MATLAB session, to years (and multiple MATLAB releases) later. You can repeat results from any point in the random number sequence at which you saved the generator settings. For example
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
Notice that while reseeding provides only a coarse reinitialization, saving and restoring the generator state using the settings structure allows you to repeat any part of the random number sequence.
The most common way to use a settings structure is to restore the generator state. However, because the structure contains not only the state, but also the generator type and seed, it's also a convenient way to temporarily switch generator types. For example, if you need to create values using one of the legacy generators from MATLAB 5.0, you can save the current settings at the same time that you switch to use the old generator.
previousSettings = rng(0,"v5uniform")
previousSettings = struct with fields: Type: 'twister' Seed: 0 State: [625x1 uint32]
You can then restore the original settings later.
You should not modify the contents of any of the fields in a settings structure. In particular, you should not construct your own state vector, or even depend on the format of the generator state.
Writing Simpler, More Flexible, Code
rng allows you to either
reseed the random number generator, or
save and restore random number generator settings
without having to know what type it is. You can also return the random number generator to its default settings without having to know what those settings are. While there are situations when you might want to specify a generator type,
rng affords you the simplicity of not having to specify it.
If you are able to avoid specifying a generator type, your code will automatically adapt to cases where a different generator needs to be used, and will automatically benefit from improved properties in a new default random number generator type.
rng provides a convenient way to control random number generation in MATLAB for the most common needs. However, more complicated situations involving multiple random number streams and parallel random number generation require a more complicated tool. The
RandStream class is that tool, and it provides the most powerful way to control random number generation. The two tools are complementary, with
rng providing a much simpler and concise syntax that is built on top of the flexibility of