PDA

View Full Version : Statistics: Random Number Streams


Tom David
10-25-2007, 07:54 AM
I got a question but did not find an answer in the manual or in the command reference.

1. Which Random Number Stream is used, if I use a distribution command and do not define the stream?

Let’s assume I use the following command:
bernoulli(num prob, num succeed-value, num fail-value, num stream)
bernoulli(30,1,2);

So with 30 percent the return of this command is 1 and with 70 percent it is 2.

2. If I use different commands of this kind, is Flexsim using the same Random Number Stream for all of them?

3. Or is Flexsim using different Random Number Streams automatically by just choosing the next not already used Random Number Stream?

I found the following commands
randantithetic(num on/off)
randinit(num stream, num seedvalue)
randnext(num stream)

which I think will be handy if you work with random number streams and take manual care on what you are going to do.

4. How many Random Number Streams are in Flexsim.
I also always get this question from my clients.
I am sure it is a large number, but I do not know the exact number.
I checked it out by using the following command and for me it looks like that there are 112207 Random Number Streams, because 112207 gives new values but 112208 does not.
bernoulli(50,1,2,112207);

5. So am I right? Does Flexsim have 112207 Random Number Streams or is it another number?

In the Command Reference it’s written several times:
"Refer to stochastics documentation for further details."

6. Where can I find this stochastic documentation?

Thanks in advance for any hint, help or answer.

Take care
tom the (A)tom

AlanZhang
10-25-2007, 09:03 AM
Tom,

In the old Flexsim user forum, I remembered there is a discussion about this. And Cliff has an explanation about the random streams. Here are my summary notes. Hope it answers at least part of your questions.

100 unique random streams could be used.
Default is stream 1.
Each stream has a seed value to determine the start position of the first number inthe stream.
Seed can be set using randinit command.
Seed value will be reset to the same value after reset the model.
If "Repeat Random Streams" is checked, same sequence of random numbers will be generated because randinit() command is automatically executed for each of the generators.Take care,
Alan

Cliff King
10-26-2007, 12:29 PM
There are currently 100 random number stream generators numerated 0 through 99.
If you use a random number stream greater than 99, it actually accesses memory that has not been allocated properly for random number stream usage. It may appear fine, but it's really messing with memory that it's not supposed to.

There are changes planned for the next release of Flexsim to provide more capability relating to random number streams as noted in item 73 of the future development list:

http://www.flexsim.com/help/developmentplan/viewchangelist.php

Tom David
10-30-2007, 08:16 AM
Okay, what I learned so far is:
100 unique random streams numerated 0 through 99 are in Flexsim
There are plans with the next release that the user can define the number of streams, which I think is a good thing.
Currently, the default stream used by a distribution is number 0 if a stream is not specified by the user.
There are plans with the next release that the default should assign a new random stream to each distribution in the model. At least give the user the option to define the default in Global Settings.
I would think it would be nice if you could choose between the two above options, which might be an option in the Global Settings (Use stream X as default. Use a new random stream for each distribution).So beside my question “6. Where can I find this stochastic documentation?” it seems that my questions are answered. But maybe here are the plans to put this documentation in the help directory of the Flexsim installation with the next release, because this would be the place where I would search for it.
Thank a lot for your help and replies, I really appreciate it.

Cliff King
10-30-2007, 06:11 PM
We have decided to hold off on implementing any automatic assignment of random number stream generators to the distributions within a model. In version 4.1 we will allow the user to specify how many random number streams they would like to use (currently this is hard-coded at 100). Each random stream generator will generate in excess of 2 billion pseudo-random numbers in its stream before repeating, as is currently the case.

A user already has the ability to manually assign specific streams to any of the stochatic distributions within Flexsim. To automate the process of assigning the same stream to groups of objects and/or distributions within the model, the user may choose to represent the stream parameter as a global variable that can be easily changed as desired.

Using the randinit() command, users may dynamically reset specific random stream generators at any time, and even assign their own reset seed value to the generators.

Using the randantithetic() command, users may also switch random streams to generate numbers between 1 and 0; rather than the default of 0 to 1. This is helpful for determining if random numbers are having a big affect on the results of the model. It's also useful when experimenting with massive models and there isn't sufficient time to run the model for multiple iterations as required for good statistical sampling. The user can choose to do just one regular run and one antithetic run of the model to obtain two diametrically apposed results. These two results can be averaged for an approximation that is somewhat better than if each run of the model used random stream generators without antithetic sampling.

