| 1 |
unit mt19937; |
| 2 |
{$IFDEF FPC} |
| 3 |
{$MODE DELPHI}{$H+} |
| 4 |
{$ENDIF} |
| 5 |
interface |
| 6 |
|
| 7 |
procedure init_genrand(s:longword); |
| 8 |
function genrand_int32:longword; |
| 9 |
|
| 10 |
implementation |
| 11 |
|
| 12 |
{ The following are inherited Comments from the original C-source.} |
| 13 |
|
| 14 |
(* |
| 15 |
A C-program for MT19937, with initialization improved 2002/1/26. |
| 16 |
Coded by Takuji Nishimura and Makoto Matsumoto. |
| 17 |
|
| 18 |
Before using, initialize the state by using init_genrand(seed) |
| 19 |
or init_by_array(init_key, key_length). |
| 20 |
|
| 21 |
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, |
| 22 |
All rights reserved. |
| 23 |
|
| 24 |
Redistribution and use in source and binary forms, with or without |
| 25 |
modification, are permitted provided that the following conditions |
| 26 |
are met: |
| 27 |
|
| 28 |
1. Redistributions of source code must retain the above copyright |
| 29 |
notice, this list of conditions and the following disclaimer. |
| 30 |
|
| 31 |
2. Redistributions in binary form must reproduce the above copyright |
| 32 |
notice, this list of conditions and the following disclaimer in the |
| 33 |
documentation and/or other materials provided with the distribution. |
| 34 |
|
| 35 |
3. The names of its contributors may not be used to endorse or promote |
| 36 |
products derived from this software without specific prior written |
| 37 |
permission. |
| 38 |
|
| 39 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 40 |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 41 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 42 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| 43 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 44 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 45 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 46 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 47 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 48 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 49 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 50 |
|
| 51 |
|
| 52 |
Any feedback is very welcome. |
| 53 |
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html |
| 54 |
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) |
| 55 |
*) |
| 56 |
|
| 57 |
(* Period parameters *) |
| 58 |
const |
| 59 |
N= 624; |
| 60 |
M= 397; |
| 61 |
MATRIX_A= $9908b0df; (* constant vector a *) |
| 62 |
UPPER_MASK= $80000000; (* most significant w-r bits *) |
| 63 |
LOWER_MASK= $7fffffff; (* least significant r bits *) |
| 64 |
var |
| 65 |
mt: array[0..N-1] of longword; (* the array for the state vector *) |
| 66 |
mti:integer=N+1; (* mti=N+1 means mt[N] is not initialized *) |
| 67 |
|
| 68 |
(* initializes mt[N] with a seed *) |
| 69 |
procedure init_genrand(s:longword); |
| 70 |
begin |
| 71 |
mt[0]:= s {and $ffffffff}; |
| 72 |
mti:=1; |
| 73 |
while mti<N do |
| 74 |
begin |
| 75 |
mt[mti]:=(1812433253*(Mt[mti-1] xor (Mt[mti-1] shr 30))+mti); |
| 76 |
|
| 77 |
///* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
| 78 |
///* In the previous versions, MSBs of the seed affect */ |
| 79 |
///* only MSBs of the array mt[]. */ |
| 80 |
///* 2002/01/09 modified by Makoto Matsumoto */ |
| 81 |
{Mt[mti]:=Mt[mti] and $ffffffff;}(* for >32 bit machines *) |
| 82 |
mti:=mti+1; |
| 83 |
end; |
| 84 |
end; |
| 85 |
|
| 86 |
///* initialize by an array with array-length */ |
| 87 |
///* init_key is the array for initializing keys */ |
| 88 |
///* key_length is its length */ |
| 89 |
///* slight change for C++, 2004/2/26 */ |
| 90 |
(* |
| 91 |
void init_by_array(unsigned long init_key[], int key_length) |
| 92 |
{ |
| 93 |
int i, j, k; |
| 94 |
init_genrand(19650218UL); |
| 95 |
i=1; j=0; |
| 96 |
k = (N>key_length ? N : key_length); |
| 97 |
for (; k; k--) { |
| 98 |
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) |
| 99 |
+ init_key[j] + j; /* non linear */ |
| 100 |
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ |
| 101 |
i++; j++; |
| 102 |
if (i>=N) { mt[0] = mt[N-1]; i=1; } |
| 103 |
if (j>=key_length) j=0; |
| 104 |
} |
| 105 |
for (k=N-1; k; k--) { |
| 106 |
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) |
| 107 |
- i; /* non linear */ |
| 108 |
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ |
| 109 |
i++; |
| 110 |
if (i>=N) { mt[0] = mt[N-1]; i=1; } |
| 111 |
} |
| 112 |
|
| 113 |
mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ |
| 114 |
} |
| 115 |
*) |
| 116 |
|
| 117 |
(* generates a random number on [0,0xffffffff]-interval *) |
| 118 |
|
| 119 |
function genrand_int32:longword; |
| 120 |
const |
| 121 |
mag01 : array[0..1] of longword=(0,MATRIX_A); |
| 122 |
|
| 123 |
(* mag01[x] = x * MATRIX_A for x=0,1 *) |
| 124 |
|
| 125 |
var |
| 126 |
y:longword; |
| 127 |
kk:integer; |
| 128 |
begin |
| 129 |
if (mti >= N) then (* generate N words at one time *) |
| 130 |
begin |
| 131 |
if (mti = N+1) then (* if init_genrand() has not been called, *) |
| 132 |
init_genrand(5489); (* a default initial seed is used *) |
| 133 |
|
| 134 |
for kk:=0 to N-M-1 do |
| 135 |
begin |
| 136 |
y:= (mt[kk] and UPPER_MASK) or (mt[kk+1] and LOWER_MASK); |
| 137 |
Mt[kk]:=Mt[kk+M] xor (y shr 1) xor mag01[y and 1]; |
| 138 |
end; |
| 139 |
for kk:=N-M to N-2 do |
| 140 |
begin |
| 141 |
y:= (mt[kk] and UPPER_MASK) or (mt[kk+1] and LOWER_MASK); |
| 142 |
mt[kk]:=mt[kk+(M-N)] xor (y shr 1) xor mag01[y and 1]; |
| 143 |
end; |
| 144 |
|
| 145 |
y:= (mt[N-1] and UPPER_MASK) or (mt[0] and LOWER_MASK); |
| 146 |
mt[N-1]:=mt[M-1] xor (y shr 1) xor mag01[y and 1]; |
| 147 |
|
| 148 |
mti:= 0; |
| 149 |
end; |
| 150 |
|
| 151 |
y:= mt[mti]; |
| 152 |
mti:=mti +1; |
| 153 |
|
| 154 |
(* Tempering *) |
| 155 |
y:=y xor (y shr 11); |
| 156 |
y:=y xor ((y shl 7) and $9d2c5680); |
| 157 |
y:=y xor ((y shl 15) and $efc60000); |
| 158 |
y:=y xor (y shr 18); |
| 159 |
result:=y; |
| 160 |
end; |
| 161 |
|
| 162 |
|
| 163 |
end. |
| 164 |
|
| 165 |
|
| 166 |
|