14 releases ()
| 1.0.0-alpha.3 | May 20, 2025 |
|---|---|
| 1.0.0-alpha.2 | May 19, 2025 |
| 0.9.5-alpha.6 | May 19, 2025 |
| 0.9.4 | Aug 8, 2024 |
#158 in Algorithms
24 downloads per month
Used in 3 crates
45KB
756 lines
MINSTD
This multiplicative congruential pseudo random number generator is called "The minimal standard generator" or MCG16807. First described in 1988 Park and Miller paper Random number generators: Good ones are hard to find.
Generator modulus m = 2^31-1 is Mersene prime M31. The multiplier a = 7^5 = 16807 was first suggested by Lewis, Goodman and Miller in 1969.
Multiplicative congruential generators of this form are ascribed to D. H. Lehmer and they are know as Lehmer random number generators. First described by Hutchinson and independently by Downham and Roberts.
Generator was later criticized by Marsaglia and Sullivan (1993). While it is still in use today (in particular: in CarbonLib, in Matlab as mcg16807, FreeBSD 5 as rand() and in C++11 as function minstd_rand0) Park, Miller and Stockmeyer "officially" since July 1990 advocate a = 48271 multiplier.
Updated version performs much better in Spectral test where performs very well up to 6th dimension.
MINSTD / 1990 version
Multiplier 48271
MINSTD0 / 1988 version
Multiplier 16807
Spectral tests
Spectral tests of popular small, easy to remember, multipliers. Larger multipliers give better results and on current 32/64 bit systems they do not have any additional computation cost.
| multiplier | 2d | 3d | 4d | 5d | 6d | 7d | 8d |
|---|---|---|---|---|---|---|---|
| 16807 | 0.3375 | 0.4412 | 0.5752 | 0.7361 | 0.6454 | 0.5711 | 0.6096 |
| 48271 | 0.8960 | 0.8269 | 0.8506 | 0.7332 | 0.8078 | 0.5865 | 0.4364 |
| 69621 | 0.7836 | 0.9205 | 0.8516 | 0.7318 | 0.7667 | 0.6628 | 0.7845 |
Value 0.75 or higher is considered good enough to pass spectral test.
Because too many multipliers pass 0.75 test for MCG M31 generator, researches changed limit to 0.8 while doing An Exhaustive Analysis of Multiplicative Congruential Random Number Generators with Modulus 2(31)-1 and found 207 optimal multipliers while first 5 are much better than the rest.
S1, S2, S3 values for best performing multipliers for m = M31
| multiplier | 2d | 3d | 4d | 5d | 6d |
|---|---|---|---|---|---|
| 742938285 | 0.8673 | 0.8607 | 0.8627 | 0.8320 | 0.8342 |
| 0.8362 | 0.6613 | 0.6618 | 0.6021 | 0.6075 | |
| 0.8673 | 0.8751 | 0.8507 | 0.7838 | 0.7983 | |
| 950706376 | 0.8574 | 0.8985 | 0.8692 | 0.8337 | 0.8274 |
| 0.9211 | 0.8183 | 0.6555 | 0.6806 | 0.6822 | |
| 0.8574 | 0.9093 | 0.8412 | 0.7565 | 0.7646 | |
| 1226874159 | 0.8411 | 0.8787 | 0.8255 | 0.8378 | 0.8441 |
| 0.8273 | 0.7240 | 0.7815 | 0.6492 | 0.6822 | |
| 0.8411 | 0.8877 | 0.8468 | 0.7107 | 0.7743 | |
| 62089911 | 0.8930 | 0.8903 | 0.8575 | 0.8630 | 0.8249 |
| 0.7169 | 0.7537 | 0.7430 | 0.7153 | 0.6603 | |
| 0.8930 | 0.8286 | 0.7712 | 0.8150 | 0.7385 | |
| 1343714438 | 0.8237 | 0.8324 | 0.8245 | 0.8262 | 0.8255 |
| 0.8676 | 0.6404 | 0.6492 | 0.6702 | 0.7103 | |
| 0.8237 | 0.7785 | 0.7906 | 0.7874 | 0.7747 | |
| 16807 | 0.3375 | 0.4412 | 0.5752 | 0.7361 | 0.6454 |
| 0.2565 | 0.3264 | 0.5714 | 0.6754 | 0.5888 | |
| 0.3375 | 0.5404 | 0.6162 | 0.6187 | 0.5889 | |
| 397204094 | 0.5564 | 0.5748 | 0.6674 | 0.7678 | 0.5947 |
| 0.5966 | 0.5038 | 0.6239 | 0.6597 | 0.4206 | |
| 0.5564 | 0.5543 | 0.7302 | 0.7849 | 0.6417 | |
| 630360016 | 0.8212 | 0.4317 | 0.7832 | 0.8021 | 0.5700 |
| 0.8823 | 0.4373 | 0.6534 | 0.7173 | 0.5047 | |
| 0.8212 | 0.6354 | 0.6441 | 0.7983 | 0.5510 |
MCG31 / 1999 version
Use of multiplier 1132489760 is recommended in paper MATHEMATICS OF COMPUTATION Volume 68, Number 225, January 1999. This multiplier have good spectral results in higher (16, 32) dimensions. Results in low dimensions are less good compared to previous table.
Paper recommends two multipliers for MCG with M31 modulo:
| multiplier | 8d | 16d | 32d |
|---|---|---|---|
| 1132489760 1583458089 | 0.72771 | 0.61996 | 0.61996 |
| 784588716 163490618 | 0.65885 | 0.65388 | 0.65388 |
Second alternative multiplier is generating the same but reversed sequence without difference in spectral test. Its modular multiplicative inverse modulo M31.
Used in Arm HPC and Intel VSL.
Custom MCG M31 Generator
You can create Multiplicative congruential generator with your custom multiplier and M31 modulo. Choose best performing multiplier in your desired dimension. You will get better results than using stock multipliers.
Functions verify_multiplier and verify_period will help you test if your choosen multiplier is capable of producing full period generator.
Function inverse_multiplier computes the modular inverse of a given multiplier a modulo M31. You can use this function to test if your multiplier is inverse of some well known multiplier.
Minimalistic code
This library have no runtime dependencies and is not using standard library. Can be used in embedded or webasm environments.
License
This is free and unencumbered software released into the public domain.
This code can be used under terms of CC0-1.0 or the Unlicense.
![]()