2

How do I get the same random numbers in Python and Matlab?

For example, my Matlab code prints random integers of 1 and 2 with the given seed:

>> rng(1);
>> randi(2,1,10)

ans =
    
         1     2     1     1     1     1     1     1     1     2

However, when I have the same seed using NumPy, I get a different order of random numbers:

np.random.seed(1)

np.random.randint(1,3,10)

array([2, 2, 1, 1, 2, 2, 2, 2, 2, 1])

Is there any way the two methods can produce the same order of random numbers?

  • 5
    the point of a seed it to initiate a **given** random number generator, not to give a predictable result for **any** generator ;) In short, I'm afraid you can't – mozway Nov 29 '21 at 15:24
  • 2
    You need to find out what generator matlab uses and then find an equivalent generator in python/numpy. – Holt Nov 29 '21 at 15:27
  • Or you can generate the array in one of the two languages and export it to the other. – Adriaan Nov 29 '21 at 15:51
  • 1
    If you want the same random number... then you don't want a random number at all... you want some sequence, that you can predefine – Ulises Bussi Nov 29 '21 at 15:52

1 Answers1

3

As seen in this answer, it is possible to produce the same random stream of uniformly distributed numbers in both MATLAB and Python/NumPy. Both use the same MT19937 Mersenne Twister:

>> format long
>> rng(1)
>> rand(1,3)
ans =
   0.417022004702574   0.720324493442158   0.000114374817345
>>> import numpy as np
>>> np.random.seed(1)
>>> np.random.rand(1,3)
array([[4.17022005e-01, 7.20324493e-01, 1.14374817e-04]])

So the difference we are seeing here is in how these numbers are converted into integers in the given range. But fortunately this is a trivial step that we can implement identically in both languages:

rng(1)
upper = 2;
lower = 1;
v = floor((rand(1,10) * (upper-lower+1)) + lower);
np.random.seed(1)
upper = 2;
lower = 1;
v = np.floor((np.random.rand(1,10) * (upper-lower+1)) + lower).astype(np.int64)

Note that this is not the best way to produce integers in a given range, this method is biased because the input random numbers can obtain only a set of discrete values, and these discrete values do not necessarily distribute uniformly within the set of output discrete values. Of course the effect is very small, and might not be important for your application. For more details on this, and a correct (but more complex) algorithm, see this anser.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • @user17534865 The distribution is (supposed to be) uniform, but not all values have the same probability. For floating-point numbers, there are the same number of different values in the range [0.01,0.1] and in the range [0.1,1]. This complicates the logic of translating one range to another quite a bit. Also, MATLAB's `rand` is biased. In Octave the bias was fixed in [this ticket](https://savannah.gnu.org/bugs/?54619). I submitted a bug report to MATLAB, but haven't seen that fixed yet. – Cris Luengo Apr 12 '23 at 15:26