comparison ch6ex2.py @ 41:d4d9650afe1e

Chapter 6, exercise 2, create a linear congruential generator.
author Brian Neal <bgneal@gmail.com>
date Sun, 13 Jan 2013 13:10:46 -0600
parents
children
comparison
equal deleted inserted replaced
40:ae310a2f42b4 41:d4d9650afe1e
1 """Chapter 6, exercise 2 in Allen Downey's Think Complexity book.
2
3 1. Write a program that implements one of the linear congruential generators
4 described at http://en.wikipedia.org/wiki/Linear_congruential_generator
5
6 """
7
8 class LCG(object):
9 """A class to implement a Linear Congruential Generator (LCG) pseudo-random
10 number generator.
11
12 """
13 def __init__(self, a=1103515245, c=12345, m=2**31,
14 output=lambda x: x & 0x7fffffff):
15 """The parameters a, c, and m are the LCG parameters:
16 xn = (a * xn + c) % m
17
18 The parameter output must be a function that transforms the next output
19 value. This can be used to shift or mask off various bits to
20 statistically improve the values produced.
21
22 """
23 self.a = a
24 self.c = c
25 self.m = m
26 self.xn = 0
27 self.output = output
28
29 def seed(self, val):
30 """Seed the pseudo-random number generator with the value val."""
31 self.xn = val
32
33 def rand(self):
34 """Generate and return the next pseudo-rando number in the sequence."""
35 self.xn = (self.a * self.xn + self.c) % self.m
36 return self.output(self.xn)
37
38
39 def main(script, prng):
40 """Rig up either our random number generator or Python's to produce output
41 on stdout so we can test it with dieharder:
42
43 $ python ch6ex2.py lcg | dieharder -a -g 200 # to test ours
44 $ python ch6ex2.py python | dieharder -a -g 200 # to test Python
45
46 """
47 import struct
48 import random
49
50 lcg = LCG()
51 py_rng = lambda : random.randint(0, 0xffffffff)
52
53 if prng == 'python':
54 r = py_rng
55 else:
56 r = lcg.rand
57
58 while True:
59 n = r()
60 s = struct.pack('>L', n)
61 sys.stdout.write(s)
62
63
64 if __name__ == '__main__':
65 import sys
66 main(*sys.argv)