Xorshiftをざっくり理解する

January 28, 2022      

はじめに

擬似乱数を発生させるアルゴリズムとして,線形合同法,Xorshift,メルセンヌ・ツイスタ,などいくつか有名なものがある. その中でも操作が単純で高速なXorshiftについて,ざっくり何をやっているのかを元論文1 2を参照しながら考えてみたい.証明やパラメタの詳細は元論文を見てもらうことにして,ここでは大まかな考えかたを追っていこう.

Es gibt mehrere Algorithmen, Pseudozufallszahlen zu generieren, z.B. Lineare Kongruenzgenratoren, Xorshift, Mersenne Twister und so weiter. In diesem Blogartikel disktirern wir über das Konzept des Xorshift Algorithms.

行列による擬似乱数の生成

擬似乱数を発生させる方法には様々なアプローチがあり得るが,大きな方向性として, n次のバイナリβ\betaに対して,n×nn \times nバイナリ行列TTを作用させていき,βT, βT2, \beta T,~\beta T^2,~\cdotsという数列を作ることで,擬似乱数を発生させる方法を考えよう.

このとき,以下の主張は同値になる.

  1. ゼロでない任意のn次バイナリに対して,n×nn \times nバイナリ行列TTを作用させていくと,ゼロ以外のn次バイナリを全て作ってくれる.
  2. n×nn \times nバイナリ行列TTの周期は2n12^n-1

同値性に関して,元の論文2では固有多項式を用いたりして議論しているが,感覚的には自然に納得できると思う.

1 \Leftarrow 2 に関して:

TTの周期がk=2n1k = 2^n-1ということは,あるバイナリβ\betaに対してβTk=β\beta T^k= \betaで,当然それまで(βT, βT2, \beta T,~\beta T^2,~\cdots)にβ\betaは踏んでいない. なのでその間,n次バイナリのとりうる元が2n2^n個あるうち,ゼロと初期バイナリを除いたすべての元を踏んでいかないといけないことが分かる(途中で同じものを踏むと,そこでループする).

1 \Rightarrow 2 に関して:

行列TTを作用させると,あるバイナリβ\betaに対して,一意にバイナリβT\beta Tを与えるので,とりうるバイナリを全て発生させていくには,毎回異なるバイナリを発生させ続けなければならない.なので,2n12^n-1回の操作で元のバイナリに戻るという周期になるはずだ.

Jetzt denken wir über eine Methode nach, bei der wir eine binäre n×n Matrix auf eine n-th binäre Vektor anwenden und die Folge von binären Vektoren erstellen. Um möglichst viele untershiedliche Zahlen zu erzeugen, sollten wir eine Matrix wählen, deren Periode 2ⁿ−1 ist.

Xorshiftを使う理由

では,周期2n12^n-1n×nn \times nバイナリ行列TTはどうやって見つければいいだろうか. すぐにわかる特徴として,行列TTは正則でなければならない(もし正則でないとすると,どこかでつぶれてゼロになってしまう). ただこれだけでは行列の形は絞れないし,実際,周期の条件を満たすような行列は大量に存在する.

むしろ方針としては,どのような行列の作り方をすれば行列計算のコストがかからないか,という視点から行列の候補を出していき,それらが周期の条件を満たすかチェックしていきたい.そこで出てくるのがXorshiftという操作だ.

ビットシフトの操作は行列では,shift matrixとして表される. 例えば4×44 \times 4の行列では,左に1ビットシフトさせる行列L1L^1,右に1ビットシフトさせる行列R1R^1,はそれぞれ次のように表される.

R1=[0100001000010000],L1=[0000100001000010]R^1 = \begin{bmatrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 \\ \end{bmatrix}, \hspace{20pt} L^1 = \begin{bmatrix} 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}

これらは正則でないので,xor(排他的論理和)の操作を加えることでT=I+LaT=I+L^aまたはT=I+RbT=I+R^bとすると,正則かつ計算コストが少ない操作を作ることが出来る.Cコードではそれぞれ次のように表される.

y ^ (y << a)
y ^ (y >> b)

なので,これらを組み合わせることで,行列TTの候補を作って,周期の条件を満たすか確認すればよい.

元論文1によれば,n=32n=32のとき,T=(I+La)(I+Rb)T=(I+L^a)(I+R^b)またはT=(I+Rb)(I+La)T=(I+R^b)(I+L^a)という形で,周期の条件を満たすものはなく,T=(I+La)(I+Rb)(I+Rc)T=(I+L^a)(I+R^b)(I+R^c)の形であれば,条件を満たす(a,b,c)(a, b, c)の組み合わせが多数存在するそうだ.

これまでの議論で分かるように,Xorshiftのアルゴリズムは,2n12^n-1個のバイナリが出現することは保証するものの,どのようなばらつき方で出てくるかについては言及していないので,その点については別途テストする必要がある. n=32n=32の場合は(a,b,c)=(13,17,15)(a,b,c) = (13,17,15)という組み合わせが良く用いられており,特に理由がなければこのパラメタを用いるのが良さそうだ.

Nun die Frage ist, wie man eine Matrix mit einer Periode von 2ⁿ−1 finden. Eine notwendige Eigenschaft ist, dass die Matrix regelmäßig sein muss. Das reicht jedoch nicht aus, um die Form der Matrix zu bestimmen. Daher suchen wir zunächst nach Matrixoperation, die mit geringem Rechenaufwand durchgeführt werden kann. Und dann prüfen wir, ob diese Matrix die Periode-Anforderung erfüllt. Für solche Matrixoperation ist xor-Shift ein guter Kandidat. Bit-Shift Operation kann als eine Shift-Matrix beschrieben werden. Da eine Shift-Matrix nicht regulär ist, führen wir eine zusätzliche xor-Operation durch. Auf diese Weise kann ein regulär Matrixoperation mit geringem Rechenaufwand erstellt werden. Für n=32 ist es möglich, eine Matirx mit der Periode von 2ⁿ−1 aus drei (oder mehr) xor-Shift Operationen zu erstellen, und normalerweise wird (a, b, c) = (13, 17, 15) verwendet.

  1. Marsaglia, G. (2003). Xorshift RNGs. Journal of Statistical Software, 8(14), 1–6. https://doi.org/10.18637/jss.v008.i14
  2. George Marsaglia, Liang-Huei Tsay, Matrices and the structure of random number sequences, Linear Algebra and its Applications, Volume 67, 1985, Pages 147-156, ISSN 0024-3795, https://doi.org/10.1016/0024-3795(85)90192-2.