summary refs log tree commit diff stats
path: root/lib/pure/mersenne.nim
diff options
context:
space:
mode:
authorMark Flamer <mflamer@vectorworks.net>2013-10-22 15:02:54 -0700
committerMark Flamer <mflamer@vectorworks.net>2013-10-22 15:02:58 -0700
commit7832f25abf25cbdffa483845ebfd6f774fcb8e84 (patch)
tree315dd3b5cb26bf9a6ad497d785f1fdb969228e39 /lib/pure/mersenne.nim
parent6fbc96fec49d8376911dcf7a827b802bc942ca70 (diff)
downloadNim-7832f25abf25cbdffa483845ebfd6f774fcb8e84.tar.gz
Mersenne twister random number generator
Diffstat (limited to 'lib/pure/mersenne.nim')
-rw-r--r--lib/pure/mersenne.nim39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/pure/mersenne.nim b/lib/pure/mersenne.nim
new file mode 100644
index 000000000..2b12cce73
--- /dev/null
+++ b/lib/pure/mersenne.nim
@@ -0,0 +1,39 @@
+import unsigned
+
+type
+  TMersenneTwister* = object
+    mt: array[0..623, uint32]
+    index: int
+
+proc newMersenneTwister*(seed: int): TMersenneTwister =   
+  result.index = 0
+  result.mt[0]= uint32(seed)
+  for i in 1..623'u32:
+    result.mt[i]= (0x6c078965'u32 * (result.mt[i-1] xor (result.mt[i-1] shr 30'u32)) + i)
+
+proc generateNumbers(m: var TMersenneTwister) =
+  for i in 0..623:
+    var y = (m.mt[i] and 0x80000000'u32) + (m.mt[(i+1) mod 624] and 0x7fffffff'u32)
+    m.mt[i] = m.mt[(i+397) mod 624] xor uint32(y shr 1'u32)
+    if (y mod 2'u32) != 0:
+     m.mt[i] = m.mt[i] xor 0x9908b0df'u32
+
+proc getNum*(m: var TMersenneTwister): int =
+  if m.index == 0:
+    generateNumbers(m)
+  var y = m.mt[m.index]
+  y = y xor (y shr 11'u32)
+  y = y xor ((7'u32 shl y) and 0x9d2c5680'u32)
+  y = y xor ((15'u32 shl y) and 0xefc60000'u32)
+  y = y xor (y shr 18'u32)
+  m.index = (m.index+1) mod 624
+  return int(y)
+
+
+
+# Test
+when isMainModule:
+  var mt = newMersenneTwister(2525)
+
+  for i in 0..99:
+    echo mt.getNum
\ No newline at end of file