Introduction
Starting in GAUSS version 12, a new suite of random number generators was introduced. GAUSS now contains several options of high quality and high-performance random number generators (RNG), such as:
- The Mersenne-Twister (MT-19937, SFMT-19937 and MT-2208).
- Pierre L'ECuyer's MRG32K3a.
- Niederreiter and Sobol quasi-random number generators.
GAUSS version 11 and older used a linear congruential generator (LCG) by default. LCG's were fine for their time, but have been superseded by higher quality RNG's such as those mentioned above.
How do I reproduce my simulations?
While new projects should always use one of the modern RNG's, it is sometimes necessary to exactly reproduce some work from the past. GAUSS has retained a set of LCG's, such as, rndLCGam
, rndLCBeta
, rndLCn
, rndLCu
and rndLCi
. These functions will allow you to reproduce the random numbers from older GAUSS versions for many distributions.
However, while rndLCn
does compute normally distributed random numbers, it will not match those from GAUSS version 10 and before. In GAUSS version 11 an improvement to the method for transforming the uniform random numbers created by the underlying LCG was implemented in rndn
.
How do I reproduce rndn from GAUSS 10 and older?
In order to allow GAUSS users to reproduce the rndn
output from older versions of GAUSS, a new function was added to GAUSS version 18. The new function is _rndng10
.
rndseed 777;
x = _rndng10(5,1);
print x;
0.80449208 0.83614293 -0.32917873 -0.47774279 0.22364814
As you can see it works in exactly the same manner as rndn
did.
Don't just replace rndn with _rndng10
While some of you may be tempted to find-and-replace rndn
with _rndng10
, you should not do this for a couple of reasons.
-
_rndng10
is available to repeat simulations run in the past. It is still inferior to the RNG used by the modernrndn
. - The code will be less portable. It will not work in a version of GAUSS older than GAUSS 18.
Swap random number generators with a define
You can think of #define as an instruction to GAUSS to replace all instances of one thing with another during the compile phase before the program is run. This will not change the code in the file, just how GAUSS interprets it.
In our case, we want to replace all instances of rndn
with _rndng10
. We can do that like this:
#define rndn _rndng10
rndseed 777;
x = rndn(5,1);
print x;
0.80449208 0.83614293 -0.32917873 -0.47774279 0.22364814
Make it portable with #ifminkernelversion
The #define
is a quick and convenient way to swap out rndn
for _rndng10
. However, it is still not portable. It will not run on any version of GAUSS that does not have the rndng10
function (version 17 and older).
While you could just comment it out #ifminkernelversion
is a better option. #ifminkernelversion
is another preprocessor (i.e. before run-time) command. It tells GAUSS to include specific code ONLY if using a certain version of GAUSS or newer.
// If we are using GAUSS 18 or newer
// replace rndn with _rndng10
#ifminkernelversion(18)
#define rndn _rndng10
#endif
rndseed 777;
x = rndn(5,1);
print x;
0.80449208 0.83614293 -0.32917873 -0.47774279 0.22364814
Conclusion
In this post, we have learned that:
- The GAUSS random number generators were upgraded in versions 11 and 12.
- How to swap between the older and newer versions of
rndn
in a convenient and portable manner.
Code and data from this blog can be found here.