steve said:
Don;t have a clue what you are 'hinting' at. I scanned through the Mersenne algorithm and there is plenty of code on the net. No mystery or puzzle.
Most of my comments had nothing whatsoever to do with Mersenne Twister.
My question was about your "URAND LG". Perhaps you should show us that code.
Execution times C++ Mersenne Twister vs LG.
for 10^10 iterations C++ took 68 seconds, URAND LG took .016 seconds.
Obviously something went badly wrong in your experiment! I'm sure you'll agree that you didn't do 10^10 iterations of anything in 16 milliseconds!
No comment about this?
- - - - - - - - - - - - - - - - - -
I will post two miscellaneous comments about my random-number routines.
(1) when choosing a uniform real variate over (0, 1) one starts with a specified number of bits. By default my library routines use 31 bits. The variate is then chosen to be distributed uniformly over
{1,3,5,7,9,... , 4294967291, 4294967293, 2
32-1 } ÷ 2
32
Note that this chooses a number from (0, 1) -- not [0,1) as many or most implementations do. Note that the mean will be 0.5 exactly. Perfectionistic? Sure, but why not? Steve, modify your code to use, say 8 bits instead of 32 bits and se what mean value you get.
(2) I'll present pseudo-code to illustrate how to minimize the number of random bits consumed by smallish selections and binary decision.
Let N
k denote {0, 1, 2, 3, ..., k-1 }
Internally, the code maintains a pair of integers (r, m). r is a uniformly-distributed random variable over N
m
I will describe two routines Augment and Decide.
Augment (k) // used to increase ("augment") the precision of (r, m)
Retrieve k bits from the PRNG; i.e. retrieve a random x uniform over N2k
Replace (r, m) as follows. Obviously shifts will be used instead of multiplies.
r ← r * 2k + x
m ← m * 2k
Decide (p) // return 1 with probability p, 0 with probability 1-p
If m is "too small" call Augment (k) for some appropriate k (e.g. make m a 31-bit number).
Approximate p as s/m for some integer s.
If r < s Then
m ← s
Return 1
Else (r ≥ s) Then
m ← m - s
r ← r - s
Return 0
The basic idea is that there is UNUSED randomness available for free after a Decide. Keep that randomness, rather than discarding it and "wasting" a call to the 32-bit PRNG every time. (As mentioned, even very good PRNGs are so good that the technique, however "nifty", has no importance unless you're working with a very expensive physical RNG.)
Anyone who takes the time to study this "Decide (p)" routine -- perhaps working simple examples -- and then understands how it works, should give themself a very big pat on the back! I've chatted with enough expert programmers to realize that this method -- however simple the above pseudo-code may appear -- is likely to baffle. Kudos to anyone who can pursue it all the way to an "Aha!" moment.