python vs octave随机生成器

时间:2012-12-06 00:36:57

标签: python random numpy octave

更具体地说,numpy:

In [24]: a=np.random.RandomState(4)
In [25]: a.rand()
Out[25]: 0.9670298390136767
In [26]: a.get_state()
Out[26]: 
('MT19937',
 array([1248735455, ..., 1532921051], dtype=uint32),
 2,0,0.0)

八度:

octave:17> rand('state',4)
octave:18> rand()
ans =  0.23605
octave:19> rand('seed',4)
octave:20> rand()
ans =  0.12852

Octave声称执行相同的算法(Mersenne Twister,周期为2 ^ {19937-1})

有人知道为什么会有差异吗?

3 个答案:

答案 0 :(得分:10)

不幸的是,Octave中的MT19937生成器不允许使用np.random.RandomState(4)的单个32位整数对其进行初始化。如果您使用rand("seed",4),这实际上会切换到先前在Octave中使用的PRNG的早期版本,PRNG根本不是MT19937,而是Fortran RANDLIB

可以在NumPy和Octave中获得相同的数字,但是您必须在Octave中使用随机种子生成算法并编写自己的函数来构造初始32位整数种子中的状态向量。我不是Octave大师,但是在Octave / Matlab上有几个关于位操作函数和整数类的Internet搜索,我能够编写以下粗略脚本来实现种子:

function state = mtstate(seed)

state = uint32(zeros(625,1));

state(1) = uint32(seed);
for i=1:623,
   tmp = uint64(1812433253)*uint64(bitxor(state(i),bitshift(state(i),-30)))+i;
   state(i+1) = uint32(bitand(tmp,uint64(intmax('uint32'))));
end
state(625) = 1;

像这样使用:

octave:9> rand('state',mtstate(4));
octave:10> rand(1,5)
ans =

   0.96703   0.54723   0.97268   0.71482   0.69773

只是为了与NumPy比较:

>>> a = numpy.random.RandomState(4)
>>> a.rand(5)
array([ 0.96702984,  0.54723225,  0.97268436,  0.71481599,  0.69772882])

数字(或至少前五个)匹配。

请注意,由random模块提供的Python中的默认随机数生成器也是MT19937,但它使用不同的种子算法,因此random.seed(4)生成完全不同的状态向量,因此然后PRN序列不同。

答案 1 :(得分:2)

如果查看details of the Mersenne Twister algorithm,会有很多参数影响实际生成的数字。我不认为Python和Octave试图产生相同的数字序列。

答案 2 :(得分:-1)

看起来numpy返回原始随机整数,而octave将它们规范化为0到1.0之间的浮点数。