DEFINITION MODULE RandomLib;
(*------------------------------------------------------------------------*)
(* Dieses Modul stellt verschiedene uniforme Pseudozufallszahlen- *)
(* generatoren zur Verfuegung. *)
(* This module providing several uniform pseudorandom number generators. *)
(*------------------------------------------------------------------------*)
(* Implementation : Michael Riedl *)
(* Licence : GNU Lesser General Public License (LGPL) *)
(*------------------------------------------------------------------------*)
(* $Id: RandomLib.def,v 1.5 2016/01/24 09:19:45 mriedl Exp $ *)
TYPE SeedVektor = ARRAY [1..25] OF INTEGER; (* Fuer RanLux *)
PROCEDURE Random(a,b : LONGREAL) : LONGREAL;
(*----------------------------------------------------------------*)
(* ACM Algorithm 133 *)
(* *)
(* Produces pseudo random numbers in the interval [a,b]. *)
(* *)
(* Very simple random number generator, do not use for production *)
(* code as randomness is weak. Code is only of historical *)
(* interrest. *)
(*----------------------------------------------------------------*)
PROCEDURE InitRandom();
(*----------------------------------------------------------------*)
(* Initialisiert Random neu mit Systemzeit oder selbstgenerierten *)
(* Zufallszahlen. *)
(* *)
(* Initializes Random with values form the system clock. If that *)
(* is not possible a fixed seed is used *)
(*----------------------------------------------------------------*)
PROCEDURE RanMarInit(ij,kl : CARDINAL);
(*----------------------------------------------------------------*)
(* Initialisierungsroutine f\"ur den Zufallszahlengenerator *)
(* RanMar() *)
(* Hinweis : Die Initialisierungsvariablen m\"ussen in dem *)
(* Bereich 0 <= ij <= 31328 und 0 <= kl <= 30081 *)
(* liegen. *)
(* *)
(* The random number sequences created by these two seeds are *)
(* of sufficient length to complete an entire calculation with. *)
(* For example, if sveral different groups are working on *)
(* different parts of the same calculation, each group could be *)
(* assigned its own ij seed. This would leave each group with *)
(* 30000 choices for the second seed. That is to say, this random *)
(* number generator can create 900 million different subsequences *)
(* with each subsequence having a length of approximately 1.0E+30 *)
(* *)
(* Use ij = 1802 & kl = 9373 to test the random number generator *)
(* The subroutine RanMar should be used to generate 20000 random *)
(* numbers. Then display the next six random numbers generated *)
(* multiplied by 4096*4096. If the random number generator is *)
(* working properly, the random numbers should be : *)
(* *)
(* 6533892.0 14220222.0 7275067.0 *)
(* 6172232.0 8354498.0 10633180.0 *)
(* *)
(* Anpassung an Modula-2 von M.Riedl am 03.06.1993 *)
(* *)
(* Um eine zufaellige Initialisierung zu erziehlen kann folgendes *)
(* Codesegment benutzt werden: *)
(* *)
(* VAR x : LONGREAL; i : CARDINAL; *)
(* BEGIN *)
(* InitZufallSysT; *)
(* FOR i:=1 TO 31328+30081 DO x:=Zufall(); END; *)
(* RanMarInit(IRandom(0,31328),IRandom(0,30081)); *)
(* ... *)
(*----------------------------------------------------------------*)
PROCEDURE RanMar() : LONGREAL;
(*----------------------------------------------------------------*)
(* Zufallszahlengenarator nach dem Algorithmus von *)
(* George Marsaglia, *)
(* Florida State University Report: FSU-SCRI-87-50 *)
(* *)
(* This random number generator originally appeared in *)
(* "Toward a Universal Random Number Generator" by *)
(* George Marsaglia and Arif Zaman. *)
(* Florida State University Report: FSU-SCRI-87-50 (1987) *)
(* *)
(* It was later modified by F. James and published in *)
(* "A Review of Pseudorandom Number Generators" *)
(* *)
(* THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE. *)
(* (However, a newly discovered technique can yield a period *)
(* of 10^600. But that is still in the development stage.) *)
(* *)
(* It passes ALL of the tests for random number generators and *)
(* has a period of 2^144, is completely portable (gives bit *)
(* identical results on all machines with at least 24-bit *)
(* mantissas in the floating point representation). *)
(* *)
(* The algorithm is a combination of a Fibonacci sequence (with *)
(* lags of 97 and 33, and operation "subtraction plus one, *)
(* modulo one") and an "arithmetic sequence" (using subtraction). *)
(* *)
(* On a Vax 11/780, this random number generator can produce a *)
(* number in 13 microseconds. *)
(* *)
(* Auf einem 386/387-64 (16MHz) werden, bei leicht ge\"andertem *)
(* Algorithmus (1 Zufallszahl je Ausfruf statt eines Feldes von *)
(* Zufallszahlen), 85 Mikrosekunden ben\"otigt. *)
(* *)
(* Anpassung an Modula-2 von M.Riedl, 03.06.1993 *)
(*----------------------------------------------------------------*)
PROCEDURE InitZufall;
(*----------------------------------------------------------------*)
(* Initialisiert den Zufallszahlengenerator Zufall(). *)
(* *)
(* Initializes Zufall with the original seed *)
(*----------------------------------------------------------------*)
PROCEDURE InitZufallSysT;
(*----------------------------------------------------------------*)
(* Initialisiert den Zufallszahlengenerator Zufall() mit Werten *)
(* die von der Systemzeit abhaengen (nicht/schwer reproduzierbar) *)
(* *)
(* Initializes the random number generator Zufall() with values *)
(* dependent on the system clock (not/difficult to reproduce) *)
(*----------------------------------------------------------------*)
PROCEDURE Zufall() : LONGREAL;
(*----------------------------------------------------------------*)
(* Berechnet Zufallszahlen im Intervall [0,1) nach dem Additive *)
(* Congruential Random Number (ACORN) Algorithmus. *)
(* *)
(* Wikramaratna, R.S. "ACORN ��� A new method for generating *)
(* sequences of uniformly distributed Pseudo-random Numbers", *)
(* J. Comp. Phys. 83,1 pp 16-31 (1989) *)
(*----------------------------------------------------------------*)
PROCEDURE IRandom(a,b : CARDINAL) : CARDINAL;
(*----------------------------------------------------------------*)
(* Berechne eine Zufallszahl im Intervall [a,b] *)
(* Calculate a random number in the intervall [a,b] *)
(* Benutzt / uses : Zufall *)
(*----------------------------------------------------------------*)
PROCEDURE RLuxGo(Lux,InS,K1,K2: INTEGER);
(*----------------------------------------------------------------*)
(* Origin : CERN Program Library (SUBROUTINE RANLUX) *)
(* *)
(* Entry to initialize from one or three integers *)
(* Initializes the generator from one 32-bit integer InS and sets *)
(* Luxury Level Lux which is integer between zero and MAXLEV, or *)
(* if Lux .GT. 24, it sets p=Lux directly. K1 and K2 should be *)
(* set to zero unless restarting at a break point given by output *)
(* of RLuxAt (see RLuxAt). RanLux will then skip over *)
(* K1 + 10**9*K2 numbers to reach the break point. This can be *)
(* rather time consuming - see RLuxUt/RLuxIn for an alternative *)
(* to restart RanLux. *)
(*----------------------------------------------------------------*)
PROCEDURE RLuxAt(VAR Lout,InOut,K1,K2 : INTEGER);
(*----------------------------------------------------------------*)
(* Origin : CERN Program Library (SUBROUTINE RANLUX) *)
(* *)
(* Entry to output the "convenient" restart point *)
(* gets the values of four integers which can be used to restart *)
(* the RanLux generator at the current point by calling RLuxGo. *)
(* K1 and K2 specify how many numbers were generated since the *)
(* initialization with LUX and INT. The restarting skips over *)
(* K1+K2*E9 numbers, so it can be long. *)
(*----------------------------------------------------------------*)
PROCEDURE RLuxUt(VAR ISDext : SeedVektor);
(*----------------------------------------------------------------*)
(* Origin : CERN Program Library (SUBROUTINE RANLUX) *)
(* *)
(* Entry to ouput seeds as integers *)
(* Outputs the current values of the 25 ++ 32-bit integer seeds, *)
(* to be used for restarting. Argument must be dimensioned 25 in *)
(* the calling program. *)
(*----------------------------------------------------------------*)
PROCEDURE RLuxIn(VAR ISDext : SeedVektor);
(*----------------------------------------------------------------*)
(* Origin : CERN Program Library (SUBROUTINE RANLUX) *)
(* *)
(* Entry to input and float integer seeds from previous run *)
(* more efficient but less convenient way of restarting is by *)
(* RLuxIn(ISDext). It restarts the generator from vector *)
(* ISVEC of 25 32-bit integers (see RLuxUt) *)
(* *)
(* HINT : If seed or luxlevel had been chenge in between they *)
(* need to be re-set by RLuxGo(originalLuxlevel,originalSeed,0,0) *)
(* before the call to RLuxIn !!! *)
(*----------------------------------------------------------------*)
PROCEDURE RanLux(VAR RVec : ARRAY OF LONGREAL;
LenV : INTEGER);
(*----------------------------------------------------------------*)
(* Origin : CERN Program Library (SUBROUTINE RANLUX) *)
(* *)
(* Returns a vector RVec of LenV of 32-bit random floating point *)
(* numbers between zero (not included) and one (also not incl.). *)
(* Subtract-and-borrow random number generator proposed by *)
(* Marsaglia and Zaman, implemented by F. James with the name *)
(* RCARRY in 1991, and later improved by Martin Luescher in 1993 *)
(* to produce "Luxury Pseudorandom Numbers". *)
(* *)
(* The available luxury levels are: *)
(* *)
(* 0 : p=24: equivalent to the original RCARRY of Marsaglia *)
(* and Zaman, very long period, but fails many tests. *)
(* 1 : p=48: considerable improvement in quality over level 0, *)
(* now passes the gap test, but still fails spectral test. *)
(* 2 : p=97: passes all known tests, but theoretically still *)
(* defective. *)
(* 3 : p=223: DEFAULT VALUE. Any theoretically possible *)
(* correlations have very small chance of being observed. *)
(* 4 : p=389: highest possible luxury, all 24 bits chaotic. *)
(* *)
(* The level can be change via routine RLuxGo *)
(*----------------------------------------------------------------*)
END RandomLib.