A new command will be added in version 4.1 called randstate() that will allow the user to get the current value of a particular random number generator.

As we receive specific requests from our users for more graphical user interface (GUI) options to manage the random number generators and their assignments to distributions in a model, we will consider them for future releases.

Kris Geisberger
11-22-2007, 01:16 PM
Cliff,

So all can see, how do you properly answer the following question:

"What random number generator engine does Flexsim use?"

Tom David
04-17-2009, 02:25 AM
I know, that this is an old thread, but I got the question Kris asked some time ago and here is still no answer to it.


Kris Geisberger:
So all can see, how do you properly answer the following question:

"What random number generator engine does Flexsim use?"

Markus Bans
04-18-2009, 07:46 AM
This is what I got from tech support in 2008, what likely could be of interest for you, too:

"...but I believe we use the cstdlib.h rand function, which gives you no
access to the state of the random number generator, other than to use
srand to initialize it."

And:

"It is the nature of the C and C++ pseudorandom number generators, which Flexsim uses, to be able to be initialized with a random number seed to make random number streams repeatable. There is no way to access the state of the pseudorandom number generator to save the state and begin where you left off. You can't load a random number generator in the middle in any C or C++ programs. You can reset the random number seed when you start the model run, and you can reset it again when you continue (to make your results repeatable), but they will be different than if you had just run the model all the way through without any interruptions."

Markus Bans
04-18-2009, 08:12 AM
Hello,

please open a new, empty model and set it in the 'Statistics' menu to 'Repeat Random Streams'.

1. Open the output console and execute this code in a script window once:

for (int row=1;row<=3;row++)
{
pr;pf(uniform(0,1));
}

Execute it again without resetting the model - the shown random numbers 4 - 6 of the used stream are (of course) different to the random numbers 1 - 3.

Now reset the model, execute the code once, then reset the model again, and execute the code again: In both cases, you see the first 3 random numbers of the used stream.

2. OK, but which stream is used by default?

Reset the model and execute this code in a script window once:

for (int row=1;row<=3;row++)
{
pr;pf(uniform(0,1,0));
}

The shown 3 random numbers are identical as in point 1. So the default random number stream in case nothing has been defined is 0.

3. Reset the model, open the output console and execute this code in a script window once:

for (int row=1;row<=3;row++)
{
pr;pf(uniform(0,1,1));
}

Now, you can see the first 3 random numbers of random number stream 1, which are (of course) different to the ones in stream 0.

4. I used random number streams > 99 in a model, and though having set the model to 'Repeat Random Streams', I couldn't reproduce my results! So you should only use random number streams from 0 to 99, though you could enter higher values.

