-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
book.tex
6258 lines (4365 loc) · 265 KB
/
book.tex
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% LaTeX source for ``Modeling and Simulation in Python''
% Copyright 2017 Allen B. Downey.
% License: Creative Commons Attribution-NonCommercial 4.0 Unported License.
% http://creativecommons.org/licenses/by-nc/4.0/
%
\documentclass[12pt]{book}
\title{Modeling and Simulation in Python}
\author{Allen B. Downey}
\newcommand{\thetitle}{Modeling and Simulation in Python}
\newcommand{\thesubtitle}{}
\newcommand{\theauthors}{Allen B. Downey}
\newcommand{\theversion}{1.0}
%%%% Both LATEX and PLASTEX
\usepackage{graphicx}
\usepackage{hevea}
\usepackage{makeidx}
\usepackage{setspace}
\usepackage{xcolor}
\usepackage{upquote}
\usepackage[listings]{tcolorbox}
% to get siunitx
% sudo apt-get install texlive-science
\usepackage{siunitx}
\sisetup{per-mode=symbol}
\definecolor{light-gray}{gray}{0.95}
\newtcblisting{python}{
skin=standard,
boxrule=0.4pt,
colback=light-gray,
listing only,
top=0pt,
bottom=0pt,
left=0pt,
right=0pt,
boxsep=2pt,
listing options={
basicstyle=\ttfamily,
language=python,
showstringspaces=false,
},
}
\newtcblisting{result}{
skin=standard,
boxrule=0.0pt,
colback=white,
listing only,
top=0pt,
bottom=0pt,
left=0pt,
right=0pt,
boxsep=2pt,
listing options={
basicstyle=\ttfamily,
language=python,
showstringspaces=false,
},
}
\makeindex
% automatically index glossary terms
\newcommand{\term}[1]{%
\item[#1:]\index{#1}}
\usepackage{amsmath}
\usepackage{amsthm}
% format end of chapter excercises
\newtheoremstyle{exercise}
{12pt} % space above
{12pt} % space below
{} % body font
{} % indent amount
{\bfseries} % head font
{} % punctuation
{12pt} % head space
{} % custom head
\theoremstyle{exercise}
\newtheorem{exercise}{Exercise}[chapter]
\usepackage{afterpage}
\newcommand\blankpage{%
\null
\thispagestyle{empty}%
\addtocounter{page}{-1}%
\newpage}
\newif\ifplastex
\plastexfalse
%%%% PLASTEX ONLY
\ifplastex
\usepackage{localdef}
\usepackage{url}
\newcount\anchorcnt
\newcommand*{\Anchor}[1]{%
\@bsphack%
\Hy@GlobalStepCount\anchorcnt%
\edef\@currentHref{anchor.\the\anchorcnt}%
\Hy@raisedlink{\hyper@anchorstart{\@currentHref}\hyper@anchorend}%
\M@gettitle{}\label{#1}%
\@esphack%
}
% code listing environments:
% we don't need these for plastex because they get replaced
% by preprocess.py
%\newenvironment{code}{\begin{code}}{\end{code}}
%\newenvironment{stdout}{\begin{code}}{\end{code}}
% inline syntax formatting
\newcommand{\py}{\verb}%}
%%%% LATEX ONLY
\else
\input{latexonly}
\fi
%%%% END OF PREAMBLE
\begin{document}
\frontmatter
%%%% PLASTEX ONLY
\ifplastex
\maketitle
%%%% LATEX ONLY
\else
\begin{latexonly}
%-half title--------------------------------------------------
\thispagestyle{empty}
\begin{flushright}
\vspace*{2.0in}
\begin{spacing}{3}
{\huge \thetitle}
\end{spacing}
\vspace{0.25in}
Version \theversion
\vfill
\end{flushright}
%--verso------------------------------------------------------
\afterpage{\blankpage}
%\newpage
%\newpage
%\clearemptydoublepage
%\pagebreak
%\thispagestyle{empty}
%\vspace*{6in}
%--title page--------------------------------------------------
\pagebreak
\thispagestyle{empty}
\begin{flushright}
\vspace*{2.0in}
\begin{spacing}{3}
{\huge \thetitle}
\end{spacing}
\vspace{0.25in}
Version \theversion
\vspace{1in}
{\Large
\theauthors \\
}
\vspace{0.5in}
{\Large Green Tea Press}
{\small Needham, Massachusetts}
%\includegraphics[width=1in]{figs/logo1.eps}
\vfill
\end{flushright}
%--copyright--------------------------------------------------
\pagebreak
\thispagestyle{empty}
Copyright \copyright ~2017 \theauthors.
\vspace{0.2in}
\begin{flushleft}
Green Tea Press \\
9 Washburn Ave \\
Needham MA 02492
\end{flushleft}
Permission is granted to copy, distribute, transmit and adapt this work under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License: \url{http://modsimpy.com/license}.
If you are interested in distributing a commercial version of this
work, please contact the author.
The \LaTeX\ source and code for this book is available from
\begin{code}
https://github.com/AllenDowney/ModSimPy
\end{code}
%--table of contents------------------------------------------
\cleardoublepage
\setcounter{tocdepth}{1}
\tableofcontents
\end{latexonly}
% HTML title page------------------------------------------
\begin{htmlonly}
\vspace{1em}
{\Large \thetitle}
{\large \theauthors}
Version \theversion
\vspace{1em}
Copyright \copyright ~2017 \theauthors.
Permission is granted to copy, distribute, and/or modify this work
under the terms of the Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International License, which is
available at \url{http://modsimpy.com/license}.
\vspace{1em}
\setcounter{chapter}{-1}
\end{htmlonly}
% END OF THE PART WE SKIP FOR PLASTEX
\fi
\chapter{Preface}
\label{preface}
This book is about modeling and simulation of physical systems.
The following diagram shows what I mean by ``modeling":
\index{modeling}
\vspace{0.2in}
\centerline{\includegraphics[height=3in]{figs/modeling_framework.pdf}}
Starting in the lower left, the {\bf system} is something in the real world we are interested in. Often, it is something complicated, so we have to decide which details can be simplified or {\bf abstracted} away.
\index{system}
The result of abstraction is a {\bf model} that includes the features we think are essential. A model can be represented in the form of diagrams and equations, which can be used for mathematical {\bf analysis}. It can also be implemented in the form of a computer program, which can run {\bf simulations}.
\index{model}
\index{abstraction}
\index{analysis}
The result of analysis and simulation can be a {\bf prediction} about what the system will do, an {\bf explanation} of why it behaves the way it does, or a {\bf design} intended to achieve a purpose.
\index{prediction}
\index{explanation}
\index{design}
We can {\bf validate} predictions and test designs by taking {\bf measurements} from the real world and comparing the {\bf data} we get with the results from analysis and simulation.
\index{validation}
\index{data}
This process is almost always iterative: for any physical system, there are many possible models, each one including and excluding different features, or including different levels of detail. The goal of the modeling process is to find the model best suited to its purpose (prediction, explanation, or design).
\index{iterative modeling}
Sometimes the best model is the most detailed. If we include more features, the model is more realistic, and we expect its predictions to be more accurate.
\index{realism}
But often a simpler model is better. If we include only the essential features and leave out the rest, we get models that are easier to work with, and the explanations they provide can be clearer and more compelling.
\index{simplicity}
As an example, suppose someone asked you why the orbit of the Earth is nearly elliptical. If you model the Earth and Sun as point masses (ignoring their actual size), compute the gravitational force between them using Newton's law of universal gravitation, and compute the resulting orbit using Newton's laws of motion, you can show that the result is an ellipse.
\index{orbit}
\index{ellipse}
Of course, the actual orbit of Earth is not a perfect ellipse, because of the gravitational forces of the Moon, Jupiter, and other objects in the solar system, and because Newton's laws of motion are only approximately true (they don't take into account relativistic effects).
\index{Newton}
\index{relativity}
But adding these features to the model would not improve the explanation; more detail would only be a distraction from the fundamental cause. However, if the goal is to predict the position of the Earth with great precision, including more details might be necessary.
So choosing the best model depends on what the model is for. It is usually a good idea to start with a simple model, even if it is likely to be too simple, and test whether it is good enough for its purpose. Then you can add features gradually, starting with the ones you expect to be most essential.
Comparing the results of successive models provides a form of {\bf internal validation}, so you can catch conceptual, mathematical, and software errors. And by adding and removing features, you can tell which ones have the biggest effect on the results, and which can be ignored.
\index{internal validation}
\index{validation!internal}
\section{Can modeling be taught?}
These essential modeling skills --- abstraction, analysis, simulation, and validation --- are central in engineering, natural sciences, social sciences, medicine, and many other fields. Some students learn these skills implicitly, but in most schools they are not taught explicitly, and students get little practice. That's the problem this book is meant to address.
At Olin College, we use this book in a class called Modeling and Simulation, which all students take in their first semester. My colleagues, John Geddes and Mark Somerville, and I developed this class and taught it for the first time in 2009.
It is based on our belief that modeling should be taught explicitly, early, and throughout the curriculum. It is also based on our conviction that computation is an essential part of this process.
If students are limited to the mathematical analysis they can do by hand, they are restricted to a small number of simple physical systems, like a projectile moving in a vacuum or a block on a frictionless plane.
And they will only work with bad models; that is, models that are too simple for their purpose. In nearly every mechanical system, air resistance and friction are essential features; if we ignore them, our predictions will be wrong and our designs won't work.
In most freshman physics classes, students don't make modeling decisions; sometimes they are not even aware of the decisions that have been made for them. Our goal is to teach, and for students to practice, the entire modeling process.
\section{How much programming do I need?}
If you have never programmed before, you should be able to read this book, understand it, and do the exercises. I will do my best to explain everything you need to know; in particular, I have chosen carefully the vocabulary I introduce, and I try to define each term the first time it it used. If you find that I have used a term without defining it, let me know.
If you have programmed before, you will have an easier time getting started, but you might be uncomfortable in some places. I take an approach to programming you have probably not seen before.
Most programming classes\footnote{Including many I have taught.} have two big problems:
\begin{enumerate}
\item They go ``bottom up", starting with basic language features and gradually adding more powerful tools. As a result, it takes a long time before students can do anything more interesting than convert Fahrenheit to Celsius.
\index{bottom up}
\item They have no context. Students learn to program with no particular goal in mind, so the exercises span an incoherent collection of topics, and the projects tend to be unmotivated.
\end{enumerate}
In this book, you learn to program with an immediate goal in mind: writing simulations of physical systems. And we proceed ``top down", by which I mean we use professional-strength data structures and language features right away. In particular, we use the following Python {\bf libraries}:
\index{top down}
\begin{itemize}
\item NumPy for basic numerical computation (see \url{http://www.numpy.org/}).\index{NumPy}
\item SciPy for scientific computation (see \url{http://www.scipy.org/}).
\index{SciPy}
\item matplotlib for visualization (see \url{http://matplotlib.org/}).
\index{Matplotlib}
\item pandas for working with data (see \url{http://pandas.pydata.org/}).\index{Pandas}
\item SymPy for symbolic computation, (see \url{http://www.sympy.org}).\index{SymPy}
\item Pint for units like kilograms and meters (see \url{http://pint.readthedocs.io}).\index{Pint}
\item Jupyter for reading, running, and developing code (see \url{http://jupyter.org}).\index{Jupyter}
\end{itemize}
These tools let you work on more interesting programs sooner, but there are some drawbacks: they can be hard to use, and it can be challenging to keep track of which library does what and how they interact.
I have tried to mitigate these problems by providing a library, called \py{modsim}, that makes it easier to get started with these tools, and provides some additional capabilities.
\index{modsim library}
Some features in the \py{modsim} library are like training wheels; at some point you will probably stop using them and start working with the underlying libraries directly. Other features you might find useful the whole time you are working through the book, or even later.
I encourage you to read the the \py{modsim} library code. Most of it is not complicated, and I tried to make it readable. Particularly if you have some programming experience, you might learn something by reverse-engineering my designs.
\section{How much math and science do I need?}
I assume that you have studied calculus. You should know what derivatives and integrals are, but that's about all. In particular, you don't need to know (or remember) much about finding derivatives or integrals of functions analytically. If you know the derivative of $x^2$ and you can integrate $2x~dx$, that will do it\footnote{And if you noticed that those two questions answer each other, even better.}.
\index{calculus}
More importantly you should understand what those concepts {\em mean}; but if you don't, this book might help you figure it out.
You don't have to know anything about differential equations.
As for science, we will cover topics from a variety of fields, including demography, epidemiology, medicine, thermodynamics, and mechanics. For the most part, I don't assume you know anything about these topics. In fact, one of the skills you need to do modeling is the ability to learn enough about new fields to develop models and simulations.
When we get to mechanics, I assume you understand the relationship between position, velocity, and acceleration, and that you are familiar with Newton's laws of motion, especially the second law, which is often expressed as $F = ma$ (force equals mass times acceleration).
I think that's everything you need, but if you find that I left something out, please let me know.
\section{Getting started}
\label{code}
To run the examples and work on the exercises in this book, you will need to be able to:
\begin{enumerate}
\item Install Python on your computer, along with the libraries we will use.
\item Copy my files onto your computer.
\item Run Jupyter, which is a tool for running and writing programs, and load a {\bf notebook}, which is a file that contains code and text.
\end{enumerate}
The next three sections provide details for these steps. I wish there were an easier way to get started; it's regrettable that you have to do so much work before you write your first program. Be persistent!
\section{Installing Python and the libraries}
You might already have Python installed on your computer, but you might not have the latest version. To use the code in this book, you need Python 3.6, or later. Even if you have the latest version, you probably don't have all of the libraries we need.
\index{intalling Python}
You could update Python and install these libraries, but I strongly recommend that you don't go down that road. I think you will find it easier to use {\bf Anaconda}, which is a free Python distribution that includes all the libraries you need for this book (and lots more).
\index{Anaconda}
Anaconda is available for Linux, macOS, and Windows. By default, it puts all files in your home directory, so you don't need administrator (root) permission to install it, and if you have a version of Python already, Anaconda will not remove or modify it.
[Detailed instructions coming soon.]
\section{Copying my files}
The code for this book is available from
\url{https://github.com/AllenDowney/ModSimPy}, which is a {\bf Git repository}. Git is a software tool that helps you keep track of the programs and other files that make up a project. A collection of files under Git's control is called a repository\footnote{The really cool kids call it a ``repo".}. GitHub is a hosting service that provides storage for Git repositories and a convenient web interface.
\index{repository}
\index{Git}
\index{GitHub}
There are several ways you can copy the files from my repository to your computer.
If you don't want to use Git at all, you can download my files
in a Zip archive from \url{http://modsimpy.com/zip}. Then you need a program like WinZip or gzip to unpack the Zip file.
To use Git, you need a {\bf Git client}, which is a program that manages git repositories. If you have not used Git before, I recommend GitHub Desktop, which is a simple graphical Git client. You can download it from \url{https://desktop.github.com}. Currently, GitHub Desktop is not available for Linux. On Linux, I suggest using the Git command-line client. Installation instructions are at \url{http://modsimpy.com/git}.
Once you have a Git client, you can use it to copy files from my repository to your computer, which is called {\bf cloning} in Git's vocabulary. If you are using a Command-line git client, type
\begin{python}
git clone https://github.com/AllenDowney/ModSimPy
\end{python}
You don't need a GitHub account to do this, but you won't be able to write your changes back to GitHub.
If you want to use GitHub to keep track of the code you write while you are using this book, you can make of a copy of my repository on GitHub, which is called {\bf forking}. If you don't already have a GitHub account, you'll need to create one.
Use a browser to view the homepage of my repository at \url{https://github.com/AllenDowney/ModSimPy}. You should see a gray button in the upper right that says {\sf Fork}. If you press it, GitHub will create a copy of my repository that belongs to you. Then you can clone your repository like this:
\begin{python}
git clone https://github.com/YourGitHubUserName/ModSimPy
\end{python}
Of course, you should replace \py{YourGitHubUserName} with your GitHub user name.
\section{Running Jupyter}
The code for each chapter, and starter code for the exercises, is in
Jupyter notebooks. If you have not used Jupyter before, you can read
about it at \url{http://jupyter.org}.
\index{Jupyter}
[Jupyter instructions coming soon.]
\section*{Contributor List}
If you have a suggestion or correction, send it to
{\tt downey@allendowney.com}. Or if you are a Git use, send me a pull request!
If I make a change based on your feedback, I will add you to the contributor list, unless you ask to be omitted.
\index{contributors}
If you include at least part of the sentence the error appears in, that makes it easy for me to search. Page and section numbers are fine, too, but not as easy to work with. Thanks!
\begin{itemize}
\item I am grateful to John Geddes and Mark Somerville for their early collaboration with me to create Modeling at Simulation, the class at Olin College this book is based on.
\item My early work on this book benefited from conversations with
my amazing colleagues at Olin College, including John Geddes, Alison
Wood, Chris Lee, and Jason Woodard.
\item I am grateful to Lisa Downey and Jason Woodard for their thoughtful and careful copy editing.
% ENDCONTRIB
\end{itemize}
\normalsize
\cleardoublepage
% TABLE OF CONTENTS
\begin{latexonly}
% \tableofcontents
\cleardoublepage
\end{latexonly}
% START THE BOOK
\mainmatter
\chapter{Modeling}
\label{chap01}
The world is a complicated place. In order to make sense of it, we use {\bf models}, which are generally smaller and simpler than the thing we want to study. The word ``model" means different things in different contexts, so it is hard to define except by example.
\index{mathematical model}
Some models are actual objects, like a scale model of a car, which has the same shape as the car, but smaller. Scale models are often useful for testing properties of mechanical systems, like air resistance.
This book is about {\bf mathematical models}, which are ideas, not objects. If you studied Newton's laws of motion, what you learned is a mathematical model of how objects move in space when forces are applied to them.
\index{Newton}
\section{The falling penny myth}
\label{penny}
Let's see an example of how models are used. You might have heard that a penny dropped from the top of the Empire State Building would be going so fast when it hit the pavement that it would be embedded in the concrete; or if it hit a person, it would break their skull.
\index{Empire State Building}
\index{penny}
\index{myth}
We can test this myth by making and analyzing a model. To get started, I'll assume that the effect of air resistance is small. This will turn out to be a bad assumption, but bear with me. If air resistance is negligible, the primary force acting on the penny is gravity, which causes the penny to accelerate downward.
\index{air resistance}
If the initial velocity is 0, the velocity after $t$ seconds is $at$, and the height the penny has dropped at $t$ is
%
\[ h = at^2/2 \]
%
Using algebra, we can solve for $t$:
%
\[ t = \sqrt{2h/a} \]
%
Plugging in the acceleration of gravity, $a = \SI{9.8}{\meter\per\second\squared}$ and the height of the Empire State Building, $h=\SI{381}{\meter}$, we get $t = \SI{8.8}{\second}$. Then computing $v=at$ we get a velocity on impact of $\SI{86}{\meter\per\second}$, which is about 190 miles per hour. That sounds like it could hurt.
Of course, these results are not exact because the model is based on simplifications. For example, we assume that gravity is constant. In fact, the force of gravity is different on different parts of the globe, and gets weaker as you move away from the surface. But these differences are small, so ignoring them is probably a good choice for this scenario.
\index{gravity}
On the other hand, ignoring air resistance is not a good choice. Once the penny gets to about \SI{18}{\meter\per\second}, the upward force of air resistance equals the downward force of gravity, so the penny stops accelerating. After that, it doesn't matter how far the penny falls; it hits the sidewalk (or your head) at about \SI{18}{\meter\per\second}, much less than \SI{86}{\meter\per\second}, as the simple model predicts.
The statistician George Box famously said ``All models are wrong, but some are useful." He was talking about statistical models, but his wise words apply to all kinds of models. Our first model, which ignores air resistance, is very wrong, and probably not useful. The second model is also wrong, but much better, and probably good enough to refute the myth.
\index{Box, George}
The television show {\it Mythbusters} has tested the myth of the falling penny more carefully; you can view the results at \url{http://modsimpy.com/myth}. Their work is based on a mathematical model of motion, measurements to determine the force of air resistance on a penny, and a physical model of a human head.
\index{Mythbusters}
\section{Computation}
There are (at least) two ways to work with mathematical models, {\bf analysis} and {\bf simulation}. Analysis often involves algebra and other kinds of symbolic manipulation. Simulation often involves computers.
\index{analysis}
\index{simulation}
In this book we do some analysis and a lot of simulation; along the way, I discuss the pros and cons of each. The primary tools we use for simulation are the Python programming language and Jupyter, which is an environment for writing and running programs.
As a first example, I'll show you how I computed the results from the previous section using Python. You can view this example, and the other code in this chapter, at \url{http://modsimpy.com/chap01}. For instructions for downloading and running the code, see Section~\ref{code}.
First I'll create a {\bf variable} to represent acceleration.
\index{variable}
\index{value}
\begin{python}
a = 9.8 * meter / second**2
\end{python}
A variable is a name that corresponds to a value. In this example, the name is \py{a} and the value is the number \py{9.8} multiplied by the units \py{meter / second**2}. This example demonstrates some of the symbols Python uses to perform mathematical operations:
\index{operator!mathematical}
\begin{tabular}{l|c}
{\bf Operation} & {\bf Symbol} \\
\hline
Addition & \py{+} \\
Subtraction & \py{-} \\
Multiplication & \py{*} \\
Division & \py{/} \\
Exponentiation & \py{**} \\
\end{tabular}
Next, we can compute the time it takes for the penny to drop \SI{381}{\meter}, the height of the Empire State Building.
\begin{python}
h = 381 * meter
t = sqrt(2 * h / a)
\end{python}
These lines create two more variables: \py{h} gets the height of the building in meters; \py{t} gets the time, in seconds, for the penny to fall to the sidewalk. \py{sqrt} is a {\bf function} that computes square roots. Python keeps track of units, so the result, \py{t}, has the correct units, seconds.
\index{unit}
\index{function}
\index{sqrt}
Finally, we can compute the velocity of the penny after $t$ seconds:
\begin{python}
v = a * t
\end{python}
The result is about \SI{86}{\meter\per\second}, again with the correct units.
This example demonstrates analysis and computation using Python. Next we'll see an example of simulation.
\section{Modeling a bike share system}
Imagine a bike share system for students traveling between Olin College and Wellesley College, which are about 3 miles apart in eastern Massachusetts.
\index{Wellesley College}
\index{Olin College}
This example demonstrates the features of Python we'll use to develop computational simulations of real-world systems. Along the way, I will make decisions about how to model the system. In the next chapter we'll review these decisions.
Suppose the system contains 12 bikes and two bike racks, one at Olin and one at Wellesley, each with the capacity to hold 12 bikes.
\index{bike share system}
As students arrive, check out a bike, and ride to the other campus,
the number of bikes in each location changes. In the simulation,
we'll need to keep track of where the bikes are. To do that, I'll
create a \py{System} object, which is defined in the \py{modsim} library.
\index{System object}
Before we can use the library, we have to \py{import} it:
\begin{python}
from modsim import *
\end{python}
This line of code is an {\bf import statement} that tells Python
to read the file {\tt modsim.py} and make the functions it defines available.
\index{import statement}
Functions in the \py{modsim.py} library include \py{sqrt}, which we used in the previous section, and \py{System}, which we are using now. \py{System} creates a \py{System} object, which is a collection of {\bf system variables}.
\index{system variable}
\begin{python}
bikeshare = System(olin=10, wellesley=2)
\end{python}
In this example, the system variables are \py{olin} and \py{wellesley} and they represent the number of bikes at Olin and Wellesley. The initial values are 10 and 2, indicating that there are 10 bikes at Olin and 2 at Wellesley. The \py{System} object created by \py{System} is assigned to a new variable named \py{bikeshare}.
\index{dot operator}
\index{operator!dot}
We can read the variables inside a \py{System} object using the {\bf dot operator}, like this:
\begin{python}
bikeshare.olin
\end{python}
The result is the value 10. Similarly, for:
\begin{python}
bikeshare.wellesley
\end{python}
The result is 2. If you forget what variables a system
object has, you can just type the name:
\begin{python}
bikeshare
\end{python}
The result looks like a table with the variable names and their values:
\begin{tabular}{lr}
& {\bf \sf value} \\
\hline
{\bf \sf olin} & 10 \\
{\bf \sf wellesley} & 2 \\
\end{tabular}
The system variables and their values make up the {\bf state} of the system. We can update the state by assigning new values to
the variables. For example, if a student moves a bike from Olin
to Wellesley, we can figure out the new values and assign them:
\index{state}
\begin{python}
bikeshare.olin = 9
bikeshare.wellesley = 3
\end{python}
Or we can use {\bf update operators}, \py{-=} and \py{+=} to subtract 1 from \py{olin} and add 1 to \py{wellesley}:
\index{update operator}
\index{operator!update}
\begin{python}
bikeshare.olin -= 1
bikeshare.wellesley += 1
\end{python}
The result is the same either way.
\section{Plotting}
As the state of the system changes, it is often useful to plot the
values of the variables over time. The \py{modsim} library provides a functions that creates a new figure:
\index{newfig}
\begin{python}
newfig()
\end{python}
In Jupyter, the behavior of this function depends on a command in the
first cell:
\begin{itemize}
\item If you want the figures to appear in the notebook, use
\begin{python}
%matplotlib notebook
\end{python}
\item If you want the figures to appear in separate windows, use
\begin{python}
%matplotlib qt
\end{python}
\end{itemize}
These commands are not actually Python; they are so-called ``magic commands" that control the behavior of Jupyter.
\index{magic command}
\index{plot}
The following lines plot the state of the system:
\begin{python}
plot(bikeshare.olin, 'rs-')
plot(bikeshare.wellesley, 'bo-')
\end{python}
The \py{plot} function takes two values, called {\bf arguments}:
\index{argument}
\begin{itemize}
\item The first argument is the variable to plot. In this example, it's a number, but we'll see later that \py{plot} can handle other objects, too.
\item The second argument is a ``style string'' that determines what the plot should look like. In general, a {\bf string} is a sequence of letters, numbers, and punctuation that appear in quotation marks. The style string \py{'rs-'} means we want red squares with lines between them; \py{'bo-'} means we want blue circles with
lines.
\index{style string}
\index{string!style}
\end{itemize}
The plotting functions in the \py{modsim} library are based on Matplotlib, which is a Python {\bf library} for generating
figures. To learn more about these functions, you can read
the Matplotlib documentation. For more about style strings, see
\url{http://modsimpy.com/plot}.
\index{Matplotlib}
\section{Defining functions}
So far we have used functions defined in \py{modsim} and other libraries. Now we're going to define our own functions.
\index{function}
\index{defining functions}
When you are developing code in Jupyter, it is often efficient to
write 1--2 lines in each cell, test them to confirm they do what
you intend, and then use them to define a new function. For
example, these lines move a bike from Olin to Wellesley:
\begin{python}
bikeshare.olin -= 1
bikeshare.wellesley += 1
\end{python}
Rather than repeat them every time a bike moves, we can define a
new function:
\begin{python}
def bike_to_wellesley():
bikeshare.olin -= 1
bikeshare.wellesley += 1
\end{python}
\py{def} is a special word in Python that indicates we are defining a new
function. The name of the function is \py{bike_to_wellesley}.
The empty parentheses indicate that this function takes no
arguments. The colon indicates the beginning of an indented
{\bf code block}.
\index{def}
\index{code block}
\index{body}
\index{indentation}
The next two lines are the {\bf body} of the function. They have
to be indented; by convention, the indentation is 4 spaces.
When you define a function, it has no immediate effect. The body
of the function doesn't run until you {\bf call} the function.
Here's how to call this function:
\index{call}
\begin{python}
bike_to_wellesley()
\end{python}
When you call this function, it updates the variables of the
{\tt bikeshare} object; you can check by displaying
or plotting the new state.
When you call a function that takes no arguments, you have to
include the empty parentheses. If you leave them out, like this:
\index{argument}
\index{parentheses}
\begin{python}
bike_to_wellesley
\end{python}
Python looks up the name of the function and displays:
\begin{python}
<function __main__.bike_to_wellesley>
\end{python}
This result indicates that \py{bike_to_wellesley} is a function. You don't have to know what \py{__main__} means, but if you see something like this, it probably means that you looked up a function but you didn't
actually run it. So don't forget the parentheses.
\section{Parameters}
Similarly, we can define a function that moves a bike from
Wellesley to Olin:
\begin{python}
def bike_to_olin():
bikeshare.wellesley -= 1
bikeshare.olin += 1
\end{python}
And run it like this:
\begin{python}
bike_to_olin()
\end{python}
One benefit of defining functions is that you avoid repeating chunks
of code, which makes programs smaller. Another benefit is that the
name you give the function documents what it does, which makes programs
more readable.
\index{parameter}
In this example, there is one other benefit that might be even
more important. Putting these lines in a function makes the program
more reliable because it guarantees that when we decrease the number
of bikes at Olin, we increase the number of bikes at Wellesley.
That way, we guarantee that the bikes in the model are neither created nor destroyed!
However, now we have two functions that are nearly identical except
for a change of sign. Repeated code makes programs harder to work with, because if we make a change, we have to make it in several places.
We can avoid that by defining a more general function that moves any number of bikes in either direction:
\begin{python}
def move_bike(n):
bikeshare.olin -= n
bikeshare.wellesley += n
\end{python}
The name in parentheses, \py{n}, is a {\bf parameter} of the function.
When we run the function, the argument we provide gets assigned to
the parameter. So if we run \py{move_bike} like this:
\begin{python}
move_bike(1)
\end{python}
It assigns the value of the argument, \py{1}, to the parameter, \py{n}, and then runs the body of the function. So the effect is the same as:
\begin{python}
n = 1
bikeshare.olin -= n
bikeshare.wellesley += n
\end{python}
Which moves a bike from Olin to Wellesley. Similarly, if we call
\py{move_bike} like this:
\begin{python}
move_bike(-1)
\end{python}
The effect is the same as:
\begin{python}
n = -1
bikeshare.olin -= n
bikeshare.wellesley += n
\end{python}
Which moves a bike from Wellesley to Olin. Now that we have
\py{move_bike}, we can rewrite the other two functions to use it:
\begin{python}
def bike_to_wellesley():
move_bike(1)
def bike_to_olin():
move_bike(-1)
\end{python}
If you define the same function name more than once, the new definition
replaces the old one.
\section{Print statements}
As you write more complicated programs, it is easy to lose track of what is going on. One of the most useful tools for debugging is the {\bf print statement}, which displays text in the Jupyter notebook.
\index{print statement}
\index{statement!print}
Normally when Jupyter runs the code in a cell, it displays the value of the last line of code. For example, if you run:
\begin{python}
bikeshare.olin
bikeshare.wellesley
\end{python}
Jupyter runs both lines of code, but it only displays the value of the second line.
If you want to display more than one value, you can use print statements:
\begin{python}
print(bikeshare.olin)
print(bikeshare.wellesley)
\end{python}
\py{print} is a function, so it takes an argument in parentheses. It can also take a sequence of arguments separated by commas, like this:
\begin{python}
print(bikeshare.olin, bikeshare.wellesley)
\end{python}
In this example, the two values appear on the same line, separated by a space.
Print statements are also useful for debugging functions. For example, if you add a print statement to \py{move_bike}, like this:
\begin{python}
def move_bike(n):
print('Running move_bike with n =', n)
bikeshare.olin -= n
bikeshare.wellesley += n
\end{python}
The first argument of \py{print} is a string; the second is the value of \py{n}, which is a number. Each time you run \py{move_bike}, it displays a message and the value \py{n}.
\index{string}
\section{If statements}
The \py{modsim} library provides a function called \py{flip} that takes
as an argument a probability between 0 and 1:
\begin{python}
flip(0.7)
\end{python}
The result is one of two values: \py{True} with probability 0.7 or \py{False} with probability 0.3. If you run this function 100 times, you should to get \py{True} about 70 times and \py{False} about 30 times. But the results are random, so they might differ from these expectations.
\index{flip}
\index{True}
\index{False}
\py{True} and \py{False} are special values defined by Python. Note
that they are not strings. There is a difference between \py{True},
which is a special value, and \py{'True'}, which is a string.