2016-07-19 2 views
4

Я хочу знать, как создавать одинаковые случайные (нормальное распределение) числа в numpy, как и в MATLAB.Достигайте одинаковых случайных чисел в numpy как matlab

В качестве примера, когда я делаю это в MATLAB

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1)); 
rand 
ans = 
    0.417022004702574 

Теперь я могу воспроизвести это с NumPy:

import numpy as np 
np.random.seed(1) 
np.random.rand() 
0.417022004702574 

Что приятно, но когда я делаю это с нормальным распределением я получаю разные номера.

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1)); 
randn 
ans = 
    -0.649013765191241 

И Numpy

import numpy as np 
np.random.seed(1) 
np.random.randn() 
1.6243453636632417 

Обе функции говорят в своей документации, что они черпают из стандартного нормального распределения, но дают мне разные результаты. Любая идея, как я могу настроить мой python/numpy, чтобы получить те же номера, что и MATLAB.

Потому что кто-то отметил это как дубликат: Речь идет о нормальном распространении, как я писал в начале и конце. Как я писал, равномерное распределение работает нормально, это касается нормального распределения. Ни один из ответов в связанной теме не помогает с нормальным распределением.

+2

Одним из возможных хак, чтобы получить такие же нормальные образцы распределения могут быть генерировать образцы из однородного распределения, а затем преобразовать их в нормальное распределение: http://stackoverflow.com/questions/75677/converting-a-uniform-distribution-to-a-normal-distribution – Prakhar

+0

См. также: http://stackoverflow.co m/questions/3722138/is-it-possible-to-reproduce-randn-of-matlab-with-numpy? rq = 1 (оно появилось в боковой панели «Related»; может также сделать его «связанным».) –

ответ

1

Я предполагаю, что матрица и numpy могут использовать разные методы для нормального распределения случайных чисел (которые каким-то образом получены из однородных чисел).

Вы можете избежать этой проблемы, написав метод box-muller для генерации случайных чисел самостоятельно. Для питона,

import numpy as np 

# Box-muller normal distribution, note needs pairs of random numbers as input 
def randn_from_rand(rand): 

    assert rand.size == 2 

    #Use box-muller to get normally distributed random numbers 
    randn = np.zeros(2) 
    randn[0] = np.sqrt(-2.*np.log(rand[0]))*np.cos(2*np.pi*rand[1]) 
    randn[1] = np.sqrt(-2.*np.log(rand[0]))*np.sin(2*np.pi*rand[1]) 

    return randn 


np.random.seed(1) 
r = np.random.rand(2) 
print(r, randn_from_rand(r)) 

, который дает,

(array([ 0.417022 , 0.72032449]), array([-0.24517852, -1.29966152])) 

и MATLAB,

% Box-muller normal distribution, note needs pairs of random numbers as input 
function randn = randn_from_rand(rand) 

    %Use box-muller to get normally distributed random numbers 
    randn(1) = sqrt(-2*log(rand(1)))*cos(2*pi*rand(2)); 
    randn(2) = sqrt(-2*log(rand(1)))*sin(2*pi*rand(2)); 

, которую мы называем с

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1)); 
r = [rand, rand] 
rn = randn_from_rand(r) 

с ответом,

r = 
    0.4170 0.7203 
rn = 
    -0.2452 -1.2997 

Обратите внимание, что вы можете проверить выход распределен нормально, для питона,

import matplotlib.pyplot as plt 

ra = [] 
np.random.seed(1) 
for i in range(1000000): 
    rand = np.random.rand(2) 
    ra.append(randn_from_rand(rand)) 


plt.hist(np.array(ra).ravel(),100) 
plt.show() 

, который дает,

enter image description here

+0

Спасибо за ответ. Но я не могу изменить код MATLAB. Похоже, MATLAB использует ziggurat, я попытаюсь переопределить его в python. – Nozdrum

+1

Я думаю, что если ваша реализация не будет точно такой же, вы не сможете получить воспроизводимые случайные числа, в соответствии с этой ссылкой https://github.com/numpy/numpy/issues/5810 код для MATLAB является собственностью, что предполагает, что это, вероятно, isn Просто. Не могли бы вы просто переопределить randn в MATLAB и использовать тот же код? –

Смежные вопросы