Is there a deterministic random number generator in <random> in C++?
The point in question is that the below code on my Windows machine:
#include<iostream>
#include<random>
int main(){
std::mt19937 g;
std::normal_distribution<double> d;
for(int i=0;i<100;++i){
g.seed(65472381);
std::cout << "List[65472381] = " << d(g) << "\n";
}
}
produces the following result:
List[65472381]=0.972683
List[65472381]=-0.773812
List[65472381]=0.972683
List[65472381]=-0.773812
List[65472381]=0.972683
List[65472381]=-0.773812
...
My confusion is with the fact that 0.972683 != -0.773812 albeit the seed it reset to 65472381 each time before g is used.
My processor is a Zen 2 and the OS is Windows 10 Pro, Version 22H2. The compiler is GCC (x86_64-w64-mingw32/12.2.0). But from testing the code online on different virtual machines and compilers, it seems the result will likely be the same on your machine as well.
What I actually seek is a way to acquire the i-th number from an arbitrary fixed universal list of length 4,294,967,295 of randomly distributed numbers in SPACETIME O(1), implying that no element of the list be ever stored.
The distribution object has internal state. So, after you reseed the random number engine, you must reset the distribution to clear its internal state. This is true for all the engines and distributions in the Standard Library. In general, when you seed an engine, you should also reset the distribution.
Here is the output:
Efficient
discardfunction for Mersenne Twister?Which C++ random number engines have a O(1) discard function?
The answers to this Stack Overflow question explain that there is a "fast jump" algorithm for Mersenne Twister. That means that an efficient
discardfunction is possible. Unfortunately, the C++ Standard does not mandate that an implementation use it.You may discover that your system is one that has an efficient
discard. You cannot, however, assume that every system will.If you decide to use
discard, be sure to reset the distribution afterwards. Otherwise, the values generated by the distribution are not guaranteed to be repeatable.Is
std::mt19937portable?As I noted in the comments below, the C++ Standard mandates that
std::mt19937be portable. It must generate the same sequences of random numbers on every implementation.I used the following program to generate 10 values from
std::mt19937. I ran it with the latest version of MSVC. If you run it on your system, you should get the same output.Here is the output.
Random number distributions are not portable
For better or worse, the C++ Standard does not require that distributions such as
std::normal_distributionbe the same in every implementation. In general, they are not portable.