8

より具体的には、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

オクターブは同じアルゴリズムを実行すると主張しています(2 ^ {19937-1}の周期のメルセンヌツイスター)

なぜ違いがあるのか​​誰にも分かりますか?

4

3 に答える 3

10

残念ながら、OctaveのMT19937ジェネレーターでは、単一の32ビット整数を使用して初期化することはできませんnp.random.RandomState(4)。これを使用するrand("seed",4)と、実際には、以前にOctaveで使用されていたPRNGの以前のバージョンに切り替わります。PRNGはMT19937ではなく、FortranRANDLIBです。

NumPyとOctaveで同じ数値を取得することは可能ですが、Octaveのランダムシード生成アルゴリズムをハックして、最初の32ビット整数シードから状態ベクトルを構築する独自の関数を作成する必要があります。私はOctaveの第一人者ではありませんが、Octave / Matlabでビット操作関数と整数クラスをインターネットで検索することで、シードを実装するための次の大まかなスクリプトを作成できました。

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])

番号(または少なくとも最初の5つ)は一致します。

モジュールによって提供されるPythonのデフォルトの乱数ジェネレーターrandomもMT19937ですが、異なるシードアルゴリズムを使用するためrandom.seed(4)、完全に異なる状態ベクトルが生成されるため、PRNシーケンスが異なります。

于 2012-12-14T10:17:50.197 に答える
2

メルセンヌツイスターアルゴリズムの詳細を見ると、実際に生成される数に影響を与えるパラメーターがたくさんあります。PythonとOctaveが同じ数列を生成しようとしているとは思いません。

于 2012-12-06T01:14:14.553 に答える
-1

numpyが生のランダムな整数を返しているように見えますが、octaveはそれらを0から1.0の間の浮動小数点数に正規化しています。

于 2012-12-06T00:54:08.337 に答える