annotate TMDrawer.py @ 45:1804f09a7adb

Chapter 6, exercise 4, part 4. A Turing Machine drawer.
author Brian Neal <bgneal@gmail.com>
date Sat, 19 Jan 2013 14:17:12 -0600
parents
children
rev   line source
bgneal@45 1 """Chapter 6, exercise 4 in Allen Downey's Think Complexity book.
bgneal@45 2
bgneal@45 3 The goal of this exercise is to implement a Turing machine.
bgneal@45 4 See http://en.wikipedia.org/wiki/Turing_machine.
bgneal@45 5
bgneal@45 6 4. Write a class named TMDrawer that generates an image that represents the
bgneal@45 7 state of the tape and the position and state of the head. For one example of
bgneal@45 8 what that might look like, see
bgneal@45 9 http://mathworld.wolfram.com/TuringMachine.html.
bgneal@45 10
bgneal@45 11 """
bgneal@45 12 import matplotlib.pyplot as pyplot
bgneal@45 13 import numpy
bgneal@45 14
bgneal@45 15 from CADrawer import Drawer
bgneal@45 16
bgneal@45 17
bgneal@45 18 class TMDrawer(Drawer):
bgneal@45 19 """Implementation of Drawer using matplotlib for Turing Machines.
bgneal@45 20
bgneal@45 21 We visualize the tape and machine head/state by drawing the tape state as
bgneal@45 22 a row, then adding a row underneath that for the head & state. The tape head
bgneal@45 23 is drawn as a solid square whose color represents the state.
bgneal@45 24
bgneal@45 25 """
bgneal@45 26 def __init__(self, tape_colors, state_colors, cmap=None):
bgneal@45 27 self.tape_colors = tape_colors
bgneal@45 28 self.state_colors = state_colors
bgneal@45 29 self.cmap = cmap if cmap else 'spectral'
bgneal@45 30
bgneal@45 31 def draw(self, tm, start=0, end=None):
bgneal@45 32 """Draws the TM using pyplot.pcolor."""
bgneal@45 33 tape = tm.get_array(start, end)
bgneal@45 34 rows, cols = tape.shape
bgneal@45 35
bgneal@45 36 # create a new array that has twice as many rows
bgneal@45 37 steps = rows
bgneal@45 38 rows *= 2
bgneal@45 39 a = numpy.zeros((rows, cols), dtype=numpy.int8)
bgneal@45 40
bgneal@45 41 # copy the tape state into the array at every other row
bgneal@45 42 for i in xrange(steps):
bgneal@45 43 for j in xrange(cols):
bgneal@45 44 #a[n, j] = self.tape_colors[tape[i, j]]
bgneal@45 45 c = self.tape_colors[tape[i, j]]
bgneal@45 46 a[i * 2, j] = c
bgneal@45 47
bgneal@45 48 # copy the head position & state into every other row
bgneal@45 49 n = 1
bgneal@45 50 for pos, state in tm.history:
bgneal@45 51 a[n, pos] = self.state_colors[state]
bgneal@45 52 n += 2
bgneal@45 53
bgneal@45 54 # flipud puts the first row at the top;
bgneal@45 55 pyplot.pcolor(numpy.flipud(a), cmap=self.cmap)
bgneal@45 56 pyplot.axis([0, cols, 0, rows])
bgneal@45 57 pyplot.colorbar()
bgneal@45 58
bgneal@45 59 # empty lists draw no ticks
bgneal@45 60 pyplot.xticks([])
bgneal@45 61 pyplot.yticks([])
bgneal@45 62
bgneal@45 63 def show(self):
bgneal@45 64 """display the pseudocolor representation of the CA"""
bgneal@45 65 pyplot.show()
bgneal@45 66
bgneal@45 67 def save(self, filename='tm.png'):
bgneal@45 68 """save the pseudocolor representation of the TM in (filename)."""
bgneal@45 69 pyplot.savefig(filename)
bgneal@45 70