comparison CA.py @ 46:d83a72eec954

Forgot to add these. Needed for Chapter 6.
author Brian Neal <bgneal@gmail.com>
date Thu, 25 Jul 2013 21:27:36 -0500
parents
children
comparison
equal deleted inserted replaced
45:1804f09a7adb 46:d83a72eec954
1 """ Code example from Complexity and Computation, a book about
2 exploring complexity science with Python. Available free from
3
4 http://greenteapress.com/complexity
5
6 Copyright 2011 Allen B. Downey.
7 Distributed under the GNU General Public License at gnu.org/licenses/gpl.html.
8 """
9
10 import numpy
11
12 class CA(object):
13 """A CA is a cellular automaton; the parameters for __init__ are:
14
15 rule: an integer in the range 0-255 that represents the CA rule
16 using Wolfram's encoding.
17 n: the number of rows (timesteps) in the result.
18 ratio: the ratio of columns to rows.
19 """
20
21 def __init__(self, rule, n=100, ratio=2):
22 """Attributes:
23 table: rule dictionary that maps from triple to next state.
24 n, m: are the number of rows, columns.
25 array: the numpy array that contains the data.
26 next: the index of the next empty row.
27 """
28 self.table = self.make_table(rule)
29 self.n = n
30 self.m = ratio*n + 1
31 self.array = numpy.zeros((n, self.m), dtype=numpy.int8)
32 self.next = 0
33
34 def make_table(self, rule):
35 """Returns a table for the given CA rule. The table is a
36 dictionary that maps 3-tuples to binary values.
37 """
38 table = {}
39 for i, bit in enumerate(binary(rule, 8)):
40 t = binary(7-i, 3)
41 table[t] = bit
42 return table
43
44 def start_single(self):
45 """Starts with one cell in the middle of the top row."""
46 self.array[0, self.m/2] = 1
47 self.next += 1
48
49 def start_random(self):
50 """Start with random values in the top row."""
51 self.array[0] = numpy.random.random([1,self.m]).round()
52 self.next += 1
53
54 def loop(self, steps=1):
55 """Executes the given number of time steps."""
56 [self.step() for i in xrange(steps)]
57
58 def step(self):
59 """Executes one time step by computing the next row of the array."""
60 i = self.next
61 self.next += 1
62
63 a = self.array
64 t = self.table
65 for j in xrange(1,self.m-1):
66 a[i,j] = t[tuple(a[i-1, j-1:j+2])]
67
68 def get_array(self, start=0, end=None):
69 """Gets a slice of columns from the CA, with slice indices
70 (start, end). Avoid copying if possible.
71 """
72 if start==0 and end==None:
73 return self.array
74 else:
75 return self.array[:, start:end]
76
77
78 def binary(n, digits):
79 """Returns a tuple of (digits) integers representing the
80 integer (n) in binary. For example, binary(3,3) returns (0, 1, 1)"""
81 t = []
82 for i in range(digits):
83 n, r = divmod(n, 2)
84 t.append(r)
85
86 return tuple(reversed(t))
87
88
89 def print_table(table):
90 """Prints the rule table in LaTeX format."""
91 t = table.items()
92 t.sort(reverse=True)
93
94 print '\\beforefig'
95 print '\\centerline{'
96 print '\\begin{tabular}{|c|c|c|c|c|c|c|c|c|}'
97 print '\\hline'
98
99 res = ['prev']
100 for k, v in t:
101 s = ''.join([str(x) for x in k])
102 res.append(s)
103 print ' & '.join(res) + ' \\\\ \n\\hline'
104
105 res = ['next']
106 for k, v in t:
107 res.append(str(v))
108 print ' & '.join(res) + ' \\\\ \n\\hline'
109
110 print '\\end{tabular}}'
111
112