Xorshift
# Xorshift

Die Xorshift-Generatoren bilden eine Klasse moderner Pseudozufallszahlengeneratoren. Durch geringe Anforderungen an Speicher und Prozessor sind sie auch für den Einsatz auf Systemen mit geringen Ressourcen, z. B. Eingebettete Systeme, geeignet. Vorgestellt wurde der Xorshift-Generator im Jahr 2003 von seinem Entwickler George Marsaglia.

## Eigenschaften

* einfach: benutzt ausschließlich die Bit-Operationen Shift und XOR;
* geringer Speicherbedarf: gerade so viel, wie für die gewünschte Periodenlänge aus Prinzip nötig ist (s. u.);
* skalierbar: die Zahl der Zustandswörter ist frei wählbar, um die gewünschte Periodenlänge zu erhalten;
* schnell: mit nur sechs bis sieben Bit-Operationen wird ein Wort generiert;
* nur für kleinere Mengen von Zufallszahlen geeignet: scheitert an einigen statistischen Tests der TestU01-Suite
* nicht kryptographisch sicher, da der interne Zustand offen liegt.

## Theorie

Der Zustand des Generators ist ein Bitvektor $b\in \{0,1\}^{n}$ mit $n$ Bit, der zur Berechnung des nächsten Zustandes mit einer binären n×n Matrix multipliziert wird. Mit den Elementen wird dabei modulo 2 gerechnet im Körper GF(2). Die Addition von Elementen (Bits) wird dabei zur XOR-Verknüpfung und die Multiplikation zur UND-Verknüpfung. Die Periodenlänge des Generators beträgt $2^{n}-1$, wenn $b$ mit einem von Null verschiedenen Wert initialisiert und die Matrix geeignet gewählt wird. Dies wird mit genau den Matrizen erreicht, die in der Allgemeinen linearen Gruppe GL(n,2) (der Gruppe der invertierbaren binären n×n Matrizen mit der Multiplikation) die Elementordnung $2^{n}-1$ haben.

Die Matrix wird außerdem so konstruiert, dass sich die Multiplikation mit dem Zustandsvektor einfach und effizient mit wenigen Maschinenoperationen (Bitverschiebung $\ll$, $\gg$ und bitweise XOR-Verknüpfung $\oplus$) ausführen lässt. Die Entwickler gingen von solchen Darstellungen in Maschinenoperationen aus und prüften, ob die dadurch definierte Multiplikationsmatrix die Elementordnung $2^{n}-1$ hat.

Es zeigte sich: wenn $b$ ein Computerwort mit $n=32$ oder $n=64$ Bit ist, dann entsprechen die drei aufeinanderfolgenden Operationen

    $b\leftarrow b\oplus (b\ll u)$
    $b\leftarrow b\oplus (b\gg v)$
    $b\leftarrow b\oplus (b\ll w)$

einer Multiplikation mit einer Matrix der Ordnung $2^{n}-1$, wenn die konstanten Schiebeweiten $u,v,w$ geeignet gewählt werden.

Um längere Perioden als $2^{64}-1$ zu erhalten, kann man den Zustand des Generators auch mit mehreren Wörtern darstellen:

    $h\leftarrow b_{i-a}\oplus (b_{i-a}\ll u);$
    $b_{i}\leftarrow h\oplus (h\gg v)\oplus b_{i-1}\oplus (b_{i-1}\gg w);\quad i=a,a+1,\dots$

Der Zustand dieses Generators ist durch die $a$ Wörter $b_{i-a},\dots ,b_{i-1}$ gegeben ($b_{0}$ bis $b_{a-1}$ sind die Saatwerte). Wenn $e$ die Wortlänge ist, enthält der Zustand somit $n=ae$ Bit. Es werden wiederum $u,v,w$ so gewählt, dass obige Operationen eine Multiplikation des Zustandsvektors mit einer n×n-Matrix der Elementordnung $2^{n}-1$ entsprechen, welche den nächsten Zustand $b_{i-a+1},\dots ,b_{i}$ ergibt. Nach jedem solchen Rechenschritt wird $b_{i}$ als Ergebnis ausgegeben und $i$ inkrementiert.

Man erhält in der Regel bessere Zufallszahlen, wenn man statt $b_{i}$ eine etwas komplexere Funktion des Zustands $b_{i-a+1},\dots ,b_{i}$ ausgibt, zum Beispiel $c\cdot b_{i}$ mit einem ungeraden konstanten Multiplikator $c$ oder $b_{i}+b_{i-1}$.

## Initialisierung

Der Anfangszustand des Generators darf nicht Null sein; mindestens eines der $n$ Zustandsbits muss den Wert 1 haben. Ansonsten erhält man einen Generator der Periodenlänge 1, der immer nur 0 ausgibt, da nur durch Shift- und XOR-Operationen aus einer Serie von „0“ niemals eine „1“ hervorgehen kann.

Von schlechter Initialisierung, d. h. nur wenige 1-Bits im Zustandsvektor, erholt sich der Xorshift relativ schnell dank seines (in der Regel) kleinen Zustandsvektors. Die Wahrscheinlichkeit, später zufällig auf solche Zustände zu stoßen, ist wegen der geringen Zahl dieser Zustände im Vergleich zur Periodenlänge vernachlässigbar.

## Vergleich mit der rand-Funktion aus Libc

Die unter C (und C++) standardmäßig verfügbare Funktion rand ist unter Linux (Glibc) und Windows als linearer Kongruenzgenerator implementiert und liefert eine Sequenz, die nicht einmal die einfachsten statistischen Tests besteht. Es ist somit von der Verwendung abzuraten.

