Shane Torbert - Applied Computer Science 2011
Shane Torbert - Applied Computer Science 2011
Shane Torbert
Shane Torbert
Center for Computational Fluid Dynamics
George Mason University
Fairfax, Virginia, USA
ISBN 978-1-4614-1887-0
e-ISBN 978-1-4614-1888-7
DOI 10.1007/978-1-4614-1888-7
Springer New York Dordrecht Heidelberg London
Library of Congress Control Number: 2011941876
Springer Science+Business Media, LLC 2012
All rights reserved. This work may not be translated or copied in whole or in part without the written
permission of the publisher (Springer Science+Business Media, LLC, 233 Spring Street, New York,
NY 10013, USA), except for brief excerpts in connection with reviews or scholarly analysis. Use in
connection with any form of information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed is forbidden.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they
are not identified as such, is not to be taken as an expression of opinion as to whether or not they are
subject to proprietary rights.
Printed on acid-free paper
Springer is part of Springer Science+Business Media (www.springer.com)
For my wife
Contents
Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Random Walk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Air Resistance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3 Lunar Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1 Pixel Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Scalable Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Building Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
34
44
54
Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1 Geospatial Population Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Particle Diffusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Approximating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
62
72
84
Efciency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.1 Text and Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
4.2 Babylonian Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
4.3 Workload Balance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
5.1 Disease Outbreak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
5.2 Runtime Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
5.3 Guessing Games . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.1 Sliding Tile Puzzle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.2 Anagram Scramble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
6.3 Collision Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
ix
Contents
Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
7.1 Predator-Prey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
7.2 Laws of Motion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
7.3 Bioinformatics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Postscript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Chapter 1
Simulation
Experiments are often limited by a high level of danger, and because they are too
expensive or simply impossible to arrange, such as in developing new medical treatments, vehicles for space ight, and also studying geologic events. In these cases
we may benet from the use of computer simulation to rene our understanding
and narrow our investigation prior to an ofcial observation. Since the promise of
this technique is to accelerate information gathering for a relatively low total cost,
interest has been gaining momentum everywhere.
Examples in this chapter include discrete, continuous, and interactive systems
with particular importance given to the long-term (asymptotic) trend as the scale
of a problem grows toward innity. Our approach favors clarity and context over
trivia or theory with the hope that this better enables early success, but of course in
learning there are never any real guarantees. Efciency matters but is not paramount
as we prefer to implement more widely accessible solutions while perhaps merely
suggesting a state-of-the-art method.
For all code listings we use Python 2 with Tk and PIL, plus gnuplot, but other
R
, Mathematica, Python 3, Java, C/C++, Fortran,
options are available (e.g., Matlab
Scheme, Pascal) and our belief is these choices are sufciently intuitive to serve
as instructive pseudocode, that also happens to run!, for any environment you use.
Regardless, we feel the central issues up-front are quality problems, a thoughtful
sequencing of topics, and rapid feedback.
1 Simulation
-----X--------X|---------X--------X|-------X-|------X--|-----X---|------X--|-----X---|------X--|-------X-|------X--|-----X---|----X----|---------|----Steps: 14
-----X---------|X--------|-X-------|X--------X--------X|-------X-|--------X|---------X--------X|-------X-|------X--|-----X---|------X--|-----X---|----X----|-----X---|----X----|---------|----Steps: 18
-----X---------|X--------|-X-------|X--------X---------|X--------|-X-------|--X------|-X-------|--X------|-X-------|X--------|-X-------|--X------|---X-----|----X
-----|----Steps: 16
other but ending only when a nal step brings you all the way there. We wish to
simulate this random drifting process with computer code. Each lab is numbered so
that the rst digit indicates chapter (1-7), the second a particular problem (1-3) in
the chapter, and the third digit your specic assignment (1-5) related to the problem.
The values of n and m remain constant here but our current position j will start
at the halfway point j = n + 1 and then change as we drift until either j = 0 or
j = m + 1 and we have arrived at a reading spot. Whenever j = 1 or j = m we are
at one of the two edges, needing but a single step more in that direction to complete
our walk. Commands to initialize and update these variables over time are shown
in Code Listings 1.1 and 1.2, respectively.
Code Listing 1.2: A complete walks loop.
while 1<=j<=m:
#
if random()<0.5: # coin flip
j+=1
else:
j-=1
#
Of course we want to see the walk, too. Once we know everything is working
properly this trace will be less important but we should rst verify that our code
is behaving as expected. We could just print the value of j at each step but it will be
better if we draw a picture instead. Helper variable k loops over the entire drifting
area in Code Listing 1.3 to display a single row from any of Table 1.1s examples.
Code Listing 1.3: A loop to display the entire drifting area.
k=1
while k<=m:
if k==j:
print X,
elif k==n+1:
print |,
else:
print -,
k+=1
print
# current position
# halfway point
Your rst assignment is to put all this code together into a 1-D random walk
simulation, including counting-up the total number of steps.
Questions to consider:
Do our examples represent a typical size n = 5 random walk?
What happens to the number of steps, on average, as n increases?
1 Simulation
Observed Probability
0.54
0.53
0.52
0.51
0.5
0.49
0.48
0.47
0.46
0.45
0
Steps
80
60
40
20
0
1
4
5
6
7
Distance to Edge, n
10
Fig. 1.2: Quadratic growth in the average number of steps to complete a walk.
1 Simulation
Fig. 1.3: A large plume of ash during an eruption of the Mt. Cleveland volcano,
Alaska, as seen from the International Space Station on 23 May 2006. Image courtesy of the Image Science and Analysis Laboratory, NASA Johnson Space Center.
Fig. 1.4: Blue Mountain supercomputer, Los Alamos National Laboratory, New
Mexico, one of the most powerful computing systems in the world at the end of
the twentieth century. Image courtesy of Los Alamos National Security, LLC.
Parallel Processing
One popular technique for large-scale simulations is the use of multiple systems
connected together to process sub-units of the overall code in parallel. For instance,
individual trials in the previous lab are independent of each other and therefore may
be run simultaneously on separate machines in order to speed up calculation.
The parallel computing system shown in Figure 1.4 was one of the worlds most
powerful supercomputers. It has since been decommissioned and not even a decade
later the same level of capability became commercially available in graphics cards,
also massively parallel but no longer the exclusive domain of a premier national lab
the use of whose image requires:
Unless otherwise indicated, this information has been authored by an employee or employees of the Los Alamos National Security, LLC (LANS), operator of the Los Alamos National Laboratory under Contract No. DE-AC52-06NA25396 with the U.S. Department of
Energy. The U.S. Government has rights to use, reproduce, and distribute this information.
The public may copy and use this information without charge, provided that this Notice
and any statement of authorship are reproduced on all copies. Neither the Government nor
LANS makes any warranty, express or implied, or assumes any liability or responsibility
for the use of this information.
1 Simulation
0.9
0.8
0.7
0.6
0.5
0
10
15
Distance to Edge, n
20
25
Fig. 1.5: As the size of the walk increases the importance of the rst step decreases.
0.9
0.8
0.7
0.6
0.5
0
10
15
Distance to Edge, n
20
25
Fig. 1.6: The importance of the rst edge reached increases with the size of the walk.
10
1 Simulation
11
Deconstructed Parabola
10
9
Height, meters
8
7
6
5
4
3
2
1
0
-1
0
10
20
30
40
Distance, meters
50
60
70
Two observations about a soccer balls motion make this simulation possible:
Horizontal and vertical movement can be treated separately.
Small enough timesteps allow for straightforward modeling.
12
1 Simulation
66.5
66
65.5
65
64.5
64
63.5
63
1e-06
1e-05
0.0001 0.001
0.01
Timestep, seconds
0.1
13
v0,
10
9
Height, meters
8
7
6
5
4
3
2
1
0
-1
0
10
20
30
40
Distance, meters
50
60
70
14
1 Simulation
Height, meters
5
4
3
2
1
0
-1
0
10
15
20
Distance, meters
25
30
35
15
Height, meters
5
4
3
2
1
0
-1
0
10
15
20
Distance, meters
25
30
35
Fig. 1.11: Trajectory plot with air resistance and a headwind of 10 mph.
Lab124: Wind
Code Listing 1.11 shows a script that xes the x-axis in place for comparison of
multiple plots. If we assume there is a horizontal wind only and call vw its velocity
then we can model this wind by calculating the relative velocity (vx vw ) as shown
in Code Listing 1.12. We use relative velocity instead of the absolute vx to determine
the horizontal accleration due to air resistance.
Since vy is not affected by vw the calculation of ay is exactly as it was before
and comparing Figures 1.10 and 1.11 we see that height is unchanged but range is
diminished. Plots reecting even stronger winds are shown in Figure 1.12.
Code Listing 1.12: Relative velocity due to wind.
#
ax=( -c1*(vx-vw))
ay=(g-c1*(vy
))
#
16
1 Simulation
7
6
Height, meters
5
4
3
2
1
0
-1
0
10
15
20
25
30
35
10
15
20
25
30
35
10
25
30
35
7
6
Height, meters
5
4
3
2
1
0
-1
7
6
Height, meters
5
4
3
2
1
0
-1
15
20
Distance, meters
Fig. 1.12: Headwind trajectory plots. Top to bottom: 20 mph, 30 mph, and 40 mph.
17
Fig. 1.13: Early users of modern computing systems. Left: A tank in Tunisia, 1943,
the World War II campaign that motivated ENIAC. Right: Ada Lovelace, 1838.
Images courtesy of the U.S. Army and NASA. Tank photo credit U.S. Army Military
History Institute, WWII Signal Corps Photograph Collection.
18
1 Simulation
Height, meters
1200
1000
800
600
400
200
0
-200
0
10
15
20
25
Distance, meters
30
35
Fig. 1.14: Trajectory plot for free fall from a height of just under one mile with a
tailwind of not quite 1 mph. Note carefully the vast difference between horizontal
and vertical scales.
19
Velocity, m/s
-5
-10
-15
-20
0
6
8
10
Time, seconds
12
14
6
8
10
Time, seconds
12
14
Acceleration, m/s2
0
-2
-4
-6
-8
-10
20
1 Simulation
21
Fig. 1.16: Descent of the lunar module (not shown to scale). Top: beginning free fall
at an altitude of 100 meters, a contrived scenario. Bottom: crashing at over 40 mph.
Images courtesy of NASA, lunar module photo credit Michael Collins.
22
1 Simulation
Altitude, meters
80
60
40
20
0
-20
0
6
8
Time, seconds
10
12
10
12
Altitude, meters
80
60
40
20
0
-20
0
Time, seconds
Fig. 1.17: Altitude over time during lunar descent. Top: crashing at over 40 mph.
Bottom: controlled landing with vertical thrusters burning just before touchdown so
that impact velocity is well under 2 mph.
23
Code Listing 1.14: A complete program, written in Python 2 with Tk and PIL.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
###############################################################################
#
# Chapter 1: Simulation
# Problem 3: Lunar Module
# Lab 1.3.1: Uncontrolled Descent
#
###############################################################################
from Tkinter import Tk,Canvas
from PIL
import Image,ImageTk
###############################################################################
d e f tick():
g l o b a l t,y,vy
#
t += dt
y += (vy*dt)
vy += (ay*dt)
#
p r i n t t,y,vy
#
yp = 0.7*h/y0*(y0-y)
cnvs.coords(tkid,w/4.0,yp)
#
i f y>0.0:
cnvs.after(1,tick)
#
###############################################################################
w,h= 800,600
#
y0 = 100.0
# meters --> we must stipulate that images are not shown to scale
vy =
0.0
# m/s
--> so, assuming some previous arrangements at play here
ay = -1.62 # m/s2, acceleration due to gravity near the surface of the Moon
#
t =
0.0
dt =
0.001
#
y =
y0
yp =
0.7*h/y0*(y0-y) # linearly interpolate --> crash before the very bottom
#
p r i n t t,y,vy
###############################################################################
#
root=Tk()
cnvs=Canvas(root,width=w,height=h,bg=black)
cnvs.pack()
#
img1=Image.open(earthrise.jpg).resize((w,h))
pmg1=ImageTk.PhotoImage(img1)
cnvs.create_image(w/2.0,h/2.0,image=pmg1)
#
img2=Image.open(eagle.jpg).resize((200,170))
pmg2=ImageTk.PhotoImage(img2)
tkid=cnvs.create_image(w/4.0,yp,image=pmg2)
#
f=(Times,14,bold)
cnvs.create_text(w-110,h-15,text=Images courtesy of NASA.,font=f)
#
cnvs.after(1,tick)
root.mainloop()
#
# end of file
#
###############################################################################
24
1 Simulation
-15.59
Fig. 1.18: Controlled lunar descent where the black rectangle now articially marks
our landing site and the current velocity is indicated in meters per second. Images
courtesy of NASA, lunar module photo credit Michael Collins.
25
Descent Patterns:
Soft Landing
100
Altitude, meters
80
60
40
20
0
-20
0
6
8
Time, seconds
10
12
14
6
8
Time, seconds
10
12
14
2
0
Velocity, m/s
-2
-4
-6
-8
-10
-12
-14
-16
-18
0
Fig. 1.19: Altitude and velocity over time during lunar descent. The case shown here
is a soft landing where vertical thrusters are burned just after the 10 second mark.
26
1 Simulation
from y to yp
100
80
84
60
168
40
252
20
336
420
4
6
8
Time, seconds
10
Altitude, meters
Linear Interpolation:
12
27
Descent Patterns:
Hovering
100
Altitude, meters
80
60
40
20
0
-20
0
10
15
20
Time, seconds
25
30
35
25
30
35
2
0
Velocity, m/s
-2
-4
-6
-8
-10
-12
-14
0
10
15
20
Time, seconds
Fig. 1.21: Altitude and velocity over time during lunar descent. In this case the lunar
module hovers mid-descent before crash landing at just under 30 mph.
28
1 Simulation
Descent Patterns:
Parabola
160
140
Altitude, meters
120
100
80
60
40
20
0
-20
0
10
15
20
25
Time, seconds
30
35
40
30
35
40
20
15
Velocity, m/s
10
5
0
-5
-10
-15
-20
-25
0
10
15
20
25
Time, seconds
Fig. 1.22: Altitude and velocity over time during lunar descent. In this case the lunar
module performs a secondary climb before crash landing at just under 50 mph.
29
Descent Patterns:
Constant Velocity
100
Altitude, meters
80
60
40
20
0
-20
0
10
10
15
20
25
Time, seconds
30
35
40
15
30
35
40
0.5
0
Velocity, m/s
-0.5
-1
-1.5
-2
-2.5
-3
-3.5
20
25
Time, seconds
Fig. 1.23: Altitude and velocity over time during lunar descent. In this case the lunar
module maintains a constant velocity prole and lands safely at just over 5 mph.
30
1 Simulation
6
5
4
3
2
1
0
0
0.2
0.4
0.6
0.8
Time, seconds
Fig. 1.24: Computing applied to diagnosis and treatment. Left: An operating room
during surgery, the culmination of extensive preparation. Right: Typical volumetric
bloodow prole from a single heartbeat, one starting point toward the expansion
of knowledge. Image courtesy of the U.S. Army, photo credit C. Todd Lopez.
Medical Applications
Simulation has become sufciently robust to inuence medicine by, for instance,
modeling the ow of blood within our bodies. Figure 1.24 suggests one piece of
minimal information needed for diagnosis or treatment.
The process by which arteries transport blood away from our heart is similar to
incompressible ow in a pipe where viscosity dictates the interaction with tissue
lining the inner wall of our blood vessels. Unlike a lunar module descent velocity,
bloodow is periodic and the waveform pattern is repeated with each heartbeat.
These ows were studied by Poiseuille in the nineteenth century while the more
general set of equations were, around the same time, formulated by both Navier and
Stokes. An inviscid model had already been developed by Euler in the eighteenth
century using Newtons famous second law of motion from the seventeenth century.
But only in the latter twentieth century have computers become powerful enough to
apply these models to practical cases.
So, science waited centuries for machines to catch up. Now what?
Running an experiment that may pose some danger to a human patient is
goverened chiey by issues related to medical ethics, and we choose to err on the
side of rst, do no harm. Again this makes simulation an attractive technique but
also when a patients life-and-death (!) depends on proper diagnosis and treatment
then the accurate performance of our code takes on a fundamentally different level
of importance.
31
-11.90
16
Fig. 1.25: Controlled lunar descent with limited fuel availability. Remaining fuel is
indicated in number of times vertical thrusters may be burned, initially set to 20.
Images courtesy of NASA, lunar module photo credit Michael Collins.
32
1 Simulation
Velocity, m/s
0
-2
-4
-6
-8
-10
-12
0
8
10
12
Time, seconds
14
16
18
Fig. 1.26: As shown, vertical thrusters re at regular intervals but we do not even
use all our fuel. Upon modication of the ring schedule your authors best effort
was a vy = 0.17 m/s landing, under 0.5 mph.
Chapter 2
Graphics
Curiosity might ask how an image is built at all. In this chapter we consider three
different representations: a bitmap assigning colors to each pixel, a scalable model
requiring later calculations to render the image, and an even higher level specication where the underlying details are completely hidden from view.
As an example of our rst distinction, PPM stands for portable pixel map and
this format species literally hundreds of thousands of red-green-blue color values
in very large image les. SVG is scalable vector graphics where images contain
only a geometric description of lines and curves, thus reducing le size by delaying
the pixel-by-pixel rendering process. This approach has the advantage that enlarging a vector image is immune from any pixelation issues the corresponding bitmap
would face, but it also means the original image must be conceived in terms of
geometric objects which is not trivial for, say, a photograph.
Fig. 2.1: Example image les: gold, silver, and Olympus Mons, Mars, the largest
known volcano. Image courtesy of NASA from the Viking 1 mission, 22 June 1978.
Code Listing 2.1: A complete program, written in Python 2 with PIL.
#
from PIL import Image
img=Image.new(RGB,(100,75),(212,175,55)) # gold
img.save(gold.png) # formats: JPG, PPM/PGM, EPS
#
33
34
2 Graphics
[1]
[2]
[3]
[4]
35
Fig. 2.2: One quadrant of the unit circle within a unit square. Note y-coordinates are
often inverted in graphical systems, for either interactive windows or stored les.
Fig. 2.3: Pixelation when a smaller bitmap is enlarged. Left: direct calculation.
Right: linear interpolation of colors using the GNU Image Manipulation Program.
36
2 Graphics
computed
3.1428
3.141676
3.14159388
runtime, seconds
0.05
1.32
132.31
Table 2.3: Size (no image), computed value of , and associated runtime.
size m
100
1000
10,000
1,000,000
computed
runtime, seconds
3.1428
0.01
3.141676
0.88
3.14159388
88.53
3.141592655988
11.55
The area of a circle is A = r2 and so for the unit circle, where r = 1, area is
A = . For only one quadrant area is A = /4. If the n pixels in our image represent
a unit square with area A = 1, the number of pixels inside the circle will relate to n
by a : 4 ratio. Since we count these pixels in our code we may approximate with
improving accuracy as n increases, shown in Tables 2.2 and 2.3 with runtimes for
R
Core i7-940 chip.
an Intel
Code Listing 2.3 converts from pixel coordinates to unit coordinates, and also
shows how the putpixel method is called on an image to set the RGB color
value of a single pixel. Of course the value of (x, y) rather than (xp, yp) determines
if a point is inside the unit circle or not.
Code Listing 2.3: Initializing variables.
#
x=(xp+0.5)/m # plus one-half --> pixel center!
#
img.putpixel((xp,yp),(160,32,240)) # purple
#
Estimated runtime for size m = 106 is over ten days. Our eleven second runtime is based on a
more efcient calculation suggested on the next page. A common story: the necessity of running a
large problem is what compels us to consider a more sophisticated technique in the rst place.
37
Fig. 2.4: Circle divide-and-conquer. Left: binary search, only the marked pixels are
checked and all other pixels are classied automatically. Right: quadtree, a similar
idea in 2-D where only the corners of each box are checked. In general our goal is to
localize calculations for larger sizes along the edge of the circle, where they matter.
12
binary search
quadtree
10
0
500
1000
1500
2000
2500
3000
Size of Image File, pixels per side
3500
Fig. 2.5: Divide-and-conquer savings. For the previous size m = 106 result we might
alternatively process the 106 106 = 1 trillion pixels in parallel using over 75, 000
computers to achieve the same runtime performance, thus we tend to prefer a better
algorithm to a bigger computer (or more computers) when possible.
38
2 Graphics
Fig. 2.6: Percolate pixelate. Top to bottom: p = 0.5, p = 0.6, and p = 0.7.
39
40
2 Graphics
41
10000
7500
5000
2500
0
0
25000
50000
75000
Total Number of Loops
100000
Fig. 2.8: Diminishing marginal returns. Since there are only so many pixels to draw
eventually more-and-more looping introduces fewer-and-fewer new pixels.
Fig. 2.9: Pascals Triangle. Obviously we could generate a similar image geometrically by starting with a whole triangle and recursively discarding the middle quarter.
Or, here we suggest a technique based on coloring the even-odd values in Pascals
much used triangle, albeit for a sample this small our image is quite pixelated.
42
2 Graphics
43
44
2 Graphics
Fig. 2.12: Turtle square, rendered in a variety of sizes, sequences, and directions.
45
###############################################################################
#
# Chapter 2: Graphics
# Problem 2: Scalable Format
# Lab 2.2.1: Turtle Square
#
###############################################################################
from PIL import Image
from math import cos,sin,pi
###############################################################################
d e f drawline(x1,y1,x2,y2):
#
t=0.0
while t<=1.0:
#
...
#
x=int(x+0.5)
# round to the nearest pixel
y=int(y+0.5)
img.putpixel((x,y), ... )
#
t+=0.001
#
#
d e f jump(xnew,ynew):
g l o b a l xt,yt
#
xt=xnew
yt=ynew
#
d e f move(r):
g l o b a l xt,yt
#
oldx,oldy=xt,yt
#
xt += r*cos(ht*pi/180.0)
yt += -r*sin(ht*pi/180.0)
# inverted
#
drawline(oldx,oldy,xt,yt)
#
d e f turn(dh):
g l o b a l ht
#
ht+=dh
# counterclockwise
#
d e f square(size):
#
...
#
#
###############################################################################
img=Image.new(RGB,(320,240), ... )
#
xt = 20.0 # x-position of turtle
yt = 100.0 # y-position
ht =
0.0 # heading, in degrees
#
square(20.0)
...
#
# end of file
#
###############################################################################
46
2 Graphics
47
Variables stored with a pointer and passed to a function may be altered but not by assignment.
48
2 Graphics
49
50
2 Graphics
Fig. 2.16: Random tree, we might also use random angles at each branching.
51
100
200
300
400
500
Random Walks
600
700
800
600
700
800
5000
4500
4000
3500
3000
2500
2000
1500
1000
500
0
0
100
200
300
400
500
Random Walks
Fig. 2.17: Diminishing marginal returns. Top: new pixels drawn by current walk.
Bottom: total pixels drawn by all walks, shown after each new walk.
52
2 Graphics
53
54
2 Graphics
3
4
11
8
9
10
5
2
7
12
1
13
14
Fig. 2.20: Click count, where your own program need not show the counts.
55
###############################################################################
#
# Chapter 2: Graphics
# Problem 3: Building Software
# Lab 2.3.1: Click Count
#
###############################################################################
from Tkinter import Tk,Canvas
###############################################################################
#
w,h=400,300
#
count = ...
#
d e f click(evnt):
g l o b a l count,x,y
#
count += ...
#
i f ...
x=evnt.x
y=evnt.y
else:
cnvs.create_line(x,y,evnt.x,evnt.y,fill=black)
#
root=Tk()
cnvs=Canvas(root,width=w,height=h,bg=#FFFFF0) # ivory
cnvs.pack()
#
root.bind(<Button-1>,click)
root.mainloop()
#
# end of file
#
###############################################################################
56
2 Graphics
3
4
5
6
1
Fig. 2.21: Polyline, right-click ends each chain, left-click starts the next one.
Lab232: Polyline
Figure 2.21 shows a polyline where a right-click ends each chain. Key events are
also shown in Code Listing 2.8 and function exit is from the sys module.
Code Listing 2.8: Mouse click events and quitting the program.
#
def click(evnt):
...
#
def rightclick(evnt):
...
#
def quit(evnt):
exit(0)
#
root.bind(<Button-1>,click)
root.bind(<Button-3>,rightclick)
root.bind(q,quit)
#
57
Fig. 2.22: A stroll down memory lane with highlights from our previous labs.
58
2 Graphics
Fig. 2.23: A lot of rectangles, each is drawn so you see it grow as you drag.
Lab234: Rectangles!
The idea is that as the mouse is dragged you can see the rectangle changing size,
updated dynamically. Each rectangle is xed in place only as the button is released.
Code Listing 2.10: Rectangle commands.
#
tkid=cnvs.create_rectangle( ... ,fill=)
cnvs.coords(tkid, ... )
#
Code Listing 2.11: Mouse released event.
#
def release(evnt):
...
#
root.bind(<ButtonRelease-1>,release)
#
59
60
2 Graphics
Fig. 2.25: Grafti tool, one of many options our users enjoy.
Chapter 3
Visualization
An ability to create graphics in various forms is not the same as an ability to say
something important and understandable using graphics. A famous high-quality
example is shown in Figure 3.1 by Charles Jospeh Minard, from 1861. This map
depicts a shrinking French army in 1812, rst invading Russia and then retreating.
Fig. 3.1: Napoleons 1812 invasion of Russia, by Charles Joseph Minard, 1861.
Illuminating complex data is not easy. In particular, when conclusions inuence a
political decision we must guard against what Orwell observed: The great enemy of
clear language is insincerity. The same holds for graphics where a pictures worth
a thousand words either sincerely spoken or not. Of course Minard did not use a
computer in the nineteenth century but our focus will be on images that are either
impossible to produce without a computer or at least very much easier with one.
61
62
3 Visualization
Fig. 3.2: Cholera outbreak in London, by John Snow, 1854. The black dots represent
cholera deaths and stacks of these can be found near the Broad Street water pump.
63
Fig. 3.3: Earth at night, a high-tech composite of satellite data, 27 November 2000.
Image courtesy of NASA, production credit C. Mayhew and R. Simmon.
Fig. 3.4: Florida county-level presidential election results from 2 November 2000.
Counties are light gray if won by George W. Bush and dark gray if won by Al Gore.
64
3 Visualization
65
66
3 Visualization
30.2492550000000016
30.2469340542000005
36.4993199124999990
36.4993666550000029
67
68
3 Visualization
69
70
3 Visualization
1.000000e+06
1.000000e+07
Fig. 3.11: Dynamic updates, a breakpoint is modied if the mouse is hovering over
its corresponding square as the scroll-wheel turns... and the polygons change colors
immediately!
71
###############################################################################
#
# Chapter 3: Visualization
# Problem 1: Geospatial Popluation Data
# Lab 3.1.5: Dynamic Updates
#
# http://www.census.gov/geo/www/cob/st2000.html
# http://www.usps.com/ncsc/lookups/usps_abbreviations.html
#
###############################################################################
...
data=open(lab313.txt,r).read().split()
tkid={}
name=None
#
j=0
w h i l e data[j]!=END_FILE:
#
i f name==None:
name=data[j]
tkid[name]=[]
# current region has yet to add a Tk ID#
xy=[]
#
e l i f data[j]==END_ONE_POLY:
#
# current polygon now has all its (x,y) points
#
xyp=[]
#
j=0
w h i l e j< l e n (xy):
# loop over current polygons (x,y) points
x,y=xy[j]
...
xyp.append((xp,yp))
j+=1
#
# fill color is based on population data
#
i f ...
color=#646464
# dark gray
e l i f ...
color=#C0C0C0
# light gray
else:
color=#FFFFFF
# white
#
tkidnum=cnvs.create_polygon(xyp,fill=color,outline=black)
#
tkid[name].append(tkidnum) # add this Tk ID# to current regions list
#
xy=[]
#
e l i f data[j]==END_ALL_POLY:
name=None
#
else:
...
xy.append((x,y))
# add one point to this polygons xy-list
#
j+=1
#
...
#
# end of file
#
###############################################################################
72
3 Visualization
1000
Fig. 3.12: Diffusion after 1000 steps where all particles began at the center.
73
2000
3000
Fig. 3.13: Particle diffusion, continued.
74
3 Visualization
Distance, pixels
140
AVG obsrvd
RMS obsrvd
SQRT(time)
120
100
80
60
40
20
0
0
2500
5000
Fig. 3.14: Average distance, measured from the particles shared starting location.
N i=0
1 N1
RMS =
di2
N i=0
AV G =
In calculating RMS, the square root in di and the square in the formula cancel
each other out; ignore both to avoid performing useless calculations.
75
160
140
120
100
80
60
40
20
0
0
2500
5000
Fig. 3.15: Standard deviation, measuring the concentration of data near the average.
76
3 Visualization
2500
Fig. 3.16: A second Tk window is used to animate a normal distribution probability
curve as the particles are moving, shown here after 2500 steps.
77
###############################################################################
#
# Chapter 3: Visualization
# Problem 2: Particle Diffusion
# Lab 3.2.4: Animate Normal Curve
#
###############################################################################
from Tkinter import Tk,Canvas
from random import random
from math
import sqrt,pi,exp
###############################################################################
...
#
# probability density function
#
d e f pdf(x,avg,sd):
i f sd==0.0:
# special case... at time=1 all particles have d_i=1.0
i f x==1.0:
r e t u r n 1.0
# so... probability is 1.0 (certain) here
else:
r e t u r n 0.0
# and... probability is 0.0 (impossible) elsewhere
else:
#
# general case...
#
r e t u r n 1.0/(sd*sqrt(2.0*pi))*exp(-1.0*(x-avg)*(x-avg)/(2.0*sd*sd))
#
###############################################################################
#
root=Tk()
cnvs=Canvas(root,width=w,height=h,bg=white)
cnvs.pack()
#
root2=Tk()
cnvs2=Canvas(root2,width=w,height=h,bg=white)
cnvs2.pack()
#
...
root.mainloop()
#
# end of file
#
###############################################################################
2
2
1
e(x ) /(2 )
2
Note that x is measured in pixels for raw screen distance with no interpolation so
we scale only by a factor of 2, but since y is a probability it must be scaled by the
window height or our curve will appear exceedingly small.
78
3 Visualization
79
2500
Fig. 3.17: Vertical and horizontal lines, the model parameters.
80
3 Visualization
Code Listing 3.8: Bins form a histogram to check our model assumptions.
#
def tick():
...
#
j=0
while j<bins:
#
# current coordinates of this bin
#
x1,y1,x2,y2=canvas2.coords( ... )
#
# desired height of this bin
#
y=bincount[j]/(1.0*num)/((w/2.0)/num_bins)
#
# translate bin height to pixel coordinates
#
y1=int(h-h*(y/0.03)+0.5)
#
# only the bin height changes !!!
#
canvas2.coords( ... ,x1,y1,x2,y2)
j+=1
#
...
81
2500
Fig. 3.18: A histogram for the observed particle distances indicating that our assumption of a normal distribution requires correction.
82
3 Visualization
83
84
3 Visualization
Approximating
Computed Value
0
0
10
15
20
Number of Terms in Series
25
30
Fig. 3.21: Plot values, showing both alternating terms and convergence to .
3.3 Approximating
Consider again how to calculate digits of but now using series approximations
such as Gregorys series, centuries-old (!) and based on tan 45 = tan ( /4) = 1.
1 1 1 1 1
1
= + +
+
4
1 3 5 7 9 11
Lab331: Text Output
A cumbersome way to visualize this series is shown in Table 3.1 where we output
the approximation as each new term is added. Note the very slow convergence.
3.3 Approximating
85
computed
4.0000000000000000
2.6666666666666670
3.4666666666666668
2.8952380952380956
3.3396825396825403
2.9760461760461765
3.2837384837384844
3.0170718170718178
3.2523659347188767
3.0418396189294032
3.2323158094055939
3.0584027659273332
3.2184027659273333
3.0702546177791854
3.2081856522619439
3.0791533941974278
3.2003655154095489
3.0860798011238346
3.1941879092319425
3.0916238066678399
current term
sign denom
1.0000000000000000 1.0
1.0
-0.3333333333333333 -1.0
3.0
0.2000000000000000 1.0
5.0
-0.1428571428571428 -1.0
7.0
0.1111111111111111 1.0
9.0
-0.0909090909090909 -1.0 11.0
0.0769230769230769 1.0 13.0
-0.0666666666666667 -1.0 15.0
0.0588235294117647 1.0 17.0
-0.0526315789473684 -1.0 19.0
0.0476190476190476 1.0 21.0
-0.0434782608695652 -1.0 23.0
0.0400000000000000 1.0 25.0
-0.0370370370370370 -1.0 27.0
0.0344827586206897 1.0 29.0
-0.0322580645161290 -1.0 31.0
0.0303030303030303 1.0 33.0
-0.0285714285714286 -1.0 35.0
0.0270270270270270 1.0 37.0
-0.0256410256410256 -1.0 39.0
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
3.1420924036835256
3.1410931531214472
3.1420919046819966
3.1410936516248467
3.1420914066759815
3.1410941491342212
3.1420909096625045
3.1410946456525419
3.1420904136386012
3.1410951411827663
3.1420899186013189
3.1410956357278415
3.1420894245477173
3.1410961292907023
3.1420889314748672
3.1410966218742717
3.1420884393798509
3.1410971134814618
3.1420879482597623
3.1410976041151719
0.0002499375156211
-0.0002498126405196
0.0002496878901373
-0.0002495632642875
0.0002494387627837
-0.0002493143854400
0.0002491901320708
-0.0002490660024907
0.0002489419965148
-0.0002488181139587
0.0002486943546381
-0.0002485707183694
0.0002484472049689
-0.0002483238142538
0.0002482005460412
-0.0002480774001488
0.0002479543763947
-0.0002478314745973
0.0002477086945752
-0.0002475860361476
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
1.0
-1.0
4001.0
4003.0
4005.0
4007.0
4009.0
4011.0
4013.0
4015.0
4017.0
4019.0
4021.0
4023.0
4025.0
4027.0
4029.0
4031.0
4033.0
4035.0
4037.0
4039.0
86
3 Visualization
4.000000
2.666667
1
3.466667
2
3.137593
250
x3 x5 x7 x9 x11
+ +
+
3! 5! 7! 9! 11!
cos x = 1
x2 x4 x6 x8 x10
+ +
+
2! 4! 6! 8! 10!
3.3 Approximating
87
2
1
1
1
1
1
1
= 2 + 2 + 2 + 2 + 2 + 2 +
6
1
2
3
4
5
6
Text output is shown in Table 3.2 where sign no longer matters (angles would
approach 45 from only one side) but we must remember to square the denominator
and take a square root after multiplying through by six. Runtime for 25 million terms
was almost 14 seconds and the last term added is nearly zero in 16-digit oatingpoint representation, assuming use of the 64-bit IEEE standard format.
computed
2.4494897427831779
2.7386127875258306
2.8577380332470415
2.9226129861250305
2.9633877010385707
2.9913764947484185
3.0117739478462142
3.0272978566578428
3.0395075895610533
3.0493616359820699
3.0574815067075627
3.0642878178339279
3.0700753718932203
3.0750569155713614
current term
denom=step2
1.0000000000000000
1.0
0.2500000000000000
4.0
0.1111111111111111
9.0
0.0625000000000000
16.0
0.0400000000000000
25.0
0.0277777777777778
36.0
0.0204081632653061
49.0
0.0156250000000000
64.0
0.0123456790123457
81.0
0.0100000000000000
100.0
0.0082644628099174
121.0
0.0069444444444444
144.0
0.0059171597633136
169.0
0.0051020408163265
196.0
2500000
5000000
7500000
10000000
12500000
15000000
17500000
20000000
22500000
25000000
3.1415922716180411
3.1415924626038212
3.1415925262654896
3.1415925580959025
3.1415925771942814
3.1415925899245529
3.1415925990227356
3.1415926058416219
3.1415926111389916
3.1415926153845746
0.0000000000001600
0.0000000000000400
0.0000000000000178
0.0000000000000100
0.0000000000000064
0.0000000000000044
0.0000000000000033
0.0000000000000025
0.0000000000000020
0.0000000000000016
6.250000e+12
2.500000e+13
5.625000e+13
1.000000e+14
1.562500e+14
2.250000e+14
3.062500e+14
4.000000e+14
5.062500e+14
6.250000e+14
88
3 Visualization
Floating-Point Representation
Computers do arithmetic in binary (base 2) because it is easier to build the machines
that way. Table 3.3 counts in binary and also hexadecimal (base 16), a convenient
intermediary because each hex digit translates directly to four binary digits (bits).
In the IEEE double-precision format a oating-point value stores 64-bits: one bit
for the sign, 11 bits for the exponent, and 52 bits for the fraction. The exponent
bits are assumed to be the actual exponent plus 1023 so that negative numbers, and
twos complement integer conversion, are not required. However, there are special
cases when the exponent bits are all the same. In the case of all ones we get either
not-a-number (NaN) or an innity. If the fractional bits are all zero then we have
either positive or negative
innity,
based on the sign. Otherwise it is NaN, meaning
there are 253 2 = O 1016 different representations for not-a-number.
Generally our value is 1.F 2(E1023) where the 1 in front of the fraction need
1022 instead. Thus, the smallest
not be stored. If E is all zerosthe value
is 0.F 2
1074
324
, but arithmetic involving 1.0 and values less
= O 10
positive value is 2
than machine epsilon mach = 1016 has no effect, as we will soon see.
One by-product of this system is that many terminating decimals in base 10 are
repeating decimals in base 2, perhaps most notably:
1
1
1
1 1
1
=
+
=
+
= 0.000102 + 0.000012 = 0.000112
10 15 30 15 2 15
Since these fractions are approximated in binary we must take great care in our code
any time we want to compare two oating-point values exactly.
3.3 Approximating
89
31
22
14
Fine-Grain Parallelism
Figure 3.23 suggests a technique for calculating any sum in parallel, in this case:
3 + 1 + 4 + 1 + 5 + 9 + 2 + 6 = 31
In serial we might initialize a variable sum=0 and do a loop that adds each term:
sum=3, sum=4, sum=8, sum=9, sum=14, sum=23, sum=25, sum=31
However, as we have seen for series requiring a large numer of terms, this loop
may need to run for a long time. An alternative is to pair the terms up so that each
pair-sum can be calculated simultaneously. Here 3+1=4 and 4+1=5 and 5+9=14
and 2+6=8 could all be calculated at the same time in parallel. This idea is repeatedly applied on the intermediate sums, so 4+5=9 and 14+8=22 at the next level,
after which 9+22=31 gives the nal result.
Rather than requiring N = 25 million loops we now need only log2 N levels of
this parallel tree. Since
log2 (25, 000, 000) < 25
we might speed up our run by a factor of a million! (In theory.) This is not an
embarrassingly parallel problem or even one where spatial decomposition applies,
but is known instead as ne-grain parallelism.
90
3 Visualization
computed
3.0000000000000000
3.1250000000000000
3.1390625000000001
3.1411551339285717
3.1415111723400302
current term 2 j 1
5.0000e-01 1.0
2.0833e-02 3.0
2.3437e-03 5.0
3.4877e-04 7.0
5.9340e-05 9.0
c2 j1 2(2 j1)
1.0000 0.5000000000000000
0.5000 0.1250000000000000
0.3750 0.0312500000000000
0.3125 0.0078125000000000
0.2734 0.0019531250000000
0.1224 0.0000000000001137
0.1196 0.0000000000000284
0.1101 0.0000000000000001
0.1081 0.0000000000000000
x3
x5
x7
x9
x11
= c1 x + c3 + c5 + c7 + c9 + c11
+
6
3
5
7
9
11
1 x3
3 x5
5 x7
7 x9
9 x11
= (1)x + c1
+ c3
+ c5
+ c7
+ c9
+
6
2 3
4 5
6 7
8 9
10 11
c1 = 1
c3 =
1
2
c5 =
13
24
c7 =
135
246
c9 =
1357
2468
c11 =
13579
246810
Note how we experience swamping after step 23 long before underow at step 531.
Chapter 4
Efciency
To solve a small problem it is unnecessary to write code that runs as fast as possible,
but here small must be understood reexively to mean only that a fast running
code is not required. Regardless, to solve problems of practical interest it will certainly be necessary that our code runs fast for large cases, and as habits govern so
much of our behavior we will do best by writing code for small cases with potential
large cases already in mind.
100
linear
quadratic
Relative Runtime
80
60
40
20
0
0
4
6
Size of Problem
10
Fig. 4.1: Comparison of runtime efciency between linear and quadratic algorithms
as the size of a problem grows. Small problems appear only in the lower-left corner.
91
92
4 Efciency
93
MaineCarolina
South
Ohio
Utah
Washington
North Carolina
Georgia
New York
North Dakota
New Mexico
Montana
Virginia
Indiana
Maryland
Michigan
New Hampshire
New Jersey
Rhode Island
Texas
Hawaii
Oklahoma
Louisiana
Wisconsin
Tennessee
Vermont
California
Colorado
Missouri
Kansas
Florida
Massachusetts
Arizona
Nebraska
South Dakota
Minnesota
Delaware
Alabama
Kentucky
Connecticut
Arkansas
Idaho
Oregon
District of Columbia
Pennsylvania
Alaska
Wyoming
Nevada
Illinois
Iowa
Code Listing 4.2: Part of the le from Lab314 containing Census 2000 data.
AL 4447100
AK 626932
AZ 5130632
AR 2673400
CA 33871648
CO 4301261
CT 3405565
...
Code Listing 4.3: Part of a le to translate state abbreviation to state full name.
AL
Alabama
AK
Alaska
AZ
Arizona
...
94
4 Efciency
seas
power
united
do
free
themselves
justice
at
has
their
the
others
refused
repeated
are
we
usurpations
government
hold
time
these
without
colonies
pass
this
our
of
is
peace
that
long
and
war
which
people
us
declaration
as
them
america
by
powers
he
assent
independent
with
most
abolishing
when
to
all
be
large
among
from
rights
states
an
have
in
absolute
such
laws
right
they
his
mankind
should
other
on
it
been
for
new
its
Fig. 4.3: Word cloud where font size is based on relative frequency in the text.
words = wordlist
f req = hashtable
while j = 0, 1, 2, . . . do
count = 0
while k = 0, 1, 2, . . . do
if match then
count = count + 1
end if
end while
f req[words[ j]] = count
end while
95
powers
usurpations
power
mankind
people
abolishing
assent
america
war
united
time
independent
free
new
laws
large
states
hold
declaration
justice
right
rights
pass
refused
government
absolute
seas
peace
colonies
repeated
themselves
Fig. 4.4: Word cloud more readily associated with the Declaration of Independence,
excluding common words and only including words that appear at least three times.
words = wordlist
f req = hashtable
while j = 0, 1, 2, . . . do
if f irst then
f req[words[ j]] = 1
else
f req[words[ j]] = f req[words[ j]] + 1
end if
end while
96
4 Efciency
Fig. 4.5: Sunset at Cerro Tololo Inter-American Observatory near La Serena, Chile.
Image courtesy of the U.S. Navy, photo credit Dr. Brian Mason.
Databases
Accumulation of data continues to grow at a faster-and-faster rate, so much so that
researchers in astronomy are now facing issues related to the mere transfer of data
from observational projects located in Chile, see Figure 4.5, before analysis can
even be performed (i.e., actually doing the science).
However, these problems will be solved because the promise of new learning
from massive amounts of data is so attractive. For instance, language translation
software that uses computational statistics has become a real alternative to formal
linguistics, not in the sense that theory could be abandoned but, as we have seen
regarding experiment and computer simulation, theory can be augmented by data.
T heory Data
Experiment Simulation
97
proportion
concerning
good
liberty
interest
faction
under
found
time
passions
popular
representatives
union
majority
public
society
party
against
citizens
causes
government
whole
republic
property
parties
views
justice
interests
local
rights
passion
common
opinions
Fig. 4.6: Word cloud from the famous Federalist 10, written by James Madison,
shown without overlap between the bounding boxes that surround each words text.
98
4 Efciency
stronger
former
place
first
security
authority
people
executive
latter
departments
parties
society
great
several
same
department
necessary
weaker
republic
control
republican
separate
system
more
federal
each
distinct
men
state
principles
very
nature
majority
against
little
citizens
power
different
members
independent
government
interests
well
under
less
one
itself
rights
principle
Fig. 4.7: Word cloud from Federalist 51, also written by James Madison.
Lab415: Comparison
Comparing the word clouds in Figures 4.6, 4.7, and 4.8, we see clearly the variety of
topics discussed in the Federalist Papers. Keep in mind also that they were written
by diffferent people: James Madison, Alexander Hamilton, and John Jay.
Implement a feature that cycles through all 85 papers showing one cloud on the
screen at a time and somehow indicating (background color, footnote) who wrote
each article. Note that frequencies of multiple similar words could be combined, too.
We might, in this case, count promise, promises, promised, and promising
as essentially the same word.
In addition, it is okay if the words in your cloud overlap.
A challenging problem for a computer to solve would be to determine the author
from the word cloud but without access to the actual papers themselves, perhaps
using only the three authors other writings as background knowledge.
99
void
powers
law
nothing
judiciary
executive
judges
well
those
upon
acts
courts
laws
body
duty
justice
offices
great
power
legislature
between
rights
themselves
independence
constitution
act
authority
ought
two
contrary
government
legislative
judicial
people
superior
one
hold
particular
nature
constitution
those
cases
shall
court
ought
appellate
general
inferior
supreme
united
laws
fact
authority
both
plan
power
body
state
one
cognizance
trial
law
upon
public
jury
same
new
courts
legislative
well
government
states
national
legislature
judicial
jurisdiction
federal
part
causes
men
judges
convention
Fig. 4.8: Word clouds from Federalists 78 and 81, written by Alexander Hamilton.
100
4 Efciency
Fig. 4.9: Some of the crumbling ruins of ancient Babylon, 1932. Image courtesy of
the G. Eric and Edith Matson Photograph Collection, Library of Congress Prints and
Photographs Division, original source American Colony (Jerusalem), Photo Dept.
101
Cobweb Diagram
6
5
4
3
2
1
0
0
3
x
Fig. 4.10: Cobweb diagram, square root of two. Even if our initial guess is absurd
the value of x stops changing after only seven steps. A vertical line shows how an
input produces an output while a horizontal line shows how we then use that ouptut
as the next input in order to build a sequence of better-and-better approximations.
102
4 Efciency
Cobweb Diagram
6
5
4
3
2
1
0
0
3
x
what sense is the formula more true? Our previous approximation of 2 converged
to 1.4142135623730949 rather than the value 1.4142135623730951 returned by the
math modules sqrt function. Pretty close. Say we were manufacturing a car and
needed this calculation; could an industrial saw cut metal with enough precision
for the difference to matter? Afterwards, could we even measure the cut metal this
precisely? And how does the sqrt function calculate its result anyway?
103
Fig. 4.12: A gecko climbing up glass. Evidence has suggested that this ability is
possible only because an exceedingly large number of very small bristles use intermolecular attraction in a massively parallel way. Image courtesy of Tim Vickers.
104
4 Efciency
Cobweb Diagram
1
0.8
0.6
0.4
0.2
0
0
0.2
0.4
0.6
0.8
Fig. 4.13: Periodic behavior, oscillation between two points: 0.802 and 0.509
Lab423: Periodic
What happens if our sequence of approximations fails to approach a single value?
Figure 4.13 shows just this kind of behavior for x = 3.21 x (1 x) and x0 = 0.25.
We run 30 loops rst with no display so the values have time to settle down, then
show the next 10 loops. Note how an input of 0.802 outputs 0.509, and vice versa.
Lab424: Chaotic
Figure 4.14 shows a very different kind of behavior, chaos, although the only change
is now x = 3.99 x (1 x) and x0 = 0.25. Systems that are this sensitive to slight
variations in a model parameter occur most famously in weather forecasting where
the so-called buttery effect discovered by Lorenz makes it difcult to predict
events beyond the very short term. (As the story goes, a buttery apping its wings
in San Francisco causes a rainstorm to develop later
in New Jersey.)
Code Listing 4.6 shows sample output after O 104 loops, seemingly a sufcient
amount of time for any transient movement to have ended and yet still no regular
pattern has emerged between any number of points.
105
Cobweb Diagram
1
0.8
0.6
0.4
0.2
0
0
0.2
0.4
0.6
0.8
Code Listing 4.6: A sequence that fails to settle down over time.
:
0.8032323382113545
0.6306200947608700
0.9294241794701987
0.2617235476045228
0.7709650856129653
0.7045459102912460
0.8305622726266709
0.5615070498244030
0.9824053624593747
0.0689674144190529
0.2562015315679398
0.7603436040928253
0.7270626191537534
0.7917858422623198
0.6577954787985217
0.8981513416142737
106
4 Efciency
107
108
4 Efciency
i = 1
Except for the rare historical genius it was only the latter half of the last century
when computers allowed humans to even see the structures these schemes generate.
109
110
4 Efciency
Fig. 4.17: Zooming in. Left: The arrow points to a box indicating the zoom region.
Right: The zoom region shows self-similarity as the overall set is present here again.
Lab433: Zooming In
Figure 4.17 shows what the Mandelbrot Set looks like as we zoom in on a particular
region and you can begin to see why this structure has fascinated so many people.
Code Listing 4.10 manually species this zoom region while Code Listing 4.11 uses
mouse clicks in order to zoom interactively, reducing both x and y by a factor of 2.
Code Listing 4.10: Manually specifying the zoom region.
#
xmin=-0.18984375
xmax=-0.12734375
ymin= 1.010546875
ymax= 1.057421875
#
Code Listing 4.11: Using mouse clicks to zoom interactively.
#
# click is at (xc,yc)
#
dx=0.5*(xmax-xmin)
dy=0.5*(ymax-ymin)
#
xmin=xc-0.5*dx
xmax=xc+0.5*dx
ymin=yc-0.5*dy
ymax=yc+0.5*dy
#
111
Fig. 4.18: Zooming and sharpening. Left: Zoom region taken from upper-left quadrant of previous zoom region. Right: Doubling of iteration count sharpens features.
This is an embarrassingly parallel problem and we can use spatial decomposition to assign different columns to different parallel nodes, but not all columns are
equal in terms of workload. Those columns with more pixels whose corresponding
sequence is well-behaved (these are actually the only points in the Mandelbrot Set)
will require more time than those with many sequences that blow up quickly.
112
4 Efciency
Fig. 4.19: Spiral, located along the upper-right edge of the overall set, as we zoom
further-and-further the spiral turns round-and-round, seemingly forever. Top: spiral
with tip rst pointing up and left, turning counterclockwise. Bottom: the same
spiral zoomed-in more so that the tip is now pointing left and down.
113
Fig. 4.20: Spiral, if we zoom in far enough the image will pixelate once the oatingpoint values are sufciently close together. Top: same as before but now pointing
down and right. Bottom: a few full spins later our spiral has become pixelated;
note that intensities have been articially enhanced to sharpen the details.
114
4 Efciency
Fig. 4.21: More features. Top: a valley between the overall head and body.
Bottom: zoomed further, one of many tendril-like owers present in this valley.
115
Lab434: Movie
We make a movie of the Mandelbrot Set by zooming in, see Code Listing 4.13,
then panning across that image. Code Listing 4.14 shows left to right motion where
only the end-column is calculated for our next image; all the others just shift over,
thus saving a factor of O(100), i.e. the max iteration count, a comparable speed-up
to rendering on a 100-node parallel system, only cheaper! Each image is saved as a
separate PNG le with frames numbered from 000 to 999, and once we have all the
frames they can be combined together into a single animated GIF le:
convert -delay 10 -loop 1 frame*.png movie.gif
In only minutes a program of size 3.4 KB is generating les of total size 15 MB,
a factor of over 4, 000. Wow!
Code Listing 4.13: Manually specifying the zoom region.
#
xmin=-2.0
xmax=-1.0
ymin=-0.0625
ymax= 0.6875
#
Code Listing 4.14: Incremental updates as we pan across a zoomed image.
#
img.save(frame%03d.png%frame) # 1000 frames
frame+=1
#
xp=0
while xp<w-1:
yp=0
while yp<h:
#
red,green,blue=img.getpixel((xp+1,yp)) # shift
img.putpixel((xp,yp),(red,green,blue))
#
yp+=1
xp+=1
#
# xp==w-1, the one new column we now need to render
#
xmin += ...
xmax += ...
116
4 Efciency
Fig. 4.22: An example Julia Set closely related to the Mandelbrot Set.
Chapter 5
Recursion
Fig. 5.1: A scene in 3-D rendered using recursive ray tracing, where reections
appear within reections of their own reections. Image courtesy of Al Hart.
117
118
5 Recursion
119
Code Listing 5.3: Random grids. Empty slots are shown as dashes, healthy people
as O, and sick people as X (also in bold). Top: 40% empty. Bottom: 30% empty.
O
O
X
O
O
O
O
O
O
O
X
X
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
X
O
O
O
O
X
O
O
O
O
O
O
X
O
-
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
X
O
X
X
O
X
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
-
X
O
O
O
O
O
X
O
O
O
X
O
X
-
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
X
X
O
O
O
O
X
O
O
O
O
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
X
-
O
O
O
O
O
O
X
O
O
O
X
X
O
O
O
O
-
O
O
X
X
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
-
O
X
O
X
O
O
X
O
O
O
X
O
X
O
X
O
X
O
X
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
X
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
-
O
X
O
O
O
O
O
O
O
X
O
X
X
O
O
X
O
O
X
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
-
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
X
O
X
O
O
O
X
O
O
O
X
O
O
X
O
O
O
X
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
X
X
O
X
O
X
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
X
X
O
O
X
O
O
O
O
X
O
-
O
O
O
O
X
O
O
O
O
X
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
X
X
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
O
X
O
O
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
X
O
X
X
O
X
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
X
O
X
-
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
X
X
O
O
O
O
X
O
O
O
O
O
O
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
X
-
O
O
O
O
O
O
O
X
O
O
O
X
X
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
-
O
X
O
X
O
O
X
O
O
O
O
O
O
X
O
X
O
X
O
X
O
X
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
X
O
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
X
X
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
O
X
O
X
X
O
O
O
X
O
O
X
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
-
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
X
O
X
O
O
O
O
X
O
O
O
O
X
O
O
X
O
O
O
O
X
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
X
O
X
O
X
O
X
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
O
X
X
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
120
5 Recursion
Code Listing 5.4: Infection. Top: Same 40% empty grid. Bottom: Once-healthy
nearest neighbors of everyone initially marked as sick are now also sick themselves.
O
O
X
O
O
O
O
O
O
O
X
X
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
X
O
O
O
O
X
O
O
O
O
O
O
X
O
-
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
X
O
X
X
O
X
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
-
X
O
O
O
O
O
X
O
O
O
X
O
X
-
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
X
X
O
O
O
O
X
O
O
O
O
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
X
-
O
O
O
O
O
O
X
O
O
O
X
X
O
O
O
O
-
O
O
X
X
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
-
O
X
O
X
O
O
X
O
O
O
X
O
X
O
X
O
X
O
X
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
X
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
-
O
X
O
O
O
O
O
O
O
X
O
X
X
O
O
X
O
O
X
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
-
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
X
O
X
O
O
O
X
O
O
O
X
O
O
X
O
O
O
X
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
X
X
O
X
O
X
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
X
X
O
O
X
O
O
O
O
X
O
-
O
O
O
O
X
O
O
O
O
X
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
X
X
X
O
O
X
O
X
X
X
X
X
X
X
O
O
O
O
O
X
X
X
O
O
X
O
X
X
X
X
X
O
O
X
X
X
O
O
O
O
X
X
X
-
X
X
O
O
X
X
O
O
O
O
O
O
O
O
O
O
X
X
X
X
O
O
X
O
O
X
X
O
X
X
O
O
O
O
O
X
O
O
O
O
O
O
X
X
O
O
O
X
X
X
O
O
O
O
O
O
-
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
X
X
X
X
O
O
O
O
O
X
X
O
O
O
X
X
X
O
X
X
O
O
O
O
O
O
X
X
X
X
X
X
O
X
X
X
X
X
X
O
O
O
O
O
X
O
X
X
O
X
X
X
-
X
X
O
O
X
O
X
O
O
X
X
X
X
-
X
X
X
O
X
X
O
O
O
O
O
X
O
X
X
X
O
O
X
X
X
O
X
X
X
X
X
O
O
O
O
X
X
X
O
X
X
X
X
O
O
O
O
O
X
X
O
O
O
O
X
X
O
X
X
X
O
X
O
X
X
X
X
O
O
X
X
O
X
O
O
O
O
X
X
X
X
X
O
X
O
X
O
O
O
X
O
X
X
X
X
X
O
O
O
X
O
O
O
O
X
O
X
X
X
X
O
X
X
-
O
O
O
X
O
X
X
X
O
X
X
X
X
X
X
O
-
O
O
X
X
X
O
O
X
X
X
X
X
O
O
X
X
O
O
O
O
O
X
X
O
X
X
O
O
O
X
O
O
O
X
O
O
X
X
O
X
X
O
O
O
X
X
X
O
O
O
O
X
X
X
O
O
O
X
O
O
O
X
O
O
O
O
X
O
O
X
X
X
X
O
O
X
X
O
X
X
X
O
O
O
O
O
X
X
X
O
X
O
-
O
X
O
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
O
O
O
X
O
O
O
O
X
X
O
X
X
X
X
X
X
X
X
X
X
X
O
O
O
O
O
O
O
X
O
O
X
X
X
X
O
O
X
X
O
X
X
O
O
X
X
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
X
X
X
X
X
X
O
O
O
O
X
X
X
O
X
X
X
X
-
X
X
O
X
O
O
O
O
X
X
X
X
X
X
O
X
X
X
X
X
O
-
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
X
X
O
-
X
X
X
O
O
O
O
O
O
O
O
O
O
O
X
X
X
-
O
O
O
O
O
O
O
X
X
X
X
O
O
O
O
O
O
X
O
X
O
O
O
O
X
O
O
O
X
X
O
X
O
O
O
O
O
O
O
X
-
X
X
X
O
O
X
X
O
O
X
X
X
X
X
O
O
X
X
O
-
X
O
O
O
X
O
O
O
X
O
X
O
X
X
O
O
O
O
X
X
X
O
O
O
O
X
X
X
X
X
X
X
X
X
O
X
X
X
O
X
X
O
O
O
O
X
O
X
X
X
X
X
X
X
O
X
X
X
X
-
O
O
O
X
X
X
O
X
X
X
X
O
O
-
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
X
X
X
X
O
O
O
O
O
O
X
X
O
O
O
O
O
O
X
X
O
O
X
X
X
O
O
121
122
5 Recursion
Lab513: Floodll
Imagine the coughing is uncontrollable. Everyone sick is coughing and everyone
they cough on gets sick. Soon the entire social circle is sick and since the newlysick are immediately coughing on their once-healthy neighbors we no longer need
to use the asterisk () to mark anyone as going to be sick. They are all just sick,
right away... thank goodness disease doesnt actually spread this fast!
Code Listing 5.7 on the next page shows the desired output, again for the same
grid initialization (go back and compare to see for yourself). Code Listing 5.6 shows
how to recursively infect the neighbors neighbors neighbor, and so on.
Code Listing 5.6: Floodll. Sick people infecting everyone else in their social circle.
#
def maybe_infect(grid,x,y):
if 0<=x<w and 0<=y<h:
# Are we even in bounds?
j=y*w+x
if grid[j]!=-:
# Is this an empty slot?
if grid[j]!=X:
# Are we already sick?
grid[j]=X
# Mark as sick.
#
# recursion...
#
maybe_infect(grid,x,y-1) # up
#
# recursion...
#
maybe_infect(grid,x,y+1) # down
#
# recursion...
#
maybe_infect(grid,x-1,y) # left
#
# recursion...
#
maybe_infect(grid,x+1,y) # right
#
In this code it is essential that we mark as sick immediately because otherwise
the recursion will go back-and-forth between neighbors, each infecting the other
over and over and over again until we reach the depth limit (typically 1000 calls).
The condition that a person is already sick is known as the base case and this is
what stops the sequence of recursive calls from continuing. After all, there are only
so many slots in the grid and thus only so many healthy people to infect.
In general this algorithm is known as oodll and it could also be used to
implement a ll-the-area tool in our drawing program from Chapter 2.
123
Code Listing 5.7: Recursive infection. Top: Again, same 40% empty grid as before.
Bottom: Everyone in the social circle of a sick person is now sick themselves, too.
O
O
X
O
O
O
O
O
O
O
X
X
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
X
O
O
O
O
X
O
O
O
O
O
O
X
O
-
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
X
O
X
X
O
X
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
-
X
O
O
O
O
O
X
O
O
O
X
O
X
-
O
O
O
O
O
X
O
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
O
O
X
O
O
O
O
O
X
X
O
O
O
O
X
O
O
O
O
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
O
O
X
-
O
O
O
O
O
O
X
O
O
O
X
X
O
O
O
O
-
O
O
X
X
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
X
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
X
O
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
-
O
X
O
X
O
O
X
O
O
O
X
O
X
O
X
O
X
O
X
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
X
O
O
X
X
O
X
O
O
O
O
O
O
O
O
O
O
X
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
X
X
O
O
O
O
O
O
O
X
O
O
O
X
O
-
O
X
O
O
O
O
O
O
O
X
O
X
X
O
O
X
O
O
X
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
X
X
-
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
-
X
O
X
O
O
O
X
O
O
O
X
O
O
X
O
O
O
X
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
O
O
X
O
X
X
O
X
O
X
O
O
O
X
O
O
X
O
O
O
O
O
O
O
O
X
X
O
O
X
O
O
O
O
X
O
-
O
O
O
O
X
O
O
O
O
X
O
O
O
-
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
X
O
O
X
O
O
O
O
O
O
O
X
O
O
O
O
O
O
O
O
O
O
O
X
O
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
O
X
X
X
X
X
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
O
X
X
X
X
X
X
O
X
X
X
X
O
X
X
-
X
X
X
X
X
X
X
X
O
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
O
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
O
X
X
X
X
X
X
X
X
X
O
X
-
O
X
O
O
O
X
X
X
X
O
X
X
X
X
X
X
X
O
O
O
O
O
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
O
O
O
O
X
X
X
X
O
O
X
X
X
X
X
124
5 Recursion
1
1
1
1
1
1
1
L
L
L
L
L
L
L
R
R
R
R
R
R
-
1
1
1
1
1
1
I
I
H
L
L
L
L
L
R
R
R
R
R
1
1
1
1
1
1
H
H
H
H
H
R
R
R
R
R
R
1
1
1
1
1
1
H
H
H
H
H
H
H
H
R
R
R
R
R
R
-
8
4
H
H
H
H
H
H
H
H
H
R
R
R
R
R
R
2
2
2
4
4
H
H
P
P
H
H
R
R
R
R
R
R
R
4
4
4
4
4
J
P
P
P
S
U
U
R
R
R
R
R
R
3
3
4
4
4
4
J
P
P
S
S
R
R
R
-
3
3
4
4
4
4
J
R
R
R
R
R
R
-
3
3
4
4
4
4
4
M
Q
R
R
R
R
R
R
R
R
R
R
R
R
R
3
3
4
4
4
4
M
M
R
R
R
R
R
R
R
R
R
R
R
R
3
7
4
4
4
4
4
M
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
3
3
4
4
D
4
4
4
R
R
R
R
R
R
R
R
3
4
4
4
R
R
R
R
R
R
R
R
b
b
c
R
4
4
4
4
N
R
R
R
R
Z
c
c
-
4
4
4
4
4
4
4
4
N
R
R
R
R
R
R
a
-
4
4
4
4
4
4
4
4
4
4
R
R
T
V
a
a
a
4
4
4
4
4
4
4
4
4
4
T
T
a
a
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
A
4
G
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
E
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
B
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
d
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
K
K
4
4
4
4
4
4
4
4
4
4
4
4
4
-
4
9
4
K
K
K
4
4
4
4
4
X
4
-
5
6
C
F
F
4
4
4
4
W
4
4
4
4
6
6
6
C
F
F
F
F
4
4
4
4
4
4
4
4
4
4
4
4
4
6
6
6
C
F
F
O
4
4
4
4
Y
Y
4
4
4
4
4
125
Code Listing 5.9: Is there a component that spans the grid? Yes or no?
3
3
3
3
3
3
3
3
3
R
R
R
R
R
R
R
g
g
3
3
3
3
3
3
3
3
3
3
3
R
R
R
R
R
Y
g
1
1
3
3
3
3
3
3
3
3
3
3
3
R
R
R
R
R
Y
Y
Y
-
2
3
3
3
3
M
3
3
Q
R
Y
Y
Y
Y
Y
2
2
2
3
3
3
3
3
N
N
3
3
3
3
Y
Y
Y
Y
Y
2
2
2
C
3
3
3
3
3
3
3
Y
Y
Y
Y
Y
2
2
H
3
3
3
3
3
3
3
3
Y
Y
Y
Y
Y
Y
2
2
2
F
3
3
3
3
3
3
3
3
3
3
3
-
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
e
e
-
2
2
2
2
2
3
3
3
3
3
3
3
3
3
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
B
3
3
3
3
3
3
3
3
3
3
3
3
S
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
b
h
-
3
3
3
3
3
3
3
3
3
3
3
3
3
3
a
a
h
h
3
3
3
3
3
3
3
3
3
3
3
3
T
3
c
-
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
-
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
-
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
-
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
9
9
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
4
9
9
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
4
9
3
3
3
3
3
3
3
3
3
3
3
3
3
5
5
E
3
3
3
3
3
3
3
3
3
3
3
3
3
-
5
5
5
5
3
3
3
3
3
3
3
3
3
3
3
3
3
3
i
i
5
5
5
5
3
3
3
3
3
3
3
3
V
3
3
i
5
5
3
3
3
3
3
3
3
3
3
3
3
3
X
X
3
3
3
i
5
5
5
3
3
3
3
3
3
3
3
3
3
3
Z
3
i
5
5
5
5
I
3
3
3
3
3
3
3
Z
i
6
7
5
5
L
3
3
3
U
3
Z
Z
i
i
6
7
7
5
3
3
3
3
3
3
Z
Z
Z
-
7
7
7
J
K
K
3
3
3
3
3
3
3
3
Z
Z
Z
Z
-
7
7
7
D
G
K
K
K
3
3
3
3
3
3
3
3
3
3
Z
j
-
7
7
7
A
K
O
3
3
3
3
3
3
3
3
3
3
j
j
7
A
A
A
A
A
3
3
3
3
3
3
3
3
3
3
-
A
A
A
A
P
3
3
3
3
3
3
k
-
A
A
A
A
A
A
A
A
A
3
3
3
3
3
W
3
3
d
l
A
A
A
A
A
A
A
A
A
A
A
A
3
3
3
3
3
3
l
l
8
A
A
A
A
A
A
A
A
3
3
3
3
3
3
3
f
l
Lab515: Spanning
Does any group reach all four borders of the grid?
We want to answer this single question, yes or no, and if yes then we also report
the group number. Such a component is said to span the grid. Code Listing 5.9
shows a case where there is a spanning component, thus the answer is Yes, component 3 spans the grid. On the previous page the answer was No, there is no spanning
component for this grid. (Closest was #4 shown in bold.) Assuming the groups are
already labeled then Algorithm 5.1.2 outlines a function to check for spanning.
Algorithm 5.1.2 A function span(grid) that checks for a spanning component.
1: while group = 1, 2, 3, . . . do
2:
if span(group) then
3:
return true
4:
end if
5: end while
6: return false
126
5 Recursion
Runtime Comparison
0.012
recursion
loop/list
Runtime, seconds
0.01
0.008
0.006
0.004
0.002
0
0
5
10
15
20
Fibonacci Number, n not Fn
25
127
Runtime Comparison
14
Runtime, seconds
12
recursion
loop/list
10
8
6
4
2
0
0
10
15
20
25
30
Fibonacci Number, n not Fn
35
Fig. 5.3: Runtime analysis, recursion versus a loop and a list, continued.
40
128
5 Recursion
a
20
72
20
12
8
b mod
72 20
20 12
12 8
8 4
4 0
Code Listing 5.13 shows three more test cases, but of course you can come up
with a set of your own cases, too. Note how in the last case Euclid requires only a
single step, and not O(1000), to determine that 999 and 1000 are relatively prime.
Code Listing 5.13: A small set of test cases.
20
72: 4
230 4050: 10
999 1000: 1
129
gcd(70, 15)
gcd(15, 10)
gcd(10, 5)
ST OP
But when the last recursive call returns the answer it does so only to the previous recursive call, who must pass it on, who must pass it on...
gcd(10, 5) 5 gcd(15, 10)
gcd(15, 10) 5 gcd(70, 15)
gcd(70, 15) 5 (main)
In this way the answer (5) is nally returned to the original call of gcd(70, 15)
in our main program. Table 5.2 shows the system call stack during execution of this
recursive function, assuming that successive calls occupy contiguous memory.
Table 5.2: Diagram of system call stack.
..
.
call #1 argument #2 b = 15
argument #1 a = 70
return address main program
local variable mod = 10
call #2 argument #2 b = 10
argument #1 a = 15
return address call #1
local variable mod = 5
call #3 argument #2 b = 5
argument #1 a = 10
return address call #2
local variable mod = 0
..
.
Now you can see why there has to be a recursive depth limit. Each function call
accounts for a non-zero amount of memory and there is nite memory available
to any computer. This also suggests that we could code recursion using only an
explicit stack and (!) no function. That is true but also a topic for another course.
130
5 Recursion
131
Spanning Plot
1
0.8
0.6
0.4
0.2
0
0.5
0.55
0.6
0.65
0.7
0.75
0.55
0.6
0.65
0.7
0.75
0.8
0.6
0.4
0.2
0
0.5
Fig. 5.4: For what probabilities are we likely to observe a spanning component?
Top: grid size 40 30. Bottom: grid size 120 90, an order of magnitude larger.
132
5 Recursion
A fast running alternative is to use a special kind of list called a queue, similar
to a system call stack only where items are added and removed from different ends
of the list. The advancing-front characteristic of the forest re is related to a famous
technique known as breadth-rst search. Again, since there is a time component to
our re burning out it does not make sense to recursively oodll all the way across
the forest at once. We could modify Lab513 in the same way.
133
Code Listing 5.15: Forest re. Top: Initial conditions. Bottom: After ve steps.
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T T T T
T T T T
T T T T
T T T T T T
T T
T T
T T
T
T
T T T
T T T
T
T
T
T T T
T T
T
T
T T
T T
T
T
T T T T T T T
T T
T
T T T
T
T T T
T T T
T
T T
T
T T
T T
T
T T
T T T
T
T
T T
T
T
T
T T
T
T T T T T
T
T
T T T T T T T
T T T
T T T T T
T T
T T
T T T
T
T T
T T
T T
T
T T
T
T
T T
T
T
T T T
T T
T T
T T
T T
T T
T
T T T
T T T T T T T
T T
T
T
T T T T
T
T
T T
T
T
T
T T T
T
T T T
T T T T T
T
T T T T T
T T T T T
T
T
T
T T T
T T
T T T
T T
T
T T T
T
T T
T T T T
T
T T
T T T
T T T T T
T
T T
T
T
T T T
T
T
T
T T
T
T T
T T
T
T
T
T
T T T
T T T T T
T
T T
T T T
T T T
T
T T T T
T
T T T T
T T T
T
T T T T
T T
T
T T T T
T
T T T T T T
T
T
T
T T
T T
T T T T T
T T T T
T T T T
T T T T T T
T T
T T
T
T T T
T T T
T
T
T
T T T
T T
T
T
T T
T T
T
T
T T T T T T T
T T
T
T T T
T
T T T
T T T
T T
T
T T
T
T T
T T T
T
T T
T
T
T
T T
T
T T T T T
T
T
T T T T T T T
T T T
T T T T T
T T
T T
T T T
T
T T
T T
T T
T
T T
T
T
T T
T
T
T T T
T
T T
T T
T T
T
T T T
T T T
T T
T
T T T T
T
T T
T
T
T T T
T
T
T T T T T
T
T T T T
T T T T T
T
T
T
T T T
T T
T T T
T T
T
T T T
T
T T
T T T T
T
T T
T T T
T T T T T
T
T T
T
T
T T T
T
T
T
T T
T
T T
T T
T
T
T
T
T T T
T T T T T
T
T T
T T T
T T T
T
T T T T
T
T T T T
T T T
T
T T T T
T T
T
T T T T
T
T T T T T T
T
T
T
T T
T T
T T T
T T
T
T
T
T
T
T T T T
T T T
T T
T
T
T T
T
T
T T
T
T T
T T
T T
T T
T T
T
T T
T T
T T
T
T T
T T
T T
T T T
T T
T
T T T
T
T
T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T T
T T
T
T
T
T
T
T T T T
T T T
T T
T
T
T T
T
T
T T
T
T T
T T
T T
T T
T T
T
T T
T T
T T
T
T T
T T
T T
T T T
T T
T
T T T
T
T
T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
T T T T
T
T
T
T T T T
T
T
T
T T T
T T
T T T T T
T T
T T
T T
T
T T
T
T T
T T
T T
T T T
T T T
T
T T
T
T
T T
T
T T T
T T T
T T
T
T
T
T
T
T T
T T
T
T
T
T
T
T
T
T
T T T T T
T
T
T T
T T T
T
T
T
T T
T
T T T T
T
T
T
T T T T
T
T
T
T T T
T T
T T T T T
T T
T T
T T
T
T T
T
T T
T T
T T
T T T
T T T
T
T T
T
T
T T
T
T T T
T T T
T T
T
T
T
T
T
T T
T T
T
T
T
T
T
T
T
T
T T T T T
T
T
T T
T T T
T
T
T T
T
T
T
T T
T T
T
T
T T
T
T
T T
T T T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T T
T T T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
T
T
T T
T
T
T
T T
T T
T
T
T T
T
T
T T
T T T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T T
T T T
T T
T
T
T T
T T
T
T T T T
T T
T T T
T T
T T
T T T T
T T
T
T
T T
T
T T
T T
T
T T T
T
T T
T T
T T T T
T
T T T
T T T T
T
T
T
T T
T
T T T T
T T T T
T
T
T T T
T T T
T T T T
T T
T T
T T
T
T
T
T
T T
T T
T
T T T T
T T
T T T
T T
T T
T T T T
T T
T
T
T T
T
T T
T T
T
T T T
T
T T
T T
T T T T
T
T T T
T T T T
T
T
T
T T
T
T T T T
T T T T
T
T
T T T
T T T
T T T T
T T
T T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
134
5 Recursion
Code Listing 5.16: Forest re. Top: After 10 steps. Bottom: After 20 steps.
T
T T
T
T T
T
T
T T
T
T
T
T T
T
T T
T
T
T
T
T
T
T T T
T
T T
T T T
T T
T
T T
T
T
T
T T T T
T T T T T
T T T T T
T T
T T T
T
T T
T
T T
T
T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T
T
T T
T
T
T T
T T
T
T T
T
T
T T T
T T T T
T
T T
T T
T T
T
T
T
T T
T T
T T
T
T T
T
T
T T
T T T
T T
T
T T T
T
T T
T T T T
T
T T
T T T
T T T T T
T
T
T T
T
T
T
T T T
T
T
T
T
T T
T
T
T T
T T
T
T
T
T
T
T
T T T
T T T T T
T
T T
T T T
T
T T T
T
T
T T T T
T
T
T T T T
T T T
T
T T T T
T T
T
T
T T T T
T
T T T T T T
T
T
T
T
T
T T T T
T
T T
T T
T T
T
T
T
T
T
T
T
T T T
T T T
T
T
T T
T
T
T
T
T
T
T
T T
T T
T
T T
T
T
T
T
T
T
T
T T T
T T T
T
T
T
T T
T T
T
T T T
T
T T T
T T
T T T
T
T
T
T
T
T T T
T T
T
T
T T
T T
T T
T T T
T T
T
T
T
T T T
T T T
T
T
T
T T
T T
T
T T T
T
T T T
T T
T T T
T
T
T
T
T
T T T
T T
T
T T
T T T
T T
T
T T T
T
T T
T T T T
T
T T
T T T
T T T T T
T
T T
T
T
T T T
T
T
T
T T
T
T T
T T
T
T
T
T
T T T
T T T T T
T
T T
T T T
T T T
T
T T T T
T T T T
T
T T T
T T
T
T T T T T
T
T
T T T T T T
T
T
T
T T
T T
T T T
T T
T
T
T
T
T
T T T T
T T T
T T
T
T
T T
T
T
T T
T
T T
T T
T T
T T
T T
T
T T
T T
T T
T
T T
T T
T T
T T T
T T
T
T T T
T
T
T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T T
T T
T
T
T
T
T
T T T T
T T T
T T
T
T
T T
T
T
T T
T
T T
T T
T T
T T
T T
T
T T
T T
T T
T
T T
T T
T T
T T T
T T
T
T T T
T
T
T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
T T T T
T
T
T
T T T T
T
T
T
T T T
T T
T T T T T
T T
T T
T T
T
T T
T
T T
T T
T T
T T T
T T T
T
T T
T
T
T T
T
T T T
T T T
T T
T
T
T
T
T
T T
T T
T
T
T
T
T
T
T
T
T T T T T
T
T
T T
T T T
T
T
T
T T
T
T T T T
T
T
T
T T T T
T
T
T
T T T
T T
T T T T T
T T
T T
T T
T
T T
T
T T
T T
T T
T T T
T T T
T
T T
T
T
T T
T
T T T
T T T
T T
T
T
T
T
T
T T
T T
T
T
T
T
T
T
T
T
T T T T T
T
T
T T
T T T
T
T
T T
T
T
T
T T
T T
T
T
T T
T
T
T T
T T T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T T
T T T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
T
T
T T
T
T
T
T T
T T
T
T
T T
T
T
T T
T T T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T T
T T T
T T
T
T
T T
T T
T
T T T T
T T
T T T
T T
T T
T T T T
T T
T
T
T T
T
T T
T T
T
T T T
T
T T
T T
T T T T
T
T T T
T T T T
T
T
T
T T
T
T T T T
T T T T
T
T
T T T
T T T
T T T T
T T
T T
T T
T
T
T
T
T T
T T
T
T T T T
T T
T T T
T T
T T
T T T T
T T
T
T
T T
T
T T
T T
T
T T T
T
T T
T T
T T T T
T
T T T
T T T T
T
T
T
T T
T
T T T T
T T T T
T
T
T T T
T T T
T T T T
T T
T T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
135
Code Listing 5.17: Forest re. Top: After 40 steps. Bottom: Done after 78 steps.
T
T T
T
T
T
T
T T
T
T T
T
T
T
T
T
T
T
T T T T
T T
T
T T T
T
T T T
T T
T
T
T T
T
T
T
T
T
T
T
T T T
T T T
T
T
T
T T
T T
T
T T T
T
T T T
T T
T T T
T
T
T
T
T
T T T
T T
T
T T
T T T
T T
T
T T T
T
T T
T T T T
T
T T
T T T
T T T T T
T
T T
T
T
T T T
T
T
T
T T
T T
T
T
T T T
T T
T
T
T
T
T
T
T T T T T
T
T T
T
T T
T
T T
T
T T
T T
T T
T T
T T
T T
T
T
T
T T
T
T T T T
T
T
T
T T T T
T
T
T
T T T
T T
T T T T T
T T
T T
T T
T
T T
T
T T
T T
T T
T T T
T T T
T
T T
T
T
T T
T
T T T
T T T
T T
T
T
T
T
T
T T
T T
T
T
T
T T
T
T
T
T
T T T T T
T
T
T T T
T
T
T
T T
T
T
T
T T
T T T T
T T T
T T
T
T
T
T
T
T T
T
T
T
T T
T T
T
T
T T
T
T
T T
T T T
T T
T
T
T T T
T T T
T
T
T
T
T T
T
T
T
T
T T T
T T T
T T
T
T
T
T
T
T
T
T
T
T
T
T
T
T T
T
T
T T
T
T T
T
T
T T
T
T T
T
T
T
T
T T
T
T
T
T
T
T
T
T
T
T
T T T
T T
T
T
T
T
T
T T T
T T
T
T
T
T T
T T
T
T T T T
T T
T T T
T T
T T
T T T T
T T
T
T
T T
T
T T
T T
T
T T T
T
T T
T T
T T T T
T
T T T
T T T T
T
T
T
T T
T
T T T T
T T T T
T
T
T T T
T T T
T T T T
T T
T T
T T
T
T
T
T
T T
T
T
T
T T
T
T T
T
T
T T
T
T T
T
T
T T
T
T
T T
T T
T
T
T
T
T
T T
T
T
T
T T
T T
T
T T
T
T
T T T
T
T T T T
T
T T T
T T T
T T
T T
T T T
T
T
T T
T
T
T T
T
T T
T T
T
T
T
T
T T
T T T
T
T
T T
T T
T T
T
T
5 Recursion
136
0.2
0.4
0.6
Density of Trees
0.8
137
Probability of Streak
0.5
0.4
0.3
0.2
0.1
0
0
3
4
5
6
Steps in Streak
Fig. 5.6: Guessing coin ips. Before we ip the rst coin a streak of nine steps is
highly unlikely: less than one-tenth of one percent. But if we have already guessed
eight ips correctly then the chance of a ninth is 50-50, a coin ip.
138
5 Recursion
Probability of Streak
0.5
0.4
0.3
0.2
0.1
0
0
3
4
5
6
Steps in Streak
Fig. 5.7: Guessing high or low. Before we make the rst guess a streak of nine steps
has a 1.3% chance of occurring. So, we have a better chance here than we did just
ipping coins but surviving the rst guess is still 50-50, a coin ip.
is
is
is
is
is
5.
2.
9.
7.
5.
Number is 7.
Next
Next
Next
Next
Next
will
will
will
will
will
Game over.
be...
be...
be...
be...
be...
high
high
high
high
high
or
or
or
or
or
low?
low?
low?
low?
low?
Correct guesses:
lower
higher
lower
lower
lower
4
139
streak = 0
number = 5
while true do
if number < 5 then
guess = higher
else if number > 5 then
guess = lower
else
guess = random
end if
nextnumber = generate
if correct then
streak = streak + 1
number = nextnumber
else
return streak
end if
end while
count = hashtable
while t = 1 trials do
streak = game()
if f irst then
count[streak] = 1
else
count[streak] = count[streak] + 1
end if
end while
while streak = 0 max(streak) do
if nonzero then
print streak, count[streak]/trials
end if
end while
140
5 Recursion
141
142
5 Recursion
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
-
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Chapter 6
Projects
Everyone has ideas, and part of the joy of computing is to see your ideas come alive.
Three very different types of projects are presented in this chapter with the hope
that everyone will nd something that speaks to them. A few guidelines:
Build everything up step-by-step... test as you go!
Think about the big picture even as you struggle with the small details.
Watch out for feature-creep. Keep in mind, what are you trying to do?
143
144
6 Projects
Tile #7
1
10
11
12
13
14
15
Fig. 6.1: Click tile, the text at top updates the tile number as the user clicks.
145
Tile #13
1
10
11
12
13
14
15
Fig. 6.2: Change tile, the text at top is still updated as before and now the tiles text
object is also modied to show where the user has clicked.
146
6 Projects
Tile #12
1
10
11
12
13
14
15
Fig. 6.3: Neighbor of blank, while the other tiles continue to be modied as before,
the neighbors of the blank space are now treated differently when clicked.
147
Step 15
5
10
11
12
13
14
15
Fig. 6.4: Slide tile, where quite obviously the user has clicked the tiles in a spiral
pattern and thus the puzzle is not much of a challenge.
Hint: do not actually move the location of the text objects, just swap their displayed text instead.
148
6 Projects
Step 20
5
10
13
15
14
11
12
Step 27
9
13
10
14
15
11
12
149
Step 60
9
10
14
15
13
12
11
8
4
Step 100
9
14
15
12
10
13
11
150
6 Projects
GO
14
15
10
12
11
13
Fig. 6.7: Possible features, here a go button is used so that after a friend has
shufed the puzzle both a timer (left) and an update of total moves (right) can start.
151
Time 0
Step 0
Time 60
Step 79
Fig. 6.8: Possible features, shufe the broken-up pieces of an image using PIL.
Image of George Washington courtesy of the U.S. Army, photo credit U.S. Army
Military History Institute.
152
6 Projects
Impossible!
1
10
11
12
13
15
14
Fig. 6.9: Impossible to solve, note that the 14 and 15 have been swapped.
153
aching
Six-letter word:
cOARSe
coarse
Six-letter word:
mODESt
modest
Six-letter word:
sACREd
sacred
Six-letter word:
sTREEt
street
154
6 Projects
155
Lab623: Anagrams
Example anagrams are shown in Code Listing 6.6, four-letter words only.
Code Listing 6.7 shows one way to directly check if two words are anagrams.
One word is converted into a list of characters and then we loop over the characters
in the other word. If at any point we nd a character that does not match then we
immediately return failure. When characters do match we must remove them from
the character list otherwise we may fall into a common trap regarding duplicate
letters: rare and area are not anagrams.
Only when all the letters have matched do we return success. Can you think of
another way to nd anagrams? Perhaps a more efcient way?
Code Listing 6.6: Sample output of four-letter anagrams.
scar arcs
lamb balm
calm clam
team mate
slow owls
part trap
save vase
Code Listing 6.7: A direct check to see if two words are anagrams.
#
def anagrams(word1,word2):
#
chlist=list(word1)
#
for ch in word2:
#
if ch not in chlist:
return False
else:
chlist.remove(ch)
#
#
return True
#
156
6 Projects
157
east
diet
amen
evil
mate
leap
nest
deus
pest
eats
edit
mane
live
meat
pale
nets
dues
pets
sate
tide
mean
veil
meta
peal
sent
sued
sept
seat teas
tied
name
vile
tame team
plea
tens
used
step
158
6 Projects
radius
radios
ratios
ration
nation
notion
motion
spider
slider
slicer
slices
slicks
clicks
clucks
crafty
crafts
grafts
grants
grands
brands
braids
brains
trains
traits
tracts
traces
braces
braves
braver
beaver
beater
better
batter
fatter
falter
salter
salver
salves
solves
wolves
Insert a letter.
Delete a letter.
Substitute a letter.
Substitute the entire word for an anagram.
Table 6.1 shows puzzles where only the substitute a letter change is allowed
but even here we may quickly face an exceedingly large search space once again.
159
Aiming the beanbag cannon by using the arrow keys to rotate left or right.
Launch a beanbag by hitting spacebar. The beanbag moves linearly offscreen.
Launch multiple beanbags in rapid succession but with a limited total number.
Randomized bubbles that move up linearly but drift back-and-forth sideways.
Detection of collisions between beanbags and bubbles... so the bubbles pop!
Safety First
Do not attempt to play this game in real life without permission and supervision.
160
6 Projects
Code Listing 6.12: Shell for part of a program to control a beanbag cannon.
#
def leftarrow(evnt):
global theta
#
theta += ...
if theta > ...
theta = ...
#
...
#
...
root.bind(<Left> ,leftarrow)
root.bind(<Right>,rightarrow)
Fig. 6.11: Aim beanbag cannon, do not allow to get too close to the horizontal.
161
Fig. 6.12: Cannon moving, 45 to right (top) and then 15 over to left (bottom).
162
6 Projects
Fig. 6.13: Launch beanbag, a single ying object is created by pressing spacebar.
Code Listing 6.14: Our beanbag object moves linearly across the screen.
def tick():
global obj
#
if obj!=None:
if obj.offscreen():
obj.delete_me()
obj=None
else:
obj.move_me()
#
cnvs.after(1,tick)
#
Code Listing 6.15: Shell for the Beanbag class, lename: beanbag.py
class Beanbag:
#
def __init__(self,x,y,vx,vy,cnvs):
#
...
#
self.r
= 5
self.w
= int(cnvs.cget(width))
self.h
= int(cnvs.cget(height))
#
self.tkid = cnvs.create_oval( ... )
#
#
def offscreen(self):
#
...
#
#
def delete_me(self):
#
self.cnvs.delete(self.tkid)
#
#
def move_me(self):
#
...
#
#
#
163
164
6 Projects
Code Listing 6.16: A program both dening and using a Turtle class.
#
from math import cos,sin,pi
#
class Turtle:
#
def __init__(self,x,y,h):
#
# instance variables
#
self.x = x
self.y = y
self.h = h
#
#
def move(self,r):
#
oldx,oldy=self.x,self.y
#
self.x += r*cos(self.h*pi/180.0)
self.y += -r*sin(self.h*pi/180.0)
#
drawline(oldx,oldy,self.x,self.y)
#
...
#
#
######################
#
# main program
#
smidge=Turtle(0,0,90)
smidge.move(100)
#
Scope
Code Listing 6.16 shows a class denition for Turtle, from Chapter 2, where instance
data such as self.x are directly accessible by functions of the class (note the rst
argument of move is named self), thus the global command is unnecessary.
Local variables such as oldx occupy memory that is allocated for their use only
during execution of the function. Once the function has ended then, as we have seen,
that portion of the system call stack may be re-allocated for other data.
165
Fig. 6.14: List of beanbags, note how their direction is not forever tied to the cannon.
166
6 Projects
Code Listing 6.18: Bubbles move up linearly but drift back-and-forth sideways.
class Bubble:
...
#
def move_me(self):
#
if random()<0.5:
self.x += self.vx*dt
else:
self.x -= self.vx*dt
#
self.y -= self.vy*dt
...
#
Lab634: Bubbles
See Code Listing 6.18 for movement. Figures 6.15 and 6.16 show one, then many.
Fig. 6.15: Bubble drifts upward, where obviously we would prefer a list of them.
167
Fig. 6.16: List of bubbles, no collisions yet so the beanbags just y right on by.
168
6 Projects
Lab635: Collisions
We use circles because they are the easiest shape to code.
In this case we know the two positions (x1 , y1 ) and (x2 , y2 ) so by nding the
distance between these points we can determine whether or not there is a collision.
There will be a collision if that distance is less than the sum of the radius of the
beanbag and the radius of the bubble.
Code Listing 6.19 shows the programs animation loop and Figure 6.17 conrms
our collision detection is working. For now Code Listing 6.20 shows the beanbag
detecting a collision and, thus, accessing the bubble objects own position data.
Code Listing 6.19: Handshake problem, two groups: beanbags and bubbles.
def tick():
#
...
#
for obj in objlist: # beanbags do not pop
#
j=len(bubbles)-1
while j>=0:
#
if obj.collide(bubbles[j]):
#
...
#
j-=1
...
Code Listing 6.20: Beanbags are the ones detecting collisions, for now.
class Beanbag:
...
#
def collide(self,the_bubble):
#
x1=self.x
y1=self.y
#
x2=the_bubble.x
y2=the_bubble.y
#
...
#
Fig. 6.17: Collisions, where clearly the bubbles hit by a beanbag now pop.
169
170
6 Projects
Chapter 7
Modeling
7.1 Predator-Prey
We rst model rabbits that move in discrete chunks (i.e., step by 2r) on a grid.
171
172
7 Modeling
Fig. 7.1: A lonely rabbit stuck on a lattice: up, down, left, right.
Code Listing 7.2: A list of rabbits but with only one object, for now.
#
from rabbit import Rabbit
#
rabbits=[]
#
def tick():
#
...
#
#
rabbits.append( Rabbit(cnvs) )
#
7.1 Predator-Prey
173
174
7 Modeling
Size of Population
70
60
50
40
30
20
10
0
0
10
15
20
25
Time, number of steps
30
35
Fig. 7.3: Carrying capacity, the initial population boom levels off quickly logistic.
Lab713: Hunger
A less articial mechanism for controlling population growth is to model the competition for food as shown in Code Listings 7.4 and 7.5. If two rabbits are close
enough together then one will get hungry (at random) because there is only so much
food to eat. Figures 7.3 and 7.4 show the results, a better match than before.
Code Listing 7.4: Handshake problem, one group: rabbits.
j=0
while j<len(rabbits):
#
k=j+1
while k<len(rabbits):
#
if rabbits[j].collide(rabbits[k]):
if ...
rabbits[j].mark_as_hungry()
else:
rabbits[k].mark_as_hungry()
...
7.1 Predator-Prey
175
Fig. 7.4: Competition for food, some neighboring rabbits are about to go hungry.
Code Listing 7.5: Looping backwards, again, so as not to skip over any rabbits.
j=len(rabbits)-1
#
while j>=0:
#
if rabbits[j].check_is_hungry():
#
rabbits[j].delete_me()
# die/starve
rabbits.pop(j)
else:
#
rabbits[j].move_me()
# move
...
176
7 Modeling
14
12
10
8
6
4
2
0
0
10
20
30
40
50
60
70
Time, number of steps
80
90
100
Fig. 7.5: Maximum age, how old is the oldest rabbit? Unfortunately not very old.
7.1 Predator-Prey
177
35
30
25
20
15
10
5
0
2
6
8
10
Age, number of steps
12
35
30
25
20
15
10
5
0
2
10
12
Fig. 7.6: Age distribution. Top: after 13 steps. Bottom: after 32 steps.
178
7 Modeling
Population Dynamics
80
rabbits
wolves
70
Population
60
50
40
30
20
10
0
0
20
40
60
80
100
120
Time, number of steps
140
160
Fig. 7.7: Population dynamics, rabbits and wolves alternate between peak and valley.
Lab715: Wolves
Code Listing 7.7 shows a wolf always winning the coin ip but also needing to eat
every four steps or it dies of hunger itself. Wolves have two offspring but only once
at age ten. Results are shown in Figures 7.7 and 7.8. Since the underlying parameters
are ad hoc you may tune them as you see t, just be prepared for major changes.
Code Listing 7.7: Handshake problem, two groups: wolves and rabbits.
shuffle(wolves)
for wolf in wolves:
#
j=len(rabbits)-1
while j>=0:
if wolf.collide(rabbits[j]):
#
rabbits[j].delete_me()
# die/eaten
rabbits.pop(j)
#
wolf.reset_hunger()
...
7.1 Predator-Prey
179
Fig. 7.8: Two extreme population snapshots. Top: step 55, 12 rabbits, 61 wolves.
Bottom: step 110, 52 rabbits, 17 wolves.
180
7 Modeling
Analytic Model
A purely mathematical model can also describe our two interacting populations:
dx = c1 x c2 xy
dy = c3 y + c4 xy
At each step the changes are calculated from the current population sizes and then
each population size is updated. Obviously this is a coupled system with each variable depending on the other variables value, too.
As shown in Figure 7.9 we call x the rabbits and y the wolves, using:
c1 = 4.00
c2 = 1.00
c3 = 2.00
c4 = 0.25
Population Dynamics
30
rabbits
wolves
Population
25
20
15
10
5
0
0
1000
2000
3000
4000
Time, number of steps
5000
6000
Fig. 7.9: Population dynamics, rabbits and wolves alternating but not as before.
Additional areas of investigation may include social networks, seasons (agents
interacting with their environment), migration patterns, clans or tribes, physical
characteristics (strength, speed, eyesight), deterioration with age, and of course a
genetic blending of parent-agents when offspring are produced.
181
Fig. 7.10: Knobs attached to springs but only the middle knob moves, for now.
182
7 Modeling
400
350
300
250
200
150
100
50
0
500 1000 1500 2000 2500 3000 3500 4000 4500 5000
Time, steps
Fig. 7.11: Vertical position of the middle knob as it oscillates between its neighbors.
183
Fig. 7.12: Hookes Law, motion goverened by displacement and spring constant.
184
7 Modeling
Fig. 7.13: Hookes Law, without the arrow we could not determine which direction
the knob is moving. Top: after 0.4 seconds. Bottom: after 1.6 seconds.
185
Velocity, vy
40
20
0
-20
-40
-60
-80
0
500 1000 1500 2000 2500 3000 3500 4000 4500 5000
Time, steps
Fig. 7.14: Vertical velocity of the middle knob as it oscillates between its neighbors.
186
7 Modeling
Fig. 7.15: Hookes Law, depending on which knobs are xed in place an asymmetry
can be established. Top: after 0.2 seconds. Bottom: after 1.2 seconds.
187
Lab723: Asymmetry
Figures 7.15 and 7.16 show multiple knobs moving. Since the initial displacement
is asymmetric relative to the xed knobs an interesting sequence unfolds.
We might also connect four nearest neighbors in 2-D (or six in 3-D) to model
a cloth mesh or even solid objects. This suggests the possibility of using computer
modeling in the real-time development of industrial products where, for instance,
simulation could limit the amount of time wasted re-shipping prototypes.
Code Listing 7.11: A loop over the list of knobs tells each to move.
def tick():
#
j=1
while j<6:
#
knobs[j].move_me(knobs[j-1],knobs[j+1])
j+=1
...
Fig. 7.16: Hookes Law after 2.2 seconds. Each knob has the same desire to be
halfway between its two nearest neighbors. Only... they might be moving, too.
188
7 Modeling
Lab724: Damping
Figures 7.17 and 7.18 show many more knobs and an extreme initial displacement.
The result is a wave that propagates rst to the right and then back to the left again.
It would continue reecting back-and-forth forever except that Code Listing 7.12
adds a damping term to ay so that the chain will eventually settle down.
Code Listing 7.12: A damping term added to each knobs acceleration calculation.
class Knob:
...
def move_me(self,knobLeft,knobRight):
#
yT = 0.5*(knobLeft.y+knobRight.y)
#
ay = 0.1*(yT-self.y)-0.5*self.vy # ad hoc damping
#
self.vy +=
ay*dt
self.y += self.vy*dt
...
Fig. 7.17: Hookes Law plus damping, xed ends and extreme initial conditions.
189
Fig. 7.18: Hookes Law plus damping, a wave pattern emerges and propagates backand-forth across the chain. Top: after 0.2 seconds. Bottom: after 1.0 seconds.
190
7 Modeling
Fig. 7.19: Hookes Law plus damping and gravity, xed ends. Top: initial conditions.
Bottom: after 1.2 seconds.
191
Lab725: Gravity
Code Listing 7.13 now adds an ad hoc gravity term to our ad hoc spring plus ad hoc
damping calculation. In this case, without gravity there would be no motion because
the initial conditions do not include any displacement. The two end-knobs are still
xed in place and Figures 7.19 and 7.20 show motion toward a steady state.
Code Listing 7.13: A gravity term added to each knobs acceleration calculation.
class Knob:
...
def move_me(self,knobLeft,knobRight):
#
yT = 0.5*(knobLeft.y+knobRight.y)
#
ay = 10.0*(yT-self.y)-0.5*self.vy+10.0 # ad hoc
#
self.vy +=
ay*dt
self.y += self.vy*dt
...
Fig. 7.20: Hookes Law plus damping and gravity, xed ends. Steady state.
192
7 Modeling
Fig. 7.21: U.S. Navy carrier group in the Pacic Ocean. Image courtesy of the U.S.
Navy, photo credit Mass Communication Specialist 2nd Class Walter M. Wayman.
A Technological World
Figure 7.21 shows one way nations project power around the world. It is not an
insignicant task to develop, build, and maintain a carrier group.
Consider now the following aspects of these operations...
Hull design.
Navigation and control.
Weapon systems.
On-board defensive measures.
Communication.
Communication security.
...and imagine all the ways that computational modeling can impact those efforts.
7.3 Bioinformatics
193
7.3 Bioinformatics
Butyrylcholinesterase is an enzyme encoded by the BCHE gene. Gene sequence
data is available from the National Center for Biotechnology Information at:
http://www.ncbi.nlm.nih.gov/
The eleven animals considered in this chapter all have BCHE gene sequences of
length O(1800) characters. In fact most are the exact same length, some are off by
only three, and one (chimpanzee) differs by O(100).
We want to build a Tree of Life based on the similarity of these gene sequences.
This is not a full alignment of an entire genome as much longer sequences would be
needed for that. (And better algorithms, and bigger computers.) Also, our investigation uses the Levenshtein distance for pairwise comparisons rather than the more
customizable Needleman-Wunsch method.
In addition, we do not convert similarity scores between genes into evolutionary
distance and, for building the actual tree, we suggest a so-called greedy algorithm
rather than a more sophisticated neighbor-join that might minimize total branch
length. Our goal is only to present a broad introduction of alignment issues and
similarity measures, and to show the kinds of results one can achieve.
194
7 Modeling
7.3 Bioinformatics
195
Code Listing 7.17: Trying all possible arrangements. Looking for the best match.
:
kitchens
ki-t-ten
6
kitchens
ki-tt-en
6
kitchens
ki-tte-n
5
kitchens
ki-tten4
kitchens
kit--ten
5
kitchens
kit-t-en
5
kitchens
kit-te-n
4
kitchens # best
kit-ten3
kitchens
kitt--en
5
kitchens
kitt-e-n
4
kitchens # best
kitt-en3
kitchens
kitte--n
5
kitchens
kitte-n4
kitchens
kitten-5
196
7 Modeling
12
191
173
178
109
115
173
7.3 Bioinformatics
197
Dynamic Programming
Even though the lengths
of the cattle and chicken sequences are off by only three
there are still O 109 possibilities for the placement of gaps. A faster way to make
these comparisons is dynamic programming as outlined in Code Listing 7.19.
Code Listing 7.19: Dynamic programming as an alternative to recursive search.
#
def levenshtein_distance(gene1,gene2):
#
dp=[0]*(m*n)
# m rows, n columns
#
# loop across the top row
dp[0*n+j]=j
#
# loop down the left column
dp[k*n+0]=k
#
# loop j=1,2,...,n-1
# loop k=1,2,...,m-1
#
if gene1[j-1]==gene2[k-1]:
dp[k*n+j]=dp[(k-1)*n+(j-1)] # match
#
else:
#
# gap in gene1
#
opt1=dp[(k )*n+(j-1)]+1
#
# gap in gene2
#
opt2=dp[(k-1)*n+(j )]+1
#
# count difference
#
opt3=dp[(k-1)*n+(j-1)]+1
#
# principal of optimality
#
dp[k*n+j]=min(opt1,min(opt2,opt3))
#
return dp[-1]
#
198
7 Modeling
0
1
2
3
4
5
6
7
8
9
bengal_tiger
domestic_cat
dog
cattle
horse
human
sumatran_orangutan
house_mouse
norway_rat
chimpanzee
chicken
1
12
2
115
109
3
176
172
192
4
149
144
162
154
5
195
190
193
175
172
6
187
182
183
170
168
23
7
330
324
335
341
332
348
343
8
331
322
335
337
331
337
329
137
9
306
301
303
282
281
132
148
445
455
10
478
477
492
468
473
471
464
509
513
566
7.3 Bioinformatics
199
Tree of Life
Using these similarity results we can now build a Tree of Life.
Note how our dynamic programming code may insert gaps even if the sequence
lengths are equal, in order to nd a closer match. Thus the similarity of mouse and
chicken is 509 and not 1336, for instance. Likewise for kittens and kitchen we
nd kit-tens and kitchen- with a score of 3, better than a straight difference
count based on equal lengths previously reported as 4.
Algorithm 7.3.1 outlines our tree building procedure. At each step we nd the
pair with the best similarity score. That pair is combined into a single node and
all other scores involving the pair are replaced with their average.
Algorithm 7.3.1 Using the Levenshtein distance to build a Tree of Life.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
while j = 0, 1, 2, . . . do
while k = j + 1, j + 2, . . . do
score[ j, k] = levenshtein
end while
end while
while t = 2 len(list) do
pair[ j, k] = min(score)
while i = not( j, k) do
score[i, pair] = (score[i, j] + score[i, k])/2
delete(score[i, j])
delete(score[i, k])
end while
end while
draw(tree)
For example, tiger and cat have the best similarity score (12) so they are paired
together rst. Then, all other scores involving tiger or cat are replaced with an average from the two. Eventually we will also pair together pairs rather than individuals
but the same rules apply. The process continues:
It should not be surprising that chicken is matched last since it is the only nonmammal in the list. Code Listing 7.22 on the following page shows our nal result.
200
7 Modeling
Postscript
I wrote this book while on a sabbatical from Thomas Jefferson High School for
Science and Technology where I have taught Computer Science since 2001.
I am fortunate to have worked in the Computer Systems Lab at TJ since 2004
and this past year in the Center for Computational Fluid Dynamics at George Mason
University. I owe more than I could ever repay to both of these places.
This book is designed to speak to a wide and varied audience. News related to
high school and undergraduate participation in Computer Science has become grim
in recent years. Efforts are underway to change those trends and over time I believe
the eld will grow. I have myself been writing courses since 2003 and this book is
my view on how best to present CS to beginning students.
I hope you nd something here to grab hold of, something to spark your interest,
something even that takes your breath away.
Fairfax, Virginia
August 2011
Shane Torbert
201