pythonnumpymatlabrandompermutation

# Recreate randperm Matlab function in Python

I have searched on stackoverflow for people facing similar issues and this topic Replicating MATLAB's `randperm` in NumPy is the most similar.

However, although it is possible to recreate the behavior of randperm function from Matlab in Python using numpy random permutation, the numbers generated are not the same, even though I choose the same seed generator for both languages. I am a bit confused since my tests were relevant for other random functions between Matlab and Python.

Here is what I have tried:

Matlab

``````rng(42);
randperm(15)
``````

which returns

``````ans =

11     7     6     5    15    14     1     4     9    10     3    13     8     2    12
``````

Python

``````np.random.seed(42)
print(np.random.permutation(range(1,16)))
``````

which returns

``````[10 12  1 14  6  9  3  2 15  5  8 11 13  4  7]
``````

How can I change my Python code so it can reproduce the same order of random numbers than Matlab ?

Solution

• It seems that Matlab and Numpy use the same random number generators by default, and the discrepancy is caused by the inner workings of `randperm` being different in the two languages.

In old Matlab versions, `randperm` worked by generating a random array and outputting the indices that would make the array sorted (using the second output of `sort`). In more modern Matlab versions (I'm using R2017b), `randperm` is a built-in function, so the source code cannot be seen, but it seems to use the same method:

``````>> rng('default')
>> rng(42)
>> randperm(15)
ans =
11     7     6     5    15    14     1     4     9    10     3    13     8     2    12
>> rng(42)
>> [~,  ind] = sort(rand(1,15))
ind =
11     7     6     5    15    14     1     4     9    10     3    13     8     2    12
``````

So, if the random number generators are actually the same in the two languages, which seems to be the case, you can replicate that behaviour in Numpy by defining your own version of `randperm` using `argsort`:

``````>>> import numpy as np
np.random.seed(42)
ind = np.argsort(np.random.random((1,16)))+1
print(ind)
[[11  7  6  5 15 16 14  1  4  9 10  3 13  8  2 12]]
``````

Note, however, that relying on the random number generators being the same in the two languages is risky, and probably version-dependent.