Ein Xorshift-RNG in der oben dargestellten Form ist mit lediglich fünf Variablen eine schnell implementierte Alternative, die jedoch auch einige statistische Tests nicht besteht.

## Vergleich mit Mersenne-Twister

Der Xorshift-Generator ist dem Mersenne-Twister zumindest ebenbürtig, wenn nicht sogar überlegen:

* Die generierten Bitsequenzen sind in beiden Fällen pseudozufällig und gleichverteilt, jedoch besteht der Mersenne-Twister nahezu alle stochastischen Tests.
* Der Speicherbedarf (für den Zustandsvektor) ist erheblich geringer (hier: 16 Bytes, statt 2496 Bytes).
* Auch ist der Xorshift-Generator knapp 60 % schneller.
* Bei schlechter Initialisierung (d. h. nur ein gesetztes Bit im Zustandsvektor) benötigt der Xorshift weniger als 10 Schritte, bis er wieder eine gleichverteilte Bit-Sequenz liefert. Der Mersenne-Twister benötigt hierzu fast 800.000 Schritte, was auch an dem größeren Zustandsvektor liegt.
* Der Xorshift-RNG hat mit $2^{128}−1$ eine kürzere Periodenlänge als der Mersenne-Twister mit $2^{19937}−1.$ Die nochmals deutlich größere Periodenlänge des Mersenne-Twisters liefert jedoch nicht wirklich eine Aussage über die Güte eines Zufallszahlengenerators: Eine längere Periode bedeutet nicht gleichzeitig eine höhere Güte oder im Ergebnis eine bessere Statistik. Darüber hinaus existieren andere moderne Generatoren mit noch längeren Perioden (bis zu $2^{131086}$ ≈ $10^{39461})$ und teils überlegenen Eigenschaften (vgl. CMWC und WELL).

## Varianten

Xorshift versagt bei einigen Tests der BigCrush Test Suite (TestU01). Das gilt für alle Generatoren, die auf linearen Operationen basieren, wie auch Mersenne-Twister oder WELL. Es ist jedoch leicht, deren Ausgaben zu verwürfeln, um ihre Qualität zu verbessern.

### Xorwow

Marsaglia schlug vor, die Periodenlänge zu vergrößern, indem Xorshift mit einem einfachen Zähler modulo $2^{32}$ kombiniert wird (was er als „Weyl-Sequenz“ bezeichnet; nach dem Gleichverteilungssatz von Weyl: die Folge $(a\cdot i{\bmod {1}})_{i\in \mathbb {N} ^{+}}$ mit irrationalem $a$ ist im Intervall ${[0,1$ gleichverteilt). Dieser Generator hat eine Periodenlänge von $(2^{128}-1)\cdot 2^{32}$:

Xorwow ist schnell, aber besteht einige Tests aus BigCrush nicht. Er ist der Standardgenerator in Nvidias CUDA.

### Xorshift*

Xorshift* entsteht aus einem normalen Xorshift, indem man die Ausgabe mit einer Konstanten modulo $2^{32}$ bzw. $2^{64}$ multipliziert (von Marsaglia vorgeschlagen). Der folgende Generator mit 64 Zustandsbits hat die Periodenlänge $2^{64}-1$ und versagt nur beim MatrixRank-Test aus BigCrush:

Ein ähnlicher Generator wird in Numerical Recipes als RanQ1 vorgeschlagen; er versagt aber ebenfalls beim BirthdaySpacings-Test.

Wenn man Xorshift* nur die 32 höchstwertigen Bits des Ergebnisses ausgeben lässt, besteht er BigCrush ohne Fehler. Dabei besteht noch eine Sicherheitsreserve, da diese Tests auch schon von einer Version des Generators mit nur 40 Zustandsbits bestanden werden.

Vigna schlägt folgenden Xorshift1024* vor, mit 1024 Zustandsbits und einer Periodenlänge von $2^{1024}-1$, der BigCrush besteht:

### Xorshift+

Statt der Multiplikation kann man auch die in der Regel schnellere Addition als nichtlineare Transformation einsetzen. Diese Idee wurde zuerst von Saito und Matsumoto (von denen auch der Mersenne-Twister stammt) vorgeschlagen, und zwar im XSadd-Generator, der zwei aufeinanderfolgende Ausgaben eines zugrundeliegenden Xorshift addiert.

XSadd hat Schwächen in den niederwertigen Ausgabebits und fällt bei einigen BigCrush-Tests durch, wenn man die Ausgabewörter invertiert, also die niederwertigsten Bits an die höchste Stelle setzt und umgekehrt. Als Abhilfe hat Vigna die Xorshift+ Familie konstruiert, die mit 64-Bit-Wörtern arbeiten: nachfolgender Xorshift128+ nutzt 128 Zustandsbits und hat eine Periodenlänge von $2^{128}-1$. Er besteht BigCrush, auch bei Invertierung.

Es ist einer der schnellsten Generatoren, die BigCrush bestehen. Ein Nachteil der Addition von aufeinanderfolgenden Ausgabewörtern ist, dass der Generator so nur noch in einer Dimension gleichverteilt ist, obwohl dies für den zugrundeliegenden Xorshift in 2 Dimensionen gilt.

### Xoroshiro und Xoshiro

Diese von Sebastiano Vigna und David Blackman entwickelten Generatoren basieren auf der gleichen Theorie wie Xorshift. Sie enthalten jedoch auch die Bitrotation als elementare Operation. Nachfolgende Versionen haben eine Periodenlänge von $2^{128}-1$.

Xoshiro ist die weiterentwickelte Variante, die nochmals bessere Zufallszahlen erzeugt und eine Periodenlänge von $2^{256}-1$ aufweist.