[BE SURE AND READ ANTHONY JOHNSON'S DESCRIPTION BELOW POSTED 05-19-2009]

Lydia Franck
04-27-2009, 05:03 AM
This is what I got from tech support in 2008, what likely could be of interest for you, too:

"...but I believe we use the cstdlib.h rand function, which gives you no
access to the state of the random number generator, other than to use
srand to initialize it."

Maybe it should be considered to use another random-number generator. cstdlib can be implemented differently on different systems so we do not know the exact behaviour. Some good generators are offered in boost (http://www.boost.org/doc/libs/1_38_0/libs/random/random-generators.html (http://www.boost.org/doc/libs/1_38_0/libs/random/random-generators.html)). Some people even recommend using two generators in parallel because each of them has its weaknesses.

[BE SURE AND READ ANTHONY JOHNSON'S DESCRIPTION BELOW POSTED 05-19-2009]

Anthony Johnson
05-13-2009, 02:38 PM
I should clarify some misinformation about the random number generator in Flexsim. Flexsim uses a prime modulus multiplicative linear congruential generator (PMMLCG), as described in Law and Kelton chapter 7. The formula for this generator is:

Zi = (aZi-1) mod m*

We use the values a=630360016 and m*=2^31 - 1, as suggested by Marse and Roberts. You can confirm the algorithm with the following sample code:

int testz0 = 10000903;
randinit(0, testz0);
uniform(0,1,0);
double z1 = fmod(630360016.0*testz0, pow(2,31)-1.0);
string resultstr = concat("randstate: ", numtostring(randstate(), 0,0),
"\ncalculated z1: ", numtostring(z1,0,0));
if(z1 == randstate())
resultstr = concat(resultstr, "\n\nCorrect");
else resultstr = concat(resultstr, "\n\nIncorrect!!!!!");
msg("", resultstr, 1);
You can replace testz0 with any number to get the next value after that seed. Note that it will be incorrect with testz>200,000,000, simply because the flexscript expression 630360016.0*testz0 will lose precision at that point.

The period for this algorithm is just below 2^31. My initial tests show that it's at 2147483645, or 2^31 - 3, as confirmed by the following code (if you run this, be prepared to wait for a while because it takes a long time to reach the cycle).
randinit(0, 1982384);
int initialstate = randstate(0);
uniform(0,1,0);
int cycle = 0;
while(initialstate != randstate(0))
{
cycle++;
uniform(0,1,0);
}
msg("Random Period", concat("Stream cycles at ", numtostring(cycle, 0,0)));
return cycle;While this algorithm exhibits moderately good pseudo-random number generation, Law and Kelton cites several disadvantages. For the next release we plan to improve the random number generation algorithm by implementing a composite generator.

Also, previously it was stated that you cannot retrieve the current state of the random number stream. You can do this using the randstate() command, as used in the example above. This will allow you to store off the state of the random number stream, and then restore that state using the randinit command.

Also, previously it was stated that the only streams available are streams 0-99. This is the default, but if you call randinit, and pass in a stream above 99, Flexsim will automatically allocate the appropriate memory for all random number streams from 0 to that stream number. For example, if you want to use 10000 random number streams, then when your model opens, call randinit(10000, somenumber), and it will then give you 10000 random number streams. Note that if you want to repeat streams, then you need to manually initialize the seed values for streams 100-10000, because Flexsim only resets streams 0-99 when repeating random streams is on, even if there are 10000 total streams.

Lydia Franck
05-19-2009, 01:38 AM
Anthony, thank you very much for these explanations!
This generator is actually recommended by Law and Kelton.

Kind regards, Lydia.

Congshi Wang
10-28-2010, 03:55 AM
Hi everyone,

I got a simple question to this topic. What is the use of the stream input. For example I wanna set a exponential distribution for the inter arrival time like this: exponetial(0,20,0). In this case I got a location of zero and a scale of 20 which equals a mean 20 and a standart deviation of 20. But what is the use of the input of stream 0. And which difference makes it if I type a one for stream like this: exponetial(0,20,1)

Thanks a lot!

Congshi

Congshi Wang
12-17-2010, 02:14 AM
Hi, annother question.

It it neccessary to define a new stream number for each distribution. For example, I got a source which generates items in statistical distributed interarrival time. It also sets the label number statistically distributed which defines the processing times on the processors later. Is it ok to use the same random number stream (default or zero) or must I use different random number streams (zero and one, for example)?

Thanks

Jason Lightfoot
12-17-2010, 03:06 AM
There's no 'must' involved, but it's generally considered good practice to have random numbers sampled from different streams, both for debugging and variance reduction. However if you're not resetting the streams to the same starting position (via the seed value) for each replication and are using multiple replications, you're further introducing variability and may undo any good work you've done with stream management.

So for example - you could just use the 'zero' stream by not specifying the the stream parameter at all. The problem with that is as soon as you add another sample or change the distribution parameters of an existing one, it will affect the random number progression of all the other samplers you have in the model since they all make the 'zero' stream step through its numbers (each stream is a long fixed sequence of numbers from a pseudo-random number generator)

Given that modelling and simulation is about 'what-if' analysis you're likely to add objects and change values of the random elements, so at the least I'd recommend a stream per object. If you have multiple distributions per object and are studying the sensitivity to parameter changes of those, you could consider splitting those up too and having different streams for each. If you're running multiple replications (almost a given) then I'd recommend managing the seed values of the streams on reset too. For reference look up "Common Random Numbers" (CRN) - Averill Law's book "Simulation Modelling and Analysis" (ISBN:9780071255196) covers the method and its uses.

Congshi Wang
12-17-2010, 04:14 AM
thanks a lot for this very precise answer. but there's still one question left ;-)

What do you mean with managing the seed values of the streams on reset. First: Is the seed value the same as the initial value of a random number stream?

Is yes, is there a need to start with the same initial value in each replication?

Like in this thread http://www.flexsim.com/community/forum/showthread.php?t=208&highlight=random+seed said, the experimenter will not repeat random numbers, because it's a experimenter and not a repeater. But it still should use the same stream in each replication and scenario, but just starts at a difference place of the same stream.

Please correct me if I'm wrong.

Thanks