Andrew McCall was looking for a random number generator.
I use this bit of code which I like because it is integer based and so gives the same answers on different machines. I think it originally came from Numerical Recipes in Pascal:
VAR { These need to be global / static } random_seed : INTEGER; { General purpose random seed } random_source : ARRAY [0..15] OF INTEGER:= (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); { 16 integers used by randgen to construct pseudo-random numbers }
FUNCTION randgen( VAR random_seed : INTEGER ): DOUBLE;
VAR i, x : integer;
BEGIN IF random_seed < 0 THEN { Setup seed array } BEGIN random_seed:= -random_seed; FOR i:= 0 TO 15 DO BEGIN random_seed:= (UINT(random_seed)*2416 + 374441) MOD 1771875; random_source[i]:= TRUNC(random_seed*0.5643738); END; END; x:= random_source[15]+random_source[0]; x:= x MOD 1000000; FOR i:= 0 TO 14 DO random_source[i]:= random_source[i+1]; random_source[15]:= x; randgen:= x*0.000001; END;
It's actually two random number generators in one! If you call it first with a negative integer random seed it sets up the array of 16 integers (in random source). These are used to generate the random number between 0 and 1 to 6 decimal places. This is a non-repeating sequence of 1 million random numbers. It also returns a new positive random seed which can be negated later on and used to generate another different non-repeating sequence of 1 million random numbers.
Regards
David Wood QinetiQ, Farnborough, Hants
The Information contained in this E-Mail and any subsequent correspondence is private and is intended solely for the intended recipient(s). For those other than the recipient any disclosure, copying, distribution, or any action taken or omitted to be taken in reliance on such information is prohibited and may be unlawful.
Wood David wrote:
Andrew McCall was looking for a random number generator.
I use this bit of code which I like because it is integer based and so gives the same answers on different machines.
BTW, GPC's built-in pseduo-random generator ("Mersenne Twister") is also integer based. (The details are available in the source, of course, p/rts/random.pas.)
Frank
Hi, all
Frank Heckenbach wrote:
BTW, GPC's built-in pseduo-random generator ("Mersenne Twister") is also integer based. (The details are available in the source, of course, p/rts/random.pas.)
The Mersenne Twister is a very high quality PRNG, and as Frank says it generates random (8 byte, unsigned) integers, which can then be converted to reals within any desired range. But it isn't the speediest out there. Part of what slows it down is that it generates the numbers in a batch of (?) 640, but doesn't use this batch efficiently. Every time you ask your program for a PRN, it calls the Random function to see if one already exists. It would be faster if it generated an array of 640, exported them, and then the program kept track of whether there was one available.
Most people would never see the difference, and don't want to have to keep count themselves. But some of my programs need several billion PRNs, at which point the function calling overhead is important. For these programs, I moved the storage of the PRN array out into the main program. If you need this kind of quantity of PRNs, I can probably excavate the relevant code.
regards, Toby
Dr. Robert P. Ewing Soil Scientist, Iowa State University
Toby Ewing wrote:
Frank Heckenbach wrote:
BTW, GPC's built-in pseduo-random generator ("Mersenne Twister") is also integer based. (The details are available in the source, of course, p/rts/random.pas.)
The Mersenne Twister is a very high quality PRNG, and as Frank says it generates random (8 byte, unsigned) integers, which can then be converted to reals within any desired range. But it isn't the speediest out there. Part of what slows it down is that it generates the numbers in a batch of (?) 640, but doesn't use this batch efficiently. Every time you ask your program for a PRN, it calls the Random function to see if one already exists. It would be faster if it generated an array of 640, exported them, and then the program kept track of whether there was one available.
Most people would never see the difference, and don't want to have to keep count themselves. But some of my programs need several billion PRNs, at which point the function calling overhead is important. For these programs, I moved the storage of the PRN array out into the main program. If you need this kind of quantity of PRNs, I can probably excavate the relevant code.
There is a highly portable C version of the Mersenne twister, in source, in my hashlib.zip. I use it to ensure that test data is reproducible across systems. It is under the name "cokusmt".
Since these things depend on nothing outside, except for the (user optional) seeding, they can always be made available in source form. Having them built in is just a convenience.
You can find hashlib.zip, and thence the cokusMT code, at my URL below.
CBFalconer wrote:
There is a highly portable C version of the Mersenne twister, in source, in my hashlib.zip. I use it to ensure that test data is reproducible across systems. It is under the name "cokusmt".
Since these things depend on nothing outside, except for the (user optional) seeding, they can always be made available in source form. Having them built in is just a convenience.
I'm not quite sure what you're getting at here. GPC's implementation of the Mersenne twister is also both portable and available in source (Pascal).
Frank