[M3devel] Mersenne Twister in Modula-3, Error?
Ken Durocher
kcdurocher at gmail.com
Wed Oct 19 02:16:08 CEST 2011
I implemented the Mersenne Twister in Modula-3 some time ago, however when I
test it out (the same test data that the authors of the Mersenne Twister
used), the output is different. I tested this code on both 32 and 64 bit
machines, and they both give me the same results, but the results are
different from that of the original Mersenne Twister code.
Here's the code:
INTERFACE MT19937ar;
IMPORT Word;
PROCEDURE initGenrand(s: Word.T);
PROCEDURE initByArray(key: ARRAY OF Word.T; length: INTEGER);
PROCEDURE genrandInt32(): Word.T;
PROCEDURE genrandInt31(): INTEGER;
PROCEDURE genrandReal1(): REAL;
PROCEDURE genrandReal2(): REAL;
PROCEDURE genrandReal3(): REAL;
END MT19937ar.
(*********)
MODULE MT19937ar;
IMPORT Word;
FROM Word IMPORT And, Xor, Or, RightShift, LeftShift;
CONST
n = 624;
m = 397;
matrix_a = 16_9908b0df;
upper_mask = 16_80000000;
lower_mask = 16_7fffffff;
VAR
mt: ARRAY [0..n] OF Word.T;
mti := n + 1;
PROCEDURE initGenrand(s: Word.T) =
BEGIN
mt[0] := And(s, 16_ffffffff);
FOR mti := 1 TO n - 1 DO
mt[mti] := 1812433253 * (Xor(mt[mti-1], RightShift(mt[mti-1], 30))) +
mti;
mt[mti] := And(mt[mti], 16_ffffffff);
END;
END initGenrand;
PROCEDURE initByArray(key: ARRAY OF Word.T; length: INTEGER) =
VAR i, j, k: INTEGER;
BEGIN
i := 1; j := 0;
initGenrand(19650218);
IF n > length THEN k := n ELSE k := length; END;
WHILE k # 0 DO
mt[i] := Xor(mt[i], Xor(mt[i-1], RightShift(mt[i-1], 30)) * 1664525)
+
key[j] + j;
mt[i] := And(mt[i], 16_ffffffff);
INC(i); INC(j);
IF i >= n THEN
mt[0] := mt[n-1];
i := 1;
END;
IF j >= length THEN
j := 0;
END;
DEC(k);
END;
k := n - 1;
WHILE k # 0 DO
mt[i] := Xor(mt[i], Xor(mt[i-1], RightShift(mt[i-1], 30)) *
1566083941) - i;
mt[i] := And(mt[i], 16_ffffffff);
INC(i);
IF i >= n THEN
mt[0] := mt[n-1];
i := 1;
END;
DEC(k);
END;
mt[0] := 16_80000000;
END initByArray;
PROCEDURE genrandInt32(): Word.T =
VAR y: Word.T;
k: INTEGER := 0;
mag01 := ARRAY [0..1] OF Word.T {0, matrix_a};
BEGIN
IF mti >= n THEN
IF mti = (n + 1) THEN
initGenrand(5489);
END;
WHILE k < (n - m) DO
y := Or(And(mt[k], upper_mask), And(mt[k+1], lower_mask));
mt[k] := Xor(Xor(mt[k+m], RightShift(y, 1)), mag01[And(y, 1)]);
INC(k);
END;
WHILE k < (n - 1) DO
y := Or(And(mt[k], upper_mask), And(mt[k+1], lower_mask));
mt[k] := Xor(Xor(mt[k+(m-n)], RightShift(y, 1)), mag01[And(y, 1)]);
INC(k);
END;
y := Or(And(mt[n-1], upper_mask), And(mt[0], lower_mask));
mt[n-1] := Xor(Xor(mt[m-1], RightShift(y, 1)), mag01[And(y, 1)]);
mti := 0;
END;
y := mt[mti];
INC(mti);
y := Xor(y, RightShift(y, 11));
y := Xor(y, And(LeftShift(y, 7), 16_9d2c5680));
y := Xor(y, And(LeftShift(y, 15), 16_efc60000));
y := Xor(y, RightShift(y, 18));
RETURN y;
END genrandInt32;
PROCEDURE genrandInt31(): INTEGER =
BEGIN
RETURN RightShift(genrandInt32(), 1);
END genrandInt31;
PROCEDURE genrandReal1(): REAL =
BEGIN
RETURN FLOAT(genrandInt32(), REAL) * (1.0 / 4294967295.0);
END genrandReal1;
PROCEDURE genrandReal2(): REAL =
BEGIN
RETURN FLOAT(genrandInt32(), REAL) * (1.0 / 4294967296.0);
END genrandReal2;
PROCEDURE genrandReal3(): REAL =
BEGIN
RETURN (FLOAT(genrandInt32(), REAL) + 0.5) * (1.0 / 4294967296.0);
END genrandReal3;
BEGIN
END MT19937ar.
(********)
MODULE Main;
IMPORT IO, Fmt, MT19937ar;
VAR init := ARRAY [0..3] OF INTEGER {16_123, 16_234, 16_345, 16_456};
len := 4;
BEGIN
MT19937ar.initByArray(init, len);
IO.Put("Random integers: ");
FOR i := 1 TO 999 DO
IO.Put(Fmt.Unsigned(MT19937ar.genrandInt32(), base := 10));
IO.Put(" ");
IF (i MOD 5) = 4 THEN IO.Put("\n"); END;
END;
IO.Put("\n");
END Main.
And here is the first few numbers it outputs:
3499211612 581869302 3890346734 3586334585 ...
Compare that to the first few numbers of output from the original Mersenne
Twister code, in C:
1067595299 955945823 477289528 4107218783 ...
Anyone know why they are different? Is the code wrong, or is it an
implementation difference, or what?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20111018/900f2289/attachment-0001.html>
More information about the M3devel
mailing list