Parent: [3445a0] (diff)

Child: [28b809] (diff)

Download this file

RandomLib.def    237 lines (206 with data), 15.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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.