├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── ModSimMatlabCode.zip ├── PhysicalModelingInMatlab.zip ├── PhysicalModelingInMatlab4.pdf ├── README.md ├── book ├── Makefile ├── back.png ├── chap00.tex ├── chap01.tex ├── chap02.tex ├── chap03.tex ├── chap04.tex ├── chap04leftovers.tex ├── chap05.tex ├── chap06.tex ├── chap07.tex ├── chap08.tex ├── chap09.tex ├── chap10.tex ├── chap11.tex ├── chap12.tex ├── chap13.tex ├── chap14.tex ├── chap15.tex ├── cover │ ├── ISBN9780615185507.eps │ ├── ISBN9780615185507.pdf │ ├── back.jpg │ ├── back.odg │ ├── cover.odg │ ├── cover.odt │ ├── cover.pdf │ ├── cover.png │ ├── front.jpg │ └── front.odg ├── figs │ ├── baseball1.eps │ ├── baseball2.eps │ ├── baseball3.eps │ ├── baseball4.eps │ ├── cannon1.eps │ ├── coffee.eps │ ├── euler.eps │ ├── fibonacci.eps │ ├── golden1.eps │ ├── golden1.fig │ ├── golden2.eps │ ├── golden2.fig │ ├── lotka.eps │ ├── modeling_framework.odg │ ├── modeling_framework.pdf │ ├── modeling_framework.png │ ├── ode45.eps │ ├── ode45_simple.eps │ ├── ode45plotLabel.eps │ ├── odeplot1.eps │ ├── odeplot2.eps │ ├── penny.eps │ ├── penny2.eps │ ├── phase.eps │ ├── rats.eps │ ├── runge.eps │ ├── secant.eps │ ├── secant.fig │ ├── secant.fig.bak │ ├── spiderman.odg │ ├── spiderman.pdf │ ├── spiderman.png │ ├── vector1.eps │ ├── vector2.eps │ └── vector3.eps ├── footer.html ├── glossary.tex ├── header.html ├── htmlonly.tex ├── images │ ├── figure01_01_new.eps │ ├── figure01_01_new.pdf │ ├── figure04_01_new.pdf │ ├── figure04_01_new_v1.eps │ ├── figure09_01_new.eps │ ├── figure09_01_new.pdf │ ├── figure09_02_new.eps │ ├── figure09_02_new.pdf │ ├── figure09_03_new.eps │ ├── figure09_03_new.pdf │ ├── figure10_01_new.eps │ ├── figure10_01_new.pdf │ ├── figure10_02_new.eps │ ├── figure10_02_new.pdf │ ├── figure11_01_new.eps │ ├── figure11_01_new.pdf │ ├── figure11_02_new.eps │ ├── figure11_02_new.pdf │ ├── figure12_01_new.eps │ ├── figure12_01_new.pdf │ ├── figure12_02_new.eps │ ├── figure12_02_new.pdf │ ├── figure12_03_new.eps │ ├── figure12_03_new.pdf │ ├── figure12_04_new.eps │ ├── figure12_04_new.pdf │ ├── figure13_01_new.eps │ ├── figure13_01_new.pdf │ ├── figure13_02_new.eps │ ├── figure13_02_new.pdf │ ├── figure14_01_new.eps │ ├── figure14_01_new.pdf │ ├── figure15_01_new.eps │ ├── figure15_01_new.pdf │ ├── figure15_02_new.eps │ ├── figure15_02_new.pdf │ ├── figure15_03_new.eps │ ├── figure15_03_new.pdf │ ├── figure15_04_new.eps │ ├── figure15_04_new.pdf │ ├── figure15_05_new.eps │ ├── figure15_05_new.pdf │ └── matlab_circleart.eps ├── latexonly.tex ├── leftovers.tex ├── links │ ├── gen_htaccess.py │ ├── get_links.py │ ├── get_urls.py │ ├── notes.txt │ ├── set_urls.py │ └── urls.csv ├── main.tex ├── mcode.sty ├── next.png ├── settings.tex └── up.png ├── build.sh ├── code ├── chap02 │ ├── bike_update.m │ ├── fibonacci1.m │ ├── myscript.m │ └── swap.m ├── chap03 │ ├── bike_loop.m │ ├── bike_update.m │ ├── fibonacci2.m │ ├── fibonacci3.m │ ├── fudge.m │ ├── old │ │ ├── bike_loop2.m │ │ ├── car.m │ │ ├── car_loop.m │ │ ├── car_loop2.m │ │ ├── car_update.m │ │ ├── fib.m │ │ ├── fib1.m │ │ ├── fib_loop.m │ │ ├── rel_error.m │ │ ├── update.m │ │ ├── update1.m │ │ └── update2.m │ ├── sequence.m │ └── series.m ├── chap04 │ ├── fibonacci4.m │ ├── fibonacci_ratio.m │ ├── logchaos.m │ ├── logmap.m │ └── lorenz.m ├── chap05 │ ├── hypotenuse.m │ ├── junk │ │ └── istriple.m │ ├── myfunc.m │ └── sumDir │ │ └── sum.m ├── chap06 │ ├── fib_triple.m │ └── find_triples.m ├── chap07 │ ├── cheby6.m │ ├── duck.m │ ├── error_func.m │ └── plot_cheby6.m ├── chap08 │ ├── duck.m │ ├── exists.m │ ├── exists2.m │ └── mysum.m ├── chap09 │ ├── coffee.m │ ├── euler.m │ ├── rats.m │ └── runge.m ├── chap10 │ ├── lorenz.m │ ├── lorenz_diff.m │ ├── lorenz_loop.m │ ├── lorenz_update.m │ ├── lotka.m │ └── plot_lorenz.m ├── chap11 │ ├── earth.m │ ├── freefall.m │ ├── penny.m │ ├── penny2.m │ └── skydiver.m ├── chap12 │ ├── baseball.m │ ├── baseball2.m │ ├── diagram.m │ ├── optimize.m │ ├── proj1.m │ └── proj2.m ├── chap13 │ ├── baseball3.m │ ├── baseball_anim.m │ ├── golden.m │ ├── manny.m │ ├── manny2.m │ └── optimization.m ├── chap14 │ └── binary.m ├── chap15 │ ├── odeplot.m │ └── planet.m ├── data │ ├── baseball_drag.csv │ ├── baseball_drag.png │ ├── world_pop_census.csv │ └── world_pop_un.csv ├── notebooks │ ├── baseball.mlx │ ├── baseball2.mlx │ ├── low_pass.mlx │ ├── penny.mlx │ ├── sir_model.mlx │ ├── world_pop_1.mlx │ └── world_pop_2.mlx └── other │ ├── Evaluation3.m │ ├── HopperSimNew.m │ ├── L_find.m │ ├── allen_ramp.m │ ├── ang_quat.m │ ├── ang_rot.m │ ├── av_quat.m │ ├── av_rot.m │ ├── chaos.m │ ├── chris.m │ ├── comp_err.m │ ├── comp_err2.m │ ├── compute_euler.m │ ├── compute_euler2.m │ ├── copper.m │ ├── copper1.m │ ├── copper_euler.m │ ├── copper_func.m │ ├── copper_ode45.m │ ├── copper_script.m │ ├── corn.m │ ├── data_gen.m │ ├── data_gen3.m │ ├── direct.m │ ├── double_pend.m │ ├── double_pend2.m │ ├── double_pend3.m │ ├── duck45.m │ ├── eigenquat.m │ ├── errfunc.m │ ├── evaluation4.m │ ├── evaluation5.m │ ├── f.m │ ├── finitewell.m │ ├── flying_duck.m │ ├── fty.m │ ├── fyt.m │ ├── interest.m │ ├── koch.m │ ├── lacrosse.m │ ├── ladderde.m │ ├── laddersim.m │ ├── magpart.m │ ├── manny1.m │ ├── moody.m │ ├── mybalance.m │ ├── myfunc1.m │ ├── mysqrt.m │ ├── mysqrt2.m │ ├── nerfdart.m │ ├── newton.m │ ├── oven.m │ ├── particle.m │ ├── pathdef.m │ ├── pendulum.m │ ├── pendulum1.m │ ├── pendulum2.m │ ├── plot_err.m │ ├── plot_particle.m │ ├── population1.m │ ├── population2.m │ ├── population3.m │ ├── population4.m │ ├── population5.m │ ├── projectile.m │ ├── projectile2.m │ ├── qtest.m │ ├── quat_ang.m │ ├── quat_rot.m │ ├── quat_rot_1.m │ ├── ramp.m │ ├── ramp2.m │ ├── ramp3.m │ ├── rampest.m │ ├── rand_av.m │ ├── random.m │ ├── ratplot.m │ ├── rot_ang.m │ ├── rot_av.m │ ├── series_loop.m │ ├── simplegame.m │ ├── skate.m │ ├── square.m │ ├── steph_balance.m │ ├── sym_examples.m │ ├── sym_worksheet.m │ ├── testing.m │ ├── testsqrt.m │ ├── untitled.m │ ├── vector_examples.m │ ├── watersphere.m │ ├── yeast1.m │ └── yeast2.m └── fonts ├── dogma └── dogmab01.ttf ├── futurans ├── FutCBO63.ttf ├── FutuBO08.ttf ├── FuturB37.ttf ├── FuturB41.ttf ├── FuturH79.ttf ├── futucb18.ttf └── futura.ttf ├── nbaskerv ├── NewBaskervilleEF-Bold.ttf ├── NewBaskervilleEF-BoldIta.ttf ├── NewBaskervilleEF-Roman.ttf └── NewBaskervilleEF-RomanIta.ttf ├── thsmc ├── TSMCBI56.ttf ├── ThSMCB02.ttf ├── ThSMCI29.ttf └── ThSMCP25.ttf └── tnr ├── Timnreb.ttf ├── times.ttf ├── times_0.ttf ├── timesbd.ttf ├── timesbd_0.ttf ├── timesbi.ttf ├── timesbi_0.ttf ├── timesi.ttf └── timesi_0.ttf /.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.glo 3 | *.idx 4 | *.log 5 | *.toc 6 | *.ist 7 | *.acn 8 | *.acr 9 | *.alg 10 | *.bbl 11 | *.blg 12 | *.dvi 13 | *.glg 14 | *.gls 15 | *.ilg 16 | *.ind 17 | *.hind 18 | *.lof 19 | *.lot 20 | *.maf 21 | *.mtc 22 | *.mtc1 23 | *.out 24 | *.synctex.gz 25 | *.pdf 26 | *.tex.bak 27 | book/html 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/CONTRIBUTING.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The text of Physical Modeling in MATLAB is under the Creative Commons Attribution-NonCommercial 4.0 Unported License, which is available at 2 | 3 | https://greenteapress.com/matlab/license. 4 | 5 | The supporting code for this book is under the MIT license at 6 | 7 | https://mit-license.org/ 8 | -------------------------------------------------------------------------------- /ModSimMatlabCode.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/ModSimMatlabCode.zip -------------------------------------------------------------------------------- /PhysicalModelingInMatlab.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/PhysicalModelingInMatlab.zip -------------------------------------------------------------------------------- /PhysicalModelingInMatlab4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/PhysicalModelingInMatlab4.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Physical Modeling in MATLAB 2 | 3 | *Physical Modeling in MATLAB* is an introduction to programming in MATLAB and simulation of physical systems by Allen B. Downey. 4 | 5 | It is available from https://greenteapress.com/wp/physical-modeling-in-matlab/ 6 | -------------------------------------------------------------------------------- /book/Makefile: -------------------------------------------------------------------------------- 1 | PDF = PhysicalModelingInMatlab4.pdf 2 | 3 | PDFFLAGS = -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress \ 4 | -dCompressPages=true -dUseFlateCompression=true \ 5 | -dEmbedAllFonts=true -dSubsetFonts=true -dMaxSubsetPct=100 6 | 7 | all: 8 | pdflatex main 9 | makeindex main 10 | mv main.pdf $(PDF) 11 | 12 | 13 | DEST = /home/downey/public_html/greent/matlab 14 | 15 | distrib: 16 | rsync -a $(PDF) html $(DEST) 17 | cd $(DEST)/..; sh back 18 | -------------------------------------------------------------------------------- /book/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/back.png -------------------------------------------------------------------------------- /book/cover/ISBN9780615185507.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-2.0 EPSF-1.2 2 | %%Creator: bookland 1.3 3 | %%Title: ISBN 978-0-6151-8550-7 4 | %%BoundingBox: 199 335 371 432 5 | %%EndComments 6 | % Command line: /home/milgram/cgi-bin/isbn.py 7 | % This is free software and comes with NO WARRANTY WHATSOVER. This file 8 | % contains portions of bookland, a free program licensed under the GNU 9 | % General Public License. The GPL notwithstanding, you may use and 10 | % redistribute this output file without restriction. 11 | 12 | /W { moduleWidth mul 0 rmoveto } def 13 | /B { dup moduleWidth mul 2 div 0 rmoveto 14 | dup moduleWidth mul barWidthReduction sub setlinewidth 15 | 0 moduleHeight rlineto 0 moduleHeight neg rmoveto 16 | currentpoint stroke moveto 17 | moduleWidth mul 2 div 0 rmoveto } def 18 | /L { dup moduleWidth mul 2 div 0 rmoveto 19 | dup moduleWidth mul barWidthReduction sub setlinewidth 20 | 0 -5 rmoveto 0 5 rlineto 21 | 0 moduleHeight rlineto 0 moduleHeight neg rmoveto 22 | currentpoint stroke moveto 23 | moduleWidth mul 2 div 0 rmoveto } def 24 | % function fitstring: 25 | % usage: width string font fitstring 26 | % scale font to fit string to desired width 27 | % leave string on stack 28 | /fitstring { dup findfont 1 scalefont setfont % w s f 29 | 3 1 roll % f w s 30 | dup stringwidth pop % f w s sw 31 | 3 2 roll exch div % f s x 32 | 3 2 roll findfont exch 33 | scalefont setfont } def 34 | % get bounding box of string. 35 | % usage: string stringbb -> llx lly urx ury 36 | /stringbb {gsave false charpath flattenpath pathbbox grestore} def 37 | % String height and width: 38 | /stringhw {stringbb exch % llx lly ury urx 39 | 4 1 roll % urx llx lly ury 40 | sub neg % urx llx h 41 | 3 1 roll % h urx llx 42 | sub % h w 43 | } def 44 | /dx { [ 0 1 2 0 1 2 0 1 2 ] } def 45 | /dy { [ 0 0 0 1 1 1 2 2 2 ] } def 46 | % Set dx and dy to shift to anchor point: 47 | /dxdy { dup dx exch % anchor dx anchor 48 | get % anchor idx 49 | dy % anchor idx dy 50 | 3 2 roll % idx dy anchor 51 | get % idx idy 52 | } def 53 | % Usage: string anchor anchorstring 54 | /anchorstring { dxdy % string idx idy 55 | 3 2 roll % idx idy string 56 | dup % idx idy string string 57 | 4 1 roll % string idx idy string 58 | stringhw % string idx idy h w 59 | 4 1 roll % string w idx idy h 60 | mul -2 div % string w idx ry 61 | 3 1 roll % string ry w idx 62 | mul -2 div % string ry rx 63 | exch 64 | rmoveto show } def 65 | 220.0 347.5 translate 0 0 moveto 66 | 0.0 0.0 0.0 1.0 setcmykcolor 67 | 68 | % 69 | % Text string 70 | % 71 | gsave 65.52 -1 translate 0 0 moveto 72 | 36.6912 (780615) /OCRB fitstring 73 | (185507) 7 anchorstring 74 | grestore 75 | 76 | % 77 | % Text string 78 | % 79 | gsave 22.464 -1 translate 0 0 moveto 80 | 36.6912 (780615) /OCRB fitstring 81 | (780615) 7 anchorstring 82 | grestore 83 | 84 | % 85 | % Text string 86 | % 87 | gsave -2 -1 translate 0 0 moveto 88 | 36.6912 (780615) /OCRB fitstring 89 | (9) 8 anchorstring 90 | grestore 91 | 92 | % 93 | % Product Code Bars 94 | % 95 | gsave 96 | 0 0 translate 0 0 moveto 97 | /moduleHeight { 72.0 } def 98 | /moduleWidth { 0.936 } def 99 | /barWidthReduction { 0.0 } def 100 | 1 L 1 W 1 L 1 W 3 B 1 W 2 B 3 W 1 B 2 W 1 B 1 W 1 B 2 W 3 B 1 W 1 B 1 W 4 B 1 W 2 B 2 W 2 B 1 W 2 B 3 W 1 B 1 W 1 L 1 W 1 L 1 W 2 B 2 W 2 B 1 W 1 B 2 W 1 B 3 W 1 B 2 W 3 B 1 W 1 B 2 W 3 B 1 W 3 B 2 W 1 B 1 W 1 B 3 W 1 B 2 W 1 L 1 W 1 L 101 | grestore 102 | 103 | % 104 | % Text string 105 | % 106 | gsave 88.92 0 translate 0 0 moveto 107 | 36.6912 (780615) /OCRB fitstring 108 | ( ) 0 anchorstring 109 | grestore 110 | 111 | % 112 | % Text string 113 | % 114 | gsave 44.46 74.0 translate 0 0 moveto 115 | /OCRB findfont 9.0 scalefont setfont 116 | (ISBN 978-0-6151-8550-7) 1 anchorstring 117 | grestore 118 | 119 | % 120 | % Product Code Bars 121 | % 122 | gsave 123 | 98 0 translate 0 0 moveto 124 | /moduleHeight { 61.344 } def 125 | /moduleWidth { 0.936 } def 126 | /barWidthReduction { 0 } def 127 | 1 B 1 W 2 B 1 W 3 B 2 W 1 B 1 W 1 B 2 W 1 B 2 W 2 B 1 W 1 B 2 W 3 B 1 W 1 B 1 W 1 B 3 W 1 B 1 W 2 B 1 W 1 B 1 W 2 B 3 W 1 B 128 | grestore 129 | 130 | % 131 | % Text string 132 | % 133 | gsave 119.996 63.344 translate 0 0 moveto 134 | 32.994 (52495) /OCRB fitstring 135 | (52495) 1 anchorstring 136 | grestore 137 | 138 | % 139 | % Text string 140 | % 141 | gsave 142.992 63.344 translate 0 0 moveto 142 | 32.994 (52495) /OCRB fitstring 143 | (>) 0 anchorstring 144 | grestore 145 | 146 | stroke 147 | % showpage OK in EPS 148 | showpage 149 | % Good luck! 150 | -------------------------------------------------------------------------------- /book/cover/ISBN9780615185507.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/ISBN9780615185507.pdf -------------------------------------------------------------------------------- /book/cover/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/back.jpg -------------------------------------------------------------------------------- /book/cover/back.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/back.odg -------------------------------------------------------------------------------- /book/cover/cover.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/cover.odg -------------------------------------------------------------------------------- /book/cover/cover.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/cover.odt -------------------------------------------------------------------------------- /book/cover/cover.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/cover.pdf -------------------------------------------------------------------------------- /book/cover/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/cover.png -------------------------------------------------------------------------------- /book/cover/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/front.jpg -------------------------------------------------------------------------------- /book/cover/front.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/cover/front.odg -------------------------------------------------------------------------------- /book/figs/golden1.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-3.0 EPSF-3.0 2 | %%Title: golden1.fig 3 | %%Creator: fig2dev Version 3.2.6a 4 | %%CreationDate: 2019-01-15 09:08:29 5 | %%BoundingBox: 0 0 218 126 6 | %Magnification: 1.0000 7 | %%EndComments 8 | %%BeginProlog 9 | /$F2psDict 200 dict def 10 | $F2psDict begin 11 | $F2psDict /mtrx matrix put 12 | /col-1 {0 setgray} bind def 13 | /col0 {0.000 0.000 0.000 srgb} bind def 14 | /col7 {1.000 1.000 1.000 srgb} bind def 15 | 16 | end 17 | 18 | /cp {closepath} bind def 19 | /ef {eofill} bind def 20 | /gr {grestore} bind def 21 | /gs {gsave} bind def 22 | /sa {save} bind def 23 | /rs {restore} bind def 24 | /l {lineto} bind def 25 | /m {moveto} bind def 26 | /rm {rmoveto} bind def 27 | /n {newpath} bind def 28 | /s {stroke} bind def 29 | /sh {show} bind def 30 | /slc {setlinecap} bind def 31 | /slj {setlinejoin} bind def 32 | /slw {setlinewidth} bind def 33 | /srgb {setrgbcolor} bind def 34 | /rot {rotate} bind def 35 | /sc {scale} bind def 36 | /sd {setdash} bind def 37 | /ff {findfont} bind def 38 | /sf {setfont} bind def 39 | /scf {scalefont} bind def 40 | /sw {stringwidth} bind def 41 | /tr {translate} bind def 42 | /tnt {dup dup currentrgbcolor 43 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 44 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 45 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} 46 | bind def 47 | /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 48 | 4 -2 roll mul srgb} bind def 49 | /DrawEllipse { 50 | /endangle exch def 51 | /startangle exch def 52 | /yrad exch def 53 | /xrad exch def 54 | /y exch def 55 | /x exch def 56 | /savematrix mtrx currentmatrix def 57 | x y tr xrad yrad sc 0 0 1 startangle endangle arc 58 | closepath 59 | savematrix setmatrix 60 | } def 61 | 62 | /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def 63 | /$F2psEnd {$F2psEnteredState restore end} def 64 | 65 | /pageheader { 66 | save 67 | newpath 0 126 moveto 0 0 lineto 218 0 lineto 218 126 lineto closepath clip newpath 68 | -71.3 306.9 translate 69 | 1 -1 scale 70 | $F2psBegin 71 | 10 setmiterlimit 72 | 0 slj 0 slc 73 | 0.06000 0.06000 sc 74 | } bind def 75 | /pagefooter { 76 | $F2psEnd 77 | restore 78 | } bind def 79 | %%EndProlog 80 | pageheader 81 | % 82 | % Fig objects follow 83 | % 84 | % 85 | % here starts figure with depth 50 86 | % Ellipse 87 | 7.500 slw 88 | n 1725 3075 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 89 | 90 | % Ellipse 91 | n 4350 3450 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 92 | 93 | % Ellipse 94 | n 2625 4050 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 95 | 96 | % Polyline 97 | 0 slj 98 | 0 slc 99 | [15 45] 45 sd 100 | n 1725 3150 m 101 | 1725 4800 l gs col0 s gr [] 0 sd 102 | % Polyline 103 | [15 45] 45 sd 104 | n 2625 4050 m 105 | 2625 4800 l gs col0 s gr [] 0 sd 106 | % Polyline 107 | [15 45] 45 sd 108 | n 4350 3450 m 109 | 4350 4800 l gs col0 s gr [] 0 sd 110 | % Polyline 111 | n 1200 4800 m 112 | 4800 4800 l gs col0 s gr 113 | /Helvetica ff 233.33 scf sf 114 | 4275 5100 m 115 | gs 1 -1 sc (x3) col0 sh gr 116 | /Helvetica ff 233.33 scf sf 117 | 2550 5100 m 118 | gs 1 -1 sc (x2) col0 sh gr 119 | /Helvetica ff 233.33 scf sf 120 | 1650 5100 m 121 | gs 1 -1 sc (x1) col0 sh gr 122 | % here ends figure; 123 | pagefooter 124 | showpage 125 | %%Trailer 126 | %EOF 127 | -------------------------------------------------------------------------------- /book/figs/golden1.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Inches 5 | Letter 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 1725 3075 38 38 1687 3075 1763 3075 11 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 4350 3450 38 38 4312 3450 4388 3450 12 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 2625 4050 38 38 2587 4050 2663 4050 13 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 14 | 1725 3150 1725 4800 15 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 16 | 2625 4050 2625 4800 17 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 18 | 4350 3450 4350 4800 19 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 20 | 1200 4800 4800 4800 21 | 4 0 0 50 0 16 14 0.0000 4 135 180 4275 5100 x3\001 22 | 4 0 0 50 0 16 14 0.0000 4 135 180 2550 5100 x2\001 23 | 4 0 0 50 0 16 14 0.0000 4 135 180 1650 5100 x1\001 24 | -------------------------------------------------------------------------------- /book/figs/golden2.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-3.0 EPSF-3.0 2 | %%Title: golden2.fig 3 | %%Creator: fig2dev Version 3.2.6a 4 | %%CreationDate: 2019-01-15 09:17:49 5 | %%BoundingBox: 0 0 492 126 6 | %Magnification: 1.0000 7 | %%EndComments 8 | %%BeginProlog 9 | /$F2psDict 200 dict def 10 | $F2psDict begin 11 | $F2psDict /mtrx matrix put 12 | /col-1 {0 setgray} bind def 13 | /col0 {0.000 0.000 0.000 srgb} bind def 14 | /col7 {1.000 1.000 1.000 srgb} bind def 15 | 16 | end 17 | 18 | /cp {closepath} bind def 19 | /ef {eofill} bind def 20 | /gr {grestore} bind def 21 | /gs {gsave} bind def 22 | /sa {save} bind def 23 | /rs {restore} bind def 24 | /l {lineto} bind def 25 | /m {moveto} bind def 26 | /rm {rmoveto} bind def 27 | /n {newpath} bind def 28 | /s {stroke} bind def 29 | /sh {show} bind def 30 | /slc {setlinecap} bind def 31 | /slj {setlinejoin} bind def 32 | /slw {setlinewidth} bind def 33 | /srgb {setrgbcolor} bind def 34 | /rot {rotate} bind def 35 | /sc {scale} bind def 36 | /sd {setdash} bind def 37 | /ff {findfont} bind def 38 | /sf {setfont} bind def 39 | /scf {scalefont} bind def 40 | /sw {stringwidth} bind def 41 | /tr {translate} bind def 42 | /tnt {dup dup currentrgbcolor 43 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 44 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 45 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} 46 | bind def 47 | /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 48 | 4 -2 roll mul srgb} bind def 49 | /DrawEllipse { 50 | /endangle exch def 51 | /startangle exch def 52 | /yrad exch def 53 | /xrad exch def 54 | /y exch def 55 | /x exch def 56 | /savematrix mtrx currentmatrix def 57 | x y tr xrad yrad sc 0 0 1 startangle endangle arc 58 | closepath 59 | savematrix setmatrix 60 | } def 61 | 62 | /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def 63 | /$F2psEnd {$F2psEnteredState restore end} def 64 | 65 | /pageheader { 66 | save 67 | newpath 0 126 moveto 0 0 lineto 492 0 lineto 492 126 lineto closepath clip newpath 68 | -71.3 306.9 translate 69 | 1 -1 scale 70 | $F2psBegin 71 | 10 setmiterlimit 72 | 0 slj 0 slc 73 | 0.06000 0.06000 sc 74 | } bind def 75 | /pagefooter { 76 | $F2psEnd 77 | restore 78 | } bind def 79 | %%EndProlog 80 | pageheader 81 | % 82 | % Fig objects follow 83 | % 84 | % 85 | % here starts figure with depth 1001 86 | % Grid 87 | 0.5 setgray 88 | % Vertical 89 | % Horizontal 90 | % here ends figure; 91 | % 92 | % here starts figure with depth 50 93 | % Ellipse 94 | 7.500 slw 95 | n 6300 3075 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 96 | 97 | % Ellipse 98 | n 8925 3450 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 99 | 100 | % Ellipse 101 | n 7200 4125 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 102 | 103 | % Ellipse 104 | n 7800 3975 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 105 | 106 | % Ellipse 107 | n 1725 3075 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 108 | 109 | % Ellipse 110 | n 4350 3450 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 111 | 112 | % Ellipse 113 | n 2625 4125 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 114 | 115 | % Ellipse 116 | n 3225 4275 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 117 | 118 | % Polyline 119 | 0 slj 120 | 0 slc 121 | n 1200 4800 m 122 | 4800 4800 l gs col0 s gr 123 | % Polyline 124 | [15 45] 45 sd 125 | n 6300 3150 m 126 | 6300 4800 l gs col0 s gr [] 0 sd 127 | % Polyline 128 | [15 45] 45 sd 129 | n 7200 4125 m 130 | 7200 4800 l gs col0 s gr [] 0 sd 131 | % Polyline 132 | [15 45] 45 sd 133 | n 8925 3450 m 134 | 8925 4800 l gs col0 s gr [] 0 sd 135 | % Polyline 136 | n 5775 4800 m 137 | 9375 4800 l gs col0 s gr 138 | % Polyline 139 | [15 45] 45 sd 140 | n 7800 4050 m 141 | 7800 4800 l gs col0 s gr [] 0 sd 142 | % Polyline 143 | [15 45] 45 sd 144 | n 1725 3150 m 145 | 1725 4800 l gs col0 s gr [] 0 sd 146 | % Polyline 147 | [15 45] 45 sd 148 | n 2625 4125 m 149 | 2625 4800 l gs col0 s gr [] 0 sd 150 | % Polyline 151 | [15 45] 45 sd 152 | n 4350 3450 m 153 | 4350 4800 l gs col0 s gr [] 0 sd 154 | % Polyline 155 | [15 45] 45 sd 156 | n 3225 4275 m 157 | 3225 4800 l gs col0 s gr [] 0 sd 158 | /Helvetica ff 233.33 scf sf 159 | 7725 5100 m 160 | gs 1 -1 sc (x4) col0 sh gr 161 | /Helvetica ff 233.33 scf sf 162 | 7125 5100 m 163 | gs 1 -1 sc (x2) col0 sh gr 164 | /Helvetica ff 233.33 scf sf 165 | 8850 5100 m 166 | gs 1 -1 sc (x3) col0 sh gr 167 | /Helvetica ff 233.33 scf sf 168 | 6225 5100 m 169 | gs 1 -1 sc (x1) col0 sh gr 170 | /Helvetica ff 233.33 scf sf 171 | 3150 5100 m 172 | gs 1 -1 sc (x4) col0 sh gr 173 | /Helvetica ff 233.33 scf sf 174 | 2550 5100 m 175 | gs 1 -1 sc (x2) col0 sh gr 176 | /Helvetica ff 233.33 scf sf 177 | 4275 5100 m 178 | gs 1 -1 sc (x3) col0 sh gr 179 | /Helvetica ff 233.33 scf sf 180 | 1650 5100 m 181 | gs 1 -1 sc (x1) col0 sh gr 182 | % here ends figure; 183 | pagefooter 184 | showpage 185 | %%Trailer 186 | %EOF 187 | -------------------------------------------------------------------------------- /book/figs/golden2.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Inches 5 | Letter 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 6300 3075 38 38 6262 3075 6338 3075 11 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 8925 3450 38 38 8887 3450 8963 3450 12 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 7200 4125 38 38 7162 4125 7238 4125 13 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 7800 3975 38 38 7762 3975 7838 3975 14 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 1725 3075 38 38 1687 3075 1763 3075 15 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 4350 3450 38 38 4312 3450 4388 3450 16 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 2625 4125 38 38 2587 4125 2663 4125 17 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 3225 4275 38 38 3187 4275 3263 4275 18 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 19 | 1200 4800 4800 4800 20 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 21 | 6300 3150 6300 4800 22 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 23 | 7200 4125 7200 4800 24 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 25 | 8925 3450 8925 4800 26 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 27 | 5775 4800 9375 4800 28 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 29 | 7800 4050 7800 4800 30 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 31 | 1725 3150 1725 4800 32 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 33 | 2625 4125 2625 4800 34 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 35 | 4350 3450 4350 4800 36 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 37 | 3225 4275 3225 4800 38 | 4 0 0 50 0 16 14 0.0000 4 135 180 7725 5100 x4\001 39 | 4 0 0 50 0 16 14 0.0000 4 135 180 7125 5100 x2\001 40 | 4 0 0 50 0 16 14 0.0000 4 135 180 8850 5100 x3\001 41 | 4 0 0 50 0 16 14 0.0000 4 135 180 6225 5100 x1\001 42 | 4 0 0 50 0 16 14 0.0000 4 135 180 3150 5100 x4\001 43 | 4 0 0 50 0 16 14 0.0000 4 135 180 2550 5100 x2\001 44 | 4 0 0 50 0 16 14 0.0000 4 135 180 4275 5100 x3\001 45 | 4 0 0 50 0 16 14 0.0000 4 135 180 1650 5100 x1\001 46 | -------------------------------------------------------------------------------- /book/figs/modeling_framework.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/modeling_framework.odg -------------------------------------------------------------------------------- /book/figs/modeling_framework.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/modeling_framework.pdf -------------------------------------------------------------------------------- /book/figs/modeling_framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/modeling_framework.png -------------------------------------------------------------------------------- /book/figs/secant.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-3.0 EPSF-3.0 2 | %%Title: secant.fig 3 | %%Creator: fig2dev Version 3.2.6a 4 | %%CreationDate: 2019-01-16 14:24:17 5 | %%BoundingBox: 0 0 223 147 6 | %Magnification: 1.0000 7 | %%EndComments 8 | %%BeginProlog 9 | /$F2psDict 200 dict def 10 | $F2psDict begin 11 | $F2psDict /mtrx matrix put 12 | /col-1 {0 setgray} bind def 13 | /col0 {0.000 0.000 0.000 srgb} bind def 14 | /col7 {1.000 1.000 1.000 srgb} bind def 15 | 16 | end 17 | 18 | /cp {closepath} bind def 19 | /ef {eofill} bind def 20 | /gr {grestore} bind def 21 | /gs {gsave} bind def 22 | /sa {save} bind def 23 | /rs {restore} bind def 24 | /l {lineto} bind def 25 | /m {moveto} bind def 26 | /rm {rmoveto} bind def 27 | /n {newpath} bind def 28 | /s {stroke} bind def 29 | /sh {show} bind def 30 | /slc {setlinecap} bind def 31 | /slj {setlinejoin} bind def 32 | /slw {setlinewidth} bind def 33 | /srgb {setrgbcolor} bind def 34 | /rot {rotate} bind def 35 | /sc {scale} bind def 36 | /sd {setdash} bind def 37 | /ff {findfont} bind def 38 | /sf {setfont} bind def 39 | /scf {scalefont} bind def 40 | /sw {stringwidth} bind def 41 | /tr {translate} bind def 42 | /tnt {dup dup currentrgbcolor 43 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 44 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add 45 | 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} 46 | bind def 47 | /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 48 | 4 -2 roll mul srgb} bind def 49 | /DrawEllipse { 50 | /endangle exch def 51 | /startangle exch def 52 | /yrad exch def 53 | /xrad exch def 54 | /y exch def 55 | /x exch def 56 | /savematrix mtrx currentmatrix def 57 | x y tr xrad yrad sc 0 0 1 startangle endangle arc 58 | closepath 59 | savematrix setmatrix 60 | } def 61 | 62 | /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def 63 | /$F2psEnd {$F2psEnteredState restore end} def 64 | 65 | /pageheader { 66 | save 67 | newpath 0 147 moveto 0 0 lineto 223 0 lineto 223 147 lineto closepath clip newpath 68 | -71.3 327.8 translate 69 | 1 -1 scale 70 | $F2psBegin 71 | 10 setmiterlimit 72 | 0 slj 0 slc 73 | 0.06000 0.06000 sc 74 | } bind def 75 | /pagefooter { 76 | $F2psEnd 77 | restore 78 | } bind def 79 | %%EndProlog 80 | pageheader 81 | % 82 | % Fig objects follow 83 | % 84 | % 85 | % here starts figure with depth 50 86 | % Ellipse 87 | 7.500 slw 88 | n 1725 3075 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 89 | 90 | % Ellipse 91 | n 4275 5400 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr 92 | 93 | % Polyline 94 | 0 slj 95 | 0 slc 96 | [15 45] 45 sd 97 | n 1725 3150 m 98 | 1725 4800 l gs col0 s gr [] 0 sd 99 | % Polyline 100 | [15 45] 45 sd 101 | n 4275 4800 m 102 | 4275 5400 l gs col0 s gr [] 0 sd 103 | % Polyline 104 | n 1200 4800 m 105 | 4800 4800 l gs col0 s gr 106 | /Helvetica ff 233.33 scf sf 107 | 4425 5400 m 108 | gs 1 -1 sc (f\(x2\)) col0 sh gr 109 | /Helvetica ff 233.33 scf sf 110 | 1875 3225 m 111 | gs 1 -1 sc (f\(x1\)) col0 sh gr 112 | % here ends figure; 113 | pagefooter 114 | showpage 115 | %%Trailer 116 | %EOF 117 | -------------------------------------------------------------------------------- /book/figs/secant.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Inches 5 | Letter 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 1725 3075 38 38 1687 3075 1763 3075 11 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 4275 5400 38 38 4237 5400 4313 5400 12 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 13 | 1725 3150 1725 4800 14 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 15 | 4275 4800 4275 5400 16 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 17 | 1200 4800 4800 4800 18 | 4 0 0 50 0 16 14 0.0000 4 165 450 4425 5400 f(x2)\001 19 | 4 0 0 50 0 16 14 0.0000 4 165 450 1875 3225 f(x1)\001 20 | -------------------------------------------------------------------------------- /book/figs/secant.fig.bak: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Inches 5 | Letter 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 1725 3075 38 38 1687 3075 1763 3075 11 | 1 4 0 1 0 0 50 -1 20 0.000 1 0.0000 4275 5400 38 38 4237 5400 4313 5400 12 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 13 | 1725 3150 1725 4800 14 | 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 15 | 4275 4800 4275 5400 16 | 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 17 | 1200 4800 4800 4800 18 | 4 0 0 50 0 16 14 0.0000 4 165 450 1950 3150 f(x1)\001 19 | 4 0 0 50 0 16 14 0.0000 4 165 450 4425 5400 f(x2)\001 20 | -------------------------------------------------------------------------------- /book/figs/spiderman.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/spiderman.odg -------------------------------------------------------------------------------- /book/figs/spiderman.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/spiderman.pdf -------------------------------------------------------------------------------- /book/figs/spiderman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/figs/spiderman.png -------------------------------------------------------------------------------- /book/footer.html: -------------------------------------------------------------------------------- 1 | 2 |

