This question has been asked before (stackoverflow) but the (accepted) answer is not satisfactory.
The following example saves and loads the state but depending on the number of generated values it works or it doesn't:
#include <fstream>
#include <iostream>
#include <random>
#include <cassert>
int main()
{
const int preN = 4;
const int middleN = 0;
// initialize randGen
std::mt19937 randGen1;
std::normal_distribution<double> distribution1;
// print some initial random numbers
for (int i=0;i<preN;++i)
std::cout << distribution1(randGen1)<<" ";
// save state
std::cout << std::endl << "Saving...\n";
{
std::ofstream fout("seed.dat");
fout << randGen1;
}
// maybe advance randGen1
for (int i=0;i<middleN;++i)
std::cout << distribution1(randGen1)<<" ";
// load saved state into randGen2
std::cout << std::endl << "Loading...\n";
std::ifstream fin("seed.dat");
std::mt19937 randGen2;
fin >> randGen2;
std::normal_distribution<double> distribution2;
// are both randGen equal?
assert(randGen1 == randGen2);
// print numbers from both generators
std::cout << "Generator1\tGenerator2\n";
std::cout << distribution1(randGen1) << "\t"
<< distribution2(randGen2) << "\n";
return 0;
}
With these parameters it works like expected. However, if I set preN=3
the output looks like:
0.13453 -0.146382 0.46065
Saving...
Loading...
Generator1 Generator2
-1.87138 0.163712
Why did the assert not apply? Now I set preN=3
and middleN=1
and the output is
0.13453 -0.146382 0.46065
Saving...
-1.87138
Loading...
Generator1 Generator2
0.163712 0.163712
If I set middleN
to anything larger than 1 the assert applies.
Can anyone explain what is going on? What am I doing wrong or not understanding?
Tested with GCC5.4.0 and CLANG3.8.0 on Linux
The problem is not your random number generator's state. The problem is your distribution's state. Yes, distributions can have state too.
You can get the same values by resetting the normal distribution's state with reset
. Alternatively, you can preserve and reconstitute the distribution's state too, using <<
and >>
.