|
a |
|
b/RandomLib.mod.m2pp |
|
|
1 |
IMPLEMENTATION MODULE RandomLib;
|
|
|
2 |
|
|
|
3 |
(*========================================================================*)
|
|
|
4 |
(* HINWEIS : Bitte nur die Datei RandomLib.mod.m2pp editieren *)
|
|
|
5 |
(*========================================================================*)
|
|
|
6 |
(* Es sind 2 Versionen enthalten die mit *)
|
|
|
7 |
(* *)
|
|
|
8 |
(* m2pp -D __{Parameter}__ < RandomLib.mod.m2pp > RandomLib.mod *)
|
|
|
9 |
(* *)
|
|
|
10 |
(* mit Parameter = {XDS|GM2} erzeugt werden koennen. *)
|
|
|
11 |
(* *)
|
|
|
12 |
(* XDS : Der Export von Objekten aus lokalen Modulen wird mit *)
|
|
|
13 |
(* "IMPORT" angezeigt - das scheint nicht ganz "regelkonform" *)
|
|
|
14 |
(* GM2 : Normales "EXPORT" wird genutzt (ELSE-Fall). *)
|
|
|
15 |
(* *)
|
|
|
16 |
(* ansonsten gibt es keine Aenderungen am Quellcode *)
|
|
|
17 |
(*------------------------------------------------------------------------*)
|
|
|
18 |
(* Dieses Modul stellt verschiedene uniforme Pseudozufallszahlen- *)
|
|
|
19 |
(* generatoren zur Verfuegung. *)
|
|
|
20 |
(* This module providing several uniform pseudorandom number generators. *)
|
|
|
21 |
(*------------------------------------------------------------------------*)
|
|
|
22 |
(* Letzte Aenderung: *)
|
|
|
23 |
(* *)
|
|
|
24 |
(* 03.06.93, MRi: Erstellen der ersten Version von RanMar / RanMarInit *)
|
|
|
25 |
(* 13.10.15, MRi: Ersetzen von LFLOAT(LTRUNC( durch LowLong.intpart( *)
|
|
|
26 |
(* 21.01.16, MRi: Einfuehren von InitZufallSysT, *)
|
|
|
27 |
(* Verbesserung der Doku im Definitionsmodul *)
|
|
|
28 |
(* 06.09.15, MRi: Uebersetzen von ACM 133 von Algol60 nach Modula-2 *)
|
|
|
29 |
(* 02.12.15, MRi: Einfuegen von InitRandom fuer ACM 133 *)
|
|
|
30 |
(* 22.01.16, MRi: Einfuegen von ACM133 in Modul Random *)
|
|
|
31 |
(* 22.01.16, MRi: Erstellen der ersten Version des CERN Library RanLux *)
|
|
|
32 |
(* Random number generators - uebersetzt von Fortran 77 *)
|
|
|
33 |
(* nach Modula-2. *)
|
|
|
34 |
(* 23.01.16, MRi: Kleinere Anpassungen an RanLux, EA hinzugefuegt *)
|
|
|
35 |
(* RanLux,RLuxGo gegen F77 Version mit 8*10**6 generierten *)
|
|
|
36 |
(* Zufallszahlen erfolgreich getestet. *)
|
|
|
37 |
(* 23.01.16, MRi: Integrieren von RanLux in Random, umbenennen des Moduls *)
|
|
|
38 |
(* in RandomLib, testen der Restart-Optionen von RanLux *)
|
|
|
39 |
(* 04.04.16, MRi: Initialisierungsroutinen von Random und Zufall ueber- *)
|
|
|
40 |
(* arbeitet um sicherzustellen dass nicht mit 0 *)
|
|
|
41 |
(* initialisiert wird. *)
|
|
|
42 |
(* 12.04.16, MRi: Initialisierungsroutinen von Random und Zufall ueber- *)
|
|
|
43 |
(* arbeitet damit nach kuerzerer Zeit eine neue Zufalls- *)
|
|
|
44 |
(* zahlenreihe abgerufen werden kann. *)
|
|
|
45 |
(*------------------------------------------------------------------------*)
|
|
|
46 |
(* Offene Punkte *)
|
|
|
47 |
(* *)
|
|
|
48 |
(* - Wieso funktioniert ein Aufruf von RLuxGo mit K1,K2 # 0 nicht bei *)
|
|
|
49 |
(* luxlev 3 & 4 - dann schlaegt auch der Restart mit RLuxAt/RLuxGo *)
|
|
|
50 |
(* fehl (merkwuergerweise sind die ersten Werte noch richtig), nicht *)
|
|
|
51 |
(* aber der mit RLuxUt/RLuxGo&RLuxIn. Wenn K1+K2=0 ist alles gut. *)
|
|
|
52 |
(* Dir Fortran-Routine verhaelt sich aber auch so ... *)
|
|
|
53 |
(* - Herausnahme der debug-optionen in RanLux (ersetzen durch *)
|
|
|
54 |
(* Praeprozessor-direktiven). *)
|
|
|
55 |
(*------------------------------------------------------------------------*)
|
|
|
56 |
(* Implementation : Michael Riedl *)
|
|
|
57 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
|
|
58 |
(*------------------------------------------------------------------------*)
|
|
|
59 |
|
|
|
60 |
(* $Id: RandomLib.mod.m2pp,v 1.7 2018/01/16 09:19:51 mriedl Exp mriedl $ *)
|
|
|
61 |
|
|
|
62 |
FROM SysClock IMPORT maxSecondParts,DateTime,CanGetClock,GetClock;
|
|
|
63 |
IMPORT LowLong;
|
|
|
64 |
IMPORT LongMath;
|
|
|
65 |
IMPORT Errors;
|
|
|
66 |
IMPORT TIO;
|
|
|
67 |
|
|
|
68 |
MODULE ACM133;
|
|
|
69 |
|
|
|
70 |
IMPORT maxSecondParts,DateTime,CanGetClock,GetClock;
|
|
|
71 |
|
|
|
72 |
<* IF (__XDS__) THEN *>
|
|
|
73 |
IMPORT Random,InitRandom; (* EXPORT *)
|
|
|
74 |
<* ELSE *>
|
|
|
75 |
EXPORT Random,InitRandom;
|
|
|
76 |
<* END *>
|
|
|
77 |
|
|
|
78 |
VAR X : ARRAY [1..2] OF INTEGER;
|
|
|
79 |
|
|
|
80 |
PROCEDURE Random(a,b : LONGREAL) : LONGREAL;
|
|
|
81 |
|
|
|
82 |
(* ACM Algorithm 133 *)
|
|
|
83 |
|
|
|
84 |
CONST mult = 5;
|
|
|
85 |
mscale = 1048576;
|
|
|
86 |
topscale = 32768;
|
|
|
87 |
mrecip = 3.435973E-10; (* 2.0**(-35) *)
|
|
|
88 |
toprecip = 3.051757E-05; (* 2.0**(-15) *)
|
|
|
89 |
BEGIN
|
|
|
90 |
X[1] := mult * X[1];
|
|
|
91 |
X[2] := mult * X[2];
|
|
|
92 |
|
|
|
93 |
(* Add overflow from X[2] and remove it from X[2] *)
|
|
|
94 |
|
|
|
95 |
IF (X[2] >= mscale) THEN
|
|
|
96 |
X[1] := X[1] + X[2] DIV mscale;
|
|
|
97 |
X[2] := X[2] MOD mscale;
|
|
|
98 |
END;
|
|
|
99 |
|
|
|
100 |
(* Possibly need to tidy up X[1] *)
|
|
|
101 |
|
|
|
102 |
IF (X[1] >= topscale) THEN
|
|
|
103 |
X[1] := X[1] MOD topscale;
|
|
|
104 |
END;
|
|
|
105 |
|
|
|
106 |
(* Generate a real value in the required range *)
|
|
|
107 |
|
|
|
108 |
RETURN (VAL(LONGREAL,X[1])*toprecip + VAL(LONGREAL,X[2])*mrecip) *
|
|
|
109 |
(b-a) + a;
|
|
|
110 |
END Random;
|
|
|
111 |
|
|
|
112 |
PROCEDURE InitRandom();
|
|
|
113 |
|
|
|
114 |
VAR dt : DateTime;
|
|
|
115 |
T,frac : CARDINAL;
|
|
|
116 |
x : REAL;
|
|
|
117 |
BEGIN
|
|
|
118 |
IF CanGetClock() THEN
|
|
|
119 |
GetClock(dt);
|
|
|
120 |
frac := dt.fractions + 1;
|
|
|
121 |
IF (frac = 1) THEN frac:=maxSecondParts; END;
|
|
|
122 |
(*
|
|
|
123 |
T:=(((dt.hour + 1)*60 + (dt.minute + 1))*60 +
|
|
|
124 |
(dt.second + 1))*maxSecondParts + frac;
|
|
|
125 |
*)
|
|
|
126 |
T:=((dt.second + 1))*maxSecondParts + frac;
|
|
|
127 |
x:=VAL(REAL,T); (* / VAL(REAL,24*360*maxSecondParts); *)
|
|
|
128 |
WHILE (x >= 10.0) DO x:=x / 3.14152927; END;
|
|
|
129 |
WHILE (x < 10.0) DO x:=x * 10.00; END;
|
|
|
130 |
X[1]:=TRUNC(x);
|
|
|
131 |
X[2]:=TRUNC(4096.0*(x-VAL(REAL,X[1])));
|
|
|
132 |
ELSE
|
|
|
133 |
X[1]:=VAL(INTEGER,Random(1.0,111.0)) DIV VAL(INTEGER,Random(1.0,111.0));
|
|
|
134 |
X[2]:=VAL(INTEGER,Random(5.0,555.0)) MOD VAL(INTEGER,Random(5.0,555.0));
|
|
|
135 |
END;
|
|
|
136 |
END InitRandom;
|
|
|
137 |
|
|
|
138 |
BEGIN
|
|
|
139 |
X[1]:=13;
|
|
|
140 |
X[2]:=19;
|
|
|
141 |
END ACM133;
|
|
|
142 |
|
|
|
143 |
MODULE RandomMar;
|
|
|
144 |
|
|
|
145 |
IMPORT Errors;
|
|
|
146 |
|
|
|
147 |
<* IF (__XDS__) THEN *>
|
|
|
148 |
IMPORT RanMarInit,RanMar; (* EXPORT *)
|
|
|
149 |
<* ELSE *>
|
|
|
150 |
EXPORT RanMarInit,RanMar;
|
|
|
151 |
<* END *>
|
|
|
152 |
|
|
|
153 |
VAR U : ARRAY [1..97] OF LONGREAL;
|
|
|
154 |
c,cd,cm : LONGREAL;
|
|
|
155 |
i97,j97 : CARDINAL;
|
|
|
156 |
|
|
|
157 |
PROCEDURE RanMarInit(ij,kl : CARDINAL);
|
|
|
158 |
|
|
|
159 |
VAR i,j,k,l,m : CARDINAL;
|
|
|
160 |
ii,jj : CARDINAL;
|
|
|
161 |
s,t : LONGREAL;
|
|
|
162 |
|
|
|
163 |
BEGIN
|
|
|
164 |
IF (ij > 31328) OR (kl > 30081) THEN
|
|
|
165 |
Errors.ErrOut("(ij IN {0..31328}) oder ");
|
|
|
166 |
Errors.FatalError("(kl IN {0..30081}) nicht erfuellt (Random.RanMarInit)");
|
|
|
167 |
END;
|
|
|
168 |
|
|
|
169 |
i := ((ij DIV 177) MOD 177) + 2;
|
|
|
170 |
j := ( ij MOD 177) + 2;
|
|
|
171 |
k := ((kl DIV 169) MOD 178) + 1;
|
|
|
172 |
l := ( kl MOD 169);
|
|
|
173 |
|
|
|
174 |
FOR ii:= 1 TO 97 DO
|
|
|
175 |
s := 0.0;
|
|
|
176 |
t := 0.5;
|
|
|
177 |
FOR jj:=1 TO 24 DO
|
|
|
178 |
m := ((i*j MOD 179)*k) MOD 179;
|
|
|
179 |
i := j;
|
|
|
180 |
j := k;
|
|
|
181 |
k := m;
|
|
|
182 |
l := (53*l+1) MOD 169;
|
|
|
183 |
IF (((l*m) MOD 64) >= 32) THEN s:=s + t; END;
|
|
|
184 |
t := 0.5 * t;
|
|
|
185 |
END;
|
|
|
186 |
U[ii] := s;
|
|
|
187 |
END;
|
|
|
188 |
|
|
|
189 |
c := 362436.0 / 16777216.0;
|
|
|
190 |
cd := 7654321.0 / 16777216.0;
|
|
|
191 |
cm := 16777213.0 / 16777216.0;
|
|
|
192 |
|
|
|
193 |
i97 := 97;
|
|
|
194 |
j97 := 33;
|
|
|
195 |
END RanMarInit;
|
|
|
196 |
|
|
|
197 |
PROCEDURE RanMar() : LONGREAL;
|
|
|
198 |
|
|
|
199 |
VAR uni : LONGREAL;
|
|
|
200 |
|
|
|
201 |
BEGIN
|
|
|
202 |
uni := U[i97] - U[j97];
|
|
|
203 |
IF ( uni < 0.0 ) THEN uni:=uni + 1.0; END;
|
|
|
204 |
U[i97] := uni;
|
|
|
205 |
DEC(i97); IF (i97 = 0) THEN i97 := 97; END;
|
|
|
206 |
DEC(j97); IF (j97 = 0) THEN j97 := 97; END;
|
|
|
207 |
c := c - cd;
|
|
|
208 |
IF (c < 0.0) THEN c:=c + cm; END;
|
|
|
209 |
uni := uni - c;
|
|
|
210 |
IF (uni < 0.0) THEN uni:=uni + 1.0; END;
|
|
|
211 |
RETURN uni;
|
|
|
212 |
END RanMar;
|
|
|
213 |
|
|
|
214 |
BEGIN
|
|
|
215 |
RanMarInit(1802,9373);
|
|
|
216 |
END RandomMar;
|
|
|
217 |
|
|
|
218 |
MODULE ZUFALL;
|
|
|
219 |
|
|
|
220 |
IMPORT LowLong;
|
|
|
221 |
IMPORT maxSecondParts,DateTime,CanGetClock,GetClock;
|
|
|
222 |
IMPORT TIO;
|
|
|
223 |
|
|
|
224 |
<* IF (__XDS__) THEN *>
|
|
|
225 |
IMPORT InitZufallSysT,InitZufall,Zufall; (* EXPORT *)
|
|
|
226 |
<* ELSE *>
|
|
|
227 |
EXPORT InitZufallSysT,InitZufall,Zufall;
|
|
|
228 |
<* END *>
|
|
|
229 |
|
|
|
230 |
CONST Order = 13;
|
|
|
231 |
|
|
|
232 |
VAR XV : ARRAY [1..Order] OF LONGREAL;
|
|
|
233 |
|
|
|
234 |
PROCEDURE InitZufall;
|
|
|
235 |
|
|
|
236 |
VAR i : CARDINAL;
|
|
|
237 |
BEGIN
|
|
|
238 |
FOR i:=3 TO Order DO XV[i]:=0.0; END;
|
|
|
239 |
XV[1]:=0.14159265E+00;
|
|
|
240 |
XV[2]:=0.70710678E+00;
|
|
|
241 |
END InitZufall;
|
|
|
242 |
|
|
|
243 |
PROCEDURE InitZufallSysT;
|
|
|
244 |
|
|
|
245 |
VAR i : CARDINAL;
|
|
|
246 |
dt : DateTime;
|
|
|
247 |
T,frac : CARDINAL;
|
|
|
248 |
x : REAL;
|
|
|
249 |
BEGIN
|
|
|
250 |
IF CanGetClock() THEN
|
|
|
251 |
GetClock(dt);
|
|
|
252 |
frac := dt.fractions + 1;
|
|
|
253 |
IF (frac = 1) THEN frac:=maxSecondParts; END;
|
|
|
254 |
T:= (dt.second + 1)*maxSecondParts + frac;
|
|
|
255 |
x:=VAL(REAL,T);
|
|
|
256 |
WHILE (x >= 10.0) DO x:=x / 3.1415927; END;
|
|
|
257 |
WHILE (x < 10.0) DO x:=x*10.0; END;
|
|
|
258 |
XV[1]:=VAL(LONGREAL,TRUNC(x));
|
|
|
259 |
XV[2]:=VAL(LONGREAL,TRUNC(1000.0*(x-VAL(REAL,XV[1]))));
|
|
|
260 |
XV[1]:=0.14159265*XV[1];
|
|
|
261 |
XV[2]:=0.70710678*XV[2];
|
|
|
262 |
FOR i:=3 TO Order DO XV[i]:=0.0; END;
|
|
|
263 |
ELSE
|
|
|
264 |
InitZufall;
|
|
|
265 |
END;
|
|
|
266 |
END InitZufallSysT;
|
|
|
267 |
|
|
|
268 |
PROCEDURE Zufall() : LONGREAL;
|
|
|
269 |
|
|
|
270 |
VAR i : CARDINAL;
|
|
|
271 |
|
|
|
272 |
BEGIN
|
|
|
273 |
FOR i:=1 TO Order-1 DO
|
|
|
274 |
XV[i+1]:=(XV[i+1]+XV[i]) - LowLong.intpart(XV[i+1]+XV[i]);
|
|
|
275 |
END;
|
|
|
276 |
RETURN XV[Order];
|
|
|
277 |
END Zufall;
|
|
|
278 |
|
|
|
279 |
BEGIN
|
|
|
280 |
InitZufall();
|
|
|
281 |
END ZUFALL;
|
|
|
282 |
|
|
|
283 |
PROCEDURE IRandom(a,b : CARDINAL) : CARDINAL; (* MR, 12.02.2015 *)
|
|
|
284 |
|
|
|
285 |
VAR min : CARDINAL;
|
|
|
286 |
BEGIN
|
|
|
287 |
IF (b >= a) THEN min:=a; a:=b-a; ELSE min:=b; a:=a-b; END;
|
|
|
288 |
RETURN VAL(CARDINAL,(LongMath.round(VAL(LONGREAL,a)*Zufall()))) + min;
|
|
|
289 |
END IRandom;
|
|
|
290 |
|
|
|
291 |
|
|
|
292 |
MODULE LuxaryRandom;
|
|
|
293 |
|
|
|
294 |
IMPORT Errors;
|
|
|
295 |
IMPORT TIO;
|
|
|
296 |
IMPORT SeedVektor;
|
|
|
297 |
|
|
|
298 |
<* IF (__XDS__) THEN *>
|
|
|
299 |
IMPORT RLuxGo,RLuxAt,RLuxUt,RLuxIn,RanLux; (* EXPORT *)
|
|
|
300 |
<* ELSE *>
|
|
|
301 |
EXPORT RLuxGo,RLuxAt,RLuxUt,RLuxIn,RanLux;
|
|
|
302 |
<* END *>
|
|
|
303 |
|
|
|
304 |
(*------------------------------------------------------------------------*)
|
|
|
305 |
(* All code derived from CERN Program Library SUBROUTINE RANLUX *)
|
|
|
306 |
(* Translated from FORTRAN77 to Modula-2 by Michael Riedl, Jan. 2016 *)
|
|
|
307 |
(*------------------------------------------------------------------------*)
|
|
|
308 |
|
|
|
309 |
CONST debug = TRUE;
|
|
|
310 |
|
|
|
311 |
CONST MaxLev = 4;
|
|
|
312 |
LXdflt = 3;
|
|
|
313 |
TwoP12 = 4096.0;
|
|
|
314 |
JSdflt = 314159265;
|
|
|
315 |
IGiga = 1000000000;
|
|
|
316 |
Itwo24 = 16777216; (* 2**24 *)
|
|
|
317 |
ICons = 2147483563;
|
|
|
318 |
|
|
|
319 |
VAR ndskip : ARRAY[0..MaxLev] OF INTEGER; (* save *)
|
|
|
320 |
seeds : ARRAY[1..24] OF LONGREAL; (* save *)
|
|
|
321 |
iseeds : ARRAY[1..24] OF INTEGER; (* save *)
|
|
|
322 |
next : ARRAY[1..24] OF INTEGER; (* save *)
|
|
|
323 |
|
|
|
324 |
notyet : BOOLEAN; (* save *)
|
|
|
325 |
luxlev : INTEGER; (* save *)
|
|
|
326 |
i24,j24,in24 : INTEGER; (* save *)
|
|
|
327 |
kount,mkount : INTEGER; (* save *)
|
|
|
328 |
nskip : INTEGER; (* save *)
|
|
|
329 |
twom24,twom12 : LONGREAL; (* save *)
|
|
|
330 |
carry : LONGREAL; (* save *)
|
|
|
331 |
|
|
|
332 |
uni : LONGREAL;
|
|
|
333 |
inseed,jseed : INTEGER;
|
|
|
334 |
|
|
|
335 |
PROCEDURE RLuxGo(Lux,InS,K1,K2 : INTEGER);
|
|
|
336 |
|
|
|
337 |
VAR izip,izip2 : INTEGER;
|
|
|
338 |
inner,iouter : INTEGER;
|
|
|
339 |
i,k,ilx,isk : INTEGER;
|
|
|
340 |
BEGIN
|
|
|
341 |
IF (Lux < 0) THEN
|
|
|
342 |
luxlev := LXdflt
|
|
|
343 |
ELSIF (Lux <= MaxLev) THEN
|
|
|
344 |
luxlev := Lux
|
|
|
345 |
ELSIF (Lux < 24) OR (Lux > 2000) THEN
|
|
|
346 |
luxlev := MaxLev;
|
|
|
347 |
Errors.ErrOut('RanLux ILLEGAL Luxury RLuxGo (not in 24 .. 2000) ');
|
|
|
348 |
ELSE
|
|
|
349 |
luxlev := Lux;
|
|
|
350 |
FOR ilx:=0 TO MaxLev DO
|
|
|
351 |
IF (Lux = (ndskip[ilx] + 24)) THEN
|
|
|
352 |
luxlev := ilx;
|
|
|
353 |
END;
|
|
|
354 |
END;
|
|
|
355 |
END;
|
|
|
356 |
IF (luxlev <= MaxLev) THEN
|
|
|
357 |
nskip := ndskip[luxlev];
|
|
|
358 |
IF debug THEN
|
|
|
359 |
TIO.WrStr(' RanLux luxury level set by RLuxGo : ');
|
|
|
360 |
TIO.WrInt(luxlev,2); TIO.WrStr(', P = '); TIO.WrInt(nskip+24,1);
|
|
|
361 |
TIO.WrLn;
|
|
|
362 |
END;
|
|
|
363 |
ELSE
|
|
|
364 |
nskip := luxlev - 24;
|
|
|
365 |
IF debug THEN
|
|
|
366 |
TIO.WrStr(' RanLux P-value set by RLuxGo to :');
|
|
|
367 |
TIO.WrInt(luxlev,1); TIO.WrLn;
|
|
|
368 |
END;
|
|
|
369 |
END;
|
|
|
370 |
in24 := 0;
|
|
|
371 |
IF (InS < 0) THEN
|
|
|
372 |
Errors.ErrOut('Illegal initialization by RLuxGo, negative input seed');
|
|
|
373 |
END;
|
|
|
374 |
IF (InS > 0) THEN
|
|
|
375 |
jseed := InS;
|
|
|
376 |
IF debug THEN
|
|
|
377 |
TIO.WrStr(' RanLux initialized by RLuxGo from seeds ');
|
|
|
378 |
TIO.WrInt(jseed,1); TIO.WrChar(",");
|
|
|
379 |
TIO.WrInt(K1,1); TIO.WrChar(",");
|
|
|
380 |
TIO.WrInt(K2,1); TIO.WrLn;
|
|
|
381 |
END;
|
|
|
382 |
ELSE
|
|
|
383 |
jseed := JSdflt;
|
|
|
384 |
IF debug THEN
|
|
|
385 |
TIO.WrStr(' RanLux initialized by RLuxGo form default seed');
|
|
|
386 |
TIO.WrLn;
|
|
|
387 |
END;
|
|
|
388 |
END;
|
|
|
389 |
inseed := jseed;
|
|
|
390 |
notyet:=FALSE;
|
|
|
391 |
twom24 := 1.0;
|
|
|
392 |
FOR i:=1 TO 24 DO
|
|
|
393 |
twom24 := twom24*0.5;
|
|
|
394 |
k := jseed DIV 53668;
|
|
|
395 |
jseed:=40014*(jseed - k*53668) - k*12211;
|
|
|
396 |
IF (jseed < 0) THEN
|
|
|
397 |
jseed:=jseed + ICons;
|
|
|
398 |
END;
|
|
|
399 |
iseeds[i]:= (jseed MOD Itwo24);
|
|
|
400 |
END;
|
|
|
401 |
twom12 := twom24*4096.0;
|
|
|
402 |
FOR i:=1 TO 24 DO;
|
|
|
403 |
seeds[i]:=VAL(LONGREAL,iseeds[i])*twom24;
|
|
|
404 |
next[i]:=i - 1;
|
|
|
405 |
END;
|
|
|
406 |
next[1]:=24;
|
|
|
407 |
i24 := 24;
|
|
|
408 |
j24 := 10;
|
|
|
409 |
carry := 0.0;
|
|
|
410 |
IF (seeds[24] = 0.0) THEN
|
|
|
411 |
carry := twom24;
|
|
|
412 |
END;
|
|
|
413 |
(* If restarting at a break point, skip K1 + IGiga*K2 *)
|
|
|
414 |
(* Note that this is the number of numbers delivered to *)
|
|
|
415 |
(* the user PLUS the number skipped (if luxury .GT. 0). *)
|
|
|
416 |
kount := K1;
|
|
|
417 |
mkount := K2;
|
|
|
418 |
IF (K1+K2 # 0) THEN
|
|
|
419 |
FOR iouter:=1 TO K2+1 DO
|
|
|
420 |
inner := IGiga;
|
|
|
421 |
IF (iouter = (K2+1)) THEN
|
|
|
422 |
inner := K1;
|
|
|
423 |
END;
|
|
|
424 |
FOR isk:=1 TO inner DO
|
|
|
425 |
uni:=seeds[j24] - seeds[i24] - carry;
|
|
|
426 |
IF (uni < 0.0) THEN
|
|
|
427 |
uni:=uni + 1.0;
|
|
|
428 |
carry := twom24;
|
|
|
429 |
ELSE
|
|
|
430 |
carry := 0.0;
|
|
|
431 |
END;
|
|
|
432 |
seeds[i24]:=uni;
|
|
|
433 |
i24 := next[i24];
|
|
|
434 |
j24 := next[j24];
|
|
|
435 |
END;
|
|
|
436 |
END;
|
|
|
437 |
(* Get the right value of IN24 by direct calculation *)
|
|
|
438 |
in24 := kount MOD (nskip+24);
|
|
|
439 |
IF (mkount > 0) THEN
|
|
|
440 |
izip := IGiga MOD (nskip+24);
|
|
|
441 |
izip2 := mkount*izip + in24;
|
|
|
442 |
in24 := izip2 MOD (nskip+24);
|
|
|
443 |
END;
|
|
|
444 |
(* Now IN24 had better be between zero and 23 inclusive *)
|
|
|
445 |
IF (in24 > 23) THEN
|
|
|
446 |
Errors.ErrOut('Error in restarting with RLuxGo:');
|
|
|
447 |
Errors.WriteString(' The values ');
|
|
|
448 |
Errors.WriteInt(InS); Errors.WriteChar(",");
|
|
|
449 |
Errors.WriteInt(K1); Errors.WriteChar(",");
|
|
|
450 |
Errors.WriteInt(K2);
|
|
|
451 |
Errors.WriteString(' cannot occur at luxury level ');
|
|
|
452 |
Errors.WriteInt(luxlev);
|
|
|
453 |
Errors.WriteLn; Errors.WriteLn;
|
|
|
454 |
in24 := 0;
|
|
|
455 |
END;
|
|
|
456 |
END; (* IF (K1+K2 # 0) *)
|
|
|
457 |
END RLuxGo;
|
|
|
458 |
|
|
|
459 |
PROCEDURE RLuxAt(VAR Lout,InOut,K1,K2 : INTEGER);
|
|
|
460 |
|
|
|
461 |
BEGIN
|
|
|
462 |
Lout:=luxlev;
|
|
|
463 |
InOut:=inseed;
|
|
|
464 |
K1:=kount;
|
|
|
465 |
K2:=mkount;
|
|
|
466 |
END RLuxAt;
|
|
|
467 |
|
|
|
468 |
PROCEDURE RLuxUt(VAR ISDext : SeedVektor);
|
|
|
469 |
|
|
|
470 |
VAR i : INTEGER;
|
|
|
471 |
BEGIN
|
|
|
472 |
FOR i:=1 TO 24 DO
|
|
|
473 |
ISDext[i] := TRUNC(seeds[i]*TwoP12*TwoP12);
|
|
|
474 |
END;
|
|
|
475 |
ISDext[25] := i24 + 100*j24 + 10000*in24 + 1000000*luxlev;
|
|
|
476 |
IF (carry > 0.0) THEN
|
|
|
477 |
ISDext[25] := -ISDext[25];
|
|
|
478 |
END;
|
|
|
479 |
END RLuxUt;
|
|
|
480 |
|
|
|
481 |
PROCEDURE RLuxIn(VAR ISDext : SeedVektor);
|
|
|
482 |
|
|
|
483 |
VAR i,isd : INTEGER;
|
|
|
484 |
BEGIN
|
|
|
485 |
notyet:=FALSE;
|
|
|
486 |
twom24 := 1.0;
|
|
|
487 |
FOR i:=1 TO 24 DO
|
|
|
488 |
next[i] := i-1;
|
|
|
489 |
twom24 := twom24*0.5;
|
|
|
490 |
END;
|
|
|
491 |
next[1] := 24;
|
|
|
492 |
twom12 := twom24*4096.0;
|
|
|
493 |
IF debug THEN
|
|
|
494 |
TIO.WrStr(' Full initialization of RanLux with 25 integers:');
|
|
|
495 |
TIO.WrLn;
|
|
|
496 |
FOR i:=1 TO 25 DO
|
|
|
497 |
TIO.WrInt(ISDext[i],1);
|
|
|
498 |
IF ((i MOD 5) = 0) THEN TIO.WrLn; ELSE TIO.WrChar(','); END;
|
|
|
499 |
END;
|
|
|
500 |
TIO.WrLn;
|
|
|
501 |
END;
|
|
|
502 |
FOR i:=1 TO 24 DO
|
|
|
503 |
seeds[i] := VAL(LONGREAL,ISDext[i])*twom24;
|
|
|
504 |
END;
|
|
|
505 |
carry := 0.0;
|
|
|
506 |
IF (ISDext[25] < 0) THEN
|
|
|
507 |
carry := twom24;
|
|
|
508 |
END;
|
|
|
509 |
isd := ABS(ISDext[25]);
|
|
|
510 |
i24 := (isd MOD 100);
|
|
|
511 |
isd := isd DIV 100;
|
|
|
512 |
j24 := (isd MOD 100);
|
|
|
513 |
isd := isd DIV 100;
|
|
|
514 |
in24 := (isd MOD 100);
|
|
|
515 |
isd := isd DIV 100;
|
|
|
516 |
luxlev := isd;
|
|
|
517 |
IF (luxlev <= MaxLev) THEN
|
|
|
518 |
nskip := ndskip[luxlev];
|
|
|
519 |
IF debug THEN
|
|
|
520 |
TIO.WrStr(' RanLux Luxury level set by RLuxIn to : ');
|
|
|
521 |
TIO.WrInt(luxlev,1); TIO.WrLn;
|
|
|
522 |
END;
|
|
|
523 |
ELSIF (luxlev >= 24) THEN
|
|
|
524 |
nskip := luxlev-24;
|
|
|
525 |
IF debug THEN
|
|
|
526 |
TIO.WrStr(' RanLux P-value set by RLuxIn to : ');
|
|
|
527 |
TIO.WrInt(luxlev,1); TIO.WrLn;
|
|
|
528 |
END;
|
|
|
529 |
ELSE
|
|
|
530 |
nskip := ndskip[MaxLev];
|
|
|
531 |
IF debug THEN
|
|
|
532 |
TIO.WrStr(' RanLux illegal Luxury RLuxIn : ');
|
|
|
533 |
TIO.WrInt(luxlev,1); TIO.WrLn;
|
|
|
534 |
END;
|
|
|
535 |
luxlev := MaxLev;
|
|
|
536 |
END;
|
|
|
537 |
inseed := -1;
|
|
|
538 |
END RLuxIn;
|
|
|
539 |
|
|
|
540 |
PROCEDURE RanLux(VAR RVec : ARRAY OF LONGREAL;
|
|
|
541 |
LenV : INTEGER);
|
|
|
542 |
|
|
|
543 |
VAR i,k,ivec,isk : INTEGER;
|
|
|
544 |
BEGIN
|
|
|
545 |
(* NOTYET is .TRUE. if no initialization has been performed yet. *)
|
|
|
546 |
(* Default Initialization by Multiplicative Congruential *)
|
|
|
547 |
IF (notyet) THEN
|
|
|
548 |
notyet := FALSE;
|
|
|
549 |
jseed := JSdflt;
|
|
|
550 |
inseed := JSdflt;
|
|
|
551 |
IF debug THEN
|
|
|
552 |
TIO.WrStr(' RanLux default initialization : ');
|
|
|
553 |
TIO.WrInt(jseed,1); TIO.WrLn;
|
|
|
554 |
END;
|
|
|
555 |
luxlev := LXdflt;
|
|
|
556 |
nskip := ndskip[luxlev];
|
|
|
557 |
in24 := 0;
|
|
|
558 |
kount := 0;
|
|
|
559 |
mkount := 0;
|
|
|
560 |
IF debug THEN
|
|
|
561 |
TIO.WrStr(' RanLux default Luxury level = ');
|
|
|
562 |
TIO.WrInt(luxlev,1);
|
|
|
563 |
TIO.WrStr(', p ='); TIO.WrInt(nskip+24,1); TIO.WrLn;
|
|
|
564 |
END;
|
|
|
565 |
twom24 := 1.0;
|
|
|
566 |
FOR i:=1 TO 24 DO
|
|
|
567 |
twom24 := twom24*0.5;
|
|
|
568 |
k := jseed DIV 53668;
|
|
|
569 |
jseed := 40014*(jseed-k*53668) - k*12211;
|
|
|
570 |
IF (jseed < 0) THEN
|
|
|
571 |
jseed:=jseed + ICons;
|
|
|
572 |
END;
|
|
|
573 |
iseeds[i] := (jseed MOD Itwo24);
|
|
|
574 |
END;
|
|
|
575 |
twom12 := twom24*4096.0;
|
|
|
576 |
FOR i:=1 TO 24 DO
|
|
|
577 |
seeds[i] := VAL(LONGREAL,iseeds[i])*twom24;
|
|
|
578 |
next[i] := i-1;
|
|
|
579 |
END;
|
|
|
580 |
next[1] := 24;
|
|
|
581 |
i24 := 24;
|
|
|
582 |
j24 := 10;
|
|
|
583 |
carry := 0.0;
|
|
|
584 |
IF (seeds[24] = 0.0) THEN
|
|
|
585 |
carry := twom24;
|
|
|
586 |
END;
|
|
|
587 |
END; (* IF notyet *)
|
|
|
588 |
|
|
|
589 |
(* The Generator proper: "Subtract-with-borrow", as proposed by *)
|
|
|
590 |
(* Marsaglia and Zaman, Florida State University, March, 1989 *)
|
|
|
591 |
|
|
|
592 |
FOR ivec:=0 TO LenV-1 DO
|
|
|
593 |
uni := seeds[j24] - seeds[i24] - carry;
|
|
|
594 |
IF (uni < 0.0) THEN
|
|
|
595 |
uni:=uni + 1.0;
|
|
|
596 |
carry := twom24
|
|
|
597 |
ELSE
|
|
|
598 |
carry := 0.0;
|
|
|
599 |
END;
|
|
|
600 |
seeds[i24] := uni;
|
|
|
601 |
i24 := next[i24];
|
|
|
602 |
j24 := next[j24];
|
|
|
603 |
RVec[ivec] := uni;
|
|
|
604 |
(* small numbers (with less than 12 "significant" bits) are "padded". *)
|
|
|
605 |
IF (uni < twom12) THEN
|
|
|
606 |
RVec[ivec]:=RVec[ivec] + twom24*seeds[j24];
|
|
|
607 |
(* and zero is forbidden in case someone takes a logarithm *)
|
|
|
608 |
IF (RVec[ivec] = 0.0) THEN
|
|
|
609 |
RVec[ivec] := twom24*twom24;
|
|
|
610 |
END;
|
|
|
611 |
END;
|
|
|
612 |
(* Skipping to luxury. As proposed by Martin Luscher. *)
|
|
|
613 |
in24:=in24 + 1;
|
|
|
614 |
IF (in24 = 24) THEN
|
|
|
615 |
in24 := 0;
|
|
|
616 |
kount:=kount + nskip;
|
|
|
617 |
FOR isk:=1 TO nskip DO
|
|
|
618 |
uni := seeds[j24] - seeds[i24] - carry;
|
|
|
619 |
IF (uni < 0.0) THEN
|
|
|
620 |
uni:=uni + 1.0;
|
|
|
621 |
carry := twom24;
|
|
|
622 |
ELSE
|
|
|
623 |
carry := 0.0;
|
|
|
624 |
END;
|
|
|
625 |
seeds[i24] := uni;
|
|
|
626 |
i24 := next[i24];
|
|
|
627 |
j24 := next[j24];
|
|
|
628 |
END;
|
|
|
629 |
END;
|
|
|
630 |
END;
|
|
|
631 |
kount:=kount + LenV;
|
|
|
632 |
IF (kount >= IGiga) THEN
|
|
|
633 |
mkount:=mkount + 1;
|
|
|
634 |
kount:=kount - IGiga;
|
|
|
635 |
END;
|
|
|
636 |
END RanLux;
|
|
|
637 |
|
|
|
638 |
BEGIN
|
|
|
639 |
notyet := TRUE; (* save *)
|
|
|
640 |
luxlev := LXdflt; (* save xxx *)
|
|
|
641 |
in24 := 0; (* save *)
|
|
|
642 |
kount := 0; (* save xxx *)
|
|
|
643 |
mkount := 0; (* save xxx *)
|
|
|
644 |
inseed := JSdflt; (* xxx *)
|
|
|
645 |
|
|
|
646 |
i24 := 24; (* save *)
|
|
|
647 |
j24 := 10; (* save *)
|
|
|
648 |
carry := 0.0; (* save *)
|
|
|
649 |
|
|
|
650 |
ndskip[0] := 0; (* save *)
|
|
|
651 |
ndskip[1] := 24;
|
|
|
652 |
ndskip[2] := 73;
|
|
|
653 |
ndskip[3] := 199;
|
|
|
654 |
ndskip[4] := 365;
|
|
|
655 |
END LuxaryRandom;
|
|
|
656 |
|
|
|
657 |
END RandomLib.
|