Python
numpy
multiprocessing
urandom

numpyで乱数発生したときに気がついたこと

どうもpjです.

些細なことでも気になったことを書いていきます.
さて, 今回は大学の課題でnumpyで乱数を発生させていたときに気がついたことです.

multiprocessing

棄却法とか逆関数法である分布から値を持ってくるときに時間がかかって, 簡単に並列化できそうだったのでmultiprocessingをつかって, ここを参考に並列化してみたときにそれは起こった.

なんか結果が周期的

っだったのである. 乱数発生させたのにこれはおかしいということで雑に実験してみた.

random1.py
from numpy.random import *
from multiprocessing import Pool
import multiprocessing as multi
import matplotlib.pyplot as plt


def rand1(x):
    sleep(0.5)
    return rand()


p = Pool(2)
x = p.map(rand1, range(32))
p.close()
print(x)

plt.title("2thread")
plt.scatter(range(32), x, s=30)
plt.savefig("rand2core.png")

p = Pool(4)
x = p.map(rand1, range(32))
p.close()
print(x)

plt.figure()
plt.title("4thread")
plt.scatter(range(32), x, s=30)
plt.savefig("rand4core.png")    

単純にnumpy.random.rand()を並列化しているだけ. sleepは二回連続で同じスレッドからxに値が入らないようにするために入れてみた.(なかったら周期がきれいに出ない) 前半は2コア2スレッド, 後半は2コア4スレッドで実行されます.

結果

rand2core.png
rand4core.png

前半は2つ周期, 後半は4つ周期になっている.
つまり同じ回数目では各スレッドが同じ乱数を取得していることになる.

次調べること

・numpyが呼び出しているmacのOSの乱数源である/dev/urandomのこと
・これが問題になることはないのか
・スレッドごとの時間をずらしたらどうか