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.
#include<iostream>
#include<random>
int main() {
std::mt19937 g;
std::normal_distribution<double> d;
for (int i = 0; i < 10; ++i) {
g.seed(65472381);
d.reset();
std::cout << "List[65472381] = " << d(g) << "\n";
}
}
Here is the output:
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
Efficient discard
function for Mersenne Twister?
Which C++ random number engines have a O(1) discard function?
The answers to this StackOverflow question explain that there is a "fast jump" algorithm for Mersenne Twister. That means that an efficient discard
function is possible. Unfortunately, the C++ Standard does not mandate that an implemenation 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::mt19937
portable?
As I noted in the comments below, the C++ Standard mandates that std::mt19937
be 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.
#include<iostream>
#include<random>
int main() {
std::mt19937 g;
unsigned seed{ 65472381u };
g.seed(seed);
std::cout << "Seed : " << seed << "\n\n";
for (int i = 0; i < 10; ++i) {
std::cout << "g() : " << g() << "\n";
}
}
Here is the output.
Seed : 65472381
g() : 3522518833
g() : 1238868101
g() : 1353561095
g() : 3289615924
g() : 1455032182
g() : 573730142
g() : 700682001
g() : 2371867773
g() : 3721872455
g() : 2742745620
Random number distributions are not portable
For better or worse, the C++ Standard does not require that distributions such as std::normal_distribution
be the same in every implementation. In general, they are not portable.