Search code examples
pythonc++numpyrandomrandom-seed

MT19937 Generator in C++ and NumPy generate different numbers


I am trying to reproduce some C++ code in Python that involves random number generations. The C++ code uses the MT19937 generator as follows:

#include <random>
#include <iostream>

int main() {
    std::mt19937 generator(1234);
    std::uniform_real_distribution<double> distribution(0.0, 1.0);

    for (int i = 0; i < 10; ++i) {
        std::cout << distribution(generator) << std::endl;
    }

    return 0;
}

The Python version is (with NumPy 1.23.3)

import numpy as np

rng = np.random.Generator(np.random.MT19937(1234))
for _ in range(10):
    print(rng.random())

In both cases, the random seed is set to 1234. But the two produce different outputs on my machine (macOS 14.0 ARM). The C++ code outputs

0.497664
0.817838
0.612112
0.77136
0.86067
0.150637
0.198519
0.815163
0.158815
0.116138

while the Python code outputs

0.12038356302504949
0.4037014194964441
0.8777026256367374
0.9565788014497463
0.42646002242298486
0.28304326113156464
0.9009410688498408
0.830833142531224
0.6752899264264728
0.3977176012599666

Why do the two MT19937 generators produce different sequences despite the same seed? How (if possible) can I make them the same?


Solution

  • The Mersenne Twister generator has a defined sequence for any seed that you give it. There are also test values that you can use to verify that the generator you use is conforming.

    The distributions are on the other hand not standardized and may produce different values in different implementations. Remove the distribution to compare the generators.


    Note also that std::mt19937 is a 32 bit generator and it's not obvious (to me) if the numpy version is a 32 or 64 bit generator. You may want to compare std::mt19937_64 with the numpy implementation - still without involving a distribution of course.