フィルターのクリア

why can't I reproduce my random numbers

10 ビュー (過去 30 日間)
Stefan Monstein
Stefan Monstein 2023 年 12 月 14 日
編集済み: Adam Danz 2023 年 12 月 14 日
as per https://ch.mathworks.com/help/matlab/math/controlling-random-number-generation.html it should be possible to save the state of the RNG. However, my example does not show the desired behavior.
  • For reproducability I need two 'instances' of an RNG.
  • Each RNG should everytime give me the same sequence of random numbers.
the two RNG-'instances' seem to run independently, e.g. when changing the amount of numbers picket by therng1 varies, the sequence for therng2 stays the same. HOWEVER, chaning the seed for therng1 also changes the sequence I get from therng2, which should not happen in my opinion. What's the reason for this?
worst of all: When I change the seed of therng1 or 2, then k=1 has different random nunmbers than k=2 and 3. although they should be re-initialized at the start of the loop.
for k=1:3
therng1 = rng(1);
therng2 = rng(2);
disp(newline);
for l=1:2
fprintf('k=%d ', k);
fprintf('l=%d ', l);
rng(therng1);
for m = 1:5
fprintf('%3d ', randi(99));
end
therng1 = rng;
fprintf(" * ");
rng(therng2);
for m = 1:4
fprintf('%3d ', randi(99));
end
therng2 = rng;
fprintf(newline);
end
end
k=1
l=1
83 45 96 44 98
*
42 72 1 30
k=1
l=2
29 55 87 15 13
*
15 10 19 35
k=2
l=1
40 54 42 68 21
*
42 72 1 30
k=2
l=2
87 3 67 42 56
*
15 10 19 35
k=3
l=1
40 54 42 68 21
*
42 72 1 30
k=3
l=2
87 3 67 42 56
*
15 10 19 35
  1 件のコメント
Dyuman Joshi
Dyuman Joshi 2023 年 12 月 14 日
編集済み: Dyuman Joshi 2023 年 12 月 14 日
Also, there was an informative response/post by @Steven Lord on this topic recently, I'll link it here if and when I find it.

サインインしてコメントする。

採用された回答

Steven Lord
Steven Lord 2023 年 12 月 14 日
I suspect you think these two lines of code do something different than what they actually do.
therng1 = rng(1);
therng2 = rng(2);
This does not make two independent random number generator streams. The first line records the current state of the global random number generator stream, sets the global random number generator stream to "state 1", then returns the recorded state. [This is so if you wanted to restore the state of the global random number generator stream to where it was prior to the rng call, you could call rng with therng1 as input.] Then the second line records the current state of the global random number generator stream, sets the global random number generator stream to "state 2", then returns the recorded state (which in this case is "state 1".)
If you want two independent random number generator streams, as the last section on the page to which you linked states, "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." So I'd follow the example on this documentation page instead. Let's make two independent streams using the "Multiplicative lagged Fibonacci generator":
[s1,s2] = RandStream.create('mlfg6331_64','NumStreams',2)
s1 =
mlfg6331_64 random stream StreamIndex: 1 NumStreams: 2 Seed: 0 NormalTransform: Ziggurat
s2 =
mlfg6331_64 random stream StreamIndex: 2 NumStreams: 2 Seed: 0 NormalTransform: Ziggurat
Now if I generate 10 numbers using the first stream then reset it:
x1 = rand(s1, 1, 10);
reset(s1);
Generating any number of random numbers from the second stream won't affect the first stream at all.
y = rand(s2, 100, 100);
x2 = rand(s1, 1, 10);
isequal(x1, x2) % true
ans = logical
1
If for some reason you need to specify seeds in your application, or need to use a generator that doesn't support multiple streams or substreams, see the "Using Seeds to Get Different Results" section on that documentation page.

その他の回答 (1 件)

Adam Danz
Adam Danz 2023 年 12 月 14 日
編集済み: Adam Danz 2023 年 12 月 14 日
Section 1 of my answer explains how to update the code in your question to get the expected behavior. Section 2 suggests a different approach all together.
Managing the rng state
This isn't doing what you think it's doing:
therng1 = rng(1);
therng2 = rng(2);
From the doc (rng), t = rng(___) returns the current random number generator settings in a structure t before changing the settings using the specified arguments. So, therng1 is the rng state before setting the seed to 1. Likewise, therng2 is actually the state for rng(1).
What you want instead is
rng(1)
therng1 = rng;
rng(2)
therng2 = rng;
I recommend also setting the generator in addition to the seed.
rng(1,'twister')
therng1 = rng;
rng(2,'twister')
therng2 = rng;
Use indpendent random number streams instead
A simpler and safer approach is to use RandStream to manage the two independent random number proccesses. It's safer because it's less susceptible to interruptions to the random number generation state if/when the code is updated in the future.
for k=1:3
therng1 = RandStream('dsfmt19937','Seed',1);
therng2 = RandStream('dsfmt19937','Seed',2);
disp(newline);
for l=1:2
fprintf('k=%d nl=%d ', k,l);
for m = 1:5
fprintf('%3d ', randi(therng1,99));
end
% fprintf(" * ");
for m = 1:4
fprintf('%3d ', randi(therng2,99));
end
fprintf(newline);
end
end
k=1 nl=1
12 91 50 87 53
12 98 28 67
k=1 nl=2
56 10 99 79 36
7 68 49 9
k=2 nl=1
12 91 50 87 53
12 98 28 67
k=2 nl=2
56 10 99 79 36
7 68 49 9
k=3 nl=1
12 91 50 87 53
12 98 28 67
k=3 nl=2
56 10 99 79 36
7 68 49 9

製品


リリース

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by