3 |

Are you using one of our books in a class?

We'd like to know about it. Please consider filling out this short survey. 4 |


5 |

Think Bayes

6 |

7 |

Think Python 2e

8 |

9 |

Think Stats 2e

10 |

11 |

Think Complexity

12 |

13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /book/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

Buy this book at Amazon.com

6 |

This HTML version of the book is provided as a convenience, but some math equations are not translated correctly. The PDF version is more reliable.

7 | -------------------------------------------------------------------------------- /book/htmlonly.tex: -------------------------------------------------------------------------------- 1 | % put commands here that should be used for the HTML 2 | % version of the book but not Postscript or PDF 3 | 4 | \newcommand{\beforefig}{} 5 | \newcommand{\afterfig}{} 6 | 7 | \newcommand{\beforeverb}{\blue \large} 8 | \newcommand{\afterverb}{\black \normalsize} 9 | 10 | \newcommand{\adjustpage}[1]{} 11 | 12 | \newcommand{\clearemptydoublepage}{} 13 | \newcommand{\blankpage}{} 14 | 15 | \newcommand{\spacing}{} 16 | \newcommand{\endspacing}{} 17 | 18 | \newcommand{\frontmatter}{} 19 | \newcommand{\mainmatter}{} 20 | 21 | \newcommand{\theoremstyle}[1]{} 22 | \newcommand{\newtheoremstyle}[1]{} 23 | 24 | \newcommand{\vfill}{} 25 | 26 | \htmlhead{\rawhtmlinput{header.html}} 27 | 28 | \htmlfoot{\rawhtmlinput{footer.html}} -------------------------------------------------------------------------------- /book/images/figure01_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure01_01_new.eps -------------------------------------------------------------------------------- /book/images/figure01_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure01_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure04_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure04_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure04_01_new_v1.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure04_01_new_v1.eps -------------------------------------------------------------------------------- /book/images/figure09_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_01_new.eps -------------------------------------------------------------------------------- /book/images/figure09_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure09_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_02_new.eps -------------------------------------------------------------------------------- /book/images/figure09_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure09_03_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_03_new.eps -------------------------------------------------------------------------------- /book/images/figure09_03_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure09_03_new.pdf -------------------------------------------------------------------------------- /book/images/figure10_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure10_01_new.eps -------------------------------------------------------------------------------- /book/images/figure10_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure10_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure10_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure10_02_new.eps -------------------------------------------------------------------------------- /book/images/figure10_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure10_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure11_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure11_01_new.eps -------------------------------------------------------------------------------- /book/images/figure11_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure11_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure11_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure11_02_new.eps -------------------------------------------------------------------------------- /book/images/figure11_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure11_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure12_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_01_new.eps -------------------------------------------------------------------------------- /book/images/figure12_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure12_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_02_new.eps -------------------------------------------------------------------------------- /book/images/figure12_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure12_03_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_03_new.eps -------------------------------------------------------------------------------- /book/images/figure12_03_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_03_new.pdf -------------------------------------------------------------------------------- /book/images/figure12_04_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_04_new.eps -------------------------------------------------------------------------------- /book/images/figure12_04_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure12_04_new.pdf -------------------------------------------------------------------------------- /book/images/figure13_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure13_01_new.eps -------------------------------------------------------------------------------- /book/images/figure13_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure13_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure13_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure13_02_new.eps -------------------------------------------------------------------------------- /book/images/figure13_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure13_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure14_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure14_01_new.eps -------------------------------------------------------------------------------- /book/images/figure14_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure14_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure15_01_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_01_new.eps -------------------------------------------------------------------------------- /book/images/figure15_01_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_01_new.pdf -------------------------------------------------------------------------------- /book/images/figure15_02_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_02_new.eps -------------------------------------------------------------------------------- /book/images/figure15_02_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_02_new.pdf -------------------------------------------------------------------------------- /book/images/figure15_03_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_03_new.eps -------------------------------------------------------------------------------- /book/images/figure15_03_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_03_new.pdf -------------------------------------------------------------------------------- /book/images/figure15_04_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_04_new.eps -------------------------------------------------------------------------------- /book/images/figure15_04_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_04_new.pdf -------------------------------------------------------------------------------- /book/images/figure15_05_new.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_05_new.eps -------------------------------------------------------------------------------- /book/images/figure15_05_new.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/figure15_05_new.pdf -------------------------------------------------------------------------------- /book/images/matlab_circleart.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/images/matlab_circleart.eps -------------------------------------------------------------------------------- /book/latexonly.tex: -------------------------------------------------------------------------------- 1 | \sloppy 2 | %\setlength{\topmargin}{-0.375in} 3 | %\setlength{\oddsidemargin}{0.0in} 4 | %\setlength{\evensidemargin}{0.0in} 5 | 6 | % Uncomment these to center on 8.5 x 11 7 | %\setlength{\topmargin}{0.625in} 8 | %\setlength{\oddsidemargin}{0.875in} 9 | %\setlength{\evensidemargin}{0.875in} 10 | 11 | %\setlength{\textheight}{7.8in} 12 | 13 | \setlength{\headsep}{3ex} 14 | \setlength{\parindent}{0.0in} 15 | \setlength{\parskip}{1.7ex plus 0.5ex minus 0.5ex} 16 | \renewcommand{\baselinestretch}{1.02} 17 | 18 | % see LaTeX Companion page 62 19 | \setlength{\topsep}{-0.0\parskip} 20 | \setlength{\partopsep}{-0.5\parskip} 21 | \setlength{\itemindent}{0.0in} 22 | \setlength{\listparindent}{0.0in} 23 | 24 | % see LaTeX Companion page 26 25 | % these are copied from /usr/local/teTeX/share/texmf/tex/latex/base/book.cls 26 | % all I changed is afterskip 27 | 28 | \makeatletter 29 | 30 | \renewcommand{\section}{\@startsection 31 | {section} {1} {0mm}% 32 | {-3.5ex \@plus -1ex \@minus -.2ex}% 33 | {0.7ex \@plus.2ex}% 34 | {\normalfont\Large\bfseries}} 35 | \renewcommand\subsection{\@startsection {subsection}{2}{0mm}% 36 | {-3.25ex\@plus -1ex \@minus -.2ex}% 37 | {0.3ex \@plus .2ex}% 38 | {\normalfont\large\bfseries}} 39 | \renewcommand\subsubsection{\@startsection {subsubsection}{3}{0mm}% 40 | {-3.25ex\@plus -1ex \@minus -.2ex}% 41 | {0.3ex \@plus .2ex}% 42 | {\normalfont\normalsize\bfseries}} 43 | 44 | % The following line adds a little extra space to the column 45 | % in which the Section numbers appear in the table of contents 46 | \renewcommand{\l@section}{\@dottedtocline{1}{1.5em}{3.0em}} 47 | \setcounter{tocdepth}{1} 48 | 49 | \makeatother 50 | 51 | \newcommand{\beforefig}{\vspace{1.3\parskip}} 52 | \newcommand{\afterfig}{\vspace{-0.2\parskip}} 53 | 54 | \newcommand{\beforeverb}{\vspace{0.6\parskip}} 55 | \newcommand{\afterverb}{\vspace{0.6\parskip}} 56 | 57 | \newcommand{\adjustpage}[1]{\enlargethispage{#1\baselineskip}} 58 | 59 | 60 | % Note: the following command seems to cause problems for Acroreader 61 | % on Windows, so for now I am overriding it. 62 | %\newcommand{\clearemptydoublepage}{ 63 | % \newpage{\pagestyle{empty}\cleardoublepage}} 64 | \newcommand{\clearemptydoublepage}{\cleardoublepage} 65 | 66 | %\newcommand{\blankpage}{\pagestyle{empty}\vspace*{1in}\newpage} 67 | \newcommand{\blankpage}{\vspace*{1in}\newpage} 68 | 69 | % HEADERS 70 | 71 | \renewcommand{\chaptermark}[1]{\markboth{#1}{}} 72 | \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}{}} 73 | 74 | \lhead[\fancyplain{}{\bfseries\thepage}]% 75 | {\fancyplain{}{\bfseries\rightmark}} 76 | \rhead[\fancyplain{}{\bfseries\leftmark}]% 77 | {\fancyplain{}{\bfseries\thepage}} 78 | \cfoot{} 79 | 80 | \pagestyle{fancyplain} 81 | 82 | 83 | % turn off the rule under the header 84 | %\setlength{\headrulewidth}{0pt} 85 | 86 | % the following is a brute-force way to prevent the headers 87 | % from getting transformed into all-caps 88 | \renewcommand\MakeUppercase{} 89 | 90 | % Exercise environment 91 | \newtheoremstyle{myex}% name 92 | {9pt}% Space above 93 | {9pt}% Space below 94 | {}% Body font 95 | {}% Indent amount (empty = no indent, \parindent = para indent) 96 | {\bfseries}% Thm head font 97 | {}% Punctuation after thm head 98 | {0.5em}% Space after thm head: " " = normal interword space; 99 | % \newline = linebreak 100 | {}% Thm head spec (can be left empty, meaning `normal') 101 | 102 | \theoremstyle{myex} 103 | -------------------------------------------------------------------------------- /book/links/gen_htaccess.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import re 3 | 4 | with open('urls.csv') as csvfile: 5 | reader = csv.reader(csvfile) 6 | for i, row in enumerate(reader): 7 | slashtag, destination = row 8 | short_url = '/matlab/' + slashtag 9 | 10 | print('Redirect', short_url, destination) 11 | -------------------------------------------------------------------------------- /book/links/get_links.py: -------------------------------------------------------------------------------- 1 | from re import findall 2 | from glob import glob 3 | 4 | urls = set() 5 | 6 | for filename in glob('../*.tex'): 7 | for line in open(filename): 8 | matches = findall(r'\\url\{([^\}]*)', line) 9 | for match in matches: 10 | #print match 11 | urls.add(match) 12 | 13 | for url in sorted(urls): 14 | print('

%s' % (url, url)) 15 | -------------------------------------------------------------------------------- /book/links/get_urls.py: -------------------------------------------------------------------------------- 1 | from re import findall 2 | from glob import glob 3 | 4 | urls = set() 5 | 6 | for filename in glob('../*.tex'): 7 | for line in open(filename): 8 | matches = findall(r'\\url\{([^\}]*)', line) 9 | for match in matches: 10 | #print match 11 | urls.add(match) 12 | 13 | for url in sorted(urls): 14 | print(",%s" % url) 15 | -------------------------------------------------------------------------------- /book/links/notes.txt: -------------------------------------------------------------------------------- 1 | 0) Replace http: with https:, and make sure all URLs are fully qualified. 2 | 3 | 1) Get the links in an HTML document for checking 4 | 5 | python get_links.py > links.html; firefox links.html & 6 | 7 | 2) Get the links into a CSV file and give them nicknames 8 | 9 | python get_urls.py > urls.csv; localc urls.csv & 10 | 11 | 3) Replace the long URLs with the short ones: 12 | 13 | python set_urls.py > book.tex 14 | meld ../book.tex book.tex 15 | 16 | 4) Generate the htaccess lines 17 | 18 | python gen_htaccess.py > htaccess 19 | 20 | 5) cp htaccess into public_html 21 | 22 | cp htaccess ~/public_html/greent/matlab/.htaccess 23 | cd ~/public_html/greent; sh back 24 | cd ~/PhysicalModelingInMatlab/links 25 | 26 | 6) Commit the latest version of book.tex, then replace it 27 | 28 | python set_urls.py 29 | mv *.tex .. 30 | 31 | 7) Get the URLs again and test them 32 | 33 | python get_links.py > links.html; firefox links.html & 34 | -------------------------------------------------------------------------------- /book/links/set_urls.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import re 3 | from glob import glob 4 | 5 | 6 | link_map = {} 7 | with open('urls.csv') as csvfile: 8 | reader = csv.reader(csvfile) 9 | for i, row in enumerate(reader): 10 | slashtag, destination = row 11 | link_map[destination] = 'https://greenteapress.com/matlab/' + slashtag 12 | 13 | for filename in glob('../*.tex'): 14 | outname = filename.split('/')[-1] 15 | fout = open(outname, 'w') 16 | 17 | for line in open(filename): 18 | 19 | 20 | matches = re.findall(r'\\url\{([^\}]*)', line) 21 | if matches: 22 | for url in matches: 23 | key = url.replace('\\#', '#') 24 | try: 25 | short = link_map[key] 26 | line = line.replace(url, short) 27 | except KeyError: 28 | pass 29 | #print url 30 | fout.write(line) 31 | fout.close() 32 | -------------------------------------------------------------------------------- /book/links/urls.csv: -------------------------------------------------------------------------------- 1 | license,http://creativecommons.org/licenses/by-nc/4.0/ 2 | book,http://greenteapress.com/matlab 3 | brent,https://en.wikipedia.org/wiki/Brents_method 4 | fixed,https://en.wikipedia.org/wiki/Fixed-point_iteration 5 | golden,https://en.wikipedia.org/wiki/Golden-section_search#Probe_point_selection 6 | gravity,https://en.wikipedia.org/wiki/Gravity 7 | cannon,https://en.wikipedia.org/wiki/Human_cannonball 8 | logistic,https://en.wikipedia.org/wiki/Logistic_map 9 | lorenz,https://en.wikipedia.org/wiki/Lorenz_system 10 | lotka,https://en.wikipedia.org/wiki/Lotka-Volterra_equations 11 | magnus,https://en.wikipedia.org/wiki/Magnus_effect 12 | nelder,https://en.wikipedia.org/wiki/Nelder-Mead_method 13 | newton,https://en.wikipedia.org/wiki/Newton's_law_of_cooling 14 | right,https://en.wikipedia.org/wiki/Right-hand_rule 15 | runge,https://en.wikipedia.org/wiki/Runge-Kutta_methods 16 | triangle,https://en.wikipedia.org/wiki/Triangle_inequality 17 | zip,https://github.com/AllenDowney/PhysicalModelingInMatlab/archive/master.zip 18 | drag,https://github.com/AllenDowney/PhysicalModelingInMatlab/blob/master/code/data/baseball_drag.png 19 | bungee,https://iopscience.iop.org/article/10.1088/0031-9120/45/1/007 20 | spider,https://spiderman.fandom.com/wiki/Peter_Parker_(Earth-616) 21 | astro,https://web.archive.org/web/20180617133223/http://curious.astro.cornell.edu/about-us/39-our-solar-system/the-earth/other-catastrophes/57-how-long-would-it-take-the-earth-to-fall-into-the-sun-intermediate 22 | anaconda,https://www.anaconda.com/products/individual#Downloads 23 | octave,https://www.gnu.org/software/octave/ 24 | matlab,https://www.mathworks.com/downloads/web_downloads/ 25 | solver,https://www.mathworks.com/help/matlab/math/choose-an-ode-solver.html 26 | nested,https://www.mathworks.com/help/matlab/matlab_prog/nested-functions.html 27 | dunk,https://www.youtube.com/watch?v=UBf7WC19lpw 28 | chain,https://www.youtube.com/watch?v=X-QFAB0gEtE 29 | -------------------------------------------------------------------------------- /book/main.tex: -------------------------------------------------------------------------------- 1 | % LaTeX source for textbook ``Physical Modeling in MATLAB'' 2 | % Copyright 2012, 2019, 2021 Allen B. Downey 3 | 4 | \documentclass{book} 5 | 6 | \newcommand{\thetitle}{Physical Modeling in MATLAB} 7 | \newcommand{\theauthors}{Allen B. Downey} 8 | \newcommand{\theversion}{4.0} 9 | 10 | \title{\thetitle} 11 | \author{\theauthors} 12 | \date{Version \theversion} 13 | 14 | \input{settings} 15 | 16 | \makeindex 17 | 18 | %\makeatletter 19 | %\def\idxdelim{\@ifnextchar{\hyperindexformat}{. }{, }} 20 | %\makeatother 21 | 22 | \begin{document} 23 | \sloppy 24 | 25 | \frontmatter 26 | 27 | \input{titlepages} 28 | 29 | \setcounter{tocdepth}{1} 30 | \clearpage 31 | \tableofcontents 32 | \clearpage 33 | 34 | \input{chap00} 35 | 36 | \mainmatter 37 | 38 | 39 | \input{chap01} 40 | 41 | \input{chap02} 42 | 43 | \input{chap03} 44 | 45 | \input{chap04} 46 | 47 | \input{chap05} 48 | 49 | \input{chap06} 50 | 51 | \input{chap07} 52 | 53 | \input{chap08} 54 | 55 | \input{chap09} 56 | 57 | \input{chap10} 58 | 59 | \input{chap11} 60 | 61 | \input{chap12} 62 | 63 | \input{chap13} 64 | 65 | \input{chap14} 66 | 67 | \input{chap15} 68 | 69 | \appendix 70 | 71 | \input{glossary} 72 | 73 | \printindex 74 | 75 | \end{document} 76 | -------------------------------------------------------------------------------- /book/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/next.png -------------------------------------------------------------------------------- /book/settings.tex: -------------------------------------------------------------------------------- 1 | \usepackage[T1]{fontenc} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage{textcomp} % provide euro and other symbols 4 | \usepackage[table]{xcolor} 5 | 6 | \usepackage{roboto} 7 | 8 | \usepackage{setspace} 9 | \usepackage{graphicx} 10 | \usepackage{makeidx} 11 | \usepackage{upquote} 12 | 13 | \usepackage{enumitem} 14 | \usepackage{textcomp} 15 | 16 | % format the table of contents 17 | \usepackage{tocloft} 18 | 19 | % exercise environment 20 | %\usepackage{exercise} 21 | %\renewcommand{\ExerciseHeader}{\textbf{ 22 | %\ExerciseName~\ExerciseHeaderNB\ExerciseHeaderTitle 23 | %\ExerciseHeaderOrigin\newline}} 24 | %\newenvironment{ex}{\begin{Exercise}}{\end{Exercise}} 25 | 26 | % use amsthm to typeset exercises 27 | \usepackage{amsmath,amsthm,amssymb} 28 | \theoremstyle{definition} 29 | \newtheorem{ex}{Exercise}[chapter] 30 | 31 | % set the page size 32 | \usepackage[twoside,centering]{geometry} 33 | 34 | % crown quarto 35 | \geometry{ 36 | %showframe=true, 37 | %showcrop=true, 38 | % total document size 39 | papersize={195mm,252mm}, 40 | % book trim size 41 | layoutsize={189mm,246mm}, 42 | layoutoffset={3mm,3mm}, 43 | % live area = 164mm x 220mm 44 | % subtract from width for the binding offset 45 | % subtract from both to improve the look 46 | total={144mm,200mm}, 47 | bindingoffset=10mm, 48 | includeheadfoot=true, 49 | centering=true, 50 | nofoot=true, 51 | } 52 | 53 | % paragraph spacing 54 | \setlength{\parindent}{0pt} 55 | \setlength{\parskip}{12pt plus 4pt minus 4pt} 56 | \linespread{1.05} 57 | \def\arraystretch{1.5} 58 | 59 | % list spacing 60 | %\setlength{\topsep}{5pt plus 2pt minus 3pt} % 10.0pt plus 4.0pt minus 6.0pt 61 | %\setlength{\partopsep}{-6pt plus 2pt minus 2pt} % 3.0pt plus 2.0pt minus 2.0pt 62 | %\setlength{\itemsep}{0pt} % 5.0pt plus 2.5pt minus 1.0pt 63 | 64 | % define colors 65 | \usepackage{xcolor} 66 | \definecolor{bgcolor}{HTML}{F0F0F0} 67 | \definecolor{comment}{HTML}{007C00} 68 | \definecolor{keyword}{HTML}{0000FF} 69 | \definecolor{string}{HTML}{B20000} 70 | \definecolor{urlcolor}{HTML}{0000FF} 71 | 72 | \definecolor{codeblue}{RGB}{31, 119, 180} 73 | \definecolor{commentblue}{RGB}{31, 119, 180} 74 | \definecolor{codegreen}{RGB}{78,121,53} 75 | \definecolor{codered}{RGB}{214, 39, 40} 76 | \definecolor{codepurple}{RGB}{148, 103, 189} 77 | \definecolor{codegray}{rgb}{0.5,0.5,0.5} 78 | \definecolor{rulecolor}{gray}{0.7} 79 | \definecolor{lightgray}{gray}{0.9} 80 | \definecolor{lightergray}{gray}{0.95} 81 | \usepackage{listings} 82 | 83 | \lstset{ 84 | language=matlab, 85 | basicstyle=\ttfamily, 86 | backgroundcolor=\color{bgcolor}, 87 | commentstyle=\color{codegreen}, 88 | keywordstyle=\color{codeblue}, 89 | stringstyle=\color{codepurple}, 90 | columns=fullflexible, 91 | emph={label}, % keyword? 92 | keepspaces=true, 93 | showstringspaces=false, 94 | upquote=true, 95 | xleftmargin=0pt, % \parindent 96 | framexleftmargin=3pt, 97 | aboveskip=\parskip, 98 | belowskip=\parskip 99 | } 100 | 101 | \lstnewenvironment{code}{}{} 102 | \lstnewenvironment{stdout}{\lstset{commentstyle=,keywordstyle=,stringstyle=}}{} 103 | 104 | % inline syntax formatting 105 | \newcommand{\mcode}[1]{\lstinline{#1}}%{ 106 | 107 | % customize page headers 108 | \usepackage{fancyhdr} 109 | \pagestyle{fancyplain} 110 | \renewcommand{\chaptermark}[1]{\markboth{#1}{}} 111 | \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}{}} 112 | \lhead[\fancyplain{}{\bfseries\thepage}]% 113 | {\fancyplain{}{\bfseries\rightmark}} 114 | \rhead[\fancyplain{}{\bfseries\leftmark}]% 115 | {\fancyplain{}{\bfseries\thepage}} 116 | \cfoot{} 117 | \cfoot{} 118 | %\renewcommand{\headrulewidth}{0pt} 119 | %\rfoot{\textcolor{gray}{\tiny Draft \today}} 120 | 121 | % pdf hyperlinks, table of contents, and document properties 122 | \usepackage{hyperref} 123 | \hypersetup{% 124 | pdftitle={\thetitle}, 125 | pdfauthor={\theauthors}, 126 | pdfsubject={Version \theversion}, 127 | pdfkeywords={}, 128 | bookmarksopen=false, 129 | colorlinks=true, 130 | citecolor=black, 131 | filecolor=black, 132 | linkcolor=black, 133 | urlcolor=codepurple 134 | } 135 | 136 | % to get siunitx 137 | % sudo apt-get install texlive-science 138 | \usepackage{siunitx} 139 | \sisetup{per-mode=symbol} 140 | 141 | \newcommand{\myreg}{\textsuperscript{{\tiny \textregistered}}} 142 | 143 | \newcommand{\console}[1]{>{}> \textbf{#1}} 144 | \newcommand{\keycap}{\textsf} 145 | 146 | % typesetting vectors 147 | % from https://tex.stackexchange.com/questions/188775/how-to-type-a-particular-kind-of-unit-vector 148 | \usepackage{bm} 149 | \renewcommand{\vec}[1]{\bm{\mathbf{#1}}} 150 | \newcommand{\uveci}{{\bm{\hat{\textnormal{\bfseries\i}}}}} 151 | \newcommand{\uvecj}{{\bm{\hat{\textnormal{\bfseries\j}}}}} 152 | \DeclareRobustCommand{\uvec}[1]{{% 153 | \ifcsname uvec#1\endcsname 154 | \csname uvec#1\endcsname 155 | \else 156 | \bm{\hat{\mathbf{#1}}}% 157 | \fi 158 | }} 159 | -------------------------------------------------------------------------------- /book/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/book/up.png -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | rm -rf PhysicalModelingInMatlab 2 | mkdir PhysicalModelingInMatlab 3 | cp LICENSE README.md PhysicalModelingInMatlab 4 | 5 | CODE="chap02/myscript.m \ 6 | chap02/fibonacci1.m \ 7 | chap03/bike_loop.m \ 8 | chap03/sequence.m \ 9 | chap03/series.m \ 10 | chap03/fibonacci2.m \ 11 | chap04/fibonacci4.m \ 12 | chap04/lorenz.m \ 13 | chap04/logmap.m \ 14 | chap05/myfunc.m \ 15 | chap06/find_triples.m \ 16 | chap07/cheby6.m \ 17 | chap08/exists.m \ 18 | chap09/euler.m \ 19 | chap09/rats.m \ 20 | chap10/lotka.m \ 21 | chap10/lorenz.m \ 22 | chap11/skydiver.m \ 23 | chap12/baseball.m \ 24 | chap13/baseball3.m \ 25 | chap14/binary.m \ 26 | chap15/odeplot.m" 27 | 28 | cd code 29 | rsync -aR ${CODE} ../PhysicalModelingInMatlab 30 | 31 | cd .. 32 | zip -r PhysicalModelingInMatlab.zip PhysicalModelingInMatlab 33 | -------------------------------------------------------------------------------- /code/chap02/bike_update.m: -------------------------------------------------------------------------------- 1 | % Update the state of the bike system. 2 | % Preconditon: b and c contains the number of bikes. 3 | % Postconditon: values of b and c are updated. 4 | 5 | b_to_c = round(0.05*b) - round(0.03*c); 6 | b = b - b_to_c 7 | c = c + b_to_c 8 | -------------------------------------------------------------------------------- /code/chap02/fibonacci1.m: -------------------------------------------------------------------------------- 1 | % Compute a numerical approximation of the nth Fibonacci number. 2 | % Precondition: you must assign a value to `n` before running 3 | % this script. 4 | % Postcondition: the result is stored in `ans`. 5 | 6 | s5 = sqrt(5); 7 | t1 = (1 + s5) / 2; 8 | t2 = (1 - s5) / 2; 9 | diff = t1^n - t2^n; 10 | ans = diff / s5 11 | -------------------------------------------------------------------------------- /code/chap02/myscript.m: -------------------------------------------------------------------------------- 1 | x=5 -------------------------------------------------------------------------------- /code/chap02/swap.m: -------------------------------------------------------------------------------- 1 | % Swap the values in x and y 2 | 3 | t = x; 4 | x = y; 5 | y = t; 6 | -------------------------------------------------------------------------------- /code/chap03/bike_loop.m: -------------------------------------------------------------------------------- 1 | % Simulates the bike share system for one month 2 | 3 | b = 100 4 | c = 100 5 | 6 | for i=1:30 7 | bike_update 8 | end 9 | -------------------------------------------------------------------------------- /code/chap03/bike_update.m: -------------------------------------------------------------------------------- 1 | % Update the state of the bike system. 2 | % Preconditon: `b` and `c` contains the number of bikes. 3 | % Postconditon: values of `b` and `c` are updated. 4 | 5 | b_to_c = round(0.05*b) - round(0.03*c); 6 | b = b - b_to_c 7 | c = c + b_to_c 8 | -------------------------------------------------------------------------------- /code/chap03/fibonacci2.m: -------------------------------------------------------------------------------- 1 | % Computes the nth Fibonacci number. 2 | % Precondition: `n` must be a positive integer. 3 | % Postcondition: the result is stored in `ans`. 4 | 5 | prev1 = 1; 6 | prev2 = 1; 7 | f = 1; 8 | 9 | for i=3:n 10 | f = prev1 + prev2; 11 | prev2 = prev1; 12 | prev1 = f; 13 | end 14 | ans = f 15 | -------------------------------------------------------------------------------- /code/chap03/fibonacci3.m: -------------------------------------------------------------------------------- 1 | % Plot the first `n` elements of a Fibonacci sequence 2 | % Precondition: `n` is a positive integer. 3 | % Postcondition: the result is stored in `ans`. 4 | 5 | F(1) = 1 6 | F(2) = 1 7 | for i=3:n 8 | F(i) = F(i-1) + F(i-2) 9 | end 10 | ans = F(n) 11 | 12 | plot(F) 13 | -------------------------------------------------------------------------------- /code/chap03/fudge.m: -------------------------------------------------------------------------------- 1 | % Compute the sum of `n` elements of a geometric sequence 2 | 3 | a = 1; 4 | total = a; 5 | r = 1/4; 6 | 7 | for i=2:n 8 | a = a * r; 9 | total = total + a; 10 | end 11 | ans = total 12 | -------------------------------------------------------------------------------- /code/chap03/old/bike_loop2.m: -------------------------------------------------------------------------------- 1 | % Simulates the bike share system for one month 2 | 3 | b = 100 4 | c = 100 5 | 6 | clf 7 | hold on 8 | for i=1:30 9 | plot(i, b, 'ro') 10 | plot(i, c, 'bd') 11 | bike_update 12 | end 13 | hold off -------------------------------------------------------------------------------- /code/chap03/old/car.m: -------------------------------------------------------------------------------- 1 | a = 200; 2 | b = 100; 3 | 4 | for i=1:10 5 | froma = round(0.03 * a); 6 | fromb = round(0.05 * b); 7 | a = a - froma + fromb; 8 | b = b - fromb + froma; 9 | fprintf('%f\t%f\n', a, b) 10 | end 11 | -------------------------------------------------------------------------------- /code/chap03/old/car_loop.m: -------------------------------------------------------------------------------- 1 | a = 150 2 | b = 150 3 | 4 | for i=1:52 5 | car_update 6 | end -------------------------------------------------------------------------------- /code/chap03/old/car_loop2.m: -------------------------------------------------------------------------------- 1 | a = 150 2 | b = 150 3 | clf 4 | hold on 5 | 6 | for i=1:52 7 | car_update 8 | plot(i, a, 'ro') 9 | plot(i, b, 'bd') 10 | end -------------------------------------------------------------------------------- /code/chap03/old/car_update.m: -------------------------------------------------------------------------------- 1 | atob = round(0.05*a) - round(0.03*b); 2 | a = a - atob 3 | b = b + atob 4 | -------------------------------------------------------------------------------- /code/chap03/old/fib.m: -------------------------------------------------------------------------------- 1 | f(1) = 1 2 | f(2) = 1 3 | 4 | for i=3:n 5 | f(i) = f(i-1) + f(i-2) 6 | end 7 | -------------------------------------------------------------------------------- /code/chap03/old/fib1.m: -------------------------------------------------------------------------------- 1 | s5 = sqrt(5); 2 | t1 = (1 + s5) / 2; 3 | t2 = (1 - s5) / 2; 4 | diff = t1^(n+1) - t2^(n+1); 5 | ans = diff / s5; 6 | -------------------------------------------------------------------------------- /code/chap03/old/fib_loop.m: -------------------------------------------------------------------------------- 1 | % Plot the first 10 elements of a Fibonacci sequence 2 | 3 | clf 4 | hold on 5 | 6 | for n=1:10 7 | fibonacci2 8 | plot(n, ans, 'ro') 9 | end 10 | hold off -------------------------------------------------------------------------------- /code/chap03/old/rel_error.m: -------------------------------------------------------------------------------- 1 | % compute the relative error of the estimated value of Fn; 2 | % precondition: n is in the workspace 3 | % postcondition: the answer is stored in ans 4 | fibonacci1; 5 | estimate = ans; 6 | fibonacci2; 7 | exact = ans; 8 | ans = (estimate - exact) / exact; 9 | -------------------------------------------------------------------------------- /code/chap03/old/update.m: -------------------------------------------------------------------------------- 1 | 2 | for i=1:10 3 | froma = round(0.03 * a); 4 | fromb = round(0.05 * b); 5 | a = a - froma + fromb; 6 | b = b - fromb + froma; 7 | fprintf('%f\t%f\n', a, b) 8 | end 9 | -------------------------------------------------------------------------------- /code/chap03/old/update1.m: -------------------------------------------------------------------------------- 1 | clf 2 | hold on 3 | 4 | a = 300 5 | b = 100 6 | 7 | for i=1:100 8 | froma = round(0.03 * a); 9 | fromb = round(0.05 * b); 10 | a = a - froma + fromb; 11 | b = b - fromb + froma; 12 | % fprintf('%f\t%f\n', a, b) 13 | plot(i, a, 'bx') 14 | plot(i, b, 'ro') 15 | end 16 | 17 | -------------------------------------------------------------------------------- /code/chap03/old/update2.m: -------------------------------------------------------------------------------- 1 | n = 35; 2 | A(1) = 150; 3 | B(1) = 150; 4 | 5 | for i=1:n-1 6 | fromA = round(0.03 * A(i)); 7 | fromB = round(0.05 * B(i)); 8 | A(i+1) = A(i) - fromA + fromB; 9 | B(i+1) = B(i) - fromB + fromA; 10 | end 11 | 12 | hold on 13 | plot(A, 'ro-') 14 | plot(B, 'bx-') 15 | -------------------------------------------------------------------------------- /code/chap03/sequence.m: -------------------------------------------------------------------------------- 1 | % Compute the first 10 elements of a geometric sequence 2 | 3 | for i=1:10 4 | a = 1*(1/2)^(i-1) 5 | end 6 | -------------------------------------------------------------------------------- /code/chap03/series.m: -------------------------------------------------------------------------------- 1 | % Compute the sum of `n` elements of a geometric sequence 2 | 3 | a = 1; 4 | total = a; 5 | 6 | for i=2:n 7 | a = a/2; 8 | total = total + a; 9 | end 10 | ans = total -------------------------------------------------------------------------------- /code/chap04/fibonacci4.m: -------------------------------------------------------------------------------- 1 | % Plot the first `n` elements of the Fibonacci series 2 | % Precondition: `n` is a positive integer. 3 | 4 | F(1) = 1 5 | F(2) = 1 6 | for i=3:n 7 | F(i) = F(i-1) + F(i-2) 8 | end 9 | 10 | plot(F) 11 | xlabel('Index') 12 | ylabel('Fibonacci number') 13 | saveas(gcf, '../../book/figs/fibonacci.eps', 'epsc') 14 | -------------------------------------------------------------------------------- /code/chap04/fibonacci_ratio.m: -------------------------------------------------------------------------------- 1 | % Plot the ratios of successive elements of a Fibonacci sequence 2 | % Precondition: `n` is a positive integer. 3 | 4 | F(1) = 1 5 | F(2) = 1 6 | for i=3:n 7 | F(i) = F(i-1) + F(i-2) 8 | end 9 | 10 | for i=1:n-1 11 | D(i) = F(i+1) / F(i) 12 | end 13 | 14 | plot(D) 15 | -------------------------------------------------------------------------------- /code/chap04/logchaos.m: -------------------------------------------------------------------------------- 1 | function logchaos 2 | clf 3 | hold on 4 | 5 | % each time through the loop we try a different value of r 6 | for r=2.4:0.01:4.0 7 | 8 | % compute the first 50 values of the sequence 9 | V = logmap(r, 0.5, 50); 10 | 11 | % trim off the first 10 values 12 | V = trim(V, 10); 13 | 14 | % make another vector the same length, all equal to r 15 | R = make_vector(r, length(V)); 16 | 17 | % plot a column of points showing all the values in V 18 | plot(R, V, 'b.') 19 | end 20 | end 21 | 22 | 23 | function M = logmap(r, x1, n) 24 | % use the logistic map function to compute the 25 | % first (n) values of the sequence, starting wih 26 | % (x1) and using parameter (r) 27 | X(1) = x1; 28 | 29 | for i=1:n-1 30 | X(i+1) = r * X(i) * (1 - X(i)); 31 | end 32 | 33 | M = X; 34 | end 35 | 36 | function W = trim(V, skip) 37 | % make a new vector that has all but the first (skip) 38 | % elements from (V) 39 | n = length(V); 40 | for i=1:n-skip 41 | W(i) = V(i+skip); 42 | end 43 | end 44 | 45 | function V = make_vector(value, len) 46 | % make a new vector with (len) elements all equal to (value) 47 | for i=1:len 48 | V(i) = value; 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /code/chap04/logmap.m: -------------------------------------------------------------------------------- 1 | % Compute the first 20 elements of the logistic map 2 | 3 | clear X 4 | X(1) = 0.5; 5 | 6 | for i=1:19 7 | X(i+1) = r * X(i) * (1 - X(i)); 8 | end 9 | 10 | plot(X) -------------------------------------------------------------------------------- /code/chap04/lorenz.m: -------------------------------------------------------------------------------- 1 | clear all 2 | X(1) = 1; 3 | Y(1) = 2; 4 | Z(1) = 3; 5 | 6 | sigma = 10; 7 | b = 8/3; 8 | r = 28; 9 | dt = 0.01; 10 | 11 | for i = 1:10000 12 | X(i+1) = X(i) + sigma * (Y(i) - X(i)) * dt; 13 | Y(i+1) = Y(i) + (X(i) * (r - Z(i)) - Y(i)) * dt; 14 | Z(i+1) = Z(i) + (X(i) * Y(i) - b * Z(i)) * dt; 15 | end 16 | 17 | comet3(X, Y, Z) -------------------------------------------------------------------------------- /code/chap05/hypotenuse.m: -------------------------------------------------------------------------------- 1 | % Compute the hypoteneuse of a right triangle. 2 | 3 | function res = hypotenuse(a, b) 4 | res = sqrt(a^2 + b^2); 5 | end 6 | -------------------------------------------------------------------------------- /code/chap05/junk/istriple.m: -------------------------------------------------------------------------------- 1 | function res = istriple (a, b, c) 2 | if hypotenuse(a, b) == c 3 | res = 1; 4 | else 5 | res = 0; 6 | end 7 | end 8 | 9 | 10 | -------------------------------------------------------------------------------- /code/chap05/myfunc.m: -------------------------------------------------------------------------------- 1 | % Compute the Manhattan distance from the origin to the 2 | % point on the unit circle with angle (x) in radians. 3 | 4 | function res = myfunc(x) 5 | s = sin(x); 6 | c = cos(x); 7 | res = abs(s) + abs(c); 8 | end 9 | -------------------------------------------------------------------------------- /code/chap05/sumDir/sum.m: -------------------------------------------------------------------------------- 1 | function res = sum(x) 2 | res = 7; 3 | end -------------------------------------------------------------------------------- /code/chap06/fib_triple.m: -------------------------------------------------------------------------------- 1 | % Find Pythagorean triples using the first `n` Fibonacci numbers. 2 | 3 | function res = fib_triple (n) 4 | F(1) = 1; 5 | F(2) = 1; 6 | for i = 3:n 7 | F(i) = F(i-1) + F(i-2); 8 | end 9 | 10 | for i = 1:n-3 11 | a = F(i) * F(i+3); 12 | b = 2 * F(i+1) * F(i+2); 13 | c = F(i+1)^2 + F(i+2)^2; 14 | if hypotenuse(a, b) ~= c 15 | [a b c] 16 | end 17 | end 18 | end -------------------------------------------------------------------------------- /code/chap06/find_triples.m: -------------------------------------------------------------------------------- 1 | % Find Pythagorean triples up to `n`. 2 | 3 | function res = find_triples (n) 4 | for a=1:n-1 5 | for b=a:n 6 | if gcd(a,b) > 1 7 | continue 8 | end 9 | c = hypotenuse(a, b); 10 | if a^2 + b^2 == c^2 11 | [a, b, c] 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /code/chap07/cheby6.m: -------------------------------------------------------------------------------- 1 | % Evaluate the 6th order Chebyshev polynomial. 2 | 3 | function res = cheby6(x) 4 | res = 32 .* x.^6 - 48 .* x.^4 + 18 .* x.^2 - 1; 5 | end 6 | -------------------------------------------------------------------------------- /code/chap07/duck.m: -------------------------------------------------------------------------------- 1 | function res = duck() 2 | error = error_func(2) 3 | ezplot(@error_func, [0, 20]) 4 | res = fzero(@error_func, 2); 5 | end 6 | 7 | function res = error_func(d) 8 | rho = 0.3; % density in g / cm^3 9 | r = 10; % radius in cm 10 | mass_duck = 4/3 * pi * r.^2 * rho;; 11 | mass_water = pi / 3 * (3*r*d.^2 - d.^3); 12 | res = mass_water - mass_duck; 13 | end -------------------------------------------------------------------------------- /code/chap07/error_func.m: -------------------------------------------------------------------------------- 1 | function res = error_func(x) 2 | res = x.^2 - 2.*x -3; 3 | end 4 | -------------------------------------------------------------------------------- /code/chap07/plot_cheby6.m: -------------------------------------------------------------------------------- 1 | % Plot the 6th order Chebyshev polynomial. 2 | 3 | function plot_cheby6(low, high) 4 | X = linspace(low, high, 100); 5 | for i=1:length(X) 6 | Y(i) = cheby6(X(i)); 7 | end 8 | plot(X, Y) 9 | end 10 | -------------------------------------------------------------------------------- /code/chap08/duck.m: -------------------------------------------------------------------------------- 1 | % Starting code for the duck problem. 2 | 3 | function res = duck() 4 | error = error_func(10) 5 | end 6 | 7 | function res = error_func(h) 8 | rho = 0.3; % density in g / cm^3 9 | r = 10; % radius in cm 10 | res = h; 11 | end 12 | -------------------------------------------------------------------------------- /code/chap08/exists.m: -------------------------------------------------------------------------------- 1 | % Check whether any elements of an array are positive. 2 | 3 | function res = exists(X) 4 | for i=1:length(X) 5 | if X(i) > 0 6 | res = 1; 7 | return 8 | end 9 | end 10 | res = 0; 11 | end 12 | -------------------------------------------------------------------------------- /code/chap08/exists2.m: -------------------------------------------------------------------------------- 1 | % Use find to check where any elements of an array are positive. 2 | 3 | function res = exists(X) 4 | L = find(X>0) 5 | res = length(L) > 0 6 | end 7 | -------------------------------------------------------------------------------- /code/chap08/mysum.m: -------------------------------------------------------------------------------- 1 | % Add up the elements of a vector. 2 | 3 | function res = mysum(X) 4 | total = 0; 5 | for i=1:length(X) 6 | total = total + X(i); 7 | end 8 | res = total; 9 | end 10 | 11 | -------------------------------------------------------------------------------- /code/chap09/coffee.m: -------------------------------------------------------------------------------- 1 | % Use ode45 to predict coffee temperature. 2 | 3 | function res = coffee() 4 | t = 0; 5 | y0 = 90; 6 | r = rate_func(t, y0); 7 | 8 | [T, Y] = ode45(@rate_func, [0, 60], y0); 9 | plot(T, Y) 10 | xlabel('Time (minutes)') 11 | ylabel('Temperature (C)') 12 | saveas(gcf, '../../book/figs/coffee.eps', 'epsc') 13 | 14 | Y(end) 15 | end 16 | 17 | function res = rate_func(t, y) 18 | k = 0.01; 19 | e = 20; 20 | res = -k * (y - e); 21 | end 22 | -------------------------------------------------------------------------------- /code/chap09/euler.m: -------------------------------------------------------------------------------- 1 | % Make a plot showing results from euler. 2 | 3 | function res = euler() 4 | T(1) = 0; 5 | Y(1) = 5; 6 | dt = 0.1; 7 | 8 | for i=1:40 9 | r = rate_func(T(i), Y(i)); 10 | T(i+1) = T(i) + dt; 11 | Y(i+1) = Y(i) + r * dt; 12 | end 13 | plot(T, Y) 14 | xlabel('Time (hours)') 15 | ylabel('Population (billions of cells)') 16 | saveas(gcf, '../../book/figs/euler.eps', 'epsc') 17 | end 18 | 19 | function res = rate_func(t, y) 20 | a = 0.2; 21 | res = a * y; 22 | end 23 | -------------------------------------------------------------------------------- /code/chap09/rats.m: -------------------------------------------------------------------------------- 1 | % Use ode45 to predict rat population growth. 2 | 3 | function res = rats() 4 | t = 365/2; 5 | y = 1000; 6 | res = rate_func(t, y); 7 | 8 | %ts = linspace(0, 365); 9 | %ys = rate_func(ts, 2000); 10 | %plot(ts, ys); 11 | 12 | [T, Y] = ode45(@rate_func, [0, 365], 1000); 13 | plot(T, Y) 14 | xlabel('Time (days)') 15 | ylabel('Population (rats)') 16 | saveas(gcf, '../../book/figs/rats.eps', 'epsc') 17 | 18 | Y(end) 19 | end 20 | 21 | function res = rate_func(t, y) 22 | a = 0.002; 23 | omega = 2*pi / 365; 24 | res = a * y * (1 - cos(omega * t)); 25 | end 26 | -------------------------------------------------------------------------------- /code/chap09/runge.m: -------------------------------------------------------------------------------- 1 | % Make a plot comparing results from euler and runge-kutta 2 | 3 | function res = runge() 4 | clf; hold on 5 | 6 | T(1) = 0; 7 | F(1) = 5; 8 | dt = 0.1; 9 | 10 | for i=1:40 11 | r = rate_func(T(i), F(i)); 12 | T(i+1) = T(i) + dt; 13 | F(i+1) = F(i) + r * dt; 14 | end 15 | plot(T, F) 16 | xlabel('Time (hours)') 17 | ylabel('Population (billions of cells)') 18 | saveas(gcf, '../../book/figs/euler.eps', 'epsc') 19 | 20 | F1 = 5; 21 | [T, F] = ode45(@rate_func, [0, 4], F1); 22 | 23 | plot(T, F, '--') 24 | legend('euler', 'ode45', 'Location', 'northwest') 25 | saveas(gcf, '../../book/figs/runge.eps', 'epsc') 26 | end 27 | 28 | function res = rate_func(t, y) 29 | a = 0.2; 30 | res = a * y; 31 | end 32 | -------------------------------------------------------------------------------- /code/chap10/lorenz.m: -------------------------------------------------------------------------------- 1 | % Solve the Lorentz system and plot the results. 2 | 3 | function res = lorenz() 4 | % Run the ode solver 5 | [T, M] = ode45(@rate_func, [0 30], [1 2 3]); 6 | 7 | % plot the results 8 | X = M(:,1); 9 | Y = M(:,2); 10 | Z = M(:,3); 11 | plot3(X, Y, Z) 12 | xlabel('X') 13 | ylabel('Y') 14 | zlabel('Z') 15 | 16 | % uncomment this to see the trajectory animated 17 | % comet3(X, Y, Z); 18 | end 19 | 20 | function res = rate_func(t, V) 21 | % unpack the state vector 22 | x = V(1); 23 | y = V(2); 24 | z = V(3); 25 | 26 | % set the parameters 27 | sigma = 10; 28 | b = 8/3; 29 | r = 28; 30 | 31 | % compute the derivatives 32 | dxdt = sigma * (y-x); 33 | dydt = x * (r-z) - y; 34 | dzdt = x*y - b*z; 35 | 36 | % pack the results in a column vector 37 | res = [dxdt; dydt; dzdt]; 38 | end 39 | -------------------------------------------------------------------------------- /code/chap10/lorenz_diff.m: -------------------------------------------------------------------------------- 1 | % Plot a solution to the Lorenz difference equations. 2 | 3 | sigma = 10; 4 | b = 8/3; 5 | r = 28; 6 | dt = 0.01; 7 | 8 | X(1) = 1; 9 | Y(1) = 2; 10 | Z(1) = 3; 11 | 12 | for i = 1:2000 13 | X(i+1) = X(i) + sigma * (Y(i) - X(i)) * dt; 14 | Y(i+1) = Y(i) + (X(i) * (r - Z(i)) - Y(i)) * dt; 15 | Z(i+1) = Z(i) + (X(i)*Y(i) - b*Z(i)) * dt; 16 | end 17 | 18 | plot3(X, Y, Z) 19 | -------------------------------------------------------------------------------- /code/chap10/lorenz_loop.m: -------------------------------------------------------------------------------- 1 | % Plot a solution to the Lorenz equations. 2 | 3 | sigma = 10; 4 | b = 8/3; 5 | r = 28; 6 | dt = 0.01; 7 | 8 | x = 1; 9 | y = 1; 10 | z = 1; 11 | 12 | hold on 13 | for i = 1:1000 14 | lorenz_update 15 | plot(x,y) 16 | end 17 | -------------------------------------------------------------------------------- /code/chap10/lorenz_update.m: -------------------------------------------------------------------------------- 1 | xnew = x + sigma * (y - x) * dt; 2 | ynew = y + (x * (r - z) - y) * dt; 3 | znew = z + (x*y - b*z) * dt; 4 | x = xnew; 5 | y = ynew; 6 | z = znew; 7 | -------------------------------------------------------------------------------- /code/chap10/lotka.m: -------------------------------------------------------------------------------- 1 | % Simulate the Lotka-Volterra model and plot the results. 2 | 3 | function res = lotka() 4 | % test the rate function 5 | t = 0; 6 | V_init = [80, 20]; 7 | R = rate_func(t, V_init) 8 | 9 | % run the ODE solver 10 | tspan = [0, 200]; 11 | [T, M] = ode45(@rate_func, tspan, V_init); 12 | 13 | % plot the time series 14 | clf; hold on 15 | R = M(:, 1); 16 | F = M(:, 2); 17 | plot(T, R, 'LineWidth', 2) 18 | plot(T, F, '--', 'LineWidth', 2) 19 | xlabel('Time (weeks)') 20 | ylabel('Polulation') 21 | legend('rabbits', 'foxes') 22 | saveas(gcf, '../../book/figs/lotka.eps', 'epsc') 23 | 24 | % plot the trajectory 25 | clf; hold on 26 | plot(R, F) 27 | xlabel('Rabbit population') 28 | ylabel('Fox population') 29 | saveas(gcf, '../../book/figs/phase.eps', 'epsc') 30 | end 31 | 32 | 33 | function res = rate_func(t, V) 34 | % unpack the elements of V 35 | x = V(1); 36 | y = V(2); 37 | 38 | % set the parameters 39 | a = 0.1; 40 | b = 0.01; 41 | c = 0.1; 42 | d = 0.002; 43 | 44 | % compute the derivatives 45 | dxdt = a*x - b*x*y; 46 | dydt = -c*y + d*x*y; 47 | 48 | % pack the derivatives into a vector 49 | res = [dxdt; dydt]; 50 | end 51 | -------------------------------------------------------------------------------- /code/chap10/plot_lorenz.m: -------------------------------------------------------------------------------- 1 | % Plot results of the Lorenz equations. 2 | 3 | [T, M] = ode45(@lorenz, [0,30], [3, 2, 23]); 4 | X = M(:,1); 5 | Y = M(:,2); 6 | Z = M(:,3); 7 | plot3(X, Y, Z); 8 | -------------------------------------------------------------------------------- /code/chap11/earth.m: -------------------------------------------------------------------------------- 1 | % Simulate the Earth falling into the Sun. 2 | 3 | function earth() 4 | y0 = 150e9; % meters 5 | t_end = 1e7; % seconds 6 | 7 | t = 0; 8 | X = [y0, 0]; 9 | rate_func(t, X) 10 | 11 | tspan = [0, t_end]; 12 | options = odeset('Events', @event_func); 13 | [T, M] = ode45(@rate_func, tspan, X, options); 14 | 15 | % convert time to days 16 | % convert distance to millions of km 17 | T = T / 60 / 60 / 24; 18 | Y = M(:, 1) / 1e9; 19 | 20 | plot(T, Y) 21 | xlabel('Time (s)') 22 | ylabel('Distance from sun (million km)') 23 | % saveas(gcf, '../../book/figs/earth.eps', 'epsc') 24 | 25 | T(end) 26 | M(end, :) 27 | end 28 | 29 | function res = rate_func(t, X) 30 | % unpack position and velocity 31 | y = X(1); 32 | v = X(2); 33 | 34 | % compute the derivatives 35 | dydt = v; 36 | dvdt = acceleration(t, X); 37 | 38 | % pack the derivatives into a column vector 39 | res = [dydt; dvdt]; 40 | end 41 | 42 | function res = acceleration(t, X) 43 | G=6.674e-11; % N / kg^2 * m^2, 44 | m_sun = 1.989e30; % kg, 45 | m_earth = 5.972e24; % kg, 46 | 47 | y = X(1); 48 | f_g = -G * m_earth * m_sun / y^2; 49 | a_g = f_g / m_earth; 50 | res = a_g; 51 | end 52 | 53 | function [value, isterminal, direction] = event_func(t, X) 54 | r_earth = 6.371e6; % meters 55 | r_sun = 695.508e6; % meters 56 | y_final = r_sun + r_earth; 57 | y = X(1); 58 | 59 | value = y - y_final; 60 | isterminal = 1; 61 | direction = -1; 62 | end -------------------------------------------------------------------------------- /code/chap11/freefall.m: -------------------------------------------------------------------------------- 1 | % Rate function for an object in freefall. 2 | 3 | function res = freefall(t, X) 4 | y = X(1); % the first component is position 5 | v = X(2); % the second component is velocity 6 | 7 | dydt = v; 8 | dvdt = acceleration(t, y, v); 9 | 10 | res = [dydt; dvdt]; % pack the results in a column vector 11 | end 12 | 13 | function res = acceleration(t, y, v) 14 | a_g = -9.8; % acceleration due to gravity in m/s^2 15 | b = 0.2; % drag constant 16 | m = 75; % mass in kg 17 | F_d = b * v^2; % drag force in N 18 | a_d = F_d / m; % drag acceleration in m/s^2 19 | res = a_g + a_d; % total acceleration 20 | end 21 | -------------------------------------------------------------------------------- /code/chap11/penny.m: -------------------------------------------------------------------------------- 1 | % Simulate a penny falling from the Empire State Building. 2 | 3 | function penny() 4 | t = 0; 5 | X = [381, 0]; 6 | rate_func(t, X) 7 | 8 | tspan = [0, 10]; 9 | [T, M] = ode45(@rate_func, tspan, X); 10 | 11 | Y = M(:, 1); 12 | V = M(:, 2); 13 | 14 | plot(T, Y) 15 | xlabel('Time (s)') 16 | ylabel('Altitude (m)') 17 | saveas(gcf, '../../book/figs/penny.eps', 'epsc') 18 | 19 | options = odeset('Events', @event_func); 20 | [T, M] = ode45(@rate_func, tspan, X, options); 21 | T(end) 22 | M(end, :) 23 | end 24 | 25 | function res = rate_func(t, X) 26 | % unpack position and velocity 27 | y = X(1); 28 | v = X(2); 29 | 30 | % compute the derivatives 31 | dydt = v; 32 | dvdt = -9.8; 33 | 34 | % pack the derivatives into a column vector 35 | res = [dydt; dvdt]; 36 | end 37 | 38 | function [value, isterminal, direction] = event_func(t,X) 39 | value = X(1); 40 | isterminal = 1; 41 | direction = -1; 42 | end 43 | -------------------------------------------------------------------------------- /code/chap11/penny2.m: -------------------------------------------------------------------------------- 1 | % Simulate a penny falling from the Empire State Building. 2 | % This version includes drag. 3 | 4 | function penny2() 5 | t = 0; 6 | X = [381, 0]; 7 | rate_func(t, X) 8 | 9 | tspan = [0, 30]; 10 | options = odeset('Events', @event_func); 11 | [T, M] = ode45(@rate_func, tspan, X, options); 12 | 13 | Y = M(:, 1); 14 | V = M(:, 2); 15 | 16 | plot(T, Y) 17 | xlabel('Time (s)') 18 | ylabel('Altitude (m)') 19 | saveas(gcf, '../../book/figs/penny2.eps', 'epsc') 20 | 21 | T(end) 22 | M(end, :) 23 | end 24 | 25 | function res = rate_func(t, X) 26 | % unpack position and velocity 27 | y = X(1); 28 | v = X(2); 29 | 30 | % compute the derivatives 31 | dydt = v; 32 | dvdt = acceleration(t, X); 33 | 34 | % pack the derivatives into a column vector 35 | res = [dydt; dvdt]; 36 | end 37 | 38 | function res = acceleration(t, X) 39 | b = 75e-6; % drag constant in kg/m 40 | v = X(2); % velocity in m/s 41 | f_d = -sign(v) * b * v^2; % drag force in N 42 | 43 | m = 2.5e-3; % mass in kg 44 | a_d = f_d / m; % drag acceleration in m/s^2 45 | 46 | a_g = -9.8; % acceleration due to gravity in m/s^2 47 | res = a_g + a_d; % total acceleration 48 | end 49 | 50 | function [value, isterminal, direction] = event_func(t,X) 51 | value = X(1); 52 | isterminal = 1; 53 | direction = -1; 54 | end 55 | -------------------------------------------------------------------------------- /code/chap11/skydiver.m: -------------------------------------------------------------------------------- 1 | % Simulate the descent of a skydiver. 2 | 3 | function skydiver() 4 | t = 0; 5 | X = [4000, 0]; 6 | rate_func(t, X) 7 | 8 | tspan = [0, 1000]; 9 | options = odeset('Events', @event_func); 10 | [T, M] = ode45(@rate_func, tspan, X, options); 11 | 12 | Y = M(:, 1); 13 | V = M(:, 2); 14 | 15 | plot(T, Y) 16 | xlabel('Time (s)') 17 | ylabel('Altitude (m)') 18 | 19 | T(end) 20 | M(end, :) 21 | end 22 | 23 | function res = rate_func(t, X) 24 | % unpack position and velocity 25 | y = X(1); 26 | v = X(2); 27 | 28 | % compute the derivatives 29 | dydt = v; 30 | dvdt = acceleration(t, X); 31 | 32 | % pack the derivatives into a column vector 33 | res = [dydt; dvdt]; 34 | end 35 | 36 | function res = acceleration(t, X) 37 | b_free = 0.2; % drag constant in kg/m 38 | b_parachute = 29; 39 | 40 | y = X(1); 41 | if y < 8 42 | b = b_parachute; 43 | else 44 | b = b_free; 45 | end 46 | 47 | v = X(2); % velocity in m/s 48 | f_d = -sign(v) * b * v^2; % drag force in N 49 | 50 | m = 75; % mass in kg 51 | a_d = f_d / m; % drag acceleration in m/s^2 52 | 53 | a_g = -9.8; % acceleration due to gravity in m/s^2 54 | res = a_g + a_d; % total acceleration 55 | end 56 | 57 | function [value, isterminal, direction] = event_func(t,X) 58 | value = X(1); 59 | isterminal = 1; 60 | direction = -1; 61 | end 62 | -------------------------------------------------------------------------------- /code/chap12/baseball.m: -------------------------------------------------------------------------------- 1 | % Simulate the flight of a baseball with no drag. 2 | 3 | function baseball() 4 | P = [0; 1]; % initial position in m 5 | V = [30; 40]; % initial velocity in m/s 6 | W = [P; V]; % initial condition 7 | rate_func(0, W) 8 | 9 | tspan = [0 8]; 10 | [T, M] = ode45(@rate_func, tspan, W); 11 | 12 | X = M(:, 1); 13 | Y = M(:, 2); 14 | 15 | clf; hold on 16 | plot(T, X) 17 | plot(T, Y) 18 | 19 | xlabel('Time (s)') 20 | ylabel('Position (m)') 21 | legend('X position', 'Y position', 'Location', 'northwest') 22 | saveas(gcf, '../../book/figs/baseball1.eps', 'epsc') 23 | end 24 | 25 | function res = rate_func(t, W) 26 | P = W(1:2); 27 | V = W(3:4); 28 | 29 | dPdt = V; 30 | dVdt = acceleration(t, P, V); 31 | 32 | res = [dPdt; dVdt]; 33 | end 34 | 35 | function res = acceleration(t, P, V) 36 | g = 9.8; % acceleration of gravity in m/s^2 37 | gravity = [0; -g]; 38 | res = gravity; 39 | end 40 | -------------------------------------------------------------------------------- /code/chap12/baseball2.m: -------------------------------------------------------------------------------- 1 | % Simulate the flight of a baseball with drag. 2 | 3 | function baseball2() 4 | P = [0; 1]; % initial position in m 5 | V = [40; 30]; % initial velocity in m/s 6 | W = [P; V]; % initial condition 7 | rate_func(0, W) 8 | 9 | tspan = [0 6]; 10 | [T, M] = ode45(@rate_func, tspan, W); 11 | 12 | X = M(:, 1); 13 | Y = M(:, 2); 14 | 15 | clf; hold on 16 | plot(T, X) 17 | plot(T, Y) 18 | 19 | xlabel('Time (s)') 20 | ylabel('Position (m)') 21 | legend('X position', 'Y position', 'Location', 'northwest') 22 | saveas(gcf, '../../book/figs/baseball2.eps', 'epsc') 23 | end 24 | 25 | function res = rate_func(t, W) 26 | P = W(1:2); 27 | V = W(3:4); 28 | 29 | dPdt = V; 30 | dVdt = acceleration(t, P, V); 31 | 32 | res = [dPdt; dVdt]; 33 | end 34 | 35 | function res = acceleration(t, P, V) 36 | g = 9.8; % acceleration of gravity in m/s^2 37 | a_gravity = [0; -g]; 38 | 39 | m = 0.145; % mass in kilograms 40 | a_drag = drag_force(V) / m; 41 | res = a_gravity + a_drag; 42 | end 43 | 44 | function res = drag_force(V) 45 | C_d = 0.3; % dimensionless 46 | rho = 1.3; % kg / m^3 47 | A = 0.0042; % m^2 48 | v = norm(V); % m/s 49 | 50 | res = - 1/2 * C_d * rho * A * v * V; 51 | end 52 | 53 | -------------------------------------------------------------------------------- /code/chap12/diagram.m: -------------------------------------------------------------------------------- 1 | % Draw a force diagram for a projectile with drag. 2 | 3 | function diagram() 4 | clf; hold on 5 | 6 | blue = [0, 0.44, 0.74]; 7 | orange = [0.85, 0.32, 0.1]; 8 | 9 | xl = [-5, 5]; 10 | yl = [-5, 5]; 11 | draw_axes(xl, yl) 12 | 13 | O = [0 0]; 14 | P = [3 4]; 15 | draw_vector(O, P, 'P', 'Color', blue) 16 | 17 | xlim(xl) 18 | ylim(yl) 19 | hold off 20 | saveas(gcf, '../../book/figs/vector1.eps', 'epsc') 21 | 22 | clf; hold on 23 | 24 | xl = [-5, 5]; 25 | yl = [-5, 5]; 26 | draw_axes(xl, yl) 27 | 28 | O = [0 0]; 29 | A = [2, 4]; 30 | draw_vector(O, A, 'A', 'Color', blue) 31 | 32 | B = [2, -2]; 33 | draw_vector(O, B, 'B', 'Color', blue) 34 | 35 | AB = A + B 36 | draw_vector(O, AB, 'A + B', 'Color', blue) 37 | 38 | draw_line(A, AB, ':', 'Color', orange) 39 | draw_line(B, AB, ':', 'Color', orange) 40 | 41 | xlim(xl) 42 | ylim(yl) 43 | hold off 44 | saveas(gcf, '../../book/figs/vector2.eps', 'epsc') 45 | 46 | clf; hold on 47 | 48 | xl = [-5, 5]; 49 | yl = [-5, 5]; 50 | draw_axes(xl, yl) 51 | 52 | O = [0 0]; 53 | V = [4, 2]; 54 | draw_vector(O, V, 'V', 'Color', blue) 55 | 56 | Vhat = hat(V); 57 | % draw_vector(O, Vhat, '', 'Color', 'blue', 'LineWidth', 2) 58 | % text(Vhat(1), Vhat(2), 'hat(V)', ... 59 | % 'FontSize', 12, ... 60 | % 'FontWeight', 'bold', ... 61 | % 'Color', 'blue', ... 62 | % 'VerticalAlignment', 'bottom', ... 63 | % 'HorizontalAlignment', 'right') 64 | 65 | D = - Vhat * 2 66 | draw_vector(O, D, '', 'Color', blue) 67 | text(D(1), D(2), 'D', ... 68 | 'FontSize', 12, ... 69 | 'FontWeight', 'bold', ... 70 | 'Color', blue, ... 71 | 'HorizontalAlignment', 'right') 72 | 73 | G = [0 -3] 74 | draw_vector(O, G, 'G', 'Color', blue) 75 | 76 | A = D+G 77 | draw_vector(O, A, '', 'Color', orange) 78 | text(A(1), A(2), 'A', ... 79 | 'FontSize', 12, ... 80 | 'FontWeight', 'bold', ... 81 | 'Color', orange, ... 82 | 'HorizontalAlignment', 'right') 83 | 84 | 85 | xlim(xl) 86 | ylim(yl) 87 | hold off 88 | saveas(gcf, '../../book/figs/vector3.eps', 'epsc') 89 | 90 | end 91 | 92 | function res = hat(V) 93 | res = V / norm(V) 94 | end 95 | 96 | function res = perp(V) 97 | res = [-V(2) V(1)] 98 | end 99 | 100 | function draw_vector(A, B, label, varargin) 101 | blue = [0, 0.44, 0.74]; 102 | 103 | draw_line(A, B, varargin{:}) 104 | 105 | V = B - A 106 | h = 0.08 * V 107 | p = perp(h) / 2 108 | 109 | draw_line(B, B-h + p, varargin{:}) 110 | draw_line(B, B-h - p, varargin{:}) 111 | 112 | T = B + h 113 | text(T(1), T(2), label, ... 114 | 'FontSize', 12, ... 115 | 'FontWeight', 'bold', ... 116 | 'Color', blue, ... 117 | 'HorizontalAlignment', 'left') 118 | end 119 | 120 | function draw_line(V, W, varargin) 121 | xs = [V(1), W(1)]; 122 | ys = [V(2), W(2)]; 123 | 124 | plot(xs, ys, varargin{:}) 125 | end 126 | 127 | function draw_axes(xl, yl) 128 | plot(xl, [0 0], 'k:') 129 | plot([0 0], yl, 'k:') 130 | end 131 | -------------------------------------------------------------------------------- /code/chap12/optimize.m: -------------------------------------------------------------------------------- 1 | function res = optimize(velocity) 2 | % Find the angle that yields the maximum range for 3 | % a given velocity. 4 | angles = 20:70; 5 | for i=1:length(angles) 6 | angle = angles(i); 7 | ranges(i) = range(velocity, angle); 8 | end 9 | plot(angles, ranges); 10 | [m, i] = max(ranges); 11 | best_angle = angles(i); 12 | res = best_angle; 13 | end 14 | 15 | function res = range(velocity, angle) 16 | % compute the horizontal distance in the air of a baseball 17 | % with initial velocity in m/s and angle in degrees 18 | theta = angle * pi / 180; 19 | vx = velocity * cos(theta); 20 | vy = velocity * sin(theta); 21 | 22 | options = odeset('Events', @events); 23 | [T, M] = ode45(@slope, [0, 100], [0, 1, vx, vy], options); 24 | 25 | X = M(:,1); 26 | Y = M(:,2); 27 | plot(X, Y) 28 | res = X(end); 29 | end 30 | 31 | function [value,isterminal,direction] = events(t,W) 32 | % Locate the time when height passes through zero in a 33 | % decreasing direction and stop integration. 34 | value = W(2); % 35 | isterminal = 1; % Stop the integration 36 | direction = -1; % Negative direction only 37 | end 38 | 39 | function res = slope(t, W) 40 | % this is a slope function invoked by ode45 41 | % W contains 4 elements, Rx, Ry, Vx, and Vy 42 | R = W(1:2); 43 | V = W(3:4); 44 | 45 | dRdt = V; 46 | dVdt = acceleration(t, R, V); 47 | 48 | res = [dRdt; dVdt]; 49 | end 50 | 51 | function res = acceleration(t, R, V) 52 | % compute acceleration due to gravity and drag 53 | Ag = [0; -9.8]; 54 | 55 | mass = 0.145; % kg 56 | Ad = drag_force(V) / mass; 57 | res = Ag + Ad; 58 | end 59 | 60 | function Fd = drag_force(V) 61 | % compute the drag force of a baseball 62 | C = 0.3; % dimensionless 63 | rho = 1.3; % kg / m^3 64 | A = 0.0042; % m^2 65 | v = norm(V); % m/s 66 | 67 | Fd = - 1/2 * C * rho * A * v * V; 68 | end 69 | -------------------------------------------------------------------------------- /code/chap12/proj1.m: -------------------------------------------------------------------------------- 1 | % Rate function for a projectile with no drag. 2 | 3 | function dWdt = proj(t, W) 4 | R = W(1:2); 5 | V = W(3:4); 6 | 7 | dRdt = V; 8 | dVdt = acceleration(t, R, V); 9 | 10 | dWdt = [dRdt; dVdt]; 11 | end 12 | 13 | function dVdt = acceleration(t, R, V) 14 | g = -9.8; % acceleration of gravity in m/s^2 15 | dVdt = [0; g]; 16 | end 17 | -------------------------------------------------------------------------------- /code/chap12/proj2.m: -------------------------------------------------------------------------------- 1 | % Rate function for a projectile with drag. 2 | 3 | function dWdt = proj(t, W) 4 | R = W(1:2); 5 | V = W(3:4); 6 | 7 | dRdt = V; 8 | dVdt = acceleration(t, R, V); 9 | 10 | dWdt = [dRdt; dVdt]; 11 | end 12 | 13 | function dVdt = acceleration(t, R, V) 14 | g = 9.8; % acceleration of gravity in m/s^2 15 | gravity = [0; -g]; 16 | 17 | m = 0.145; % mass in kilograms 18 | drag = drag_force(V) / m; 19 | dVdt = gravity + drag; 20 | end 21 | 22 | function Fd = drag_force(V) 23 | C = 0.3; % dimensionless 24 | rho = 1.3; % kg / m^3 25 | A = 0.0042; % m^2 26 | v = norm(V); % m/s 27 | 28 | Fd = - 1/2 * C * rho * A * v * V; 29 | end 30 | -------------------------------------------------------------------------------- /code/chap13/baseball3.m: -------------------------------------------------------------------------------- 1 | % Plot distance flown versus launch angle for a baseball. 2 | 3 | function baseball3() 4 | P = [0; 1]; % initial position in m 5 | V = [40; 30]; % initial velocity in m/s 6 | W = [P; V]; % initial condition 7 | rate_func(0, W) 8 | 9 | tspan = [0 10]; 10 | options = odeset('Events', @event_func); 11 | [T, M] = ode45(@rate_func, tspan, W, options); 12 | 13 | T(end) 14 | M(end, :) 15 | 16 | clf; hold on 17 | X = M(:, 1); 18 | Y = M(:, 2); 19 | 20 | plot(X, Y) 21 | 22 | xlabel('Y Position (m)') 23 | ylabel('X Position (m)') 24 | saveas(gcf, '../../book/figs/baseball3.eps', 'epsc') 25 | 26 | thetas = linspace(0, pi/2); 27 | for i = 1:length(thetas) 28 | ranges(i) = baseball_range(thetas(i)); 29 | end 30 | 31 | clf; hold on 32 | plot(thetas, ranges) 33 | 34 | [x, fval] = fminsearch(@min_func, pi/4) 35 | plot([x x], [0, max(ranges)], 'k:') 36 | 37 | xlabel('Launch angle (radian)') 38 | ylabel('Distance traveled (m)') 39 | saveas(gcf, '../../book/figs/baseball4.eps', 'epsc') 40 | 41 | end 42 | 43 | function res = min_func(angle) 44 | res = -baseball_range(angle); 45 | end 46 | 47 | function res = baseball_range(theta) 48 | P = [0; 1]; 49 | v = 50; 50 | [vx, vy] = pol2cart(theta, v); 51 | 52 | V = [vx; vy]; % initial velocity in m/s 53 | W = [P; V]; % initial condition 54 | 55 | tspan = [0 10]; 56 | options = odeset('Events', @event_func); 57 | [T, M] = ode45(@rate_func, tspan, W, options); 58 | 59 | res = M(end, 1); 60 | end 61 | 62 | function res = rate_func(t, W) 63 | P = W(1:2); 64 | V = W(3:4); 65 | 66 | dPdt = V; 67 | dVdt = acceleration(t, P, V); 68 | 69 | res = [dPdt; dVdt]; 70 | end 71 | 72 | function [value, isterminal, direction] = event_func(t, W) 73 | value = W(2); 74 | isterminal = 1; 75 | direction = -1; 76 | end 77 | 78 | function res = acceleration(t, P, V) 79 | g = 9.8; % acceleration of gravity in m/s^2 80 | a_gravity = [0; -g]; 81 | 82 | m = 0.145; % mass in kilograms 83 | a_drag = drag_force(V) / m; 84 | res = a_gravity + a_drag; 85 | end 86 | 87 | function res = drag_force(V) 88 | C_d = 0.3; % dimensionless 89 | rho = 1.3; % kg / m^3 90 | A = 0.0042; % m^2 91 | v = norm(V); % m/s 92 | 93 | res = - 1/2 * C_d * rho * A * v * V; 94 | end 95 | -------------------------------------------------------------------------------- /code/chap13/baseball_anim.m: -------------------------------------------------------------------------------- 1 | % Animate the flight of a baseball. 2 | 3 | function baseball_anim() 4 | P = [0; 1]; % initial position in m 5 | V = [40; 30]; % initial velocity in m/s 6 | W = [P; V]; % initial condition 7 | rate_func(0, W) 8 | 9 | tspan = 0:0.1:10; 10 | options = odeset('Events', @event_func); 11 | [T, M] = ode45(@rate_func, tspan, W, options); 12 | 13 | animate(T, M) 14 | end 15 | 16 | function animate(T,M) 17 | X = M(:,1); 18 | Y = M(:,2); 19 | 20 | minmax = [min([X]), max([X]), min([Y]), max([Y])]; 21 | 22 | for i=1:length(T) 23 | clf; hold on 24 | axis(minmax); 25 | plot(X(i), Y(i), 'o') 26 | drawnow; 27 | 28 | if i < length(T) 29 | dt = T(i+1) - T(i); 30 | pause(dt); 31 | end 32 | end 33 | end 34 | 35 | function res = rate_func(t, W) 36 | P = W(1:2); 37 | V = W(3:4); 38 | 39 | dPdt = V; 40 | dVdt = acceleration(t, P, V); 41 | 42 | res = [dPdt; dVdt]; 43 | end 44 | 45 | function res = acceleration(t, P, V) 46 | g = 9.8; % acceleration of gravity in m/s^2 47 | a_gravity = [0; -g]; 48 | 49 | m = 0.145; % mass in kilograms 50 | a_drag = drag_force(V) / m; 51 | res = a_gravity + a_drag; 52 | end 53 | 54 | function res = drag_force(V) 55 | C_d = 0.3; % dimensionless 56 | rho = 1.3; % kg / m^3 57 | A = 0.0042; % m^2 58 | v = norm(V); % m/s 59 | 60 | res = - 1/2 * C_d * rho * A * v * V; 61 | end 62 | 63 | function [value, isterminal, direction] = event_func(t, W) 64 | value = W(2); 65 | isterminal = 1; 66 | direction = -1; 67 | end 68 | -------------------------------------------------------------------------------- /code/chap13/golden.m: -------------------------------------------------------------------------------- 1 | % Demonstrate a golden section search. 2 | 3 | function res = optimize(V) 4 | x1 = V(1); 5 | x2 = V(2); 6 | x3 = V(3); 7 | 8 | fx1 = height_func(x1); 9 | fx2 = height_func(x2); 10 | fx3 = height_func(x3); 11 | 12 | for i=1:50 13 | if x3-x2 > x2-x1 14 | x4 = (x2+x3) / 2; 15 | fx4 = height_func(x4); 16 | if fx4 > fx2 17 | x1 = x2; fx1 = fx2; 18 | x2 = x4; fx2 = fx4; 19 | else 20 | x3 = x4; fx3 = fx4; 21 | end 22 | else 23 | x4 = (x1+x2) / 2; 24 | fx4 = height_func(x4); 25 | if fx4 > fx2 26 | x3 = x2; fx3 = fx2; 27 | x2 = x4; fx2 = fx4; 28 | else 29 | x1 = x4; fx1 = fx4; 30 | end 31 | end 32 | 33 | if abs(x3-x1) < 1e-1 34 | break 35 | end 36 | end 37 | i 38 | res = [x1 x2 x3]; 39 | height_func(44.4) 40 | end 41 | 42 | function res = height_func(angle) 43 | % compute the horizontal distance in the air of a baseball 44 | % with initial velocity in m/s and angle in degrees 45 | velocity = 42; 46 | theta = angle * pi / 180; 47 | vx = velocity * cos(theta); 48 | vy = velocity * sin(theta); 49 | 50 | options = odeset('Events', @events); 51 | [T, M] = ode45(@slope, [0, 100], [0, 1, vx, vy], options); 52 | 53 | X = M(:,1); 54 | Y = M(:,2); 55 | plot(X, Y) 56 | res = Y(end); 57 | end 58 | 59 | function [value,isterminal,direction] = events(t,W) 60 | % Locate the time when height passes through zero in a 61 | % decreasing direction and stop integration. 62 | value = W(1) - 97; % 63 | isterminal = 1; % Stop the integration 64 | direction = 1; % Negative direction only 65 | end 66 | 67 | function res = slope(t, W) 68 | % this is a slope function invoked by ode45 69 | % W contains 4 elements, Rx, Ry, Vx, and Vy 70 | R = W(1:2); 71 | V = W(3:4); 72 | 73 | dRdt = V; 74 | dVdt = acceleration(t, R, V); 75 | 76 | res = [dRdt; dVdt]; 77 | end 78 | 79 | function res = acceleration(t, R, V) 80 | % compute acceleration due to gravity and drag 81 | Ag = [0; -9.8]; 82 | 83 | mass = 0.145; % kg 84 | Ad = drag_force(V) / mass; 85 | res = Ag + Ad; 86 | end 87 | 88 | function Fd = drag_force(V) 89 | % compute the drag force of a baseball 90 | C = 0.3; % dimensionless 91 | rho = 1.3; % kg / m^3 92 | A = 0.0042; % m^2 93 | v = norm(V); % m/s 94 | 95 | Fd = - 1/2 * C * rho * A * v * V; 96 | end 97 | -------------------------------------------------------------------------------- /code/chap13/manny.m: -------------------------------------------------------------------------------- 1 | % Solve the Manny Ramirez problem using a golden section search. 2 | 3 | function res = manny() 4 | % find the velocity that _just_ gets the ball over the wall 5 | initial_guess = 45; % m/s 6 | velocity = fzero(@crossover_func, initial_guess); 7 | res = velocity; 8 | end 9 | 10 | function res = crossover_func(velocity) 11 | % this function crosses through zero when the height of 12 | % the ball at the wall is equal to the goal 13 | goal = 12; % height of the wall in meters 14 | res = height_at_wall_func(velocity) - goal; 15 | end 16 | 17 | function res = height_at_wall_func(velocity) 18 | % search for the angle that maximizes the height of the 19 | % ball when it reaches the Green Monster, and return the height 20 | angle = golden_angle_func(velocity); 21 | height = height_func(velocity, angle); 22 | res = height; 23 | end 24 | 25 | function res = golden_angle_func(velocity) 26 | % find the launch angle that yields the maximum height when 27 | % the ball reaches the wall. For simplicity, this function 28 | % uses bisection rather than the golden ratio. 29 | a = 20; 30 | b = 40; 31 | c = 60; 32 | 33 | fa = height_func(velocity, a); 34 | fb = height_func(velocity, b); 35 | fc = height_func(velocity, c); 36 | 37 | for i=1:20 38 | if c-b > b-a 39 | x = (b+c) / 2; 40 | fx = height_func(velocity, x); 41 | if fx > fb 42 | a = b; fa = fb; 43 | b = x; fb = fx; 44 | else 45 | c = x; fc = fx; 46 | end 47 | else 48 | x = (a+b) / 2; 49 | fx = height_func(velocity, x); 50 | if fx > fb 51 | c = b; fc = fb; 52 | b = x; fb = fx; 53 | else 54 | a = x; fa = fx; 55 | end 56 | end 57 | 58 | % loop until the interval is smaller than 1/10th of a degree 59 | if abs(c-a) < 0.1 60 | break 61 | end 62 | end 63 | res = (a+c) / 2; 64 | end 65 | 66 | 67 | function res = height_func(velocity, angle) 68 | % compute the height of the ball when it reaches the wall, 69 | % for a baseball with initial velocity in m/s and angle in degrees 70 | theta = angle * pi / 180; 71 | vx = velocity * cos(theta); % m/s 72 | vy = velocity * sin(theta); % m/s 73 | 74 | options = odeset('Events', @events_func); 75 | [T, M] = ode45(@slope_func, [0, 100], [0, 1, vx, vy], options); 76 | 77 | X = M(:,1); 78 | Y = M(:,2); 79 | %plot(X, Y) 80 | res = Y(end); % the result is the final Y position in meters 81 | end 82 | 83 | function [value,isterminal,direction] = events_func(t,W) 84 | % stop the integration when the ball gets to the wall. 85 | wall_range = 97; % distance to the wall in meters 86 | value = W(1) - wall_range; % equals 0 when you hit the wall 87 | isterminal = 1; 88 | direction = 1; 89 | end 90 | 91 | function res = slope_func(t, W) 92 | % this is a slope function invoked by ode45 93 | % W contains 4 elements, Rx, Ry, Vx, and Vy 94 | R = W(1:2); % position of the ball in meters 95 | V = W(3:4); % velocity of the ball in m/s 96 | 97 | dRdt = V; 98 | dVdt = acceleration_func(t, R, V); 99 | 100 | res = [dRdt; dVdt]; 101 | end 102 | 103 | function res = acceleration_func(t, R, V) 104 | % compute acceleration due to gravity and drag 105 | Ag = [0; -9.8]; % m / s^2 106 | 107 | mass = 0.145; % kg 108 | Ad = drag_force_func(V) / mass; % m / s^2 109 | res = Ag + Ad; 110 | end 111 | 112 | function Fd = drag_force_func(V) 113 | % compute the drag force of a baseball, given the velocity 114 | % in m/s 115 | C = 0.3; % dimensionless 116 | rho = 1.3; % kg / m^3 117 | A = 0.0042; % m^2 118 | v = norm(V); % m/s 119 | 120 | Fd = - 1/2 * C * rho * A * v * V; % kg m / s^2 121 | end 122 | -------------------------------------------------------------------------------- /code/chap13/manny2.m: -------------------------------------------------------------------------------- 1 | % Solve the Manny Ramirez problem using fminsearch. 2 | 3 | function res = manny() 4 | % find the velocity that _just_ gets the ball over the wall 5 | initial_guess = 45; % m/s 6 | velocity = fzero(@crossover_func, initial_guess); 7 | res = velocity; 8 | end 9 | 10 | function res = crossover_func(velocity) 11 | % this function crosses through zero when the height of 12 | % the ball at the wall is equal to the goal 13 | goal = 12; % height of the wall in meters 14 | res = optimal_height_at_wall_func(velocity) - goal; 15 | end 16 | 17 | function res = optimal_height_at_wall_func(velocity) 18 | % search for the angle that maximizes the height of the 19 | % ball when it reaches the Green Monster, and return the height 20 | angle = optimal_angle_func(velocity); 21 | height = height_func(velocity, angle); 22 | res = height; 23 | end 24 | 25 | function res = optimal_angle_func(velocity) 26 | % find the optimal launch angle in degrees for the given 27 | % velocity in m/s 28 | 29 | function res = minimization_func(angle) 30 | % return the height of the ball at the wall, negated 31 | % so that we can find a _minimum_ 32 | res = -height_func(velocity, angle); 33 | end 34 | 35 | angle = fminsearch(@minimization_func, 45); 36 | res = angle; 37 | end 38 | 39 | function res = height_func(velocity, angle) 40 | % compute the height of the ball when it reaches the wall, 41 | % for a baseball with initial velocity in m/s and angle in degrees 42 | theta = angle * pi / 180; 43 | vx = velocity * cos(theta); % m/s 44 | vy = velocity * sin(theta); % m/s 45 | 46 | options = odeset('Events', @events_func); 47 | [T, M] = ode45(@slope_func, [0, 100], [0, 1, vx, vy], options); 48 | 49 | X = M(:,1); 50 | Y = M(:,2); 51 | %plot(X, Y) 52 | res = Y(end); % the result is the final Y position in meters 53 | end 54 | 55 | function [value,isterminal,direction] = events_func(t,W) 56 | % stop the integration when the ball gets to the wall. 57 | wall_range = 97; % distance to the wall in meters 58 | value = W(1) - wall_range; % equals 0 when you hit the wall 59 | isterminal = 1; 60 | direction = 1; 61 | end 62 | 63 | function res = slope_func(t, W) 64 | % this is a slope function invoked by ode45 65 | % W contains 4 elements, Rx, Ry, Vx, and Vy 66 | R = W(1:2); % position of the ball in meters 67 | V = W(3:4); % velocity of the ball in m/s 68 | 69 | dRdt = V; 70 | dVdt = acceleration_func(t, R, V); 71 | 72 | res = [dRdt; dVdt]; 73 | end 74 | 75 | function res = acceleration_func(t, R, V) 76 | % compute acceleration due to gravity and drag 77 | Ag = [0; -9.8]; % m / s^2 78 | 79 | mass = 0.145; % kg 80 | Ad = drag_force_func(V) / mass; % m / s^2 81 | res = Ag + Ad; 82 | end 83 | 84 | function Fd = drag_force_func(V) 85 | % compute the drag force of a baseball, given the velocity 86 | % in m/s 87 | C = 0.3; % dimensionless 88 | rho = 1.3; % kg / m^3 89 | A = 0.0042; % m^2 90 | v = norm(V); % m/s 91 | 92 | Fd = - 1/2 * C * rho * A * v * V; % kg m / s^2 93 | end 94 | -------------------------------------------------------------------------------- /code/chap13/optimization.m: -------------------------------------------------------------------------------- 1 | % Demonstrate fzero and fminsearch. 2 | 3 | function optimization() 4 | x = fzero(@error_func, 1) 5 | 6 | x = fminsearch(@error_func, 1) 7 | 8 | [x, fval] = fminsearch(@error_func, 1) 9 | 10 | end 11 | 12 | function res = error_func(x) 13 | res = x^2 - 2; 14 | end 15 | -------------------------------------------------------------------------------- /code/chap14/binary.m: -------------------------------------------------------------------------------- 1 | % Calculate and plot the trajectories of two bodies with 2 | % the given parameters, acting under the force of gravity. 3 | 4 | function binary() 5 | au = 150e9; % astronomical unit in meters 6 | day = 24 * 60 * 60; % year in seconds 7 | sunmass = 2.0e30; % mass of the sun in kg 8 | 9 | d = 779e9; % initial distance in meters 10 | v = 13e3; % initial velocity in meters per second 11 | m1 = 2.0e30; % mass of the sun in kg 12 | m2 = 1.9e27; % mass of Jupiter 13 | G = 6.67e-11; % gravitation constant in N m^2 / kg^2 14 | period = 4332; % one orbit in days 15 | end_time = period * day; % period in seconds 16 | 17 | % scaling distances 18 | d = d / au; 19 | v = v / au; 20 | G = G / au^3; 21 | 22 | % scaling times 23 | end_time = end_time / day; 24 | v = v * day; 25 | G = G * day^2; 26 | 27 | % scaling masses 28 | m1 = m1 / sunmass; 29 | m2 = m2 / sunmass; 30 | G = G * sunmass; 31 | 32 | P1 = [0;0]; % simple initial conditions 33 | P2 = [d;0]; 34 | V1 = [0;0]; 35 | V2 = [0;v]; 36 | 37 | options = odeset('RelTol', 1e-5); 38 | step = end_time/period*100; 39 | [T, M] = ode45(@rate_func, [0:step:end_time], [P1; P2; V1; V2], options); 40 | animate_func(T,M); 41 | energy_func(T,M); 42 | 43 | function animate_func(T,M) 44 | % animate the positions of the planets, assuming that the 45 | % columns of M are x1, y1, x2, y2. 46 | X1 = M(:,1); 47 | Y1 = M(:,2); 48 | 49 | X2 = M(:,3); 50 | Y2 = M(:,4); 51 | 52 | minmax = [min([X1;X2]), max([X1;X2]), min([Y1;Y2]), max([Y1;Y2])]; 53 | 54 | for i=1:length(T) 55 | clf; 56 | hold on; 57 | axis(minmax); 58 | draw_func(X1(i), Y1(i), X2(i), Y2(i)); 59 | drawnow; 60 | if i < length(T) 61 | dt = T(i+1) - T(i); 62 | speedup = 1000; 63 | pause(dt/speedup); 64 | end 65 | end 66 | hold off 67 | end 68 | 69 | function energy_func(T,M) 70 | for i=1:length(T) 71 | P1 = M(i,1:2); 72 | P2 = M(i,3:4); 73 | pe = potential_func(P1, P2); 74 | V1 = M(i,5:6); 75 | V2 = M(i,7:8); 76 | ke = kinetic_func(V1, m1) + kinetic_func(V2, m2); 77 | E(i) = ke + pe; 78 | end 79 | plot(T, E); 80 | loss = (E(1) - E(end)) / E(1) 81 | end 82 | 83 | function res = potential_func(P1, P2) 84 | r = norm(P1-P2); 85 | pe = -G * m1 * m2 / r; 86 | res = pe; 87 | end 88 | 89 | function res = kinetic_func(V, m) 90 | v = norm(V); 91 | ke = m * v^2 / 2; 92 | res = ke; 93 | end 94 | 95 | function draw_func(x1, y1, x2, y2) 96 | plot(x1, y1, 'r.', 'MarkerSize', 50); 97 | plot(x2, y2, 'b.', 'MarkerSize', 20); 98 | end 99 | 100 | function res = rate_func(t, W) 101 | % this is a slope function invoked by ode45 102 | n = length(W)/2; 103 | P = W(1:n); 104 | V = W(n+1:end); 105 | 106 | dRdt = V; 107 | dVdt = acceleration_func(t, P, V); 108 | 109 | res = [dRdt; dVdt]; 110 | end 111 | 112 | function res = acceleration_func(t, P, V) 113 | % compute acceleration due to gravity 114 | P1 = P(1:2); 115 | P2 = P(3:4); 116 | 117 | F12 = gravity_force_func(P1, P2, m1, m2); 118 | 119 | A1 = F12 / m1; 120 | A2 = -F12 / m2; 121 | res = [A1; A2]; 122 | end 123 | 124 | function Fg = gravity_force_func(P1, P2, m1, m2) 125 | % compute the force of gravity acting on a body at 126 | % P1 with mass m1, due to a body at P2 with mass m2 127 | R = P2 - P1; 128 | r = norm(R); 129 | Rhat = R/r; 130 | 131 | Fg = G * m1 * m2 / r^2 * Rhat; 132 | end 133 | 134 | end 135 | -------------------------------------------------------------------------------- /code/chap15/odeplot.m: -------------------------------------------------------------------------------- 1 | % Run ode45 and plot the locations where it evaluates the rate func. 2 | 3 | function odeplot() 4 | clf; hold on 5 | total = 0; 6 | 7 | y0 = 1; 8 | tspan=[0 4]; 9 | options = odeset('Refine', 1); 10 | [T, Y] = ode45(@rate_func, tspan, y0, options); 11 | plot(T, Y, '-') 12 | 13 | xlabel('t') 14 | ylabel('y') 15 | saveas(gcf, '../../book/figs/odeplot1.eps', 'epsc') 16 | 17 | plot(T, Y, 'bs') 18 | xlim([0.78 1.22]) 19 | saveas(gcf, '../../book/figs/odeplot2.eps', 'epsc') 20 | 21 | total 22 | 23 | function res = rate_func(t, y) 24 | dydt = y * sin(t); 25 | res = dydt; 26 | 27 | plot(t, y, 'ro') 28 | dt = 0.01; 29 | ts = [t t+dt]; 30 | ys = [y y+dydt*dt]; 31 | plot(ts, ys, 'r-') 32 | 33 | total = total +1; 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /code/chap15/planet.m: -------------------------------------------------------------------------------- 1 | % Calculate and plot the trajectory of a planet acting under the force of gravity. 2 | 3 | function planet() 4 | d = 1; % initial distance between stars 5 | v = 0.6; % initial velocity of the small one 6 | m1 = 1; % mass of the large star 7 | m2 = 1; % mass of the small star 8 | 9 | P1 = [-d;0]; % simple initial conditions 10 | P2 = [d;0]; 11 | V1 = [0;v]; 12 | V2 = [0;-v]; 13 | 14 | years = 10; 15 | [T, M] = ode45(@slope_func, [0, years*2*pi], [P1; P2; V1; V2]); 16 | animate_func(T,M); 17 | 18 | function animate_func(T,M) 19 | % animate the positions of the planets, assuming that the 20 | % columns of M are. Playback is in real time with speedup. 21 | X1 = M(:,1); 22 | Y1 = M(:,2); 23 | 24 | X2 = M(:,3); 25 | Y2 = M(:,4); 26 | 27 | for i=1:length(T)-1 28 | clf; 29 | hold on; 30 | axis([min([X1;X2]), max([X1;X2]), min([Y1;Y2]), max([Y1;Y2])]); 31 | plot(X1(i), Y1(i), 'r.', 'MarkerSize', 50); 32 | plot(X2(i), Y2(i), 'b.', 'MarkerSize', 50); 33 | hold off; 34 | drawnow; 35 | dt = T(i+1) - T(i); 36 | speedup = 3.0; 37 | pause(dt / speedup); 38 | end 39 | end 40 | 41 | function res = slope_func(t, W) 42 | % this is a slope function invoked by ode45 43 | n = length(W)/2; 44 | P = W(1:n); 45 | V = W(n+1:end); 46 | 47 | dRdt = V; 48 | dVdt = acceleration_func(t, P, V); 49 | 50 | res = [dRdt; dVdt]; 51 | end 52 | 53 | function res = acceleration_func(t, P, V) 54 | % compute acceleration due to gravity 55 | P1 = P(1:2); 56 | P2 = P(3:4); 57 | 58 | Fg = gravity_force_func(P1, P2, m1, m2); 59 | 60 | A1 = -Fg / m1; 61 | A2 = Fg / m2; 62 | res = [A1; A2]; 63 | end 64 | 65 | function Fg = gravity_force_func(P1, P2, m1, m2) 66 | % compute the force of gravity acting on a body at 67 | % P2 with mass m2, due to a body at P1 with mass m1 68 | G = 1; 69 | V = P1 - P2; 70 | Vhat = V/norm(V); 71 | dist = norm(V); 72 | 73 | Fg = G * m1 * m2 / dist^2 * Vhat; 74 | end 75 | 76 | end 77 | -------------------------------------------------------------------------------- /code/data/baseball_drag.csv: -------------------------------------------------------------------------------- 1 | Velocity in mph,Drag coefficient 2 | 0.058486,0.49965 3 | 19.845,0.49878 4 | 39.476,0.49704 5 | 50.181,0.48225 6 | 60.134,0.45004 7 | 68.533,0.40914 8 | 73.769,0.38042 9 | 77.408,0.36562 10 | 83.879,0.34822 11 | 90.507,0.33081 12 | 97.29,0.31427 13 | 104.54,0.30035 14 | 113.83,0.28816 15 | 120.9,0.28381 16 | 127.34,0.28033 17 | 134.41,0.28207 18 | -------------------------------------------------------------------------------- /code/data/baseball_drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/data/baseball_drag.png -------------------------------------------------------------------------------- /code/data/world_pop_census.csv: -------------------------------------------------------------------------------- 1 | 1950,2.557628654 2 | 1951,2.594939877 3 | 1952,2.636772306 4 | 1953,2.682053389 5 | 1954,2.730228104 6 | 1955,2.782098943 7 | 1956,2.835299673 8 | 1957,2.891349717 9 | 1958,2.948137248 10 | 1959,3.000716593 11 | 1960,3.043001508 12 | 1961,3.083966929 13 | 1962,3.140093217 14 | 1963,3.209827882 15 | 1964,3.281201306 16 | 1965,3.350425793 17 | 1966,3.420677923 18 | 1967,3.490333715 19 | 1968,3.562313822 20 | 1969,3.63715905 21 | 1970,3.712697742 22 | 1971,3.790326948 23 | 1972,3.866568653 24 | 1973,3.942096442 25 | 1974,4.016608813 26 | 1975,4.089083233 27 | 1976,4.16018501 28 | 1977,4.232084578 29 | 1978,4.304105753 30 | 1979,4.379013942 31 | 1980,4.451362735 32 | 1981,4.534410125 33 | 1982,4.614566561 34 | 1983,4.695736743 35 | 1984,4.774569391 36 | 1985,4.856462699 37 | 1986,4.940571232 38 | 1987,5.027200492 39 | 1988,5.114557167 40 | 1989,5.20144011 41 | 1990,5.288955934 42 | 1991,5.371585922 43 | 1992,5.456136278 44 | 1993,5.538268316 45 | 1994,5.618682132 46 | 1995,5.699202985 47 | 1996,5.779440593 48 | 1997,5.857972543 49 | 1998,5.935213248 50 | 1999,6.012074922 51 | 2000,6.088571383 52 | 2001,6.165219247 53 | 2002,6.242016348 54 | 2003,6.318590956 55 | 2004,6.395699509 56 | 2005,6.473044732 57 | 2006,6.551263534 58 | 2007,6.629913759 59 | 2008,6.70904978 60 | 2009,6.788214394 61 | 2010,6.858584755 62 | 2011,6.935999491 63 | 2012,7.013871313 64 | 2013,7.092128094 65 | 2014,7.169968185 66 | 2015,7.247892788 67 | 2016,7.325996709 68 | -------------------------------------------------------------------------------- /code/data/world_pop_un.csv: -------------------------------------------------------------------------------- 1 | 1950,2.525149 2 | 1951,2.572850917 3 | 1952,2.619292068 4 | 1953,2.665865392 5 | 1954,2.713172027 6 | 1955,2.761650981 7 | 1956,2.811572031 8 | 1957,2.863042795 9 | 1958,2.916030167 10 | 1959,2.970395814 11 | 1960,3.026002942 12 | 1961,3.082830266 13 | 1962,3.141071531 14 | 1963,3.201178277 15 | 1964,3.263738832 16 | 1965,3.329122479 17 | 1966,3.397475247 18 | 1967,3.468521724 19 | 1968,3.541674891 20 | 1969,3.616108749 21 | 1970,3.691172616 22 | 1971,3.766754345 23 | 1972,3.842873611 24 | 1973,3.919182332 25 | 1974,3.995304922 26 | 1975,4.071020434 27 | 1976,4.14613585 28 | 1977,4.220816737 29 | 1978,4.295664825 30 | 1979,4.371527871 31 | 1980,4.449048798 32 | 1981,4.528234634 33 | 1982,4.608962418 34 | 1983,4.69155984 35 | 1984,4.776392828 36 | 1985,4.863601517 37 | 1986,4.95337671 38 | 1987,5.045315871 39 | 1988,5.138214688 40 | 1989,5.23 41 | 1990,5.320816667 42 | 1991,5.408908724 43 | 1992,5.49489957 44 | 1993,5.578865109 45 | 1994,5.661086346 46 | 1995,5.741822412 47 | 1996,5.82101675 48 | 1997,5.898688337 49 | 1998,5.975303657 50 | 1999,6.05147801 51 | 2000,6.127700428 52 | 2001,6.204147026 53 | 2002,6.280853817 54 | 2003,6.357991749 55 | 2004,6.435705595 56 | 2005,6.514094605 57 | 2006,6.593227977 58 | 2007,6.673105937 59 | 2008,6.753649228 60 | 2009,6.834721933 61 | 2010,6.916183482 62 | 2011,6.99799876 63 | 2012,7.080072417 64 | 2013,7.162119434 65 | 2014,7.243784 66 | 2015,7.349472 67 | 2016, 68 | -------------------------------------------------------------------------------- /code/notebooks/baseball.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/baseball.mlx -------------------------------------------------------------------------------- /code/notebooks/baseball2.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/baseball2.mlx -------------------------------------------------------------------------------- /code/notebooks/low_pass.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/low_pass.mlx -------------------------------------------------------------------------------- /code/notebooks/penny.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/penny.mlx -------------------------------------------------------------------------------- /code/notebooks/sir_model.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/sir_model.mlx -------------------------------------------------------------------------------- /code/notebooks/world_pop_1.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/world_pop_1.mlx -------------------------------------------------------------------------------- /code/notebooks/world_pop_2.mlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/code/notebooks/world_pop_2.mlx -------------------------------------------------------------------------------- /code/other/Evaluation3.m: -------------------------------------------------------------------------------- 1 | av=zeros(10,1); 2 | bv=zeros(10,1); 3 | av(1)=200; 4 | bv(1)=100; 5 | for i=2:10; 6 | froma=round(0.03*av(i-1)); 7 | fromb=round(0.05*bv(i-1)); 8 | a=av(i-1)-froma+fromb; 9 | b=bv(i-1)-fromb+froma; 10 | av(i)=a; 11 | bv(i)=b; 12 | end 13 | [av bv] 14 | -------------------------------------------------------------------------------- /code/other/HopperSimNew.m: -------------------------------------------------------------------------------- 1 | clear 2 | 3 | lrest = .0843; 4 | l = .21; 5 | m = .09; 6 | dx = l - lrest; 7 | k = 76.2; 8 | g = 9.8; 9 | c = .03; 10 | 11 | ry(1) = 0; 12 | vy(1) = sqrt (3 * (k * dx^2) / m); 13 | ay(1) = -9.8; 14 | 15 | i = 1; 16 | t(1) = 0; 17 | 18 | while ry(i)>=0 19 | i=i + 1; 20 | dt=.001; 21 | t(i)=i * dt; 22 | 23 | ry(i) = vy(i-1) * dt + ry(i-1); 24 | vy(i) = ay(i-1) * dt + vy(i-1); 25 | ay(i) = -g - (c * (vy(i))^2) / m; 26 | 27 | end 28 | 29 | plot (t,ry,'r') 30 | -------------------------------------------------------------------------------- /code/other/L_find.m: -------------------------------------------------------------------------------- 1 | td = sym('td'); 2 | pd = sym('pd'); 3 | 4 | theta = sym('theta'); %primary angle 5 | % t = sym('t'); 6 | dthetadt = sym('dthetadt');%diff(theta) 7 | phi = sym('phi'); 8 | dphidt = sym('dphidt'); diff(phi) 9 | 10 | l1=sym('l1'); %length of the upper lever arm 11 | l2=sym('l2'); %length of th lower lever arm 12 | l3 = sym('l3'); %throwing arm 13 | m1=sym('m1'); % mass of the upper lever arm 14 | m2=sym('m2'); %mass of the lower lever arm 15 | m3=sym('m3'); %throwing arm 16 | 17 | 18 | %converting the Y cordinance into theta cordinance 19 | Y1=-l1*cos(1/2*td^2); 20 | dY1dt= l1*sin(1/2*td^2)*td; 21 | Y2=-l2*cos(1/2*pd^2) + Y1; 22 | dY2dt= l2*sin(1/2*pd^2)*pd +dY1dt; 23 | Y3=-l3*cos(1/2*td^2); 24 | dY3dt= -l3*sin(1/2*td^2)*td; 25 | 26 | 27 | %conveting the X cordinace to phi cordinance 28 | X1= l1*sin((1/2)*td^2); 29 | dX1dt= l1*cos((1/2)*td^2)*td; 30 | X2=l2*sin(1/2*pd^2)+X1; 31 | dX2dt= l2*cos(1/2*pd^2)*pd+ dX1dt; 32 | X3=-l3*sin(phi); 33 | dX3dt= -l3*cos(1/2*td^2)*td; 34 | 35 | g =-9.8 %gravity 36 | 37 | T = 1/2*m1*(dX1dt^2+dY1dt^2) + 1/2*m2*(dX2dt^2+dY2dt^2)+1/2*m3*(dX3dt^2+dY3dt^2); 38 | U = g*m1*Y1 + g*m2*Y2 +g*m3*Y3; 39 | 40 | L = T-U; %lagrangian 41 | 42 | q = diff(L,td); 43 | w = diff(L,theta)-diff(q,t); 44 | e = diff(L,pd); 45 | r = diff(L,phi)-diff(e,t); 46 | -------------------------------------------------------------------------------- /code/other/ang_quat.m: -------------------------------------------------------------------------------- 1 | function [ quat ] = ang_quat ( ang ) 2 | % ang is a set of euler angles. 3 | % compute the corresponding quaternion, using the 4 | % formulae from the wikipedia page 5 | % http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles 6 | 7 | a1 = ang(1); 8 | a2 = ang(2); 9 | a3 = ang(3); 10 | 11 | c1 = cos(a1/2); 12 | c2 = cos(a2/2); 13 | c3 = cos(a3/2); 14 | 15 | s1 = sin(a1/2); 16 | s2 = sin(a2/2); 17 | s3 = sin(a3/2); 18 | 19 | q0 = c1*c2*c3 + s1*s2*s3; 20 | q1 = s1*c2*c3 - c1*s2*s3; 21 | q2 = c1*s2*c3 + s1*c2*s3; 22 | q3 = c1*c2*s3 - s1*s2*c3; 23 | 24 | quat = [q0 q1 q2 q3]'; 25 | 26 | -------------------------------------------------------------------------------- /code/other/ang_rot.m: -------------------------------------------------------------------------------- 1 | function [ rot ] = ang_rot (ang) 2 | % given the euler angles in ang, compute the 3 | % rotation matrix, using the Wikipedia page 4 | % http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles 5 | 6 | s1 = sin(ang(1)); 7 | s2 = sin(ang(2)); 8 | s3 = sin(ang(3)); 9 | c1 = cos(ang(1)); 10 | c2 = cos(ang(2)); 11 | c3 = cos(ang(3)); 12 | 13 | rot = [ c2*c3, -c1*s3 + s1*s2*c3, s1*s3 + c1*s2*c3; 14 | c2*s3, c1*c3 + s1*s2*s3, -s1*c3 + c1*s2*s3; 15 | -s2, s1*c2, c1*c2 ]; 16 | -------------------------------------------------------------------------------- /code/other/av_quat.m: -------------------------------------------------------------------------------- 1 | function [ quat ] = av_quat(av) 2 | % convert from angle vector form to quaterion 3 | % [ q0, q1, q2, q3 ] 4 | % = [ cos(Phi/2), sin(Phi/2) w1, sin(Phi/2) w2, sin(Phi/2) w3 ] 5 | 6 | Phi = av(1); 7 | w = av(2:4); 8 | 9 | c = cos(Phi/2); 10 | s = sin(Phi/2); 11 | quat = [c, w(1)*s, w(2)*s, w(3)*s]; 12 | -------------------------------------------------------------------------------- /code/other/av_rot.m: -------------------------------------------------------------------------------- 1 | function [ rot ] = av_rot(av) 2 | % compute the rotation matrix from the angle vector form 3 | % of the quaternion using the matrix on pg 101 of Mukundan 4 | 5 | Phi = av(1); 6 | l = av(2); 7 | m = av(3); 8 | n = av(4); 9 | 10 | c = cos(Phi); 11 | s = sin(Phi); 12 | omc = 1 - c; 13 | 14 | rot(1,1) = (l^2)*omc + c; 15 | rot(2,1) = (l*m)*omc + n*s; 16 | rot(3,1) = (n*l)*omc - m*s; 17 | 18 | rot(1,2) = (l*m)*omc - n*s; 19 | rot(2,2) = (m^2)*omc + c; 20 | rot(3,2) = (m*n)*omc + l*s; 21 | 22 | rot(1,3) = (n*l)*omc + m*s; 23 | rot(2,3) = (m*n)*omc - l*s; 24 | rot(3,3) = (n^2)*omc + c; 25 | -------------------------------------------------------------------------------- /code/other/chaos.m: -------------------------------------------------------------------------------- 1 | function dVdt = f(t, V) 2 | x = V(1); 3 | y = V(2); 4 | z = V(3); 5 | 6 | sigma = 10; 7 | b = 8/3; 8 | r = 99.96; 9 | 10 | dxdt = sigma * (y-x); 11 | dydt = x * (r-z) - y; 12 | dzdt = x*y - b*z; 13 | 14 | dVdt = [dxdt; dydt; dzdt]; % pack the results in a column vector 15 | end 16 | -------------------------------------------------------------------------------- /code/other/chris.m: -------------------------------------------------------------------------------- 1 | function res = eb_beam() 2 | 3 | clear all 4 | 5 | syms w x wx wxx wxxx b c1 c2 c3 c4 L bL 6 | 7 | 8 | 9 | w = c1*cos(b*x) + c2*sin(b*x) + c3*cosh(b*x) + c4*sinh(b*x) 10 | wx = diff(w,x) 11 | wxx = diff(w,x,2) 12 | wxxx = diff(w,x,3) 13 | 14 | 15 | 16 | % apply boundary conditions 17 | 18 | ws = subs(w, {x}, {0}) 19 | wxs = subs(wx, {x}, {0}) 20 | wxxs = subs (wxx, {x}, {L}) 21 | wxxxs = subs (wxxx, {x}, {L}) 22 | 23 | for e = {ws wxs wxxs wxxxs} 24 | for c = {c1 c2 c3 c4} 25 | coeffs(e,c) 26 | end 27 | end 28 | 29 | pause 30 | 31 | % need to group coefficients of c1 c2 c3 c4 into a square matrix 32 | % how can this be done? need some kind of collect 33 | 34 | 35 | 36 | % by inspection 37 | [c t] = coeffs(wxxxs, c1) 38 | [c t] = coeffs(wxxxs, c2) 39 | [c t] = coeffs(wxxxs, c3) 40 | [c t] = coeffs(wxxxs, c4) 41 | c = coeffs(ws, c4) 42 | pause 43 | 44 | 45 | char_det = [ 1 0 1 0; 0 b 0 b; ... 46 | 47 | -cos(b*L)*b^2 -sin(b*L)*b^2 cosh(b*L)*b^2 sinh(b*L)*b^2; ... 48 | 49 | sin(b*L)*b^3 -cos(b*L)*b^3 sinh(b*L)*b^3 cosh(b*L)*b^3] 50 | 51 | 52 | 53 | 54 | 55 | % det = 0 yields characteristic eqn in which c's .ne. 0 56 | 57 | char_eqn = simplify( det(char_det) ) 58 | 59 | char_eqn = (1+cos(bL)*cosh(bL)) 60 | 61 | f = matlabFunction(char_eqn) 62 | 63 | 64 | % need string to num? 65 | 66 | 67 | 68 | 69 | 70 | bln = fzero(f, 0) 71 | 72 | 73 | 74 | 75 | 76 | %solve (char_eqn, b) 77 | 78 | 79 | -------------------------------------------------------------------------------- /code/other/comp_err.m: -------------------------------------------------------------------------------- 1 | function [rms] = comp_err (ang, noise, func) 2 | % ang is the set of euler angles we are interested in. 3 | % noise is the level of instrumentation error (0.01 seems to 4 | % be an interesting value) 5 | % func is a handle for a function that takes G, H and returns 6 | % two values; the first is the recovered rotation 7 | % matrix and the second is ignored. 8 | 9 | % generate N sets of simulated data with random noise 10 | % added, then invoke the given function to try to recover 11 | % the rotation matrix. 12 | 13 | % Compute the difference between the original (correct) rot 14 | % and the recovered rot_out, in terms of euler angles. 15 | 16 | % return the root-mean-squared error as a 3-vector with 17 | % elements dphi, dtheta, dpsi. 18 | 19 | sum = zeros(size(ang)); 20 | N = 2; 21 | for i=1:N 22 | [ G, H ] = data_gen (ang, noise); 23 | rot = ang_rot(ang); 24 | [ rot_out, other ] = feval(func, G, H); 25 | 26 | % rot_err is the rotation that takes rot onto rot_out 27 | rot_err = rot_out * rot'; 28 | 29 | % ang_err is the error rotation in terms of euler angles 30 | ang_err = rot_ang(rot_err); 31 | 32 | sum = sum + ang_err.^2; 33 | end 34 | rms = sqrt(sum/N); 35 | end 36 | -------------------------------------------------------------------------------- /code/other/comp_err2.m: -------------------------------------------------------------------------------- 1 | function [rms] = comp_err (ang, noise, ang_error) 2 | sum = zeros(size(ang)); 3 | N=2; 4 | for i=1:N 5 | [ G, H ] = data_gen (ang, noise, ang_error); 6 | rot = ang_rot(ang) 7 | [ rot_out, quat, ang_out, av ] = tiax_Joel (G,H); 8 | rot_out = quat_rot(quat) 9 | 10 | % rot_err is the rotation that takes rot onto rot_out 11 | rot_err = rot_out * rot' 12 | 13 | % ang_err is the error rotation in terms of euler angles 14 | ang_err = rot_ang(rot_err) 15 | 16 | sum = sum + ang_err.^2 17 | end 18 | rms = sqrt(sum/N); 19 | end 20 | 21 | 22 | function [ M ] = squash (M) 23 | low = M < -6; 24 | M = M + low * 2*pi; 25 | high = M > 6; 26 | M = M - high * 2*pi; 27 | end 28 | -------------------------------------------------------------------------------- /code/other/compute_euler.m: -------------------------------------------------------------------------------- 1 | function [ phi, theta, psi ] = compute_euler( rotation, trans ) 2 | 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % this function computes the euler angles from the known 5 | % rotation matrix found by the quaternions 6 | % the original rotation matrix to which we're comparing: rotation 7 | % and if we're working with the original matrix (trans = 0) or not (=1) 8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 | if ( trans == 0 ) 10 | r_mat = rotation; 11 | else 12 | r_mat = rotation'; 13 | end 14 | 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | % use bottom row of rotation matrix to get theta and phi 17 | % (3,1) term of rotation matrix is -sin(theta) 18 | % (3,2) term of rotation matrix is sin(phi)cos(theta) 19 | % (3,3) term of rotation matrix is cos(phi)cos(theta) 20 | % therefore, tan(phi) = (3,2)/(3,3) 21 | % tan(theta) = -(3,1)/sqrt((3,2)^2+(3,3)^2) 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | phi = atan2(r_mat(3,2), r_mat(3,3)); 24 | theta = atan2(-r_mat(3,1), sqrt(r_mat(3,2)^2 + r_mat(3,3)^2)); 25 | 26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 | % (1,1) term of rotation matrix is cos(theta)cos(psi) 28 | % (2,1) term of rotation matrix is cos(theta)sin(psi) 29 | % therefore, tan(psi) = (2,1)/(1,1) 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | psi = atan2(r_mat(2,1), r_mat(1,1)); 32 | 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | % dealing with singularity 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | test_theta = ( abs(theta) > pi/2 - 1e-4 ) & ( abs(theta) < pi/2 + 1e-4 ); 37 | if (test_theta) 38 | phi = -999; 39 | psi = -999; 40 | end 41 | -------------------------------------------------------------------------------- /code/other/compute_euler2.m: -------------------------------------------------------------------------------- 1 | function [ ang ] = compute_euler ( q ) 2 | % q is a quaternion containing euler parameters 3 | % compute the corresponding euler angles, using the 4 | % formulae from the wikipedia page 5 | 6 | q0 = q(1); 7 | q1 = q(2); 8 | q2 = q(3); 9 | q3 = q(4); 10 | 11 | y = 2 * (q0*q1 - q2*q3); 12 | x = 1 - 2 * (q1^2 + q2^2); 13 | ang(1) = atan2(y, x); 14 | 15 | s = 2 * (q0*q2 - q3*q1); 16 | ang(2) = asin(s); 17 | 18 | y = 2 * (q0*q3 - q1*q2); 19 | x = 1 - 2 * (q2^2 + q3^2); 20 | ang(3) = atan2(y, x); 21 | 22 | -------------------------------------------------------------------------------- /code/other/copper.m: -------------------------------------------------------------------------------- 1 | function res = rate_func(t, Q) 2 | m = 10; % mass of the block in kg 3 | T_block = 30; % temperature of the block in degC 4 | T_out = 0; % temperature of the environment degC 5 | 6 | density = 8.94 * 0.001 / 0.01^3; % g/cm3 * (kg/g) / (m/cm)^3 7 | volume = m / density; % m^3 8 | 9 | length = volume^(1/3); % m 10 | area = 6 * length^2; % m^2 11 | 12 | r_value = 30; 13 | resistivity = r_value * 0.1761; % K m^2 / W 14 | 15 | deltaT = T_out - T_block; % K (also degC) 16 | 17 | % compute the rate of change for internal energy, dUdt 18 | dUdt = 1/resistivity * area * deltaT; % W (aka J/s) 19 | 20 | c = 386; % specific heat of copper in J / (kg K) 21 | 22 | % compute the rate of change in temperature, dQdt 23 | dQdt = dUdt / m / c; 24 | res = dQdt; 25 | end 26 | -------------------------------------------------------------------------------- /code/other/copper1.m: -------------------------------------------------------------------------------- 1 | 2 | m = 10; % mass of the block in kg 3 | T_block = 30; % temperature of the block in degC 4 | T_out = 0; % temperature of the environment degC 5 | 6 | density = 8.94 * 0.001 / 0.01^3; % g/cm3 * (kg/g) / (m/cm)^3 7 | volume = m / density; % m^3 8 | 9 | length = volume^(1/3); % m 10 | area = 6 * length^2; % m^2 11 | 12 | r_value = 30; 13 | resistivity = r_value * 0.1761; % K m^2 / W 14 | 15 | deltaT = T_out - T_block; % K (also degC) 16 | dUdt = 1/resistivity * area * deltaT; % W (aka J/s) 17 | 18 | c = 386; % specific heat of copper in J / (kg K) 19 | 20 | dQdt = dUdt / m / c; -------------------------------------------------------------------------------- /code/other/copper_euler.m: -------------------------------------------------------------------------------- 1 | t_end = 24 * 3600; % 24 hours in seconds 2 | n = 4000; % number of time steps 3 | timestep = t_end / n; % size of timestep in seconds 4 | 5 | T(1) = 30; % initial temperature in degC 6 | 7 | for i = 1:n 8 | dTdt = copper_func(0, T(i)); 9 | T(i+1) = T(i) + dTdt * timestep; 10 | end 11 | 12 | T(end) -------------------------------------------------------------------------------- /code/other/copper_func.m: -------------------------------------------------------------------------------- 1 | function res = copper_func(t, T) 2 | m = 10; % mass of the block in kg 3 | T_block = T; % temperature of the block in degC 4 | T_out = 0; % temperature of the environment degC 5 | 6 | % find the size and area of the block 7 | density = 8.94 * 0.001 / 0.01^3; % g/cm3 * (kg/g) / (m/cm)^3 8 | volume = m / density; % m^3 9 | 10 | length = volume^(1/3); % m 11 | area = 6 * length^2; % m^2 12 | 13 | % convert american r-value to SI r-value 14 | r_value_english = 30; % dram fathoms per fortnight 15 | r_value = r_value_english * 0.1761; % K m^2 / W 16 | 17 | % compute the rate of heat (energy) flow, dU/dt 18 | deltaT = T_out - T_block; % K (also degC) 19 | dUdt = 1/r_value * area * deltaT; % W (aka J/s) 20 | 21 | % compute the rate of temperature change, dT/dt 22 | c = 386; % specific heat of copper in J / (kg K) 23 | dTdt = dUdt / m / c; % K / s 24 | res = dTdt; 25 | end 26 | -------------------------------------------------------------------------------- /code/other/copper_ode45.m: -------------------------------------------------------------------------------- 1 | t_end = 24 * 3600; % 24 hours in seconds 2 | T0 = 30; % initial temperature in degC 3 | 4 | [Time,Temp] = ode45(@copper_func, [0, t_end], T0); 5 | Temp(end) -------------------------------------------------------------------------------- /code/other/copper_script.m: -------------------------------------------------------------------------------- 1 | 2 | m = 10; % mass of the block in kg 3 | T_block = 30; % temperature of the block in degC 4 | T_out = 0; % temperature of the environment degC 5 | 6 | % find the size and area of the block 7 | density = 8.94 * 0.001 / 0.01^3; % g/cm3 * (kg/g) / (m/cm)^3 8 | volume = m / density; % m^3 9 | 10 | length = volume^(1/3); % m 11 | area = 6 * length^2; % m^2 12 | 13 | % convert american r-value to SI r-value 14 | r_value_english = 30; % dram fathoms per fortnight 15 | r_value = r_value_english * 0.1761; % K m^2 / W 16 | 17 | % compute the rate of heat (energy) flow, dU/dt 18 | deltaT = T_out - T_block; % K (also degC) 19 | dUdt = 1/r_value * area * deltaT; % W (aka J/s) 20 | 21 | % compute the rate of temperature change, dT/dt 22 | c = 386; % specific heat of copper in J / (kg K) 23 | dTdt = dUdt / m / c; % K / s 24 | 25 | -------------------------------------------------------------------------------- /code/other/corn.m: -------------------------------------------------------------------------------- 1 | function res = corn() 2 | % run a simulation of the enzyme action in fuel alcohol production 3 | % and return the time (in hours) to reduce the unavailable starch 4 | % concentation to 0.01 (mMol/L) 5 | options = odeset('Events', @event_func); 6 | 7 | tend = 50 * 60 * 60; % 50 hours in seconds 8 | Sinit = 0.1512; % mMol/L 9 | Sinit = Sinit / 1000; % now Mol/L 10 | [T, M] = ode45(@rate_func, [0,tend], [Sinit 0 0 0 0 0], options); 11 | plot(T, M) 12 | 13 | % return the end time in hours 14 | res = T(end) / 60 / 60; 15 | end 16 | 17 | function [value, isterminal, direction] = event_func(t, X) 18 | % check whether the concentration of unavailable starch has 19 | % reached its final value (in Mol/L) 20 | value = X(1) - 0.01e-3; 21 | isterminal = 1; 22 | direction = -1; 23 | end 24 | 25 | function res = rate_func(t, X) 26 | % compute the rate of change for each of the six substrates, 27 | % given the vector of concentrations (X) 28 | r0 = reaction_rate(0, X); 29 | for i=1:12 30 | r(i) = reaction_rate(i, X); 31 | end 32 | 33 | % since rate constants are not available for two of the 34 | % reactions, we have to fudge 35 | r(4) = 0.05 * r(3); 36 | r(7) = 0.05 * r(6); 37 | 38 | % the following rates are in mMol/L / minute (or second?) 39 | Sun = -r0; 40 | Savail = r0 - r(1) - r(2) - r(3) - r(4); 41 | D = r(1) - r(5) - r(6) - r(7) - r(8); 42 | M = r(3) + r(6) + r(10) + r(11) - r(9) - r(12); 43 | MT = r(2) + r(5) - r(10) - r(11); 44 | G = r(4) + r(7) + r(8) + r(9) + r(10) + r(11) + r(12); 45 | 46 | % pack the results into a column vector 47 | res = [Sun Savail D M MT G]'; 48 | end 49 | 50 | function res = reaction_rate(i, X) 51 | % compute the rate of the (i)th reaction, given the vector of 52 | % concentrations (X) 53 | 54 | % kcats are in (1/seconds) 55 | kcat = [14.48 0.16 0.36 -Inf 0.16 0.36 -Inf 0.85 0.13 0.27 1.07 1.01]; 56 | 57 | % Kms are in (Mol/L) 58 | Km = [37.17 0.46 0.09 -Inf 0.46 0.09 -Inf 0.25 1210 360 1300 1300]; 59 | 60 | % which enzyme and substrate pertain to each reaction? 61 | enzyme = [1 1 1 1 1 1 1 2 2 2 3 3]; 62 | substrate = [2 2 2 2 3 3 3 3 4 5 5 4]; 63 | 64 | % enzyme concentrations in Mol/L 65 | E = [9.8e-5 1e-4 3.02e-2]; 66 | 67 | if i == 0 68 | Vmax = 0.005; 69 | Km = 250; 70 | rate = Vmax * X(1) / (Km + X(1)); 71 | else 72 | j = enzyme(i); 73 | k = substrate(i); 74 | rate = kcat(i) * E(j) * X(k) / (Km(i) + X(k)); 75 | end 76 | res = rate; 77 | end 78 | -------------------------------------------------------------------------------- /code/other/data_gen.m: -------------------------------------------------------------------------------- 1 | function [ G,H ] = data_gen (ang, noise) 2 | % ang is the actual set of Euler angles that describe the rotation 3 | % from body frame to earth frame. 4 | % noise is the size of the instrument error (no units). 5 | 6 | % g is grav, Hh is horizontal and Hv is vertical component of mag field 7 | % in Earth's frame 8 | g = 9.8; 9 | Hh = 4E4; 10 | Hv = 2E4; 11 | 12 | gnoise = randn(3,1) * noise * g; 13 | hnoise = randn(3,1) * noise * sqrt(Hh^2+Hv^2); 14 | 15 | rot = ang_rot(ang); 16 | 17 | G = gnoise + rot' * [0, 0, g]'; 18 | H = hnoise + rot' * [Hh 0 Hv]'; 19 | -------------------------------------------------------------------------------- /code/other/data_gen3.m: -------------------------------------------------------------------------------- 1 | % takes input of roll, pitch and heading angles and outputs accel and mag 2 | % data in body frame with noise 3 | function [ G,H ] = data_gen (ang, noise) 4 | % g is grav, Hh is horizontal and Hv is vertical component of mag field 5 | % in Earth's frame 6 | g = 9.8; 7 | Hh = 4E4; 8 | Hv = 2E4; 9 | 10 | gnoise = noise*g; 11 | hnoise = noise*(Hh^2+Hv^2)^0.5; 12 | 13 | %ith col: axis i reading 14 | G = zeros(3, 1); 15 | H = zeros(3, 1); 16 | 17 | rot = ang_rot(ang) 18 | 19 | G = rot' * [0, 0, -g]'; 20 | 21 | H = rot' * [Hh 0 Hv]'; 22 | -------------------------------------------------------------------------------- /code/other/direct.m: -------------------------------------------------------------------------------- 1 | function [ rot, ang ] = direct( G, H ) 2 | % Inputs: 3-vectors G accelerometer data and H magnetometer data. 3 | % Output: rotation matrix (body to earth) 4 | % this is the computation documented in the memo from TIAX 5 | 6 | gx = G(1); 7 | gy = G(2); 8 | gz = G(3); 9 | 10 | hx = H(1); 11 | hy = H(2); 12 | hz = H(3); 13 | 14 | phi = atan2(gy, gz); 15 | theta = -atan2(gx, sqrt(gy^2 + gz^2)); 16 | 17 | cphi = cos(phi); 18 | sphi = sin(phi); 19 | stheta = sin(theta); 20 | 21 | y = cphi * hy - sphi * hz; 22 | x = cos(theta) * hx + stheta * sphi * hy + stheta * cphi * hz; 23 | psi = -atan2(y, x); 24 | 25 | ang = [phi theta psi]'; 26 | rot = ang_rot(ang); -------------------------------------------------------------------------------- /code/other/double_pend.m: -------------------------------------------------------------------------------- 1 | function res = double_pendulum() 2 | syms x1 y1 x2 y2 t real 3 | syms g m1 m2 l1 l2 real 4 | syms V T L real 5 | syms th1 th2 om1 om2 aa1 aa2 real 6 | 7 | x1 = l1 * sin(th1); 8 | y1 = -l1 * cos(th1); 9 | x2 = x1 + l2 * sin(th2); 10 | y2 = y1 - l2 * cos(th2); 11 | 12 | vx1 = mydiff(x1, 1) 13 | vy1 = mydiff(y1, 1) 14 | vx2 = mydiff(x2, 1) 15 | vy2 = mydiff(y2, 1) 16 | 17 | v1sq = vx1^2 + vy1^2; 18 | v2sq = vx2^2 + vy2^2; 19 | 20 | V = m1 * g * y1 + m2 * g * y2; 21 | T = m1 * v1sq / 2 + m2 * v2sq / 2; 22 | L = T - V; 23 | pretty(simplify(L)) 24 | 25 | dLdom1 = diff(L, om1); 26 | ddt1 = mydiff(dLdom1, 1); 27 | dLdth1 = diff(L, th1); 28 | EL1 = simplify(ddt1 - dLdth1) 29 | solve(EL1, aa1) 30 | 31 | dLdom2 = diff(L, om2); 32 | ddt2 = mydiff(dLdom2, 1); 33 | dLdth2 = diff(L, th2); 34 | EL2 = simplify(ddt2 - dLdth2) 35 | solve(EL2, aa2) 36 | 37 | res = L 38 | end 39 | 40 | 41 | 42 | function res = mydiff(f, n) 43 | syms dot1 dot2 t real 44 | syms th1 th2 om1 om2 aa1 aa2 real 45 | 46 | th1ft = exp(dot1*t); 47 | om1ft = diff(th1ft, t); 48 | aa1ft = diff(th1ft, t, 2); 49 | 50 | th2ft = exp(dot2*t); 51 | om2ft = diff(th2ft, t); 52 | aa2ft = diff(th2ft, t, 2); 53 | 54 | FT = {aa1ft, om1ft, th1ft, aa2ft, om2ft, th2ft}; 55 | SYM = {aa1, om1, th1, aa2, om2, th2}; 56 | STR = {'aa1', 'om1', 'th1', 'aa2', 'om2', 'th2'}; 57 | 58 | temp = subs(f, SYM, FT); 59 | temp = diff(temp, t, n); 60 | temp = subs(temp, FT, STR); 61 | 62 | res = temp; 63 | end 64 | 65 | function res = pol2vec(r, theta) 66 | res = r * [cos(theta); sin(theta)]; 67 | end 68 | 69 | function res = mynorm(V) 70 | res = (V(1)^2 + V(2)^2) ^ (1/2); 71 | end 72 | -------------------------------------------------------------------------------- /code/other/double_pend2.m: -------------------------------------------------------------------------------- 1 | function res = double_pendulum() 2 | syms g m1 m2 l1 l2 positive 3 | syms V T L real 4 | syms t th1 th2 om1 om2 aa1 aa2 real 5 | 6 | th1 = sym('th1(t)'); 7 | th2 = sym('th2(t)'); 8 | 9 | X1 = pol2vec(l1, th1-pi/2); 10 | X2 = X1 + pol2vec(l2, th2-pi/2); 11 | 12 | V1 = diff(X1, t); 13 | V2 = diff(X2, t); 14 | 15 | v1sq = dot(V1, V1); 16 | v2sq = dot(V2, V2); 17 | 18 | V = m1 * g * X1(2) + m2 * g * X2(2); 19 | T = m1 * v1sq / 2 + m2 * v2sq / 2; 20 | L = T - V; 21 | L = subs(L, {diff(th1,t) diff(th2,t)}, {om1 om2}) 22 | simplify(L) 23 | 24 | M = (m1 + m2) / 2 * l1^2 * om1^2 + m2/2 * l2^2 * om2^2 + ... 25 | m2 * l1 * l2 * om1 * om2 * cos(th1-th2) + ... 26 | (m1 + m2) * g * l1 * cos(th1) + m2 * g * l2 * cos(th2); 27 | 28 | simplify(L-M); 29 | 30 | dLdom1 = diff(L, om1); 31 | ddt1 = diff(dLdom1, t); 32 | dLdth1 = diff(L, 'th1'); 33 | EL1 = simplify(ddt1 - dLdth1); 34 | %pretty(EL1); 35 | 36 | %FL1 = (m1 + m2) * l1 * aa1 + m2 * l2 * aa2 * cos(th1-th2) + ... 37 | % m2 * l2 * om2^2 * sin(th1-th2) + g * (m1 + m2) * sin(th1) 38 | 39 | %diffs = {sin(th1-th2), cos(th1-th2)} 40 | %expand = {sin(th1) * cos(th2) - cos(th1) * sin(th2), 41 | % cos(th1) * cos(th2) + sin(th1) * sin(th2)} 42 | %FL1 = subs(FL1, diffs, expand) 43 | 44 | %simplify(EL1 - FL1) 45 | 46 | dLdom2 = diff(L, om2); 47 | ddt2 = diff(dLdom2, t); 48 | dLdth2 = diff(L, 'th2'); 49 | EL2 = simplify(ddt2 - dLdth2); 50 | %solve(EL2, aa2) 51 | %pretty(EL2); 52 | 53 | FL2 = m2 * l2 * aa2 + m2 * l1 * aa1 * cos(th1-th2) - ... 54 | m2 * l1 * om1^2 * sin(th1-th2) + m2 * g * sin(th2); 55 | 56 | simplify(EL2 - FL2); 57 | end 58 | 59 | 60 | 61 | function res = mydiff(f, n) 62 | syms dot1 dot2 t real 63 | syms th1 th2 om1 om2 aa1 aa2 real 64 | 65 | th1ft = 'th1(t)'; 66 | om1ft = diff(th1ft, t); 67 | aa1ft = diff(th1ft, t, 2); 68 | 69 | th2ft = 'th2(t)'; 70 | om2ft = diff(th2ft, t); 71 | aa2ft = diff(th2ft, t, 2); 72 | 73 | FT = {aa1ft, om1ft, th1ft, aa2ft, om2ft, th2ft}; 74 | SYM = {aa1, om1, th1, aa2, om2, th2}; 75 | STR = {'aa1', 'om1', 'th1', 'aa2', 'om2', 'th2'}; 76 | 77 | temp = subs(f, SYM, FT); 78 | temp = diff(temp, t, n); 79 | temp = simplify(temp) 80 | temp = subs(temp, FT, STR); 81 | 82 | res = temp; 83 | end 84 | 85 | function res = pol2vec(r, theta) 86 | res = r * [cos(theta); sin(theta)]; 87 | end 88 | 89 | function res = mynorm(V) 90 | res = (V(1)^2 + V(2)^2) ^ (1/2); 91 | end 92 | -------------------------------------------------------------------------------- /code/other/double_pend3.m: -------------------------------------------------------------------------------- 1 | function res = double_pendulum() 2 | syms g m1 m2 l1 l2 positive 3 | syms V T L real 4 | syms th1 th2 om1 om2 aa1 aa2 real 5 | 6 | X1 = pol2vec(l1, th1-pi/2); 7 | X2 = X1 + pol2vec(l2, th2-pi/2); 8 | 9 | V1 = mydiff(X1, 1); 10 | V2 = mydiff(X2, 1); 11 | 12 | v1sq = dot(V1, V1); 13 | v2sq = dot(V2, V2); 14 | 15 | V = m1 * g * X1(2) + m2 * g * X2(2); 16 | T = m1 * v1sq / 2 + m2 * v2sq / 2; 17 | L = T - V; 18 | simplify(L); 19 | 20 | M = (m1 + m2) / 2 * l1^2 * om1^2 + m2/2 * l2^2 * om2^2 + ... 21 | m2 * l1 * l2 * om1 * om2 * cos(th1-th2) + ... 22 | (m1 + m2) * g * l1 * cos(th1) + m2 * g * l2 * cos(th2); 23 | 24 | simplify(L-M); 25 | 26 | dLdom1 = diff(L, om1); 27 | dLdom1 = simplify(dLdom1) 28 | ddt1 = mydiff(dLdom1, 1); 29 | ddt1 = simplify(ddt1) 30 | pretty(ddt1) 31 | dLdth1 = diff(L, th1); 32 | EL1 = simplify(ddt1 - dLdth1); 33 | pretty(EL1); 34 | 35 | %FL1 = (m1 + m2) * l1 * aa1 + m2 * l2 * aa2 * cos(th1-th2) + ... 36 | % m2 * l2 * om2^2 * sin(th1-th2) + g * (m1 + m2) * sin(th1) 37 | 38 | %diffs = {sin(th1-th2), cos(th1-th2)} 39 | %expand = {sin(th1) * cos(th2) - cos(th1) * sin(th2), 40 | % cos(th1) * cos(th2) + sin(th1) * sin(th2)} 41 | %FL1 = subs(FL1, diffs, expand) 42 | 43 | %simplify(EL1 - FL1) 44 | 45 | dLdom2 = diff(L, om2); 46 | ddt2 = mydiff(dLdom2, 1); 47 | dLdth2 = diff(L, th2); 48 | EL2 = simplify(ddt2 - dLdth2); 49 | %solve(EL2, aa2) 50 | pretty(EL2); 51 | 52 | FL2 = m2 * l2 * aa2 + m2 * l1 * aa1 * cos(th1-th2) - ... 53 | m2 * l1 * om1^2 * sin(th1-th2) + m2 * g * sin(th2); 54 | 55 | simplify(EL2 - FL2); 56 | end 57 | 58 | 59 | 60 | function res = mydiff(f, n) 61 | syms dot1 dot2 t real 62 | syms th1 th2 om1 om2 aa1 aa2 real 63 | 64 | aa1ft = dot1^2 * exp(dot1*t); 65 | om1ft = int(aa1ft, t); 66 | th1ft = int(om1ft, t); 67 | 68 | aa2ft = dot2^2 * exp(dot2*t); 69 | om2ft = int(aa2ft, t); 70 | th2ft = int(om2ft, t); 71 | 72 | FT = {aa1ft, om1ft, th1ft, aa2ft, om2ft, th2ft}; 73 | SYM = {aa1, om1, th1, aa2, om2, th2}; 74 | STR = {'aa1', 'om1', 'th1', 'aa2', 'om2', 'th2'}; 75 | 76 | temp = subs(f, SYM, FT); 77 | temp = diff(temp, t, n); 78 | temp = simplify(temp) 79 | temp = subs(temp, FT, STR); 80 | 81 | res = temp; 82 | end 83 | 84 | function res = pol2vec(r, theta) 85 | res = r * [cos(theta); sin(theta)]; 86 | end 87 | 88 | function res = mynorm(V) 89 | res = (V(1)^2 + V(2)^2) ^ (1/2); 90 | end 91 | -------------------------------------------------------------------------------- /code/other/duck45.m: -------------------------------------------------------------------------------- 1 | function duck45(beta) 2 | [t, M] = ode45(@slope, [0,2], [0,10]); 3 | H = M(:,1); 4 | V = M(:,2); 5 | plot(t,H) 6 | 7 | function res = slope(t, X) 8 | p = X(1); % the first component is position 9 | v = X(2); % the second component is velocity 10 | 11 | dpdt = v; 12 | dvdt = acceleration(t, p, v); 13 | 14 | res = [dpdt; dvdt]; % pack the results in a column vector 15 | end 16 | 17 | function res = acceleration(t, p, v) 18 | a_grav = -9.8; % acceleration of gravity in m/s^2 19 | m = duck_mass(10); % mass in kg 20 | F_drag = -beta * v^2 * sign(v); % drag force in N 21 | a_drag = F_drag / m; % drag acceleration in m/s^2 22 | res = a_grav + a_drag; % total acceleration 23 | end 24 | 25 | function res = duck_mass(radius) 26 | rho = 0.3; % duck density in g/cm^3 27 | res = rho * 4/3 * pi * radius^3 / 1000; % mass in kg 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /code/other/eigenquat.m: -------------------------------------------------------------------------------- 1 | function [ rot, quat ] = eigenquat(G,H) 2 | % given G accelerometer data and H magnetometer data, 3 | % compute the rotation matrix (body to earth) and the 4 | % quaternion representation of that rotation 5 | 6 | grav = 9.8; 7 | 8 | % change coordinates so that G has norm 1 9 | % and H is orthnormal to G 10 | G_tilde = -G/norm(G); 11 | H_tilde = H - dot(G_tilde,H)*G_tilde; 12 | H_tilde = H_tilde/norm(H_tilde); 13 | 14 | % compute transpose of the rotation matrix 15 | % rot = [H_tilde; cross(H_tilde,G_tilde); -G_tilde]; 16 | rot(:,1) = H_tilde; 17 | rot(:,2) = (cross(H_tilde,G_tilde)); 18 | rot(:,3) = (-G_tilde); 19 | 20 | % and then transpose it 21 | rot = rot'; 22 | 23 | % compute the quat. in the form of [angle, vector] 24 | av = rot_av(rot); 25 | 26 | % convert from angle vector to get out the quaternion 27 | quat = av_quat(av); 28 | 29 | % convert back to Euler angles 30 | % ang = quat_ang(quat); 31 | -------------------------------------------------------------------------------- /code/other/errfunc.m: -------------------------------------------------------------------------------- 1 | function res = errfunc(y) 2 | res = (1 + y + y^2 - y^3) / (1-y)^3 - 0.892; 3 | end 4 | -------------------------------------------------------------------------------- /code/other/evaluation4.m: -------------------------------------------------------------------------------- 1 | % stephani gulbrandsen 2 | 3 | a=0.9; 4 | deltat=1; 5 | N(1)=100; 6 | B=[0.007, 0.0036, 0.0011, 0.0001, 0.0004, 0.0013, 0.0028, 0.0043, 0.0056]; 7 | 8 | for i=2:9 9 | N(i)=N(i-1)+(a*N(i-1)-B(i-1).*N(i-1)^1.7)*deltat; 10 | end 11 | N 12 | -------------------------------------------------------------------------------- /code/other/evaluation5.m: -------------------------------------------------------------------------------- 1 | function zebra=result(i,j) 2 | zebra=sin(2*pi*i)+cos(2*pi*j); 3 | -------------------------------------------------------------------------------- /code/other/f.m: -------------------------------------------------------------------------------- 1 | function y = f(x) 2 | a = 4; 3 | y = x^2 - a 4 | end 5 | -------------------------------------------------------------------------------- /code/other/finitewell.m: -------------------------------------------------------------------------------- 1 | function res = finitewell( u0, start ) 2 | % Finds a root of the finite well equation for given u0, 3 | % with start as an initial guess. 4 | 5 | res = fzero(@error_func, start); 6 | 7 | function res = error_func(v) 8 | % This inner function is passed to fzero. 9 | % It uses elementwise operators (.* and .^), so it works 10 | % for both scalars and vectors. 11 | res = sqrt(u0^2 - v.^2) - v .* tan(v); 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /code/other/flying_duck.m: -------------------------------------------------------------------------------- 1 | function [t, h] = duck(v0) 2 | exact = 2 * 10 / 9.8 3 | dts = [0.0001 0.001 0.01 0.1]; 4 | for i = 1:length(dts) 5 | [T, V, H] = euler(v0, dts(i)); 6 | h(i) = max(H); 7 | t(i) = (T(end) - exact) / exact 8 | end 9 | loglog(dts, t) 10 | end 11 | 12 | function [T, V, H] = euler(v0, dt) 13 | T(1) = 0; 14 | H(1) = 0; 15 | V(1) = 10; 16 | 17 | i = 2; 18 | while 1 19 | T(i) = T(i-1) + dt; 20 | V(i) = V(i-1) + acceleration() * dt; 21 | H(i) = H(i-1) + V(i-1) * dt; 22 | if H(i) < 0 23 | break 24 | end 25 | i = i + 1; 26 | end 27 | end 28 | 29 | function res = acceleration() 30 | res = -9.8; 31 | r = 10; 32 | end 33 | -------------------------------------------------------------------------------- /code/other/fty.m: -------------------------------------------------------------------------------- 1 | function dydt = f(t, y) 2 | dydt = t + y 3 | end -------------------------------------------------------------------------------- /code/other/fyt.m: -------------------------------------------------------------------------------- 1 | function e = solvand (i) 2 | % if I am trying to reach a balance of a, how much will I be off by? 3 | a = 300000; 4 | e = balance(i) - a; 5 | end 6 | 7 | function b = balance (i) 8 | % given interest rate i, monthly payment p, how much money 9 | % will I have after n months? 10 | p = 200; 11 | n = 300; 12 | b = p/i * ((i+1)^n - 1); 13 | end 14 | -------------------------------------------------------------------------------- /code/other/interest.m: -------------------------------------------------------------------------------- 1 | function e = solvand (i) 2 | % if I am trying to reach a balance of a, how much will I be off by? 3 | a = 300000; 4 | e = balance(i) - a; 5 | end 6 | 7 | function b = balance (i) 8 | % given interest rate i, monthly payment p, how much money 9 | % will I have after n months? 10 | p = 200; 11 | n = 300; 12 | b = p/i * ((i+1)^n - 1); 13 | end 14 | -------------------------------------------------------------------------------- /code/other/koch.m: -------------------------------------------------------------------------------- 1 | function koch () 2 | clf; axis equal 3 | title 'quadric Koch curve by Allen' 4 | 5 | subplot(2,2,1) 6 | koch_square (1) 7 | 8 | subplot (2,2,2) 9 | koch_square (2) 10 | 11 | subplot (2,2,3) 12 | koch_square (3) 13 | 14 | subplot (2,2,4) 15 | koch_square (4) 16 | 17 | function koch_square (n) 18 | v1 = [0,0]; 19 | v2 = [1,0]; 20 | v3 = [1,1]; 21 | v4 = [0,1]; 22 | 23 | draw_koch (v1, v2, n) 24 | draw_koch (v2, v3, n) 25 | draw_koch (v3, v4, n) 26 | draw_koch (v4, v1, n) 27 | 28 | function draw_koch (v1, v2, n) 29 | v = v2 - v1; 30 | length = norm (v); 31 | 32 | if n == 0 33 | drawline (v1, v2); 34 | return 35 | end 36 | 37 | p1 = v1 + v / 3; 38 | p2 = v1 + 2 * v / 3; 39 | 40 | height = length/3 / sqrt(2); 41 | p3 = p1 + height * normalize (perp (v)); 42 | p4 = p2 - height * normalize (perp (v)); 43 | 44 | draw_koch (v1, p1, n-1); 45 | draw_koch (p1, p3, n-1); 46 | draw_koch (p3, p4, n-1); 47 | draw_koch (p4, p2, n-1); 48 | draw_koch (p2, v2, n-1); 49 | 50 | 51 | function vp = perp (v) 52 | vp = [-v(2), v(1)]; 53 | 54 | function vn = normalize (v) 55 | vn = v / norm (v); 56 | 57 | function drawline (v1, v2) 58 | z = [v1;v2]; 59 | line (z(:,1), z(:,2)) 60 | -------------------------------------------------------------------------------- /code/other/ladderde.m: -------------------------------------------------------------------------------- 1 | function result=ladderde(t,x,I,m,g,l); 2 | 3 | % This function returns the angular velocity and angular acceleration for a 4 | % ladder falling without friction 5 | 6 | % Unpack the input values 7 | theta=x(1); 8 | thetadot=x(2); 9 | 10 | numerator=m*g-(m*l/2)*thetadot^2*sin(theta); 11 | denominator=-2*I/(l*cos(theta)) - (m*l/2)*cos(theta); 12 | 13 | thetaddot=numerator./denominator; 14 | 15 | % Return the results 16 | result=[thetadot;thetaddot]; -------------------------------------------------------------------------------- /code/other/laddersim.m: -------------------------------------------------------------------------------- 1 | % Ladder Simulation 2 | 3 | close all 4 | clear 5 | x=[pi/2-1 0] % Set initial conditions: Theta=pi/2-1,thetadot=0 6 | options=odeset; % Prepare options to use in DE solver 7 | m=10; % Masses, lengths, and moment of inertia 8 | l=10; 9 | I=1/12*m*l^2; 10 | g=10; 11 | 12 | [t,y]=ode45(@ladderde,[0:0.02:10],x,options,I,m,g,l) 13 | 14 | figure; 15 | clf; % Prepare to animate 16 | i=1; 17 | for i=1:length(y) 18 | clf; 19 | axis([-10 10 -10 10]); 20 | axis image; % Set real aspect ratio for plot 21 | hold on; 22 | h=l/2*sin(y(i,1)); 23 | d=l/2*cos(y(i,1)); 24 | plot([-d,d],[0,h*2],'LineWidth',2); % Plot the ladder 25 | plot([-10 10],[0 0],'r'); % Plot the ground 26 | plot(0,h,'o'); % Plot the location of the center of mass 27 | drawnow; % Clear the plotting buffer (for better animation) 28 | hold off; 29 | end 30 | -------------------------------------------------------------------------------- /code/other/magpart.m: -------------------------------------------------------------------------------- 1 | function magpart(te) 2 | % te is the duration of the time range 3 | 4 | % initial conditions 5 | P = [-0.1 0 0]'; 6 | V = [0.1 0.1 0]'; 7 | 8 | % call ode45 9 | [T, M] = ode45(@part, [0, te], [P; V]); 10 | 11 | % plot the results 12 | X = M(:,1); 13 | Y = M(:,2); 14 | Z = M(:,3); 15 | comet3(X, Y, Z); 16 | 17 | %XY = M(:, 1:2) 18 | %plot(T,X) 19 | end 20 | 21 | function dXdt = part(t, X) 22 | % t is the current time; X contains the position and velocity 23 | % vectors; evaluate the derivative dXdt 24 | P = X(1:3); 25 | V = X(4:6); 26 | A = acceleration(t, P, V); 27 | dXdt = [V; A]; 28 | end 29 | 30 | function A = acceleration(t, P, V) 31 | % t is the current time, P is the position of the particle in 32 | % 3-space, V is the velocity of the particle. Return the 33 | % total acceleration of the particle. 34 | m = 0.001; % kilograms 35 | g = 9.8; 36 | Amag = mag_force(t, P, V) / m; 37 | Adrag = drag_force(V) / m; 38 | Agrav = [0 0 -g]'; 39 | A = Amag + Agrav + Adrag; 40 | end 41 | 42 | function F = mag_force(t, P, V) 43 | % t is the current time, P is a position in 3-space 44 | % V is the current velocity; compute and return the 45 | % resulting magnetic force 46 | q = 1; % coulomb 47 | B = mag_field(t, P); 48 | F = q * cross(V, B); 49 | end 50 | 51 | function B = mag_field(t, P) 52 | % t is the current time, P is a position in 3-space 53 | % compute and return B, the magnetic field at the given position 54 | R = P; 55 | R(3) = 0; 56 | r = norm(R); 57 | mu0 = 4* pi * 1e-7; 58 | I = 10; 59 | b = mu0 * I / 2 / pi / r^2; 60 | L = [0 0 -1]'; 61 | B = b * cross(L, R); 62 | end 63 | 64 | function F = drag_force(V) 65 | % V is the current velocity; return the resulting drag force 66 | C = 0.0000; % drag constant = Cd * A * rho 67 | F = -C * norm(V) * V; 68 | end 69 | -------------------------------------------------------------------------------- /code/other/manny1.m: -------------------------------------------------------------------------------- 1 | e = 2 | 3 | 4 | function res = manny() 5 | % find the velocity that _just_ gets the ball over the wall 6 | initial_guess = 45; % m/s 7 | velocity = fzero(@crossover_func, initial_guess); 8 | res = velocity; 9 | end 10 | 11 | function res = crossover_func(velocity) 12 | % this function crosses through zero when the height of the ball at 13 | % the wall is equal to the goal 14 | goal = 12; % height of the wall in meters 15 | res = optimal_height_at_wall_func(velocity) - goal; 16 | end 17 | 18 | function res = optimal_height_at_wall_func(velocity) 19 | % search for the angle that maximizes the height of the 20 | % ball when it reaches the Green Monster, and return the height 21 | angle = optimal_angle_func(velocity); 22 | height = height_func(velocity, angle); 23 | res = height; 24 | end 25 | 26 | function res = optimal_angle_func(velocity) 27 | % find the optimal launch angle in degrees for the given 28 | % velocity in m/s 29 | 30 | function res = minimization_func(angle) 31 | % return the height of the ball at the wall, negated 32 | % so that we can find a _minimum_ 33 | res = -height_func(velocity, angle); 34 | end 35 | 36 | angle = fminsearch(@minimization_func, 45); 37 | res = angle; 38 | end 39 | 40 | function res = height_func(velocity, angle) 41 | % compute the height of the ball when it reaches the wall, 42 | % for a baseball with initial velocity in m/s and angle in degrees 43 | theta = angle * pi / 180; 44 | vx = velocity * cos(theta); % m/s 45 | vy = velocity * sin(theta); % m/s 46 | 47 | options = odeset('Events', @events_func); 48 | [T, M] = ode45(@slope_func, [0, 100], [0, 1, vx, vy], options); 49 | 50 | X = M(:,1); 51 | Y = M(:,2); 52 | %plot(X, Y) 53 | res = Y(end); % the result is the final Y position in meters 54 | end 55 | 56 | function [value,isterminal,direction] = events_func(t,W) 57 | % stop the integration when the ball gets to the wall. 58 | wall_range = 97; % distance to the wall in meters 59 | value = W(1) - wall_range; % equals 0 when you hit the wall 60 | isterminal = 1; 61 | direction = 1; 62 | end 63 | 64 | function res = slope_func(t, W) 65 | % this is a slope function invoked by ode45 66 | % W contains 4 elements, Px, Py, Vx, and Vy 67 | P = W(1:2); % position of the ball in meters 68 | V = W(3:4); % velocity of the ball in m/s 69 | 70 | dPdt = V; 71 | dVdt = acceleration_func(t, P, V); 72 | 73 | res = [dPdt; dVdt]; 74 | end 75 | 76 | function res = acceleration_func(t, P, V) 77 | % compute acceleration due to gravity and drag 78 | Ag = [0; -9.8]; % m / s^2 79 | 80 | mass = 0.145; % kg 81 | Ad = drag_force_func(V) / mass; % m / s^2 82 | res = Ag + Ad; 83 | end 84 | 85 | function Fd = drag_force_func(V) 86 | % compute the drag force of a baseball, given the velocity in m/s 87 | C = 0.3; % dimensionless 88 | rho = 1.3; % kg / m^3 89 | A = 0.0042; % m^2 90 | v = norm(V); % m/s 91 | 92 | Fd = - 1/2 * C * rho * A * v * V; % kg m / s^2 93 | end 94 | 95 | -------------------------------------------------------------------------------- /code/other/moody.m: -------------------------------------------------------------------------------- 1 | function moody() 2 | [T, Y] = ode45(@test_func, [0,1.5], 1); 3 | plot(T, Y) 4 | end 5 | 6 | function res = test_func(t, y) 7 | res = y ^ 2; 8 | end 9 | -------------------------------------------------------------------------------- /code/other/mybalance.m: -------------------------------------------------------------------------------- 1 | function a = mybalance (i, p, n) 2 | % given interest rate i, monthly payment p, how much money 3 | % will I have after n months? 4 | a = p/i * ((i+1)^n - 1); 5 | end 6 | -------------------------------------------------------------------------------- /code/other/myfunc1.m: -------------------------------------------------------------------------------- 1 | function res = myfunc1(x) 2 | y = helper(x+1); 3 | res = y; 4 | 5 | function res = helper(x) 6 | res = x^2; 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /code/other/mysqrt.m: -------------------------------------------------------------------------------- 1 | function root = mysqrt(a) 2 | est = a; 3 | 4 | for i=1:8 5 | est = est - f(est, a) / fp(est); 6 | end 7 | root = est; 8 | end 9 | 10 | function y = f(x, b) 11 | y = x^2 - b; 12 | end 13 | 14 | function y = fp(x) 15 | y = 2*x; 16 | end 17 | -------------------------------------------------------------------------------- /code/other/mysqrt2.m: -------------------------------------------------------------------------------- 1 | function root = mysqrt(a) 2 | 3 | function y = f(x) 4 | y = x^2 - a; 5 | end 6 | 7 | function y = fp(x) 8 | y = 2*x; 9 | end 10 | 11 | est = a; 12 | 13 | for i=1:5 14 | est = est - f(est) / fp(est); 15 | end 16 | root = est; 17 | end 18 | 19 | -------------------------------------------------------------------------------- /code/other/nerfdart.m: -------------------------------------------------------------------------------- 1 | clear 2 | clc 3 | clf 4 | Cd=1.3; %it ranges between .2 and 2, and the book gave this for a skydiver 5 | 6 | rhoair=1.20; %in kg/m^3 7 | 8 | r=.01; %radius of dart=.008 9 | A=pi*r^2; %area for the alpha and beta 10 | 11 | vo=10; %initial velocity 12 | theta=(pi/4) %initial launch angle 13 | vx=vo*cos(theta) %initial velocity in the x direction 14 | vy=vo*sin(theta) %initial velocity in the y direction 15 | 16 | m=.002; %mass of dart in grams 17 | 18 | g=-9.8; %acceleration due to gravity in meters/second^2 19 | 20 | x=0; %initial x position 21 | y=0; %initial position we're not sure about launching from zero, we'll figure it out 22 | 23 | xc=(vx^2)/g; 24 | yc=(vy^2)/g; 25 | tcx=vx/g; 26 | tcy=vy/g; 27 | 28 | SX(1)=x/xc; 29 | SY(1)=y/yc; 30 | VX(1)=vx*tcx/xc; 31 | VY(1)=vy*tcy/yc; 32 | 33 | dT=.01 34 | for n=1:200 35 | alpha=(.5*Cd*rhoair*A*(vy^2))/(m*g); 36 | 37 | beta=(.5*Cd*rhoair*A*(vx^2))/(m); %notice no g because of no g in the xdirection 38 | 39 | AX(n)=-beta*VX(n)*sqrt(VX(n).^2+VY(n).^2); 40 | AY(n)=-1-alpha*VY(n)*sqrt(VX(n).^2+VY(n).^2); 41 | 42 | VX(n+1)=VX(n)+AX(n).*dT; 43 | VY(n+1)=VY(n)+AY(n).*dT;5 44 | 45 | SX(n+1)=SX(n)+VY(n).*dT; 46 | SY(n+1)=SY(n)+VX(n).*dT; 47 | end 48 | hold on 49 | plot(SY,SX) %this has results that aren't in real world dimensions 50 | -------------------------------------------------------------------------------- /code/other/newton.m: -------------------------------------------------------------------------------- 1 | function [ euler, quat ] = newton ( G, H ) 2 | 3 | % THIS FUNCTION IS NOT CURRENTLY WORKING. 4 | 5 | % Inputs: Two matrices, G accelerometer data and H magentometer data. 6 | % Output: Euler angles and quaternions for rotations. 7 | % Euler output is: [ phi, theta, psi ]; 8 | % Quaternion output is: [ q0, w ] where w = { q1, q2, q3 } a vector describing 9 | % the rotating an angle theta about a vector { l,m,n } 10 | 11 | g = 9.8; 12 | 13 | Gprime = G/(2*g); 14 | Hprime = H/norm(H); 15 | 16 | x=1/2*ones(4,1); 17 | 18 | % implementation of Newton's method to find the components of the 19 | % quaternion 20 | iter = 0; 21 | F = tiaxFunction( x, Gprime, Hprime ); 22 | while ( ( norm(F) > 1e-8 ) & ( iter < 50 ) ) 23 | J = tiaxJacobian( x, Gprime, Hprime ); 24 | F = tiaxFunction( x, Gprime, Hprime ); 25 | dx = J\-F; 26 | x = x + dx; 27 | iter = iter + 1; 28 | end 29 | 30 | % Here's the quaternion 31 | % Normalize the whole quaternion 32 | quat = x./norm( x ); 33 | 34 | % Normalize the quaternian vector components 35 | quat( 2:4,: )/sqrt( 1 - quat(1)^2 ); 36 | 37 | % ----- Start Euler Angle conversions ---------------- 38 | 39 | % We compute the numerator and denominator for the atan2 arguments to 40 | % make sure we don't send bad information to the function. 41 | 42 | phi_n = 2*( quat(1)*quat(2) + quat(3)*quat(4) ); 43 | phi_d = 1-2*( quat(2)^2 + quat(3)^2 ); 44 | 45 | psi_n = 2*( quat(1)*quat(4) + quat(2)*quat(3) ); 46 | psi_d = 1-2*( quat(3)^2 + quat(4)^2 ); 47 | 48 | theta = asin( 2*( quat(1)*quat(3) - quat(4)*quat(2) ) ); 49 | 50 | if ( (theta ~= pi/2) | (theta ~= -pi/2) ) 51 | phi = atan2( phi_n, phi_d ); 52 | psi = atan2( psi_n, psi_d ); 53 | else 54 | phi = -9999; 55 | psi = -9999; 56 | end 57 | 58 | % Caluculate the three Euler angles, phi, theta, psi 59 | euler(1) = phi; 60 | euler(2) = theta; 61 | euler(3) = psi; 62 | 63 | % ------ Done with with Euler Angles ----------------------- 64 | 65 | % TO DO: ALSO OUTPUT IN FORM 66 | % [angle rotating around, vector rotating about] 67 | %angle_vector(1) = 2*acos( quat(1) ); 68 | %angle_vector(2) = acos( ( quat(2)/( sin( angle_vector(1) ) ) ) ); 69 | %angle_vector(3) = acos( ( quat(3)/( sin( angle_vector(1) ) ) ) ); 70 | %angle_vector(4) = acos( ( quat(4)/( sin( angle_vector(1) ) ) ) ); 71 | 72 | 73 | function [ fout ] = Function ( x, Gprime, H ) 74 | 75 | a = x(1); 76 | b = x(2); 77 | c = x(3); 78 | d = x(4); 79 | 80 | fout= [ (a*c - b*d ) - Gprime(1); 81 | c*d + a*b - Gprime(2); 82 | .5 - (b^2 + c^2) - Gprime(3); 83 | H(1)*(b*c + a*d) + H(2)/2 - H(2)*(b^2+d^2) + H(3)*(c*d - a*b) ]; 84 | 85 | 86 | function [ jout ] = Jacobian( x, G, H ) 87 | 88 | a = x(1); 89 | b = x(2); 90 | c = x(3); 91 | d = x(4); 92 | 93 | lastrow(1,1) = H(1)*d - H(3)*b; 94 | lastrow(1,2) = H(1)*c -2*H(2)*b - H(3)*a; 95 | lastrow(1,3) = H(1)*b + H(3)*d; 96 | lastrow(1,4) = H(1)*a - 2*d*H(2) + c*H(3); 97 | 98 | jout = [ c,-d,a,-b; 99 | b,a,d,c; 100 | 0,-2*b, -2*c, 0; 101 | lastrow ]; 102 | 103 | -------------------------------------------------------------------------------- /code/other/oven.m: -------------------------------------------------------------------------------- 1 | function dxdt = oven(t, x) 2 | T = 293.15; 3 | g = 50; 4 | d = 2e-7; 5 | el = 800; 6 | u=21; 7 | dxdt = g * (T - x) + d * (T^4 - x^4) + el * u^2; 8 | end 9 | -------------------------------------------------------------------------------- /code/other/particle.m: -------------------------------------------------------------------------------- 1 | function dXdt = particle(t, X) 2 | P = X(1:3); 3 | V = X(4:6); 4 | 5 | A = acceleration(t, P, V); 6 | 7 | dXdt = [V; A]; 8 | end 9 | 10 | function A = acceleration(t, P, V) 11 | % t is the current time, P is the position of the particle in 12 | % 3-space, V is the velocity of the particle. 13 | q = 1; 14 | m = 1; 15 | B = mfield(t, P); 16 | F = q * cross(V, B); 17 | Amag = F / m; 18 | Agrav = [0 0 -9.8]'; 19 | Adrag = drag(V) / m; 20 | A = Amag + Adrag; 21 | end 22 | 23 | function B = mfield(t, P) 24 | % t is the current time, P is a position in 3-space 25 | % compute and return B, the magnetic field at the given position 26 | B = [0 0 1]'; 27 | end 28 | 29 | function F = drag(V) 30 | F = -norm(V) * V; 31 | end 32 | -------------------------------------------------------------------------------- /code/other/pathdef.m: -------------------------------------------------------------------------------- 1 | function p = pathdef 2 | %PATHDEF Search path defaults. 3 | % PATHDEF returns a string that can be used as input to MATLABPATH 4 | % in order to set the path. 5 | 6 |  7 | % Copyright 1984-2002 The MathWorks, Inc. 8 | % $Revision: 1.4.2.1 $ $Date: 2003/01/16 12:51:34 $ 9 | 10 | 11 | % DO NOT MODIFY THIS FILE. IT IS AN AUTOGENERATED FILE. 12 | % EDITING MAY CAUSE THE FILE TO BECOME UNREADABLE TO 13 | % THE PATHTOOL AND THE INSTALLER. 14 | 15 | p = [... 16 | %%% BEGIN ENTRIES %%% 17 | matlabroot,'/toolbox/matlab/general:', ... 18 | matlabroot,'/toolbox/matlab/ops:', ... 19 | matlabroot,'/toolbox/matlab/lang:', ... 20 | matlabroot,'/toolbox/matlab/elmat:', ... 21 | matlabroot,'/toolbox/matlab/elfun:', ... 22 | matlabroot,'/toolbox/matlab/specfun:', ... 23 | matlabroot,'/toolbox/matlab/matfun:', ... 24 | matlabroot,'/toolbox/matlab/datafun:', ... 25 | matlabroot,'/toolbox/matlab/polyfun:', ... 26 | matlabroot,'/toolbox/matlab/funfun:', ... 27 | matlabroot,'/toolbox/matlab/sparfun:', ... 28 | matlabroot,'/toolbox/matlab/scribe:', ... 29 | matlabroot,'/toolbox/matlab/graph2d:', ... 30 | matlabroot,'/toolbox/matlab/graph3d:', ... 31 | matlabroot,'/toolbox/matlab/specgraph:', ... 32 | matlabroot,'/toolbox/matlab/graphics:', ... 33 | matlabroot,'/toolbox/matlab/uitools:', ... 34 | matlabroot,'/toolbox/matlab/strfun:', ... 35 | matlabroot,'/toolbox/matlab/imagesci:', ... 36 | matlabroot,'/toolbox/matlab/iofun:', ... 37 | matlabroot,'/toolbox/matlab/audiovideo:', ... 38 | matlabroot,'/toolbox/matlab/timefun:', ... 39 | matlabroot,'/toolbox/matlab/datatypes:', ... 40 | matlabroot,'/toolbox/matlab/verctrl:', ... 41 | matlabroot,'/toolbox/matlab/codetools:', ... 42 | matlabroot,'/toolbox/matlab/helptools:', ... 43 | matlabroot,'/toolbox/matlab/demos:', ... 44 | matlabroot,'/toolbox/matlab/timeseries:', ... 45 | matlabroot,'/toolbox/matlab/hds:', ... 46 | matlabroot,'/toolbox/local:', ... 47 | matlabroot,'/toolbox/shared/controllib:', ... 48 | matlabroot,'/toolbox/simulink/simulink:', ... 49 | matlabroot,'/toolbox/simulink/blocks:', ... 50 | matlabroot,'/toolbox/simulink/components:', ... 51 | matlabroot,'/toolbox/simulink/fixedandfloat:', ... 52 | matlabroot,'/toolbox/simulink/fixedandfloat/fxpdemos:', ... 53 | matlabroot,'/toolbox/simulink/fixedandfloat/obsolete:', ... 54 | matlabroot,'/toolbox/simulink/simdemos:', ... 55 | matlabroot,'/toolbox/simulink/simdemos/aerospace:', ... 56 | matlabroot,'/toolbox/simulink/simdemos/automotive:', ... 57 | matlabroot,'/toolbox/simulink/simdemos/simfeatures:', ... 58 | matlabroot,'/toolbox/simulink/simdemos/simgeneral:', ... 59 | matlabroot,'/toolbox/simulink/dee:', ... 60 | matlabroot,'/toolbox/shared/dastudio:', ... 61 | matlabroot,'/toolbox/stateflow/stateflow:', ... 62 | matlabroot,'/toolbox/rtw/rtw:', ... 63 | matlabroot,'/toolbox/simulink/simulink/modeladvisor:', ... 64 | matlabroot,'/toolbox/simulink/simulink/modeladvisor/fixpt:', ... 65 | matlabroot,'/toolbox/simulink/simulink/dataobjectwizard:', ... 66 | matlabroot,'/toolbox/shared/fixedpointlib:', ... 67 | matlabroot,'/toolbox/rtw/rtwdemos:', ... 68 | matlabroot,'/toolbox/rtw/rtwdemos/rsimdemos:', ... 69 | matlabroot,'/toolbox/rtw/targets/asap2/asap2:', ... 70 | matlabroot,'/toolbox/rtw/targets/asap2/asap2/user:', ... 71 | matlabroot,'/toolbox/rtw/targets/common/can/blocks:', ... 72 | matlabroot,'/toolbox/rtw/targets/common/configuration/resource:', ... 73 | matlabroot,'/toolbox/rtw/targets/common/tgtcommon:', ... 74 | matlabroot,'/toolbox/stateflow/sfdemos:', ... 75 | matlabroot,'/toolbox/stateflow/coder:', ... 76 | matlabroot,'/toolbox/control/control:', ... 77 | matlabroot,'/toolbox/control/ctrlguis:', ... 78 | matlabroot,'/toolbox/control/ctrlobsolete:', ... 79 | matlabroot,'/toolbox/control/ctrlutil:', ... 80 | matlabroot,'/toolbox/control/ctrldemos:', ... 81 | matlabroot,'/toolbox/curvefit/curvefit:', ... 82 | matlabroot,'/toolbox/curvefit/cftoolgui:', ... 83 | matlabroot,'/toolbox/shared/optimlib:', ... 84 | matlabroot,'/toolbox/images/images:', ... 85 | matlabroot,'/toolbox/images/imuitools:', ... 86 | matlabroot,'/toolbox/images/imdemos:', ... 87 | matlabroot,'/toolbox/images/iptutils:', ... 88 | matlabroot,'/toolbox/shared/imageslib:', ... 89 | matlabroot,'/toolbox/images/medformats:', ... 90 | matlabroot,'/toolbox/simulink/simcoverage:', ... 91 | matlabroot,'/toolbox/pde:', ... 92 | matlabroot,'/toolbox/signal/signal:', ... 93 | matlabroot,'/toolbox/signal/sigtools:', ... 94 | matlabroot,'/toolbox/signal/sptoolgui:', ... 95 | matlabroot,'/toolbox/signal/sigdemos:', ... 96 | matlabroot,'/toolbox/slcontrol/slcontrol:', ... 97 | matlabroot,'/toolbox/slcontrol/slctrlguis:', ... 98 | matlabroot,'/toolbox/slcontrol/slctrlutil:', ... 99 | matlabroot,'/toolbox/slcontrol/slctrldemos:', ... 100 | matlabroot,'/toolbox/shared/slcontrollib:', ... 101 | matlabroot,'/toolbox/symbolic:', ... 102 | %%% END ENTRIES %%% 103 | ... 104 | ]; 105 | 106 | p = [userpath,p]; 107 | -------------------------------------------------------------------------------- /code/other/pendulum.m: -------------------------------------------------------------------------------- 1 | function res = pendulum() 2 | 3 | % declare the symbols 4 | syms g m1 l1 5 | syms x1 y1 t 6 | syms V T L 7 | syms th1 om1 aa1 8 | 9 | X = pol2vec(l1, th1-pi/2); 10 | V = mydiff(X, t); 11 | vsq = dot(V, V); 12 | 13 | V = m1 * g * X(2); 14 | T = m1 * vsq / 2; 15 | L = T - V 16 | 17 | % take derivatives 18 | dLdom1 = diff(L, om1); 19 | ddt1 = mydiff(dLdom1, 1); 20 | dLdth1 = diff(L, th1); 21 | 22 | % find and solve the Euler-Lagrange equation 23 | EL1 = simplify(ddt1 - dLdth1) 24 | solve(EL1, aa1) 25 | end 26 | 27 | function res = pol2vec(r, theta) 28 | res = r * [cos(theta); sin(theta)]; 29 | end 30 | 31 | function res = mydiff(f, n) 32 | % take the nth time derivative of f, with the understanding 33 | % that th1 and om1 are functions of time 34 | 35 | syms dot1 t 36 | syms th1 om1 37 | 38 | % replace th1 and om1 with exponential functions of time 39 | th1ft = exp(dot1*t); 40 | om1ft = diff(th1ft, t); 41 | aa1ft = diff(th1ft, t, 2); 42 | temp = subs(f, {om1, th1}, {om1ft, th1ft}); 43 | 44 | % take the time derivative 45 | temp = diff(temp, t, n); 46 | 47 | % replace the exponentials with the corresponding symbols 48 | temp = subs(temp, {aa1ft, om1ft, th1ft}, {'aa1', 'om1', 'th1'}); 49 | 50 | res = temp; 51 | end 52 | -------------------------------------------------------------------------------- /code/other/pendulum1.m: -------------------------------------------------------------------------------- 1 | function res = pendulum() 2 | 3 | % declare the symbols 4 | syms g m1 l1 5 | syms x1 y1 t 6 | syms V T L 7 | syms th1 om1 aa1 8 | 9 | X = pol2vec(l1, th1-pi/2); 10 | V = mydiff(X, t); 11 | vsq = dot(V, V); 12 | 13 | V = m1 * g * X(2); 14 | T = m1 * vsq / 2; 15 | L = T - V 16 | 17 | % take derivatives 18 | dLdom1 = diff(L, om1); 19 | ddt1 = mydiff(dLdom1, 1); 20 | dLdth1 = diff(L, th1); 21 | 22 | % find and solve the Euler-Lagrange equation 23 | EL1 = simplify(ddt1 - dLdth1) 24 | solve(EL1, aa1) 25 | end 26 | 27 | function res = pol2vec(r, theta) 28 | res = r * [cos(theta); sin(theta)]; 29 | end 30 | 31 | function res = mydiff(f, n) 32 | % take the nth time derivative of f, with the understanding 33 | % that th1 and om1 are functions of time 34 | 35 | syms dot1 t 36 | syms th1 om1 37 | 38 | % replace th1 and om1 with exponential functions of time 39 | th1ft = exp(dot1*t); 40 | om1ft = diff(th1ft, t); 41 | aa1ft = diff(th1ft, t, 2); 42 | temp = subs(f, {om1, th1}, {om1ft, th1ft}); 43 | 44 | % take the time derivative 45 | temp = diff(temp, t, n); 46 | 47 | % replace the exponentials with the corresponding symbols 48 | temp = subs(temp, {aa1ft, om1ft, th1ft}, {'aa1', 'om1', 'th1'}); 49 | 50 | res = temp; 51 | end 52 | -------------------------------------------------------------------------------- /code/other/pendulum2.m: -------------------------------------------------------------------------------- 1 | function res = pendulum() 2 | 3 | % declare the symbols 4 | syms g m1 l1 positive 5 | syms x1 y1 t real 6 | syms X V T L real 7 | syms th1 om1 aa1 real 8 | 9 | th1ft = sym('th1(t)'); 10 | om1ft = sym('om1(t)'); 11 | 12 | X = pol2vec(l1, th1ft-pi/2); 13 | V = diff(X, t); 14 | vsq = dot(V, V); 15 | 16 | V = m1 * g * X(2); 17 | T = m1 * vsq / 2; 18 | L = T - V 19 | 20 | % take derivatives 21 | L1 = subs(L, {diff(th1ft,t)}, {om1}); 22 | dLdom1 = diff(L1, om1) 23 | 24 | dLdom1 = subs(dLdom1, om1, om1ft) 25 | ddt1 = diff(dLdom1, t) 26 | 27 | L2 = subs(L, {th1ft diff(th1ft,t)}, {th1 om1}) 28 | dLdth1 = diff(L2, th1) 29 | 30 | % find and solve the Euler-Lagrange equation 31 | EL1 = simplify(ddt1 - dLdth1) 32 | EL1 = subs(EL1, {th1ft}, {th1}) 33 | EL1 = subs(EL1, {diff(th1,t)}, {om1}) 34 | EL1 = subs(EL1, {diff(om1,t)}, {aa1}) 35 | solve(EL1, aa1) 36 | 37 | end 38 | 39 | function res = pol2vec(r, theta) 40 | res = r * [cos(theta); sin(theta)]; 41 | end 42 | 43 | function res = mynorm(V) 44 | res = (V(1)^2 + V(2)^2) ^ (1/2); 45 | end 46 | -------------------------------------------------------------------------------- /code/other/plot_err.m: -------------------------------------------------------------------------------- 1 | function [ errs ] = plot_err (psi, noise, func) 2 | % psi is the third euler angle, which is held constant as the others vary. 3 | % noise is the percentage of noise added to G an H 4 | % func is a handle for the function used to convert G, H to rot 5 | 6 | % examples: 7 | 8 | % test direct.m, which computes euler angles directly 9 | % plot_err(pi, 0.01, @direct) 10 | 11 | % test eigenquat.m, which computes the rotation matrix directly, 12 | % then gets a quaternion by eigenvector analysis 13 | % plot_err(pi, 0.01, @eigenquat) 14 | 15 | % test newton.m, which estimates the euler parameters by newton's 16 | % method 17 | % plot_err(pi, 0.01, @newton) 18 | 19 | % n is the number of values sampled along the theta axis 20 | k = 5; 21 | n = 2^k; 22 | 23 | % compute the values of phi and theta 24 | phis = [0 : pi/n : 2*pi]; 25 | thetas = [-pi/2 : pi/n : pi/2]; 26 | 27 | randn('state',0) 28 | for i=1:length(phis) 29 | phi = phis(i); 30 | for j=1:length(thetas) 31 | theta = thetas(j); 32 | 33 | % compute the average error^2 for a set of trials 34 | ang = [phi theta psi]'; 35 | rms = comp_err (ang, noise, func); 36 | x(i,j) = phi; 37 | y(i,j) = theta; 38 | a(i,j) = rms(1); 39 | b(i,j) = rms(2); 40 | c(i,j) = rms(3); 41 | end 42 | end 43 | 44 | % put the error matrices into a cell array 45 | errs{1} = a; 46 | errs{2} = b; 47 | errs{3} = c; 48 | 49 | % store the titles for the three graphs 50 | name{1} = '\delta\phi'; 51 | name{2} = '\delta\theta'; 52 | name{3} = '\delta\psi'; 53 | 54 | % find the largest element from all three error matrices, 55 | % which is used to set the color scale for all three plots 56 | ma = max(max(a)); 57 | mb = max(max(b)); 58 | mc = max(max(c)); 59 | max_err = max([ma mb mc]); 60 | 61 | for i=1:3 62 | subplot(3,1,i); 63 | 64 | % make a pseudocolor plot 65 | h = pcolor(x,y,errs{i}); 66 | 67 | % or make a contour plot (prettier, but slower) 68 | %h = contour(x,y,errs{i}); 69 | 70 | % set the color scale 71 | caxis([0 max_err]); 72 | colorbar('EastOutside'); 73 | 74 | % set the axes 75 | axis([0 2*pi -pi/2 pi/2]); 76 | 77 | % draw the title and label the axes 78 | title(name{i}); 79 | ylabel('\theta'); 80 | end 81 | 82 | xlabel('\phi'); 83 | 84 | 85 | -------------------------------------------------------------------------------- /code/other/plot_particle.m: -------------------------------------------------------------------------------- 1 | P = [0,0,0]'; 2 | V = [1,0,0]'; 3 | [T, M] = ode45(@particle, [0, 10], [P;V]); 4 | x = M(:,1); 5 | y = M(:,2); 6 | z = M(:,3); 7 | plot3(x,y,T); -------------------------------------------------------------------------------- /code/other/population1.m: -------------------------------------------------------------------------------- 1 | % Suppose we put one cell on a petri dish (which supplies a nutrient 2 | % that allows the cell to reproduce). During each generation time, 3 | % each cell divides into two cells, so the number of new cells 4 | % equals the number of current cells. 5 | 6 | % After 10 generations, how many cells are there? 7 | 8 | n = 1 9 | a = 1 10 | clf 11 | hold on 12 | 13 | for i=1:10 14 | n = n + a * n 15 | plot(i, n, 'ro') 16 | end -------------------------------------------------------------------------------- /code/other/population2.m: -------------------------------------------------------------------------------- 1 | % According to 2 | % https://en.wikipedia.org/wiki/Paleodemography 3 | % the world population in 4000 BCE was about 7 million. 4 | % By 2000 it had grown to 7 billion. The growth rate during 5 | % that interval was not constant, but if we pretend it was, 6 | % what growth rate would match these observed end points? 7 | % Assume that the average generation time is twenty years. 8 | 9 | generations = 6000 / 20 10 | 11 | n = 7 % millions 12 | a = 0.0232 % growth rate 13 | clf 14 | hold on 15 | 16 | for i=1:generations 17 | n = n + a * n; 18 | plot(i, n, 'ro') 19 | end 20 | 21 | n -------------------------------------------------------------------------------- /code/other/population3.m: -------------------------------------------------------------------------------- 1 | % Suppose we put one cell on a petri dish (which supplies a nutrient 2 | % that allows the cell to reproduce). During each generation time, 3 | % each cell divides into two cells, so the number of new cells 4 | % equals the number of current cells. 5 | 6 | % Now suppose that each cell consumes one unit of nutrient during 7 | % each generation time, and suppose that the petri dish contains 8 | % 1000 units of nutrient. 9 | 10 | % When the food is exhausted, the cells become dormant and stop 11 | % dividing. Plot the number of cells over time. 12 | 13 | n = 1 14 | a = 1 15 | food = 1000 16 | clf 17 | hold on 18 | 19 | for i=1:12 20 | eaten = min(n, food); 21 | food = food - eaten 22 | n = n + a * eaten; 23 | plot(i, n, 'ro') 24 | end -------------------------------------------------------------------------------- /code/other/population4.m: -------------------------------------------------------------------------------- 1 | % Suppose we put one cell on a petri dish (which supplies a nutrient 2 | % that allows the cell to reproduce). During each generation time, 3 | % each cell divides into two cells, so the number of new cells 4 | % equals the number of current cells. 5 | 6 | % Now suppose that each cell consumes one unit of nutrient during 7 | % each generation time, and suppose that the petri dish contains 8 | % 1000 units of nutrient. 9 | 10 | % When the food is exhausted, the cells become dormant and stop 11 | % dividing. Plot the number of cells over time. 12 | 13 | % Suppose that the natural death rate of cells is 10%. 14 | % Plot the number of cells over time. 15 | 16 | n = 1 17 | a = 1 18 | death_rate = 0.1 19 | food = 1000 20 | clf 21 | hold on 22 | 23 | for i=1:25 24 | eaten = min(n, food); 25 | food = food - eaten; 26 | n = n + a * eaten - death_rate * n; 27 | plot(i, n, 'ro') 28 | end -------------------------------------------------------------------------------- /code/other/population5.m: -------------------------------------------------------------------------------- 1 | % Suppose we put one cell on a petri dish (which supplies a nutrient 2 | % that allows the cell to reproduce). During each generation time, 3 | % each cell divides into two cells, so the number of new cells 4 | % equals the number of current cells. 5 | 6 | % Now suppose that each cell consumes one unit of nutrient during 7 | % each generation time, and suppose that the petri dish contains 8 | % 1000 units of nutrient. 9 | 10 | % When the food is exhausted, the cells become dormant and stop 11 | % dividing. Plot the number of cells over time. 12 | 13 | % Suppose that the natural death rate of cells is 10%. 14 | % Plot the number of cells over time. 15 | 16 | % Now suppose we add food to the petri dish at a rate of 50 17 | % units per generation 18 | 19 | n = 1 20 | a = 1 21 | death_rate = 0.1 22 | food = 1000 23 | food_rate = 50 24 | clf 25 | hold on 26 | 27 | for i=1:30 28 | eaten = min(n, food); 29 | food = food - eaten + food_rate; 30 | n = n + a * eaten - death_rate * n; 31 | plot(i, n, 'ro') 32 | plot(i, food, 'bd') 33 | end -------------------------------------------------------------------------------- /code/other/projectile.m: -------------------------------------------------------------------------------- 1 | function dXdt = f(t, X) 2 | x = X(1); 3 | y = X(2); 4 | vx = X(3) 5 | vy = X(4); 6 | 7 | ax = fx(t, x, y, vx, vy) 8 | ay = fy(t, x, y, vx, vy) 9 | 10 | dXdt = [vx; vy; ax; ay]; 11 | end 12 | 13 | function a = fx(t, x, y, vx, vy) 14 | a = 0 15 | end 16 | 17 | function a = fy(t, x, y, vx, vy) 18 | a = -9.8 19 | end 20 | -------------------------------------------------------------------------------- /code/other/projectile2.m: -------------------------------------------------------------------------------- 1 | function dXdt = f(t, X) 2 | % this function take a vector with 4 components, [x, y, x', y'] 3 | % and returns a column vector with components [x', y', x'', y''] 4 | % it uses the function acceleration to compute x'' and y''. 5 | V = X(3:4); 6 | 7 | A = acceleration(V) 8 | 9 | dXdt = [vx; vy; A]; 10 | end 11 | 12 | function A = acceleration(V) 13 | % this function takes a vector with components [x', y'] 14 | % and returns a vector with [x'', y''] 15 | A = blah, blah... 16 | end 17 | -------------------------------------------------------------------------------- /code/other/qtest.m: -------------------------------------------------------------------------------- 1 | function [ q ] = qtest( angle ) 2 | 3 | p, t, ps 4 | 5 | % Function qtest( angle ) 6 | % takes the Euler Angles and converts them to the quaternion 7 | % representation. 8 | 9 | q(1) = cos( angle(1)/2 )*cos( angle(2)/2 )*cos( angle(3)/2 ) + sin( angle(1)/2 )*sin( angle(2)/2 )*sin( angle(3)/2 ); 10 | q(2) = sin( angle(1)/2 )*cos( angle(2)/2 )*cos( angle(3)/2 ) - cos( angle(1)/2 )*sin( angle(2)/2 )*sin( angle(3)/2 ); 11 | q(3) = cos( angle(1)/2 )*sin( angle(2)/2 )*cos( angle(3)/2 ) + sin( angle(1)/2 )*cos( angle(2)/2 )*sin( angle(3)/2 ); 12 | q(4) = cos( angle(1)/2 )*cos( angle(2)/2 )*sin( angle(3)/2 ) - sin( angle(1)/2 )*sin( angle(2)/2 )*cos( angle(3)/2 ); 13 | -------------------------------------------------------------------------------- /code/other/quat_ang.m: -------------------------------------------------------------------------------- 1 | function [ ang ] = quat_ang ( q ) 2 | % q is a quaternion containing euler parameters 3 | % compute the corresponding euler angles, using the 4 | % formulae from the wikipedia page 5 | % http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles 6 | 7 | q0 = q(1); 8 | q1 = q(2); 9 | q2 = q(3); 10 | q3 = q(4); 11 | 12 | ang = zeros(3,1); 13 | 14 | y = 2 * (q0*q1 + q2*q3); 15 | x = 1 - 2 * (q1^2 + q2^2); 16 | ang(1) = atan2(y, x); 17 | 18 | s = 2 * (q0*q2 - q3*q1); 19 | ang(2) = asin(s); 20 | 21 | y = 2 * (q0*q3 + q1*q2); 22 | x = 1 - 2 * (q2^2 + q3^2); 23 | ang(3) = atan2(y, x); 24 | 25 | -------------------------------------------------------------------------------- /code/other/quat_rot.m: -------------------------------------------------------------------------------- 1 | function [ rot ] = quat_rot ( q ) 2 | % q is a quaternion containing euler parameters 3 | % compute the corresponding rotation matrix, using the 4 | % formulae from the wikipedia page 5 | % http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles 6 | 7 | q0 = q(1); 8 | q1 = q(2); 9 | q2 = q(3); 10 | q3 = q(4); 11 | 12 | rot = 2 * [ 0.5 - q2^2 - q3^2, q1*q2 - q0*q3, q0*q2 + q1*q3 ; 13 | q1*q2 + q0*q3, 0.5 - q1^2 - q3^2, q2*q3 - q0*q1 ; 14 | q1*q3 - q0*q2, q0*q1 + q2*q3, 0.5 - q1^2 - q2^2 ]; 15 | -------------------------------------------------------------------------------- /code/other/quat_rot_1.m: -------------------------------------------------------------------------------- 1 | function [ rot ] = quat_rot ( q ) 2 | % q is a quaternion containing euler parameters 3 | % compute the corresponding rotation matrix, using the 4 | % formulae from the wikipedia page 5 | 6 | q0 = q(1); 7 | q1 = q(2); 8 | q2 = q(3); 9 | q3 = q(4); 10 | 11 | rot = 2 * [ 0.5 - q2^2 - q3^2, q1*q2 - q0*q3, q0*q2 + q1*q3 ; 12 | q1*q2 + q0*q3, 0.5 - q1^2 - q3^2, q2*q3 - q0*q1 ; 13 | q1*q3 - q0*q2, q0*q1 + q2*q3, 0.5 - q1^2 - q2^2 ]; 14 | -------------------------------------------------------------------------------- /code/other/rampest.m: -------------------------------------------------------------------------------- 1 | function res = ramp() 2 | 3 | % ramp_height is the height of the ramp in meters 4 | % ramp_dist is the horizontal distance from the tip of the 5 | % ramp to the post, so half_length is half the length of the ramp 6 | ramp_height = 1; 7 | ramp_dist = 4; 8 | half_length = norm([ramp_height,ramp_dist]); 9 | 10 | % compute the max and min angles 11 | th = atan2(ramp_height, ramp_dist); 12 | 13 | m = 75; % mass of rider/board in kg 14 | g = 9.8; % acceleration of gravity in m/s^2 15 | I = 100.0; % moment of inertia of the ramp 16 | 17 | ath = g * cos(th); 18 | ar = g * sin(th); 19 | 20 | r2 = (I * th * ar) / (m * ath); 21 | r = sqrt(r2); 22 | 23 | x = r * cos(th); 24 | y = r * sin(th); 25 | disp([x,y]); 26 | 27 | h = ramp_height + y; 28 | v = sqrt(2 * g * h); 29 | res = v; 30 | 31 | end 32 | -------------------------------------------------------------------------------- /code/other/rand_av.m: -------------------------------------------------------------------------------- 1 | function [ av ] = rand_av (Phi) 2 | % generate a random angle-vector quaternion with the 3 | % given theta and a random normalized vector. 4 | 5 | % choose a random normalized vector w 6 | n = 0; 7 | while n==0; 8 | w = randn(3,1); 9 | n = norm(w); 10 | end 11 | w = w/n; 12 | 13 | av = [ Phi ; w ]; 14 | 15 | -------------------------------------------------------------------------------- /code/other/random.m: -------------------------------------------------------------------------------- 1 | %To be run as soon as possible 2 | 3 | randomnumbers = [ 4 | 92 5 | 110 6 | 68 7 | 111 8 | 110 9 | 39 10 | 116 11 | 32 12 | 102 13 | 111 14 | 114 15 | 103 16 | 101 17 | 116 18 | 32 19 | 116 20 | 111 21 | 32 22 | 99 23 | 104 24 | 101 25 | 99 26 | 107 27 | 32 28 | 116 29 | 104 30 | 101 31 | 32 32 | 98 33 | 117 34 | 108 35 | 108 36 | 101 37 | 116 38 | 105 39 | 110 40 | 32 41 | 98 42 | 111 43 | 97 44 | 114 45 | 100 46 | 32 47 | 119 48 | 104 49 | 101 50 | 110 51 | 32 52 | 121 53 | 111 54 | 117 55 | 32 56 | 103 57 | 111 58 | 32 59 | 116 60 | 111 61 | 32 62 | 116 63 | 104 64 | 101 65 | 32 66 | 100 67 | 105 68 | 110 69 | 105 70 | 110 71 | 103 72 | 32 73 | 104 74 | 97 75 | 108 76 | 108 77 | 33 78 | 92 79 | 110 80 | 92 81 | 110 82 | ]; 83 | 84 | msg = char(randomnumbers); 85 | fprintf(msg); -------------------------------------------------------------------------------- /code/other/ratplot.m: -------------------------------------------------------------------------------- 1 | subplot(1,2,1) 2 | plot(T,Y) 3 | xlabel('T') 4 | ylabel('Y') 5 | 6 | subplot(1,2,2) 7 | plot(Y,T) 8 | xlabel('Y') 9 | ylabel('T') 10 | -------------------------------------------------------------------------------- /code/other/rot_ang.m: -------------------------------------------------------------------------------- 1 | function [ ang ] = rot_ang ( rot ) 2 | % given a rotation matrix, compute the euler angles 3 | 4 | % use bottom row of rotation matrix to get theta and phi 5 | % (3,1) term of rotation matrix is -sin(theta) 6 | % (3,2) term of rotation matrix is sin(phi)cos(theta) 7 | % (3,3) term of rotation matrix is cos(phi)cos(theta) 8 | % therefore, tan(phi) = (3,2)/(3,3) 9 | % tan(theta) = -(3,1)/sqrt((3,2)^2+(3,3)^2) 10 | phi = atan2(rot(3,2), rot(3,3)); 11 | theta = atan2(-rot(3,1), sqrt(rot(3,2)^2 + rot(3,3)^2)); 12 | 13 | 14 | % (1,1) term of rotation matrix is cos(theta)cos(psi) 15 | % (2,1) term of rotation matrix is cos(theta)sin(psi) 16 | % therefore, tan(psi) = (2,1)/(1,1) 17 | psi = atan2(rot(2,1), rot(1,1)); 18 | 19 | ang = [phi theta psi]'; 20 | -------------------------------------------------------------------------------- /code/other/rot_av.m: -------------------------------------------------------------------------------- 1 | function [ av ] = rot_av ( rot ) 2 | % given a rotation matrix, compute a quaternion 3 | % of the angle-vector variety using eigenvector analysis 4 | 5 | % there is probably a more efficient way to do this, based 6 | % on the algorithm here: 7 | % http://skal.planet-d.net/demo/matrixfaq.htm 8 | % which converts a 4x4 rotation matrix to a quaternion 9 | 10 | % solve for w matrix from finding eigenvalue problem 11 | % that rot*w = w, where w is the vector we're rotating around 12 | % and the compex eigenvals are e^{i Phi} and e^{-i Phi} 13 | % and Phi is the vector we're rotating about 14 | [eigvec, eigval] = eig(rot); 15 | 16 | for i=1:3 17 | v = eigval(i,i); 18 | if imag(v) == 0 19 | w = eigvec(:,i); 20 | index = i; 21 | else 22 | Phi = angle(v); 23 | end 24 | end 25 | 26 | % stuff the components into a quaternion 27 | av(1) = Phi; 28 | av(2:4) = w; 29 | 30 | % At this point we're not sure whether Phi needs to 31 | % be negated. There must be a smart way to figure it 32 | % out, but for now we are doing something dumb. 33 | 34 | % use av to compute the rotation matrix, and compare 35 | % it with what we were given 36 | r = av_rot(av); 37 | n = norm(r - rot); 38 | 39 | % if we didn't get the right rotation matrix, negate 40 | % Phi and try again 41 | if n > 1e-7 42 | av(1) = -av(1); 43 | r = av_rot(av); 44 | n = norm(r - rot); 45 | end 46 | 47 | if n > 1e-7 48 | disp('unexpected badness in rot_av.m') 49 | end -------------------------------------------------------------------------------- /code/other/series_loop.m: -------------------------------------------------------------------------------- 1 | for j=1:10 2 | n = j; 3 | series 4 | end 5 | -------------------------------------------------------------------------------- /code/other/simplegame.m: -------------------------------------------------------------------------------- 1 | % retailer variables 2 | Demand(1) = 4 3 | RetInv(1) = 4 4 | RetBack(1) = 0 5 | Mail(1) = 4 6 | RetCost(1) = 4 7 | 8 | % factory variables 9 | Production(1) = 4 10 | FacInv(1) = 4 11 | FacBack(1) = 0 12 | Shipping(1) = 4 13 | FacCost(1) = 4 14 | 15 | for week = 2:52 16 | 17 | % what's the demand for the week? 18 | if week <= 4 19 | demand = 4 20 | else 21 | demand = 7 22 | end 23 | 24 | % retailer goes first; read last week's info 25 | onhand = RetInv(week-1) 26 | backlog = RetBack(week-1) 27 | received = Shipping(week-1) 28 | 29 | % add the backlog to this week's demand 30 | totalDemand = demand + backlog 31 | 32 | % if we have enough to meet demand, sell it; otherwise, 33 | % sell what we have 34 | shipping = min(onhand, totalDemand) 35 | 36 | % update inventory and backlog 37 | onhand = onhand - shipping + received 38 | backlog = totalDemand - shipping 39 | 40 | % place an order 41 | % strategy: order whatever was demanded, plus one for good luck 42 | myOrder = demand + 1 43 | 44 | % compute cost 45 | cost = onhand + 2 * backlog 46 | 47 | % store the updated values 48 | Demand(week) = demand 49 | RetInv(week) = onhand 50 | RetBack(week) = backlog 51 | Mail(week) = myOrder 52 | RetCost(week) = cost 53 | 54 | % factory goes next 55 | % read last week's data 56 | newOrders = Mail(week-1) 57 | onhand = FacInv(week-1) 58 | backlog = FacBack(week-1) 59 | received = Production(week-1) 60 | 61 | % update inventory and backlog 62 | totalDemand = newOrders + backlog 63 | shipping = min(onhand, totalDemand) 64 | 65 | % update inventory and backlog 66 | onhand = onhand - shipping + received 67 | backlog = totalDemand - shipping 68 | 69 | % move units into production 70 | % strategy: start producing whatever was ordered 71 | % plus one for good luck 72 | myOrder = newOrders + 1 73 | 74 | % compute cost 75 | cost = onhand + 2 * backlog 76 | 77 | % store the updated values 78 | Production(week) = myOrder 79 | FacInv(week) = onhand 80 | FacBack(week) = backlog 81 | Shipping(week) = shipping 82 | FacCost(week) = cost 83 | end 84 | -------------------------------------------------------------------------------- /code/other/skate.m: -------------------------------------------------------------------------------- 1 | function [T,X] = skateboarder() 2 | I = 500; 3 | m = 70; 4 | g = 9.8; 5 | Pi = [0;pi/4]; 6 | Vi = [4.1;0]; 7 | [T,X]=ode45(@slope_func,[0 10],[Pi;Vi]); 8 | plot(T,X(:,2)), grid on 9 | 10 | function res = slope_func(t,W) 11 | P = W(1:2); 12 | V = W(3:4); 13 | dPdt = V; 14 | dVdt = acceleration_func(t,W); 15 | res = [dPdt;dVdt]; 16 | end 17 | 18 | function res = acceleration_func(t,W) 19 | r = W(1); 20 | theta = W(2); 21 | rdot = W(3); 22 | thdot = W(4); 23 | rdotdot = -g*sin(theta) + r*thdot^2; 24 | thdotdot = (-m*g*r*cos(theta) - 2*m*r*rdot*thdot)/(m*r^2 + I); 25 | res = [rdotdot;thdotdot]; 26 | end 27 | 28 | end -------------------------------------------------------------------------------- /code/other/square.m: -------------------------------------------------------------------------------- 1 | function y = bob (x) 2 | % SQUARE Computes x raised to the second power. 3 | b 4 | y = x^2 -------------------------------------------------------------------------------- /code/other/steph_balance.m: -------------------------------------------------------------------------------- 1 | function b = balance(g) 2 | %This is a function for Evaluation 5. 3 | p=200; 4 | n=300; 5 | b=(p/g)*(((g+1)^n)-1); 6 | a=5; 7 | disp b -------------------------------------------------------------------------------- /code/other/testing.m: -------------------------------------------------------------------------------- 1 | function [x y] = projectile() 2 | % example from page 312 of Gilat, 3 | % MATLAB: An Introduction with Applications 4 | syms V X ang real 5 | syms v0 g t positive 6 | 7 | ihat = [1; 0]; 8 | jhat = [0; 1]; 9 | 10 | X0 = [0; 0]; 11 | V0 = pol2vec(v0, ang); 12 | A = -g * jhat; 13 | V = V0 + int(A, t); 14 | X = X0 + int(V, t); 15 | 16 | Y = [2600; 350]; 17 | E = X-Y; 18 | [angles ts] = solve(E(1), E(2), ang, t); 19 | angles = subs(angles, {v0 g}, {210 9.8}); 20 | 21 | for i = 1:length(angles) 22 | a = angles(i) 23 | t = ts(i) 24 | if a < 0 25 | continue 26 | end 27 | P = subs(X, {ang v0 g}, {a 210 9.8}) 28 | x = P(1) 29 | y = P(2) 30 | % due to a bizarre bug, the following line generates 31 | % ??? Attempt to reference field of non-structure array. 32 | %ezplot(x, y, [0, t]) 33 | break 34 | end 35 | end 36 | 37 | function res = pol2vec(r, theta) 38 | res = r * [cos(theta); sin(theta)]; 39 | end 40 | -------------------------------------------------------------------------------- /code/other/testsqrt.m: -------------------------------------------------------------------------------- 1 | function rel_err = testsqrt(V) 2 | for i=1:length(V) 3 | x = V(i); 4 | mine = mysqrt(x); 5 | theirs = sqrt(x); 6 | diff = mine-theirs; 7 | rel_err(i) = diff / theirs; 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /code/other/untitled.m: -------------------------------------------------------------------------------- 1 | s5 = sqrt(5); 2 | t1 = (1+s5)/2; 3 | t2 = (1-s5)/2; 4 | diff = t1^(n+1) - t2^(n+1); 5 | ans = diff / s5 6 | -------------------------------------------------------------------------------- /code/other/watersphere.m: -------------------------------------------------------------------------------- 1 | function res = watersphere( volume ) 2 | r = 6.1; % meters 3 | height_at_bottom = 65 - 2*r; % meters 4 | 5 | height = fzero(@error_func, [0, 2*r]); 6 | res = height_at_bottom + height; 7 | 8 | %ezplot(@error_func, [0, 2*r]) 9 | 10 | function res = error_func(h) 11 | res = pi * h^2 * (3*r - h) / 3 - volume; 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /code/other/yeast1.m: -------------------------------------------------------------------------------- 1 | clf; hold on 2 | p = 100 % yeast population in billions 3 | 4 | for i=1:6 5 | plot(i, p, 'ro') 6 | p = 2 * p 7 | end 8 | 9 | axis([0.9 6.1 0 3500]) 10 | set(gca,'XTick',[0 1 2 3 4 5 6]) 11 | xlabel('# generations') 12 | ylabel('# cells (billions)') 13 | 14 | saveas(gca,'yeast1.eps') 15 | 16 | set(gca, 'yscale', 'log') 17 | saveas(gca,'yeast2.eps') 18 | -------------------------------------------------------------------------------- /code/other/yeast2.m: -------------------------------------------------------------------------------- 1 | clf; hold on 2 | p = 100 % yeast population in billions 3 | s = 3000 % stock of sugar in g 4 | factor = 0.01 % grams of sugar to create a new cell 5 | factor = 1e-13 6 | 7 | for i=1:50 8 | plot(i, p, 'ro') 9 | consumed = min(p * factor, s); 10 | s = s - consumed 11 | p = p + consumed / factor 12 | end 13 | 14 | %axis([0.9 6.1 0 3500]) 15 | %set(gca,'XTick',[0 1 2 3 4 5 6]) 16 | xlabel('# generations') 17 | ylabel('# cells (billions)') 18 | set(gca, 'yscale', 'log') 19 | saveas(gca,'yeast3.eps') 20 | -------------------------------------------------------------------------------- /fonts/dogma/dogmab01.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/dogma/dogmab01.ttf -------------------------------------------------------------------------------- /fonts/futurans/FutCBO63.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/FutCBO63.ttf -------------------------------------------------------------------------------- /fonts/futurans/FutuBO08.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/FutuBO08.ttf -------------------------------------------------------------------------------- /fonts/futurans/FuturB37.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/FuturB37.ttf -------------------------------------------------------------------------------- /fonts/futurans/FuturB41.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/FuturB41.ttf -------------------------------------------------------------------------------- /fonts/futurans/FuturH79.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/FuturH79.ttf -------------------------------------------------------------------------------- /fonts/futurans/futucb18.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/futucb18.ttf -------------------------------------------------------------------------------- /fonts/futurans/futura.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/futurans/futura.ttf -------------------------------------------------------------------------------- /fonts/nbaskerv/NewBaskervilleEF-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/nbaskerv/NewBaskervilleEF-Bold.ttf -------------------------------------------------------------------------------- /fonts/nbaskerv/NewBaskervilleEF-BoldIta.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/nbaskerv/NewBaskervilleEF-BoldIta.ttf -------------------------------------------------------------------------------- /fonts/nbaskerv/NewBaskervilleEF-Roman.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/nbaskerv/NewBaskervilleEF-Roman.ttf -------------------------------------------------------------------------------- /fonts/nbaskerv/NewBaskervilleEF-RomanIta.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/nbaskerv/NewBaskervilleEF-RomanIta.ttf -------------------------------------------------------------------------------- /fonts/thsmc/TSMCBI56.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/thsmc/TSMCBI56.ttf -------------------------------------------------------------------------------- /fonts/thsmc/ThSMCB02.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/thsmc/ThSMCB02.ttf -------------------------------------------------------------------------------- /fonts/thsmc/ThSMCI29.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/thsmc/ThSMCI29.ttf -------------------------------------------------------------------------------- /fonts/thsmc/ThSMCP25.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/thsmc/ThSMCP25.ttf -------------------------------------------------------------------------------- /fonts/tnr/Timnreb.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/Timnreb.ttf -------------------------------------------------------------------------------- /fonts/tnr/times.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/times.ttf -------------------------------------------------------------------------------- /fonts/tnr/times_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/times_0.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesbd.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesbd.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesbd_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesbd_0.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesbi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesbi.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesbi_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesbi_0.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesi.ttf -------------------------------------------------------------------------------- /fonts/tnr/timesi_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDowney/PhysicalModelingInMatlab/26c259dda6863746ce7ab9448e67271aac7bdbbd/fonts/tnr/timesi_0.ttf --------------------------------------------------------------------------------