Zufallszahlengeneratoren in F und C

F

Der F9x-Standard enthält neben anderen mathematischen Funktionen auch einen Zufallszahlengenerator, der gleichverteilte Pseudo-Zufallszahlen aus dem Intervall [0,1) liefert. Standardisiert (und portabel) ist allerdings nur der Aufruf; welcher Generator tatsächlich verwendet wird, hängt vom Compilerhersteller und von der Computerarchitektur ab.
Da bei einem Aufruf des Zufallszahlengenerators nicht nur ein Wert zurückgegeben, sondern auch der interne Status der Prozedur verändert werden muß (Nebeneffekt), ist der Generator nicht als Funktion, sondern als subroutine implementiert. Die Syntax lautet
call random_number(random)
Dabei ist random ein Skalar oder Array vom Typ real, der nach dem Aufruf die Zufallszahl bzw. einen ganzen Satz von Zufallszahlen enthält. Wiederholte Aufrufe liefern aufeinanderfolgende Zufallszahlen aus der Sequenz des Generators.
Der momentane Status des Generators ist in einem Vektor vom Typ integer gespeichert und kann mit
call random_seed(get=seed)
abgefragt und mit
call random_seed(put=seed)
gesetzt werden. Die (installationsabhänigige) Länge length des Vektors seed kann man mit
call random_seed(size=length)
abfragen.
Die Möglichkeit, den Status des Generators auszulesen bzw. zu setzen, ist wichtig, wenn man eine lange, zusammenhängende Simulation in kürzere Teilabschnitte zerlegen will: Man liest am Ende jeder Teilrechnung den Status des Generators aus und initialisiert ihn damit am Beginn der nächsten. Will man (für Testzwecke) mehrere Male exakt dieselbe Folge von Zufallszahlen bekommen, so muß man analog jeweils den Generator auf denselben Ausgangszustand setzen.
In F von Imagine1 ist derzeit der "Minimalgenerator"
in+1 = 16807·in    mod    231-1
implementiert. Der Statusvektor seed besteht aus einem einzigen Element, nämlich in.

C

In C gibt es eine ganze Reihe von Zufallszahlengeneratoren, die aber häufig nicht direkt Werte aus dem Intervall [0,1) liefern, sondern ganze Zahlen im Bereich 0,¼,m-1. Ein halbwegs einfacher und ähnlich wie in F zu handhabender Generator ist drand48. Im Gegensatz zu F ist er als Funktion (vom Typ double) implementiert und kann daher entweder in der Form
random=drand48();
oder direkt an Stelle eines double- oder float-Werts in numerischen Ausdrücken verwendet werden.
Der interne Status wird in einem 3-elementigen Vektor von vorzeichenlosen ganzen 16-Bit-Zahlen gespeichert und kann mit
unsigned short int seed[3],dummy[3];
...
seed=seed48(dummy);
ausgelesen und mit
seed48(seed);
gesetzt werden. dummy ist eine Hilfsvariable vom selben Typ wie der Statusvektor seed (genaugenommen setzt die Funktion seed48 einen neuen Statusvektor und gibt gleichzeitig den alten als Funktionswert zurück).
Der verwendete Generator ist
in+1 = (25214903917·in + 11)    mod    248
wobei der "Funktionswert" xn+1=in+1/m allerdings nicht durch Division gebildet wird, sondern es werden die 48 Bits von in+1 direkt als Mantisse der double-Zahl xn+1 verwendet. (Da in der üblichen IEEE-Darstellung 52 Bits für die Mantisse vorgesehen sind, werden die 4 niedrigsten Bits von xn+1 nicht gesetzt.)



File translated from TEX by TTH, version 3.33.
On 20 Jun 2003, 10:33.