Mercurial > public > think_complexity
comparison CircularCA.py @ 42:039249efe42f
Chapter 6, exercise 2, #4. Wrote a program to output the center column of
a rule 30 CA as a stream of bytes. It is very slow though. It has to run a very
long time to produce enough data for dieharder. Committing it now but will have
to let it run overnight or something to generate a large file.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sun, 13 Jan 2013 16:24:00 -0600 |
parents | ae310a2f42b4 |
children | 6cd37534c12e |
comparison
equal
deleted
inserted
replaced
41:d4d9650afe1e | 42:039249efe42f |
---|---|
12 | 12 |
13 | 13 |
14 class CircularCA(CA): | 14 class CircularCA(CA): |
15 """A circular cellular automaton; the cells are arranged in a ring.""" | 15 """A circular cellular automaton; the cells are arranged in a ring.""" |
16 | 16 |
17 def __init__(self, rule, n=100, ratio=2): | 17 def __init__(self, rule, n=100, m=50): |
18 """Parameters: | 18 """Parameters: |
19 | 19 |
20 * rule: an integer in the range 0-255 that represents the CA rule | 20 * rule: an integer in the range 0-255 that represents the CA rule |
21 using Wolfram's encoding | 21 using Wolfram's encoding |
22 * n: the number of rows (time steps) in the result | 22 * n: the number of rows (time steps) in the result |
23 * ratio: the ratio of columns to rows | 23 * m: the number of columns |
24 | 24 |
25 """ | 25 """ |
26 self.table = self.make_table(rule) | 26 self.table = self.make_table(rule) |
27 self.n = n | 27 self.n = n |
28 # a ghost column is added to either end | 28 # a ghost column is added to either end |
29 self.m = ratio * n + 3 # add 2 ghost columns | 29 self.m = m + 2 # add 2 ghost columns |
30 self.array = numpy.zeros((n, self.m), dtype=numpy.int8) | 30 self.array = numpy.zeros((n, self.m), dtype=numpy.int8) |
31 self.next = 0 | 31 self.next = 0 |
32 | 32 |
33 def start_single(self): | 33 def start_single(self): |
34 self.array[0, 1] = 1 | 34 self.array[0, 1] = 1 |
48 a[i - 1, self.m - 1] = a[i - 1, 1] | 48 a[i - 1, self.m - 1] = a[i - 1, 1] |
49 | 49 |
50 for j in xrange(1, self.m - 1): | 50 for j in xrange(1, self.m - 1): |
51 a[i, j] = t[tuple(a[i - 1, j-1:j+2])] | 51 a[i, j] = t[tuple(a[i - 1, j-1:j+2])] |
52 | 52 |
53 def loop(self, steps=1): | |
54 """Executes the given number of time steps.""" | |
55 for i in xrange(steps): | |
56 self.step() | |
53 | 57 |
54 def get_array(self, start=0, end=None): | 58 def get_array(self, start=0, end=None): |
55 """Gets a slice of columns from the CA, with slice indices | 59 """Gets a slice of columns from the CA, with slice indices |
56 (start, end). | 60 (start, end). |
57 | 61 |
60 if end==None: | 64 if end==None: |
61 return self.array[:, start+1:self.m-1] | 65 return self.array[:, start+1:self.m-1] |
62 else: | 66 else: |
63 return self.array[:, start+1:end+1] | 67 return self.array[:, start+1:end+1] |
64 | 68 |
69 def wrap(self): | |
70 """Copies the last row to row 0, then resets the CA to start back at the | |
71 top. | |
72 | |
73 """ | |
74 a = self.array | |
75 a[0, :] = a[self.next - 1, :] | |
76 self.next = 1 | |
77 | |
65 | 78 |
66 if __name__ == '__main__': | 79 if __name__ == '__main__': |
67 | 80 |
68 import sys | 81 import sys |
69 from CADrawer import PyplotDrawer | 82 from CADrawer import PyplotDrawer |
70 | 83 |
71 def main(script, rule, n): | 84 def main(script, rule, n, m): |
72 rule = int(rule) | 85 rule = int(rule) |
73 n = int(n) | 86 n = int(n) |
74 ca = CircularCA(rule, n) | 87 m = int(m) |
88 ca = CircularCA(rule, n, m) | |
75 ca.start_single() | 89 ca.start_single() |
76 ca.loop(n - 1) | 90 ca.loop(n - 1) |
77 | 91 |
78 drawer = PyplotDrawer() | 92 drawer = PyplotDrawer() |
79 drawer.draw(ca) | 93 drawer.draw(ca) |