Physical Modeling in MATLAB
Allen B. Downey Version 1.1.1

R

2

Physical Modeling in MATLAB
Copyright 2007, 2008 Allen B. Downey

R

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; this book contains no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You can obtain a copy of the GNU Free Documentation License from www.gnu.org or by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The original form of this book is LaTeX source code. Compiling this LaTeX source has the effect of generating a device-independent representation of a book, which can be converted to other formats and printed. This book was typeset by the author using latex, dvips and ps2pdf, among other free, open-source programs. The LaTeX source for this book is available from http://greenteapress.com/matlab. MATLAB is a registered trademark of The Mathworks, Inc. The Mathworks does not warrant the accuracy of this book; they probably don’t even like it.
R

I explain the math as I go along. If you have suggestions and corrections. Downey Needham. the order of presentation is unusual.1 of the book.Preface Most books that use MATLAB are aimed at readers who know how to program. differential equations. This book is for people who have never programmed before. Allen B.com. This is Version 1. please send them to downey@allendowney. As a result. I assume that readers know calculus. I made some corrections based on feedback from students and others. The book puts a lot of emphasis on functions. in part because they are an important mechanism for controlling program complexity. This approach is good for beginning programmers. but the descriptions might not be enough for someone who hasn’t seen the material before. the book explains the necessary vocabulary early and deciphers some of the messages that beginners find confusing. 2007 . But there are problems: • The MATLAB documentation is written in terms of matrices. then added some exercises and additional chapters. because it is hard to understand composite objects until you understand basic programming semantics. but not linear algebra. and a few larger exercises at the end of some chapters. To mitigate this problem. I address this problem in the second half by translating the examples into a more standard style. The book starts with scalar values and works up to vectors and matrices very gradually. and physics. and so are the error messages. and also because they are useful for working with MATLAB tools like fzero and ode45. There are small exercises within each chapter.9 for my class in Fall 2007. MA December 28. • Many of the examples in the first half of the book are not idiomatic MATLAB. I used Version 0.

• Kaelyn Stadtmueller reminded me of the importance of linking verbs. • Pietro Peterlongo pointed out that Binet’s formula is an exact expression for the nth Fibonacci number. . • Li Tao pointed out several errors. not an approximation. • Roydan Ongie knows a matrix when he sees one. • Keerthik Omanakuttan knows that acceleration is not the second derivative of acceleration.ii Preface Contributor’s list The following are some of the people who have contributed to this book: • Michael Lintz spotted the first (of many) typos.

. .2 1. . . . . . .4 2. .7 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 A glorified calculator . . . . . . . . . . . . . . . . . . . . . . .6 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variables . . . . . . . . . . . . . . .Contents Preface 1 Variables and values 1. . Pre. . . . . . . . . . . . . . . . . . .5 2. . . . . . . . . . . . . . . . . . i 1 1 2 3 4 5 6 7 8 9 10 11 13 13 14 15 16 16 17 1. . . . . . . . . . . . . . . . . Documentation . . . .3 1.6 M-files . . . . . . .2 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comments . . Errors . . . . . . . . . .1 2. . . . . .5 1. . . . . . . . . . . . . Why scripts? . . . . . . . . . . . . .10 Glossary . .11 Exercises 2 Scripts 2. . . . . . . . Floating-point arithmetic . . . . . . . . . . . Math functions . . . . . . . . . . . . . . . . .1 1. . .and post-conditions .3 2. Assignment and equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1. . . .4 1. . . Assignment statements . . . . . . . . . . . . . . . . . . . More errors . . . . . . . . . . . . . . . . The workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Why variables? . . . . . . . . . . . . . . . .

. . . . . . .9 Contents Incremental development . . . . . . . . . . . . . . . . . . .7 4. . Absolute and relative error . . . . . . . . . . . . . . . . . . . 18 19 20 20 23 23 24 24 25 26 27 28 29 30 31 33 33 34 35 35 36 37 38 39 40 41 42 42 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 3. . . . . . Generalization . .1 4. . . . . . . . . . . . . Indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. . . . . . . .3 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 Plotting vectors . . .5 3. Everything is a matrix . . . . . . . . . . . . . . . . . . . . . . . Unit testing . . . . . . . . . . . . . . 4. . . . . . . . .6 4. . . . . . . . .8 2. . . . . . . . Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . if . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10 Exercises 4 Vectors 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 3. . . . . . . . . .7 3. . . . . . . Vector arithmetic .2 4. . . . . . . . . . . . . . . . . . . . . . . . . 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Relational operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 4. . . . . . . . . . . . .4 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 Updating variables . . . . Glossary . . . . . . . . . . . 4. . . .4 3. . . . . . plotting . Sequences . . . . . . . .10 Exercises 3 Loops 3. . .2 3. .10 Vectors and sequences . . . . . . . . . . . . . . . . . . . . . . . . . . .iv 2. . . . . . . . . . . . . . . . Series . . . . . . . . . . . . . . . . . . . . . . . .1 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 4. . . . . Indexing errors . .3 4. . . . . . . . . . . . . .9 Checking preconditions . . . Kinds of error . . . . . . . . . . . . . . . . for loops . Logical operators . . . . . . . . . . . . . . . . Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12 Reduce .7 2. . . . . . . . . . . . . . . . . . . . . . . . . . .

12 continue . . . . . . . . . . . .4 6. . . . . . . . . . .1 6. . . . . An incremental development example . . . . . . . . . . . . . . 5. . . . . . . . . . . .13 Mechanism and leap of faith . . . . . . . . . . v 43 43 45 46 46 49 49 50 51 52 53 54 55 56 57 58 60 61 62 63 64 65 65 65 66 66 68 69 Nested loops . . . . . . . . . . . . . . . .15 Exercises 6 Zero-finding 6. . . . .14 Search . . . . . . Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nonlinear equations . . . . . . . . . . Conditions and flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5. . . . . . . . . . . . . . . . .10 Encapsulation and generalization . . . . . . . . . . 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 6. . . . . . .3 5. . . . . . . . . . . . . . . . . . . . . . . .5 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Function names . . . . . . . . . . . . . 4. . . . . . . . . . . . Maps . . . . . . . . . . . .7 5. . . . . . . . . . . . . . . . . Functions . . . . . . . . . . . . .17 Exercises 5 Functions 5. . . . . . . . . . . . . . . . . . . .11 A misstep . . A note on notation . . . . . . . . . . . Logical functions . .13 Apply . . . . . . .14 Glossary . . Zero-finding . . . . . . . . . . . . . . . . . . .2 5. . fzero . . . . . . . . . . . . . . . . . . .9 Name Collisions . . . .16 Glossary . . . . . . . 5. . . . . .Contents 4. . . . . . 5. . . . . . . . . . . . . . . .6 5. . . . . . . . . . 5. . . . . . . . . . . . . .4 5. . . . . . . . . . . .5 6. . . . . . . . . . . . . . . .6 Why functions? . . 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 5. . . . . . . . . . 4. . . . .15 Spoiling the fun . . . . . . 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 6. . . . . . . . . . . . . . . . . . . . . . . . .1 5. . . . . . . . . . Multiple input variables . . . . . . . . .

. . . . . . Physical modeling .6 8. . . . . . . . . . . . . . . . . . . .7 8. . . . . . . . . . . . . .8 6. .vi 6. . . . . . . . . .4 7. . . . . . . . . Universal quantification . 8 Ordinary Differential Equations 8. . . . . . . . . . . . . . .2 8. . . . . . . . . . More name collisions . . . . . . . . . . . . . . . . . .2 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 Functions and files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. . . . . . Products and ratios . . . .7 6. . . . . . . . . .5 8. . . . . . . . . . . . . . . . . . . . . . . . . . . Finding an initial guess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ode45 . . . . . . . . . . . . Vectors as output variables . . . . . . . . . . . . . . . . .10 Exercises . 102 8. . . . . . . . . . . . . . . . . . . .6 7. . . . . . . Analytic or numerical? . . . . . . . . . . . . . . . . . . . . . . . . . .4 8. . . . . Sums and differences . . Euler’s method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 8. . . . . . . . . . . . . . . . .3 8.9 Contents What could go wrong? . . . . . . . . . . . . . . Another note on notation . . Stiffness . . . . . . . . . . . . . . . . . . . . . . . .1 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Functions of vectors 7. . . . . . . . . . . . . . . . . . . .8 7. . . . . . 101 . . 7. .10 Logical vectors . . . What can go wrong? . . . . . . 7. . . . 6. . . . . .11 Glossary . .9 Differential equations . . . . . . . . . . . Multiple output variables . . . . . . . . . . . . . . . . . .5 7. . . . . . . . . . . Vectorizing your functions . . . . . . . . . . . . . . . . . . . . . . . .7 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vectors as input variables .3 7.1 7. . . . . . . . 71 73 73 74 76 76 79 79 80 81 82 83 84 85 86 86 87 88 91 91 92 93 94 96 97 98 6. . . . . . . . . . . . . . . . . . Existential quantification . . . . . . . . . . . . . . . .10 Debugging in four acts .11 Glossary . . . . . . . . . . . . . . 100 Glossary . .12 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . 124 127 11 Optimization and Interpolation 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 10. . . . . . . . . . . . . . . . . . . . . 128 11. . . . . . 122 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 10. . . . . .6 Two dimensions . . . . . . .7 9. . . . . . .5 9. . . . . . . . .3 Golden section search . . . . . .7 Field mice . . . . 137 . . . . . . . . . . . . . . . . . . . . . . . . 132 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 10. . . . . . 107 Lotka-Voltera .2 9. . . . . . . . . . . . 120 10. . . . . . . . . . . . . .8 Glossary . . . . . . . . . . . . . . . .2 Optimization . . . . . . . . . . . . . . . . . . . . . . . . 113 115 10 Second-order systems 10. . 105 Row and column vectors . . . . . . . . . . . . . . . . . . . 134 11.4 Air resistance . . . . . . . . . . . . . . . . . .6 9.2 Newtonian motion . . . . . . . . . . 110 Output matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 The transpose operator . . . . . . . . . . . 127 11. . . . . . . . . . . 112 Exercises . . . . . . . . . . .3 Freefall . . . . . . . 117 10. . . . . . . . . . . . . . . .9 Exercises . . . . . . . . . 108 What can go wrong? . . . .6 Interpolating the inverse function . . . . . . . . . . . . .1 9. . . . . . . . 136 11. . . . . . . . 133 11. . . . . . . . . . . . . . . . .4 Discrete and continuous maps . . . . . . .Contents 9 Systems of ODEs 9. . . . . . . . . . . . . . 137 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 Glossary . . . . . . 120 10. . .3 9. . . . . . . . . . . . . . . . . . . . . . . .7 What could go wrong? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 11. . . . . . . . . 118 10. . . . . . . . . 110 Glossary . . . . . . . . . . . . . . . . . . . . . . .8 vii 105 Matrices . . . . . . . . . . . . . . . . . . .4 9. . . . .5 Parachute! . . . . . . . . . . . . .5 Interpolation . . . . . . . . . . . . . . .9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 ODE Events . . . . . . .1 Nested functions . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 12. . . . . . . . . . . . . . . .2 Dot and cross products . . . . 139 12. . . . . . . . . . . . 142 12. . . . . . . . . . . . . . .viii 12 Vectors as vectors Contents 139 12. . . . . . . . . . . . . . .4 Animation . . . . . . . . .1 What’s a vector? .5 Conservation of Energy . . . . 146 12. . .6 What is a model for? . . . . . . . . . . . .8 Exercises . . . . . . . . . . . . . . . . .7 Glossary . . . . . . . . . . . . . . . . . . . 141 12. . . . . . . . . . 143 12. . . . . . . . . . . . . . . . . . . . . . . . . .3 Celestial mechanics . . . . . . . . . . . 147 . . . 145 12. . . . . . . . . . . . . . . . . . .

followed by a chevron: >> which is the MATLAB prompt. and MATLAB printed ans = 3. in the example above. Initially. >> 2 + 1 ans = 3 Just to be clear. for example) and operators (like the plus sign. I typed 2 + 1 and then hit Enter. then executes them and prints the result.Chapter 1 Variables and values 1. The simplest kind of command is a mathematical expression. An expression can contain any number of operators and operands. this symbol prompts you to enter a command. When you start MATLAB you will see a window entitled MATLAB that contains smaller windows entitled Current Directory. +). You don’t have to put spaces between them. MATLAB is a glorified calculator.” I really mean “displayed on the screen. which is made up of operands (like numbers. MATLAB printed >>. that is.” which might be confusing. Command History and Command Window. which allows you to type MATLAB commands. but it’s the way people talk. some people do and some people don’t.1 A glorified calculator At heart. And when I say “printed. . If you type an expression and then press Enter (or Return). The Command Window runs the MATLAB interpreter. the Command Window contains a welcome message with information about the version of MATLAB you are running. MATLAB evaluates the expression and prints the result.

1. And that brings us to the First Theorem of debugging: Readable code is debuggable code. >> 2 * (3-4) / 5 ans = -0. If you want to override the order of operations. So 2 raised to the 16th power is >> 2^16 ans = 65536 As in basic algebra. sometimes pronounced “carat” or “hat”. -.4/5 ans = 5. division by a forward slash /. Subtraction is denoted by a minus sign. multiplication by an asterisk. and the most important human who will read your code is you. It is worth spending some time to make your code pretty.2 Math functions MATLAB knows how to compute pretty much every math function you’ve heard of. * (sometimes pronounced “splat”). >> 2*3 . But human readers do. This is the first of many style guidelines I will recommend for making your programs easier to read. you can use parentheses to override the order of operations. the MATLAB interpreter doesn’t check for style.8415 .4000 When I added the parentheses I also changed the spacing to make the grouping of operands clearer to a human reader. It knows all the trigonometric functions. if it saves you time debugging! The other common operator is exponentiation.2000 The order of operations is what you would expect from basic algebra: multiplication and division happen before addition and subtraction. you might have noticed that MATLAB puts some space between ans = and the result. The other arithmetic operators are pretty much what you would expect. you can use parentheses.2 >> 1+2+3+4+5+6+7+8+9 ans = 45 Variables and values Speaking of spaces. In my examples I will leave it out to save paper. Style doesn’t change what the program does. here’s how you use them: >> sin(1) ans = 0. exponentiation happens before multiplication and division. which uses the ^ symbol. but again.

sind. To learn about other functions. you can use a function call as an operand in an expression. >> sqrt(sin(0.5)^2) ans = 1 As you probably guessed.5)^2 + cos(0. All the trig functions in MATLAB work in radians.1. 1. in which case they are separated by commas.7854 If that bit of trigonometry isn’t familiar to you. sqrt computes the square root. The name of the function is sin. >> atan2(1. that is. which is the usual abbreviation for the trigonometric sine. There are lots of other math functions. >> help sin SIN Sine of argument in radians. . >> exp(1) ans = 2.1) ans = 0. don’t worry about it. More generally. The help command works from the Command Window. For example. like exp. which is the angle in radians between the positive x-axis and the point with the given y and x coordinates. Some functions take more than one argument. which computes e raised to the given power.3 Documentation MATLAB comes with two forms of online documentation. which computes the logarithm base e: >> log(exp(3)) ans = 3 This example also demonstrates that function calls can be nested. just type help followed by the name of a command.7183 The inverse of exp is log. See also asin. but this is not meant to be a reference manual. So exp(1) is just e. atan2 computes the inverse tangent. you should read the documentation. MATLAB also provides exponential functions. you can use the result from one function as an argument for another. help and doc. The value in parentheses is called the argument.3 Documentation 3 This command is an example of a function call. It’s just an example of a function with multiple arguments. SIN(X) is the sine of the elements of X.

1. this documentation is not beginner-friendly. as an operand in an expression: >> pi * 3^2 ans = 28. Another problem is that the help page uses vocabulary you don’t know yet.1416 And if you do anything with complex numbers. The doc pages are usually better. but for now it’s best to pretend. A named value is called a variable. “the elements of X” won’t make sense until we get to vectors and matrices a few chapters from now. You can use a variable name anywhere you can use a number. If you type doc sin. The examples often use vectors and arrays. so they may not make sense yet. the name pi refers to the mathematical quantity π.0000 + 0.4 Variables One of the features that makes MATLAB more powerful than a calculator is the ability to give a name to a value.0000i 1 Technically pi is a function. For example1 . For example. including examples of how to use it. but if you type it like that in MATLAB. MATLAB comes with a few predefined variables. you might find it convenient that both i and j are predefined as the square root of −1. One gotcha is that the name of the function appears in the help page in capital letters. a browser appears with more detailed information about the function. but you can get a preview of what’s coming. which is approximately >> pi ans = 3. . you get an error: >> SIN(1) ??? Undefined command/function ’SIN’.m Reference page in Help browser doc sin Unfortunately.4 Variables and values Overloaded functions or methods (ones with the same name in other directories) help sym/sin.2743 or as an argument to a function: >> sin(pi/2) ans = 1 >> exp(i * pi) ans = -1. not a variable.

>> LENGTH = 10. The assignment operator is the equals sign. so x and X are different variables. . but not at the beginning. =. Almost any sequence of lower and upper case letters is a legal variable name. Whenever you evaluate an expression. with an assignment statement. >> 3^2 + 4^2 ans = 25 >> sqrt(ans) ans = 5 But keep in mind that the value of ans changes every time you evaluate an expression. >> x = 6 * 7 x = 42 This example creates a new variable named x and assigns it the value of the expression 6 * 7. >> fibonacci0 = 1. is the only commonly used non-letter.1. which suppresses the output from a command. This example demonstrates Euler’s Equality: eiπ = −1. and give them values. A sequence of characters in single quotes is a string.5 Assignment statements You can create your own variables. . The third example demonstrates that not everything in MATLAB is a number. many MATLAB functions work with complex numbers. Numbers are fine. The right side can be any expression. but the underscore. You can use ans in a subsequent calculation as shorthand for “the value of the previous expression”.5 Assignment statements 5 As the second example shows. MATLAB responds with the variable name and the computed value. the left side has to be a legal variable name. Variable names are “case sensitive”. In this case MATLAB creates the variables and assigns them values. Some punctuation is also legal. including function calls. Spaces are not allowed. 1. In every assignment statement. MATLAB assigns the result to a variable named ans. but displays nothing. >> first_name = ’allen’ first_name = allen The first two examples demonstrate the use of the semi-colon.

6 Why variables? The most common reasons to use variables are • To avoid recomputing a value that is used repeatedly. .theta denom = shiftx * sqrt(2 * pi) * sigma temp = (log(shiftx) . exp(-1/2 * (log(x . hairy expression like this: ans = ((x .theta) * sqrt(2 * pi) * sigma) ^ -1 * . shiftx = x . It should be no surprise that exponent is the argument of exp. Just type . • To break a long computation into a sequence of steps.theta) . But often it is better to break the computation into a sequence of steps and assign intermediate results to variables. and denom ends up in the denominator.zeta)^2 / sigma^2) You can use an ellipsis to break the expression into multiple lines. If you are computing the area of a circle. It is common to use i and j for other purposes.7183 • To make the connection between the code and the underlying mathematics more apparent. Choosing informative names makes the code easier to read and understand (see the First Theorem of Debugging). you might want to compute it once and save the result.. j and pi are predefined. at the end of the first line and continue on the next.6 Variables and values Although i. >> e = exp(1) e = 2.. if you are performing computations involving e... you might want to use a variable named r: >> r = 3 r = 3 >> area = pi * r^2 area = 28.zeta) / sigma exponent = -1/2 * temp^2 ans = exp(exponent) / denom The names of the intermediate variables explain their role in the computation. but it is probably not a good idea to change the value of pi! 1. Suppose you are evaluating a big. you are free to reassign them. For example. shiftx is the value of x shifted by theta.2743 That way your code resembles the familiar formula πr2 .

1.7 Errors

7

1.7

Errors

It’s early, but now would be a good time to start making errors. Whenever you learn a new feature, you should try to make as many errors as possible, as soon as possible. When you make deliberate errors, you get to see what the error messages look like. Later, when you make accidental errors, you will know what the messages mean. A common error for beginning programmers is leaving out the * for multiplication. >> area = pi r^2 ??? area = pi r^2 | Error: Unexpected MATLAB expression. The error message indicates that, after seeing the operand pi, MATLAB was “expecting” to see an operator, like *. Instead, it got a variable name, which is the “unexpected expression” indicated by the vertical line, | (which is called a “pipe”). Another common error is to leave out the parentheses around the arguments of a function. For example, in math notation, it is common to write something like sin π, but not in MATLAB. >> sin pi ??? Function ’sin’ is not defined for values of class ’char’. The problem is that when you leave out the parentheses, MATLAB treats the argument as a string (rather than as an expression). In this case the sin function generates a reasonable error message, but in other cases the results can be baffling. For example, what do you think is going on here? >> abs pi ans = 112 105

There is a reason for this “feature”, but rather than get into that now, let me suggest that you should always put parentheses around arguments. This example also demonstrates the Second Theorem of Debugging: The only thing worse than getting an error message is not getting an error message. Beginning programmers hate error messages and do everything they can to make them go away. Experienced programmers know that error messages are your friend. They can be hard to understand, and even misleading, but it is worth making some effort to understand them.

8

Variables and values

Here’s another common rookie error. If you were translating the following mathematical expression into MATLAB: 1 √ 2 π You might be tempted to write something like this: 1 / 2 * sqrt(pi) But that would be wrong. So very wrong.

1.8

Floating-point arithmetic

In mathematics, there are several kinds of numbers: integer, real, rational, irrational, imaginary, complex, etc. MATLAB only has one kind of number, called (for reasons I won’t explain here) floating-point. You might have noticed that MATLAB expresses values in decimal notation. So, for example, the rational number 1/3 is represented by the floating-point value >> 1/3 ans = 0.3333 which is only approximately correct. It’s not quite as bad as it seems; MATLAB uses more digits than it shows by default. You can change the format to see the other digits. >> format long >> 1/3 ans = 0.33333333333333 Internally, MATLAB uses the IEEE double-precision floating-point format, which provides about 15 significant digits of precision (in base 10). Leading and trailing zeros don’t count as “significant” digits, so MATLAB can represent large and small numbers with the same precision. Very large and very small values are displayed in scientific notation. >> factorial(100) ans = 9.332621544394410e+157 The e in this notation is not the transcendental number known as e; it is just an abbreviation for “exponent”. So this means that 100! is approximately 9.33 × 10157 . The exact solution is a 158-digit integer, but we only know the first 16 digits. You can enter numbers using the same notation.

1.9 Comments >> speed_of_light = 3.0e8 speed_of_light = 300000000

9

Although MATLAB can handle large numbers, there is a limit. The predefined variables realmax and realmin contain the largest and smallest numbers that MATLAB can handle2 . >> realmax ans = 1.797693134862316e+308 >> realmin ans = 2.225073858507201e-308 If the result of a computation is too big, MATLAB “rounds up” to infinity. >> factorial(170) ans = 7.257415615307994e+306 >> factorial(171) ans = Inf Division by zero also returns Inf, but in this case MATLAB gives you a warning because in many circles division by zero is considered undefined. >> 1/0 Warning: Divide by zero. ans = Inf A warning is like an error message without teeth; the computation is allowed to continue. Allowing Inf to propagate through a computation doesn’t always do what you expect, but if you are careful with how you use it, Inf can be quite useful. For operations that are truly undefined, MATLAB returns NaN, which stands for “not a number”. >> 0/0 Warning: Divide by zero. ans = NaN

1.9

Comments

Along with the commands that make up a program, it is useful to include comments that provide additional information about the program in natural language. The percent symbol % separates the comments from the code.
2 The names of these variables are misleading; floating-point numbers are sometimes, wrongly, called “real”.

or the meaning of a variable: >> p = 0 >> v = 100 >> a = -9. command: A line of MATLAB code executed by the interpreter.8 % position from the origin in meters % velocity in meters / second % acceleration of gravity in meters / second^2 If you use longer variable names. but bad comments are useless or (even worse) misleading. prompt: The symbol the interpreter prints to indicate that it is waiting for you to type a command. Good comments make programs more readable. operator: One of the symbols.10 Glossary interpreter: The program that reads and executes MATLAB code. MATLAB would keep track of units and propagate them through the computation. but for now that burden falls on the programmer. it can be useful to make your program consistent with your math. In an ideal world. value: The numerical result of a computation.10 >> speed_of_light = 3. . like units in the example above. 1. Also. expression: A sequence of operands and operators that specifies a mathematical computation and yields a value. operand: A number or variable that appears in an expression along with operators. if you are translating from math that uses short variable names. evaluate: To compute the value of an expression. Comments have no effect on the execution of the program. that represent mathematical operations. In this case it specifies the units of the value. Avoid comments that are redundant with the code: >> x = 5 % assign the value 5 to x Good comments provide additional information that is not in the code.0e8 speed_of_light = 300000000 Variables and values % meters per second The comment runs from the percent symbol to the end of the line. you might not need explanatory comments. They are there for human readers. but there is a tradeoff: longer code can become harder to read. like * and +.

variable: A named value.1) Note: you can’t use Greek letters in MATLAB.1. assignment statement: A command that creates a new variable (if necessary) and gives it a value. 3.g.11 Exercises Exercise 1. e. scientific notation: A format for typing and displaying large and small numbers. but does not affect its execution.000.0 × 108 or 300. floating-point: The kind of number MATLAB works with. when translating math expressions with Greek letters. 1. comment: Part of a program that provides additional information about the program. . sigma and x already exist. which represents 3.000. string: A value that consists of a sequence of characters (as opposed to a number). argument: An expression that appears in a function call to specify the value the function operates on. function call: A kind of command that executes a function. for example log10 is the name of a function that computes logarithms in base 10. call: To cause a function to execute and compute a result.11 Exercises 11 order of operations: The rules that specify which operations in an expression are performed first. You can assume that the variables mu. All floating-point numbers can be represented with about 16 significant decimal digits (unlike mathematical integers and reals). nested function call: An expression that uses the result from one function call as an argument for another.0e8.1 Write a MATLAB expression that evaluates the following math expression. function: A named computation. it is common to write out the name of the letter (assuming you know it). − “ x−µ √ σ 2 e ”2 √ σ 2π (1.

12 Variables and values .

which is short for MATLAB. MATLAB executes the commands in the M-File.1 M-files So far we have typed all of our programs “at the prompt. MATLAB will store your script in a directory that is on the search path. Change the name to myscript. A script is a file that contains MATLAB code. Beyond that. . exactly as if you had typed them at the prompt. which is the list of directories MATLAB searches for scripts.” which is fine if you are not writing more than a few lines. MATLAB executes your script and displays the result.m. or select Save from the File menu. >> myscript x = 5 When you run a script. By default. Go back to the Command Window and type myscript (without the extension) at the prompt. one after another. a dialog box appears where you can choose the file name and the directory where it should go. you will want to store your program in a script and then execute the script. Either way. but the simplest way is by selecting New→M-File from the File menu. Type the following code in the editor x = 5 and then press the (outdated) floppy disk icon.Chapter 2 Scripts 2.m and leave the directory unchanged. You can create and edit scripts with any text editor or word processor. These files are also called “Mfiles” because they use the extension . A window appears running a text editor specially designed for MATLAB.

and use the Tab key or the mouse to switch between them. particularly those with petals or scales arranged in the form of a logarithmic spiral. Keeping track of your scripts can be a pain. 2.1 The Fibonacci sequence. Exercise 2. and for i ≥ 3. or modify the search path to include the directory where you keep your scripts. The following expression computes the nth Fibonacci number: 1 Fn ≈ √ 5 √ 1+ 5 2 n − √ 1− 5 2 n (2. F2 = 1. is described by the equations F1 = 1. At the prompt. Fi = Fi−1 + Fi−2 . • If you run a script repeatedly. The last line of your script should assign the value of Fn to ans. you will get an error message like: >> myscript ??? Undefined function or variable ’myscript’.1) Translate this expression into MATLAB and store your code in a file named fibonacci1. The terms of this sequence occur naturally in many plants. On the other hand. it is faster to type the name of the script than to retype the code! . and you might be able to reuse a script from one project to the next. for now. To keep things simple.14 Scripts If something goes wrong and MATLAB can’t find your script. it might take a few tries to get everything right. it can be a pain to switch back and forth between the Command Window and the Editor. I suggest keeping all of your scripts in the default directory.2 Why scripts? The most common reasons to use scripts are • When you are writing more than a couple of lines of code. set the value of n to 10 and then run your script. You’ll have to consult the documentation for the details (sorry!). • If you choose good names for your scripts. In this case you can either save your script again in a directory that is on the search path. (The correct value of F10 is 55). you will be able to remember which script does what. denoted F . Putting your code in a script makes it easier to edit than typing it at the prompt. Try to arrange your windows so you can see the Editor and the Command Window at the same time.

and if you are not careful.2. It is easy to write a script that has the same name as a MATLAB function. whenever you start an new script. Also. Either way. you will be running the old version. 2. whenever you edit your script. which is that you have to make sure that the code you are running is the code you think you are running. MATLAB comes with a lot of predefined functions. >> >> >> >> x=5. who Your variables are: x y z The clear command removes variables. y=7. If you forget to save it. which is a set of variables and their values. you have to save it before you run it. you might find yourself running the MATLAB function instead of your script. First. you can use the disp function. >> disp(z) 9 . if the code you are running is not the code you are looking at. you will find debugging a frustrating exercise! And that brings us to the Third Theorem of Debugging You must always be 100% sure that the code you are running is the code you think you are running.3 The workspace The variables you create are stored in the workspace. z=9. start with something simple. The who command prints the names of the variables in the workspace.3 The workspace 15 Unfortunately. >> clear y >> who Your variables are: x z To display the value of a variable. the great power of scripts comes with great responsibility. like x=5 that produces a visible effect. Then run your script and confirm that you get what you expect.

not where it was caused. If you don’t: >> fibonacci1 ??? Undefined function or variable "n". and displays the line. But the general idea is that n is undefined. For example. in a sense. Notice that MATLAB tells you what line of your program the error is in. but beware! MATLAB is telling you where the error was discovered. it is. the name of a variable is an expression. so evaluating it should assign a value to ans. Error in ==> fibonacci1 at 4 diff = t1^(n+1) . but MATLAB seems to handle this as a special case.4 More errors Again. The details of this message might be different for you. >> z z = 9 Scripts (Strictly speaking.) 2. I might put something like this at the beginning of fibonacci1: . 2. and what the requirements are for the workspace.5 Pre. Which brings us to the Fourth Theorem of Debugging: Error messages tell you where the problem was discovered. depending on what’s in your script. In this case. This information can be helpful. when you try something new. For example. The most common error with scripts is to run a script without creating the necessary variables. The object of the game is to find the cause and fix it—not just to make the error message go away. not where the error is. the error is not in the script at all.16 But it’s easier to just type the variable name. in the workspace.t2^(n+1). you should make a few mistakes on purpose so you’ll recognize them later. fibonacci1 requires you to assign a value to n.and post-conditions Every script should contain a comment that explains what it does.

x does not get updated.2. Postcondition: the result is stored in ans. in order for it to work correctly. Another difference is that an assignment statement is only temporary. as long as you know what a “target” is. but it’s not. which is called the target of the assignment. Precondition: you must assign a value to n before running this script. You can even use the doc command to see your comment in the Help Window. MATLAB assumes it is the documentation for the script. So this is legal: >> y = 1. If there is a comment at the beginning of a script. Postcondition: the result is stored in ans. If y changes later. you get the current value of y. when the script starts. One difference is that the sides of an assignment statement are not interchangeable. you get the contents of the comment (without the percent signs). A postcondition is something that will be true when the script completes.6 Assignment and equality 17 % Computes the nth Fibonacci number. In this case the error message is pretty helpful. scripts that you write behave just like predefined scripts. That way. A third difference is that a mathematical equality is a statement that may or may not be true. but the left side has to be a variable. in the following sense.6 Assignment and equality In mathematics the equals sign means that the two sides of the equation have the same value. 2. For example. When you assign x = y+1. The right side can be any legal expression. so if you type help fibonacci1. >> x = y+1 x = 2 But this is not: >> y+1 = x ??? y+1 = x | Error: The expression to the left of the equals sign is not a valid target for an assignment. >> help fibonacci1 Computes the nth Fibonacci number. In MATLAB an assignment statement looks like a mathematical equality. % Precondition: you must assign a value to n before running % this script. y = y + 1 is a statement that happens to be . A precondition is something that must be true.

When this process works. 3. If not.18 Scripts false for all real values of y. Always start with a working program. and replaces the old value with the new value. and it brings us to the Fifth Theorem of Debugging: . y = y+1 is a sensible and useful assignment statement. start with that. adds one.” So x = y+1 is pronounced “x gets the value of y plus one. you might find yourself spending more and more time debugging. This step is important. 2. Ideally. If you have an example from a book or a program you wrote that is similar to what you are working on. you should know what the correct answer is. If so.7 Incremental development When you start writing scripts that are more than a few lines. or the problem is obvious. but if the change you made was small. try this exercise: Exercise 2. you will find that your changes usually work the first time. >> y = y+1 y = 2 When you read MATLAB code. like x=5. 2. That’s a good thing. Get them out of the way so you can focus on programming. because in most environments there are lots of little things that can trip you up when you start a new project. it shouldn’t take long to find the problem. It reads the current value of y. In MATLAB. start with something you know is correct. or be able to check it by performing another computation.” To test your understanding of assignment statements. >> y = 1. Run the program and confirm that you are running the program you think you are running. The fundamental steps are 1. Make one small. go back to Step 2. A “testable” change is one that displays something on the screen (or has some other effect) that you can check.2 Write a few lines of code that swap the values of x and y. Otherwise. testable change at a time. Run the program and see if the change worked. the harder it is to find the problem. Incremental development is a way of programming that tries to minimize the pain of debugging. Put your code in a script called swap and test it. you will have to do some debugging. The more code you write before you start debugging. you might find it helpful to pronounce the equals sign “gets” rather than “equals.

For example. we could try >> asin(0) ans = 0 which is correct. The programs we have seen so far are not big enough to need unit testing.8 Unit testing The best kind of debugging is the kind you don’t have to do. So the correct answer is π/2. it is usually not obvious how to choose the steps that get from x=5 to the program you are trying to write. You should test it in isolation before you put it into your program.2. you should try incremental development. and you are pretty sure it computes the inverse sine function.5708 Oops. there are two problems with incremental development: 19 • Sometimes you have to write some extra code in order to generate visible output that you can check. we expect the answer to be 90. and you are spending a lot of time debugging. Pretty sure is not good enough. But time you save on debugging is almost always worth the time you spend on scaffolding. You find the MATLAB function asin. so if we try asin(1). suppose you know that x is the sine of some angle and you want to find the angle. but the same principle applies when you are working with a new function or a new language feature for the first time.8 Unit testing In large software projects. We forgot that the trig functions in MATLAB work in radians. 2. There is an extended example in Section 5. This extra code is called scaffolding because you use it to build the program and then remove it when you are done. you want to be very sure. unit testing is the process of testing software components in isolation before putting them together. Since we know sin 0 = 0. Also. In practice. right? >> asin(1) ans = 1. which we can confirm by dividing through by pi: . not degrees.7. we know that the sine of 90 degrees is 1. • When you are getting started. If you find yourself writing more than a few lines of code before you start testing.

20 >> asin(1) / pi ans = 0. Which brings us to the Sixth Theorem of Debugging: The worst bugs aren’t in your code. they are in your head. 2. scaffolding: Code you write to help you program or debug.9 Glossary M-file: A file that contains a MATLAB program. incremental development: A way of programming by making a series of small. you are checking your understanding. there are 150 cars at each location. script: An M-file that contains a sequence of MATLAB commands. 2. you have observed that each week 5% of the cars in Albany are dropped off in Boston.5000 Scripts With this kind of unit testing. precondition: Something that must be true when the script starts. postcondition: Something that will be true when the script completes. target: The variable on the left side of an assignment statement.” picking up a car in Albany and returning it in Boston. Albany and Boston. workspace: A set of variables and their values. you are not really checking for errors in MATLAB. it looks right. If you make an error because you are confused about how MATLAB works. . because when you look at the code. testable changes. but which is not part of the finished program. it might take a long time to find. in order for it to work correctly. and 3% of the cars in Boston get dropped off in Albany. At the beginning of the year. Some of your customers do “one-way rentals.10 Exercises Exercise 2. or the other way around. search path: The list of directories where MATLAB looks for M-files.3 Imagine that you are the owner of a car rental company with two locations. unit testing: A process of testing software by testing each component in isolation. Over time.

The script should display the updated values of a and b. initialize a and b at the prompt and then execute the script. but not any intermediate variables. What do you think will happen to the number of cars? Will all the cars end up in one place? Will the number of cars reach an equilibrium.2. You might want to use the round function to compute the number of cars that move during each week. Note: cars are countable things. you can simulate the passage of time from week to week. . and how to plot the values of a and b versus time. To test your program.10 Exercises 21 Write a script called car update that updates the number of cars in each location from one week to the next. or will it oscillate from week to week? In the next chapter we will see how to execute your script automatically. If you execute your script repeatedly. The postcondition is that a and b have been modified to reflect the number of cars that moved. so a and b should always be integer values. The precondition is that the variables a and b contain the number of cars in each location at the beginning of the week.

22 Scripts .

0. The following is an alternative solution that has the added advantage of simplifying the computation: atob = 0.05*a .3.0.03*b a = a .atob b = b + atob It is easy to look at this code and confirm that it obeys Conversation of Cars. so when the second line runs.0.03*b b = b + 0. Even if the value of atob is wrong.Chapter 3 Loops 3. it gets the old value of b and the new value of a. And that brings us to the Seventh Theorem of Debugging: The best way to avoid a bug is to make it impossible.” that is. so very wrong.0. Why? The problem is that the first line changes the value of a.05*a + 0. which violates the principle of Conversation of Cars! One solution is to use temporary variables anew and bnew: anew = a .1 Updating variables In Exercise 2.05*a .03*b But that would be wrong.03*b bnew = b + 0.0.03*b a = anew b = bnew This has the effect of updating the variables “simultaneously.05*a + 0.05*a . it reads both old values before writing either new value. removing redundancy also eliminates the opportunity for a bug. As a result. the change in a is not always the same as the change in b. you might have been tempted to write something like a = a . at least the total number of cars is right. In this case. .

Numerical error: Most computations in MATLAB are only approximately right. Run time errors are harder because. called absolute and relative. The problem in the previous section. . where we changed the value of a before reading the old value. Most of the time the errors are small enough that we don’t care. MATLAB produces the floatingpoint value that is closest to the exact solution. Logical error: Your program runs without generating any error messages. the bug is in your head! Numerical errors can be tricky because it’s not clear whether the problem is your fault. if you try to access a variable that doesn’t exist. there’s nothing wrong with the program. Syntax errors are usually the easiest. From MATLAB’s point of view. For example. it prints an error message and stops running your program. Sometimes the error messages are confusing. that’s a runtime error. as I mentioned before. but it doesn’t do the right thing. For most simple computations. But some computations are ill-conditioned.3 Absolute and relative error There are two ways of thinking about numerical errors. which means that the first 15 significant digits should be correct. but in some cases the roundoff errors are a problem.24 Loops 3. 3. at least roughly. you can’t have two operands in a row without an operator. but not what caused it.2 Kinds of error There are four kinds of error: Syntax error: You have written a MATLAB command that cannot execute because it violates one of the rules of syntax. For example. so only you can check it. it prints an error message and stops. is a logical error. When MATLAB detects the problem. When MATLAB finds a syntax error. but not always! Precision (the number of digits in the answer) does not imply accuracy (the number of digits that are right). Runtime error: Your program starts running. so pi r^2 contains a syntax error. Sometimes MATLAB can warn you that this is happening. but MATLAB can usually tell you where the error is. Logical errors are hard because MATLAB can’t help at all. the roundoff errors accumulate and the number of correct digits can be smaller. Only you know what the program is supposed to do. MATLAB can tell you where it detected the problem. but something goes wrong along the way. which means that even if your program is correct.

In this case. ignoring its sign. we might want to estimate 9! using the formula 18π(9/e)9 . in which case you use i or j for −1). j and k as loop variables √ (except when you are using complex numbers. :. The colon operator. In the spirit of unit testing. It is a common convention to use the names i. because it doesn’t matter whether the approximation is too high or too low. The statements inside the loop are called the body. which is just less than 1%. that sounds like a lot—we’re off by three thousand—but it is worth taking into account the size of the thing we are estimating.3. up to 52. For example. $3000 matters a lot if we are talking about my annual salary. 536. a for loop is the kind of loop that uses the for statement. The absolute error is 3.4 for loops 25 An absolute error is just the difference between the correct value and the approximation. yielding . A natural way to handle this problem is to use relative error. in the last chapter we wrote a script named car update that simulates one week in the life of a rental car company. At first glance. and it is like an assignment statement. For many purposes.00921. they are indented to show that they are inside the loop. 3.880. but the indentation does not . we would divide the error by 362. We usually write the magnitude of the error. The first time it runs. By convention. To simulate an entire year.87. i gets the value 2. it creates the variable i and assigns it the value 1. you can create a range at the prompt: >> 1:5 ans = 1 2 3 4 5 The variable you use in the for statement is called the loop variable.13. The second time. being off by 1% is good enough.343. specifies a range of integers. The exact answer is 9 · 8 · 7 · 6 · 5 · 4 · 3 · 2 · 1 = 362. we have to run it 52 times: for i=1:52 car_update end The first line looks like an assignment statement. For example.4 for loops A loop is a part of a program that executes repeatedly. except that it runs more than once. The simplest use of a for loop is to execute one or more lines a fixed number of times. which is the error expressed as a fraction (or percentage) of the exact value. The approximation is 359. √ For example. and so on. but not at all if we are talking about the national debt. 880.

Unfortunately. type >> plot(1. blue dot at x position 1 and y position 2. But it is probably too long to fit.26 Loops actually affect the execution of the program. you can specify a different shape: >> plot(1.5 plotting plot is a versatile function for plotting points and lines on a two-dimensional graph. it would be hard to interpret. To see the loop in action you can run a loop that displays the loop variable: >> for i=1:5 i end i i i i i = = = = = 1 2 3 4 5 As this example shows. yellow and black. For this exercise. *. magenta. s (for square). 2) A Figure Window should appear with a graph and a single. ’o’) The letter in single quotes is a string that specifies how the point should be plotted. 2. blue. We will start simple and work our way up. and even if it fit. To plot a single point. . and ^ (for a triangle). you can run a for loop from the command line. but it’s much more common to put it in a script. You can also specify the color: >> plot(1. 2. ’ro’) r stands for red. d (for diamond). Remember that before you run car update. start with the values a = 150 and b = 150. The end of the loop is officially marked by the end statement. If everything goes smoothly. Other shapes include +. it is so versatile that it can be hard to use (and hard to read the documentation!). cyan. A graph would be much better! 3. Exercise 3. x. the other colors include green. To make the dot more visible. you have to assign values to a and b. your script will display a long stream of numbers on the screen.1 Create a script named car loop that uses a for loop to run car update 52 times.

the elements are denoted with subscripts. hold on tells MATLAB not to clear the figure when it makes a new plot.6 Sequences 27 When you use plot this way. in a geometric sequence. ’o’) You should see a figure with two points. with the command clf. The hold command lets you override that behavior.6 Sequences In mathematics a sequence is a set of numbers that corresponds to the positive integers. Once you get that working. it can only plot one point at a time. each element is a constant multiple of the previous element. 3. you might want to clear the figure yourself. The numbers in the sequence are called elements. it clears the figure before making the new plot. Notice that the loop range starts at 2 because the initial value of a corresponds to A1 . One more thing: if you use hold on to prevent MATLAB from clearing the figure. In other words. let’s look at the sequence with A1 = 1 and the ratio Ai+1 = Ai /2. followed by A2 . each element is half as big as the one before it. If you run plot again. Exercise 3. modify it so it plots the values of a with red circles and the values of b with blue diamonds.3. so the first element of the series A is A1 . hold off returns to the default behavior. 1. from time to time. MATLAB scales the plot automatically so that the axes run from the lowest value in the plot to the highest. In math notation. we find the next value of a by dividing the previous value by 2. . and so on. Try this: >> hold on >> plot(1. ’o’) >> plot(2. As a more specific example. The following loop computes the first 10 elements of A: a = 1 for i=2:10 a = a/2 end Each time through the loop. As an example.2 Modify car loop so that each time through the loop it plots the value of a versus the value of i. for all i. for loops are a natural way to compute the elements of a sequence. so the first time through the loop we are computing A2 . 2. So in this example the points are plotted in the corners.

For example. we replace the previous element with the next. Before the loop we initialize it to 0.3 Write a script named sequence that uses a loop to computes elements of A directly. without using the previous element. total = total + a. a contains the 10th element. that is. .5^(i-1). In math notation.7 Series In mathematics. as a function of i. Each time through the loop we add in the ith element. For this sequence it is also possible to compute the ith element directly. but in math. “sequence” and “series” mean pretty much the same thing. Ai = A1 ri−1 . we assign it to ans. This loop computes the sequence recurrently. the sum of the first 10 elements of A is 10 Ai i=1 A for loop is a natural way to compute the value of this series: A1 = 1. for i=1:10 a = A1 * 0. total = 0. but they are not saved in a variable. which means that each element depends on the previous one. a series is the sum of the elements of a sequence.28 Loops Each time through the loop. The way we are using total is sometimes called an accumulator. we will see how to save all of the elements of a sequence in a vector. At the end of the loop total contains the sum of the elements. so at the end. a variable that accumulates a result a little bit at a time. a sequence is a set of numbers. Since that’s the value we were looking for. It’s a terrible name. 3. In math notation. and a series is an expression (a sum) that has a single value. Later. Exercise 3. a series is often written using the summation symbol . so each time through the loop a is the ith element. The other elements are displayed on the screen. end ans = total A1 is the first element of the sequence. because in common English.

for i=1:n a = A1 * 0. we could replace the constant. series total = 1. as an exercise. . with the precondition that you have to set n before you execute the script. the previous example always adds up the first 10 elements of the sequence. end ans = total Now the script can compute any number of terms. Here’s how you could run it with different values of n: >> n=10.4 This example computes the terms of the series directly. To see if that’s true for our program.3. that is.99999809265137 >> n=30. 3. but we might be curious to know what happens to total as we increase the number of terms in the sequence. as the number of terms goes to infinity. you might know that this series converges on 2. series total = 1. You will have to be careful about where you start and stop the loop. the sum approaches 2 asymptotically. 10. write a script named series that computes the same sum by computing the elements recurrently.8 Generalization 29 Exercise 3.99804687500000 >> n=20.99999999813735 >> n=40. series total = 1. series total = 1.5^(i-1). total = total + a. If you have studied geometric series.8 Generalization As written. total = 0. with a variable named n: A1 = 1.99999999999818 It sure looks like it’s converging on 2.

relative error: The difference between an approximation and an exact answer. for example by replacing a specific value with a variable that can have any value. element: A member of the set of numbers in a sequence. the new script is more general. sequence: In mathematics. it can compute any number of terms. that gets assigned a different value each time through the loop. 3. . a set of numbers that correspond to the positive integers. generalization: A way to make a program more versatile. specific number of terms.9 Glossary absolute error: The difference between an approximation and an exact answer. This is an important idea we will come back to when we talk about functions. loop: A part of a program that runs repeatedly. defined in a for statement. Instead of computing a fixed. body: The statements inside the for loop that are run repeatedly. for example 1:5. range: The set of values assigned to the loop variable. often specified with the colon operator.30 Loops Replacing a constant with a variable is called generalization. series: The sum of the elements in a sequence. recurrently: A way of computing the next element of a sequence based on previous elements. accumulator: A variable that is used to accumulate a result a little bit at a time. directly: A way of computing an element in a sequence without using previous elements. loop variable: A variable. expressed as a fraction or percentage of the exact answer.

Initially. You might want to call them prev1 and prev2. As a postcondition. To keep things simple for now. and plots Fi for each i with a series of red circles. The most common Fibonacci sequence starts with F1 = 1 and F2 = 1. think carefully about the order of the updates! Exercise 3. your script should assign the 10th element to ans. but once you have those. prev1 = F1 and prev2 = F2 . you will have to update prev1 and prev2. Write a script called fibonacci2 that uses a for loop to compute the first 10 elements of this Fibonacci sequence. uses fibonacci2 to compute Fibonacci numbers.10 Exercises Exercise 3. .3. you can assume that n is greater than 2.5 We have already seen the Fibonacci sequence. which is defined recurrently as Fi = Fi−1 + Fi−2 In order to get started. Hint: you will have to use two variables to keep track of the previous two elements of the sequence. with the precondition that you have to set n before you run the script. At the end of the loop.6 Write a script named fib plot that loops i through a range from 1 to 20. you have to specify the first two elements.10 Exercises 31 3. Now generalize your script so that it computes the nth element for any value of n. you can compute the rest. F .

32 Loops .

which is why in this example the value of total is zero for any negative value of n.Chapter 4 Vectors 4.” but there you have it. you get: total = 0 Why? Because the expression 1:-1 means “all the numbers from 1 to -1. For example. this loop computes the sum of the first n elements of a geometric sequence: A1 = 1. the loop never runs at all.5^(i-1). total = total + a. end ans = total It works for any positive value of n. but what if n is negative? In that case. total = 0. counting up by 1. if you loop over an empty range. for i=1:n a = A1 * 0.” It’s not immediately obvious what that should mean. so the result is >> 1:-1 ans = Empty matrix: 1-by-0 If the matrix is empty.1 Checking preconditions Some of the loops in the previous chapter don’t work if the value of n isn’t set correctly before the loop runs. In any case. . but MATLAB’s interpretation is that there aren’t any numbers that fit that description. you might expect it to be “0-by-0.

34

Vectors

If you are sure that you will never make a mistake, and that the preconditions of your functions will always be satisfied, then you don’t have to check. But for the rest of us, it is dangerous to write a script, like this one, that quietly produces the wrong answer (or at least a meaningless answer) if the input value is negative. A better alternative is to use an if statement.

4.2

if

The if statement allows you to check for certain conditions and execute statements if the conditions are met. In the previous example, we could write: if n<0 ans = NaN end The syntax is similar to a for loop. The first line specifies the condition we are interested in; in this case we are asking if n is negative. If it is, MATLAB executes the body of the statement, which is the indented sequence of statements between the if and the end. MATLAB doesn’t require you to indent the body of an if statement, but it makes your code more readable, so you should do it, and don’t make me tell you again. In this example, the “right” thing to do if n is negative is to set ans = NaN, which is a standard way to indicate that the result is undefined (not a number). If the condition is not satisfied, the statements in the body are not executed. Sometimes there are alternative statements to execute when the condition is false. In that case you can extend the if statement with an else clause. The complete version of the previous example might look like this: if n<0 ans = NaN else A1 = 1; total = 0; for i=1:n a = A1 * 0.5^(i-1); total = total + a; end ans = total end Statements like if and for that contain other statements are called compound statements. All compound statements end with, well, end.

4.3 Relational operators

35

In this example, one of the statements in the else clause is a for loop. Putting one compound statement inside another is legal and common, and sometimes called nesting.

4.3

Relational operators

The operators that compare values, like < and > are called relational operators because they test the relationship between two values. The result of a relational operator is one of the logical values: either 1, which represents “true,” or 0, which represents “false.” Relational operators often appear in if statements, but you can also evaluate them at the prompt: >> x = 5; >> x < 10 ans = 1 You can assign a logical value to a variable: >> flag = x > 10 flag = 0 A variable that contains a logical value is often called a flag because it flags the status of some condition. The other relational operators are <= and >=, which are self-explanatory, ==, for “equal,” and ~=, for “not equal.” (In some logic notations, the tilde is the symbol for “not.”) Don’t forget that == is the operator that tests equality, and = is the assignment operator. If you try to use = in an if statement, you get a syntax error: if x=5 ??? if x=5 | Error: The expression to the left of the equals sign is not a valid target for an assignment. MATLAB thinks you are making an assignment to a variable named if x!

4.4

Logical operators

To test if a number falls in an interval, you might be tempted to write something like 0 < x < 10, but that would be wrong, so very wrong. Unfortunately, in many cases, you will get the right answer for the wrong reason. For example:

36 >> x = 5; >> 0 < x < 10 ans = 1 But don’t be fooled! >> x = 17 >> 0 < x < 10 ans = 1 % just plain wrong

Vectors

% right for the wrong reason

The problem is that MATLAB is evaluating the operators from left to right, so first it checks if 0<x. It is, so the result is 1. Then it compares the logical value 1 (not the value of x) to 10. Since 1<10, the result is true, even though x is not in the interval. For beginning programmers, this is an evil, evil bug! One way around this problem is to use a nested if statement to check the two conditions separately: ans = 0 if 0<x if x<10 ans = 1 end end But it is more concise to use the AND operator, &&, to combine the conditions. >> x = 5; >> 0<x && x<10 ans = 1 >> x = 17; >> 0<x && x<10 ans = 0 The result of AND is true if both of the operands are true. The OR operator, ||, is true if either or both of the operands are true.

4.5

Vectors

The values we have seen so far are all single numbers, which are called scalars to contrast them with vectors and matrices, which are collections of numbers.

MATLAB increments each element of the vector: >> Y = X+5 Y = 6 7 8 9 10 The result is a new vector. the numbers that make up the vector are called elements. MATLAB adds the corresponding elements of each vector and creates a new vector that contains the sums: >> Z = X+Y Z = 7 >> W = 1:3 W = 1 2 3 9 11 13 15 But adding vectors only works if the operands are the same size. If you add a scalar to a vector. the original value of X is not changed. The problem is a slight mismatch between math vocabulary and MATLAB vocabulary. What we called a “range” in the previous chapter was actually a vector. In general. 4. but for beginning programmers it is a useful way to remember what is a scalar and what is a vector.6 Vector arithmetic You can perform arithmetic with vectors. it is a set of numbers that correspond to positive integers. You can assign a vector value to a variable: >> X = 1:5 X = 1 2 3 4 5 Variables that contain vectors are often capital letters.6 Vector arithmetic 37 A vector in MATLAB is similar to a sequence in mathematics.4. That’s just a convention. anything you can do with a scalar. MATLAB doesn’t require it. because we are thinking of these values as vectors. If you add two vectors. you can also do with a vector. not matrices. Just as with sequences. Otherwise: >> X+W ??? Error using ==> plus Matrix dimensions must agree. too. The error message in this case is confusing. .

>> whos Name scalar vector matrix Size 1x1 1x5 2x3 Bytes 8 40 32 Class double array double array double array According to MATLAB. Now let’s see what we’ve got. The thing we called scalar is.38 Vectors 4.3) matrix = 1 1 1 1 1 1 ones is a function that builds a new matrix with the given number of rows and columns. of course.7 Everything is a matrix In math (specifically in linear algebra) a vector is a one-dimensional sequence of values and a matrix is two-dimensional (and. if you want to think of it that way. vectors. Our vector is really a matrix with one row and 5 columns. and sets all the elements to 1. as long as you remember that MATLAB thinks everything is a matrix. whos is similar to who except that it also displays the size and type of each variable. . which is specified by the number of rows and columns. a matrix with one row and one column. And. matrix is a matrix. and matrices. a scalar is zero-dimensional). everything is a double array: “double” is another name for double-precision floating-point numbers. First I’ll make one of each kind of value: >> scalar = 5 scalar = 5 >> vector = 1:5 vector = 1 2 3 4 5 >> matrix = ones(2. The point of all this is that you can think of your values as scalars. You can see this if you use the whos command to display the variables in the workspace. The only difference is the size. and “array” is another name for a matrix. and I think you should. according to MATLAB. In MATLAB. everything is a matrix.

When you saw X*Y you probably expected it to multiply each the the elements of X by the corresponding element of Y and put the results into a new vector. this doesn’t make much sense.* Y ans = 1 4 9 16 25 We’ll get back to the elementwise operators later.4. you can forget about them for now. The reason the “inner matrix dimensions must agree” is that the way matrix multiplication is defined in linear algebra. mtimes is the MATLAB function that performs matrix multiplication. the number of rows in X has to equal the number of columns in Y (those are the inner dimensions).8 Indices 39 Here’s another example where the error message only makes sense if you know what is happening under the hood: >> X = 1:5 X = 1 >> Y = 1:5 Y = 1 2 3 4 5 2 3 4 5 >> Z = X*Y ??? Error using ==> mtimes Inner matrix dimensions must agree. If you don’t know linear algebra. and the operator that performs it is . That operation is called elementwise multiplication.8 Indices You can select elements of a vector with parentheses: >> Y = 6:10 Y = 6 >> Y(1) ans = 6 >> Y(5) ans = 10 7 8 9 10 . 4. First of all.*: >> X .

this message is pretty clear. which returns the number of elements in a vector: for i=1:length(Y) Y(i) end There. >> Y(i+1) ans = 7 Loops and vectors go together like the storm and rain.40 Vectors This means that the first element of Y is 6 and the fifth element is 10. And you can forget about “logicals” for now. The index can be any kind of expression. If it’s zero or negative. Finally. this loop displays the elements of Y. For example. 4. If the index is too big. The number in parentheses is called the index because it indicates which element of the vector you want. There’s the “m” word again. Now that will work for a vector of any length. We can make it more general by using the length function. you get this: >> Y(6) ??? Index exceeds matrix dimensions. but the value of the expression has to be a positive integer. “Subscript indices” is MATLAB’s longfangled way to say “indices. you get this: >> Y(0) ??? Subscript indices must either be real positive integers or logicals. for i=1:5 Y(i) end Each time through the loop we use a different value of i as an index into Y. don’t forget that the index has to be an integer: .” “Real positive integers” means that complex numbers are out. >> i = 1.9 Indexing errors An index can be any kind of expression. A limitation of this example is that we had to know the number of elements in Y. but other than that. and it has to be less than or equal to the length of the vector.

The MATLAB syntax is similar to the math notation. and Fi = Fi−1 + Fi−2 for i ≥ 3. If you had any trouble with Exercise 3. For example. At the end. and each time we assign a value to the ith element. It would also work to “shift” the index over by two. which makes it easier to check correctness. the loop runs from 3 to n. But if wasting space makes your code easier to write and debug. so that each time through the loop it assigns the ith element. another way to evaluate the Fibonacci sequence is by storing successive values in a vector. but you have to choose one approach and be consistent. F2 = 1. In MATLAB. you will get confused. • If you really only want the nth Fibonacci number. The only drawbacks are • You have to be careful with the range of the loop.10 Vectors and sequences >> Y(1. the definition of the Fibonacci sequence is F1 = 1. If you combine elements of both. running the loop from 1 to n-2: F(1) = 1 F(2) = 1 for i=1:n-2 F(i+2) = F(i+1) + F(i) end ans = F(n) Either version is fine. that’s probably ok. that looks like F(1) = 1 F(2) = 1 for i=3:n F(i) = F(i-1) + F(i-2) end ans = F(n) Notice that I am using a capital letter for the vector F and lower-case letters for the scalars i and n. you have to appreciate the simplicity of this version. then storing the whole sequence wastes some storage space. In this version.4. not the whole sequence. .5. I prefer the version that has F(i) on the left side of the assignment. since the result of this script is supposed to be the nth Fibonacci number. Again.5) ??? Subscript indices must either be real positive integers or logicals. the script extracts the final element of F and stores it in ans. 41 4.10 Vectors and sequences Vectors and sequences go together like ice cream and apple pie.

especially if your vectors are big enough that displaying the elements on the screen is unwieldy. For example. In this example. Notice that the math notation puts Ai+1 on the left side of the equality. Y) By default. . If you call plot with two vectors as arguments. y) points. For example. MATLAB draws a blue line.11 Plotting vectors Plotting and vectors go together like the moon and June. you could just as well plot X as a function of Y. it treats the first vector as a sequence of x values and the second as corresponding y value and plots a sequence of (x. This kind of operation is called reduce. etc. whatever that means.42 Vectors Exercise 4. that is. To plot the Fibonacci numbers we computed in the previous section: plot(F) This display is often useful for debugging. When you translate to MATLAB. or multiply them together. MATLAB plots the indices on the x-axis and the elements on the y-axis. but you can override that setting with the same kind of string we saw in Section 3. If you call plot with a single vector as an argument. the hyphen means the points should be connected with a line.5. X = 1:5 Y = 6:10 plot(X. this loop adds up the elements of a vector named X (which we assume has been defined). MATLAB always treats the first vector as the “independent” variable. I stuck with the convention of naming the first argument X (since it is plotted on the x-axis) and the second Y. because it reduces a vector with multiple elements down to a single scalar. MATLAB plots the second one as a function of the first. There is nothing special about these names. you may want to shift the index. the string ’ro-’ tells MATLAB to plot a red circle at each data point. and the second as the “dependent” variable (if those terms are familiar to you). or compute the sum of their squares. 4.1 Write a loop that computes the first n elements of the geometric sequence Ai+1 = Ai /2 with A1 = 1. 4.12 Reduce A frequent use of loops is to run through the elements of an array and add them up.

2 Write a similar loop that multiplies all the elements of a vector together. Each time through the loop. You might want to call the accumulator product. and create a new vector with the results. 2. For example. if a vector contains the computed altitude of a falling object. we add in the ith element of X. the following loop computes a vector Y that contains the squares of the elements of X (assuming. Uses your loop to store the sines in Y.14 Search Yet another use of loops is to search the elements of a vector and return the index of the value you are looking for (or the first value that has a particular property). 4.13 Apply total = 0 for i=1:length(X) total = total + X(i) end ans = total 43 The use of total as an accumulator is similar to what we saw in Section 3. so at the end of the loop total contains the sum of the elements.4. Plots the elements of Y as a function of the elements of X. Uses linspace (see the documentation) to assign to X a vector with 100 elements running from 0 to 2π. because you apply the operation to each element in the vector. 3.13 Apply Another common use of a loop is to run through the elements of a vector. To test your loop. so this loop will work regardless of the length of X. 4.7. we use the length function to find the upper bound of the range. that X is already defined). This kind of operation is called apply. you . Exercise 4.3 Write a loop that computes a vector Y that contains the sines of the elements of X. perform some operation on the elements. Again. again. for i=1:length(X) Y(i) = X(i)^2 end Exercise 4. write a script that 1. and you might want to think about the initial value you give it before the loop. For example.

this loop provides the index of the last one. if the target value appears more than one. we’ll use an extended version of the colon operator: X = 10:-1:-10 The values in this range run from 10 to -10. Y) You can see in the plot that the value of sin x goes through 0. The step size is the interval between elements of the range. there isn’t one. But if you want the index of the first one (or you know that there is only one). That might be what you want. but it also demonstrates a dangerous use of the if statement. you will come up empty.9 in this range. you might not find it. so the script ends). you can save some unnecessary looping by using the break statement.2) for i=1:length(X) Y(i) = sin(X(i)) end plot(X. It ends the loop and proceeds immediately to the next statement after the loop (in this case.9 ans = i . for i=1:length(Y) if Y(i) == 0. For example. Remember that floating-point values are often only approximately right. This example demonstrates the basic idea of a search. for i=1:length(X) if X(i) == 0 ans = i break end end break does pretty much what it sounds like. but if you search for the index where Y(i) == 0. try this: X = linspace(1. To create some fake data. with a step size of -1.9. That means that if you look for a perfect match.44 Vectors might want to know the index where the object touches down (assuming that the ground is at altitude 0). The following loop finds the index of the element 0 in X: for i=1:length(X) if X(i) == 0 ans = i end end One funny thing about this loop is that it keeps going after it finds what it is looking for.

I started with simple loops because I wanted to demonstrate the basic concepts and give you a chance to practice. so for now you are better off on your own.^ 2 Also. 2*pi) Y = sin(X) plot(X. you can always write out the loop. Exercise 4. At some point you will probably have to write a loop for which there is no MATLAB shortcut. but understanding it requires a couple of concepts we haven’t got to. feel free to use them! Otherwise. but you have to work your way up from somewhere. For example.13 Y = X . we will get to them later. Even though the plot shows a continuous line. so it is a good way to indicate the special case). don’t forget that X and Y are sequences of discrete (and usually approximate) values.15 Spoiling the fun Experienced MATLAB programmers would never write the kind of loops in this chapter. it should set ans to -1 (which is not a legal index.5 Write an expression that computes the sum of the squares of the elements of a vector. If you understand loops and you are are comfortable with the shortcuts. As a rule. so the body of the if statement is never executed.15 Spoiling the fun break end end 45 The condition is never true. Y) Finally. most built-in MATLAB functions work with vectors: X = linspace(0.4. . because MATLAB provides simpler and faster ways to perform many reduce. the find function can perform search operations. Many apply operations can be done with elementwise operators. the sum function computes the sum of the elements in a vector and prod computes the product. The following statement is more concise than the loop in Section 4. filter and search operations. If there are no negative numbers. 4. There are a number of ways to get around this limitation.4 Write a loop that finds the index of the first negative number in a vector and stores it in ans. you should (almost) never use the == operator to compare floating-point values. Exercise 4.

converges to a constant value as n increases. flag: A variable that contains a logical value. apply: A way of processing a vector by performing some operation on each of the elements. and then computes a new vector that contains the ratios of consecutive Fibonacci numbers. elementwise: An operation that acts on the individual elements of a vector or matrix (unlike some linear algebra operations). index: An integer value used to indicate one of the values in a vector or matrix (also called subscript in some MATLAB documentation).17 Exercises Exercise 4. scalar: A single value. Write a script that computes a vector with the first n elements of a Fibonacci sequence (assuming that the variable n is defined). element: One of the values in a vector or matrix. often used to store the status of some condition. 4. like if and for. Fn+1 /Fn .16 Glossary compound: A statement.46 Vectors 4. Plot this vector to see if it seems to converge. search: A way of processing a vector by examining the elements in order until one is found that has the desired property. matrix: A two-dimensional collection of values (also called “array” in some MATLAB documentation). nesting: Putting one compound statement in the body of another. reduce: A way of processing the elements of a vector and generating a single value. vector: A sequence of values. MATLAB uses the values 1 and 0. What value does it converge on? . for example.6 The ratio of consecutive Fibonacci numbers. respectively. logical value: A value that represents either “true” or “false”. the sum of the elements. producing a vector that contains the results. that contains other statements in an indented body. relational operator: An operator that compares two values and generates a logical value as a result.

It was popularized in a seminal 1976 paper by the biologist Robert May. there are two processes at work: (1) A reproductive process increases the biomass of the species in proportion to the current population.2) (4.4. with values σ = 10. b = 8/3 and r = 28. It has been used to model the biomass of a species in the presence of limiting factors such as food supply and disease. What effect does it have on the result? • Run the program with different values for σ. In this case.17 Exercises 47 Exercise 4. • Run the program again with different starting conditions.5. • Read the documentation for plot3 and comet3 and plot the results in 3 dimensions. • Once the code is working. 1000 and 10000. b and r and see if you can get a sense of how each variable affects the system. . Mathematically this can be written as Xi+1 = rXi (1 − Xi ) where Xi is a number between zero and one that represents the biomass at year i. Use the initial values X1 = 1. use semi-colons to suppress the output and then run the program with sequence length 100. chaotic behaviour can arise from simple non-linear dynamical equations [some of this description is adapted from the Wikipedia page on the logistic map].9 and X1=0. where r is the parameter of the logistic map and X1 is the initial population. • Write a script named logmap that computes the first 50 elements of X with r=3.01. and with time step dt = 0.8 The logistic map is often cited as an example of how complex. Y and Z and stores them in vectors named X. Exercise 4. Y and Z.7 A certain famous system of differential equations can be approximated by a system of difference equations that looks like this: xi+1 yi+1 zi+1 = xi + σ (yi − xi ) dt (4.1) (4. and r is a positive number that represents a combined rate for reproduction and starvation.3) = yi + [xi (r − zi ) − yi ] dt = zi + (xi yi − bzi ) dt • Write a script that computes the first 10 elements of the sequences X. (2) A starvation process causes the biomass to decrease at a rate proportional to the carrying capacity of the environment less the current population. Y1 = 2 and Z1 = 3.

• One way to characterize the effect of r is to make a plot with r on the x-axis and biomass on the y axis. and to show.0.4 to 4. .48 Vectors • Plot the results for a range of values of r from 2. See if you can figure out how to generate this plot. for each value of r. the values of biomass that occur in steady state. How does the behavior of the system change as you vary r.

you might be surprised to find. you might find that they work separately and then break when you try to combine them. total = total + a. and they get longer and more complex.5^(i-1). Avoiding this problem is one of the motivations for functions. A1 = 1. that their values had changed. so if one script changes the value of a variable. i and a. For example. This kind of interaction is called a name collision.1 Name Collisions Remember that all of your scripts run in the same workspace. but it also has the side-effect of assigning values to A1.Chapter 5 Functions 5. end ans = total If you were using any of those variable names before calling this script. name collisions become more of a problem. the following (increasingly familiar) script computes the sum of the first n terms in a geometric sequence. If you have two scripts that use the same variable names. As the number of scripts you write increases. total = 0. after running the script. With a small number of simple scripts. total. for i=1:10 a = A1 * 0. but eventually the interactions between scripts become unmanageable. . that’s not a problem. all your other scripts see the change.

so any variables defined inside a function only exist while the function is running. the argument provided by the user will be assigned to x. because that’s how MATLAB tells the difference between a script and a function file.” You can call the output variable whatever you want.m and put the following definition into it. If you call the function as a statement. you call it the same way you call built-in MATLAB functions. except • Each function has its own workspace. to create a function named myfunc. The first line is called the signature of the function.38177329067604 But it is more common (and better style) to assign the result to a variable: . Once you have defined a new function. and put a function definition in it. and don’t interfere with variables in other workspaces. which is short for “result.54030230586814 res = 1. MATLAB puts the result into ans: >> myfunc(1) s = 0. • Function inputs and outputs are defined carefully to avoid unexpected interactions. For example.84147098480790 c = 0. A function definition is a compound statement. function res = myfunc(x) s = sin(x) c = cos(x) res = abs(s) + abs(c) end The first word of the file has to be the word function. it defines the inputs and outputs of the function. In this case the input variable is named x. even if they have the same name. you create an M-file with the name you want. The output variable is named res.2 Functions A function is like a script. Usually the last thing a function does is assign a value to the output variable.38177329067604 ans = 1. I like to call it res. To define a new function. create an M-file named myfunc.50 Functions 5. but as a convention. When this function is called.

they will still be there when the function completes. If you have variables named s or c in your workspace before you call myfunc. >> who Your variables are: y >> s ??? Undefined function or variable ’s’. If you try to access (read or write) the variables defined inside a function. c s = 1 c = 1 So inside a function you can use whatever variable names you want without worrying about collisions.5. but once it is working. 5. . which is created when the function starts and destroyed when the function ends.54030230586814 res = 1.38177329067604 While you are debugging a new function. Most built-in functions are silent.84147098480790 c = 0. >> clear >> y = myfunc(1). >> s. but they don’t display anything (except sometimes warning messages). >> s = 1.3 Documentation >> y = myfunc(1) s = 0. The only value from the function that you can access is the result.38177329067604 51 y = 1. Each function has its own workspace. you will want to add semi-colons to make it a silent function. you should include a comment that explains what the function does. you will find that they don’t exist. they compute a result. you might want to display intermediate results like this. >> c = 1.3 Documentation At the beginning of every function file. >> y = myfunc(1). which in this case is assigned to y.

end Functions When you ask for help. In the spirit of making errors on purpose.52 % res = myfunc (x) % Compute the Manhattan distance from the origin to the % point on the unit circle with angle (x) in radians. concise. the input variable(s) and the output variable(s). function res = myfunc (x) s = sin(x). you should make sure that they are always the same. The first is that the “real” name of your function is determined by the file name. • Any preconditions and postconditions. An abstract description is one that leaves out the details of how the function works. it is a good idea to include • The signature of the function. There are lots of conventions about what should be included in these comments. res = abs(s) + abs(c). 5. but if you make a mistake. for example. MATLAB prints the comment you provide. change the name of the function in myfunc to something else. If this is what you put in myfunc. You can put additional comments inside the function that explain the details. c = cos(x). or if you change the name of a function. in this case it is important to note that x is considered to be an angle in radians. it is easy to get confused. >> help myfunc res = myfunc (x) Compute the Manhattan distance from the origin to the point on the unit circle with angle (x) in radians. • An explanation of what the input variables mean. Among other things. and then run it again. As a matter of style. and includes only information that someone using the function needs to know. • A clear. abstract description of what the function does.4 Function names There are two “gotchas” that come up when you start naming functions.m: . not by the name you put in the function signature. which includes the name of the function.

m. end And then try this: >> sum(1:3) ans = 6 >> sum ans = 7 In the first case MATLAB used the built-in function. a and b: function res = hypotenuse(a. MATLAB might call your new function. Before you create a new function. end If you remember the Pythagorean Theorem. check to see if there is already a MATLAB function with the same name. As an example. end Then here’s what you’ll get: >> y = myfunc(1). and often do. in the second case it ran your function! This kind of interaction can be very confusing. you probably figured out that this function computes the length of the hypotenuse of a right triangle if the lengths .5.m: function res = sum(x) res = 7. b) res = sqrt(a^2 + b^2). and (in some cases) on the arguments. res = abs(s) + abs(c). choose another name! 5. If there is. For example. and then call sum. put the following code in a file named sum. 53 The other gotcha is that your function names can collide with built-in MATLAB functions. >> y = something_else(1).5 Multiple input variables function res = something_else (x) s = sin(x). For example.5 Multiple input variables Functions can. take more than one input variable. if you create an M-file named sum. ??? Undefined command/function ’something_else’. not the built-in version! Which one actually gets called depends on the order of the directories in the search path. the following function takes two input variables. c = cos(x).

>> isprime(17) ans = 1 >> isprime(21) ans = 0 The functions isscalar and isvector check whether a value is a scalar or vector. Which is a better message. isprime checks to see whether a number is prime. so in this case 3 is assigned to a and 4 is assigned to b. >> c = hypotenuse(3. 5. Error in ==> hypotenuse at 2 res = sqrt(a^2 + b^2).) If we call it from the Command Window with arguments 3 and 4. we can confirm that the length of the third side is 5.6 Logical functions In Section 4. MATLAB checks that you provide the right number of arguments. This error message is confusing. 5) ??? Error using ==> hypotenuse Too many input arguments. because it suggests that the problem is in hypotenuse rather than in the function call. MATLAB also provides logical functions that check for certain conditions and return logical values: 1 for “true” and 0 for “false”. if both are false. you get >> c = hypotenuse(3. 4. 4) c = 5 The arguments you provide are assigned to the input variables in order. If you provide too many arguments. (There is a MATLAB function called hypot that does the same thing. you can assume it is a matrix (at least for now).4 we used logical operators to compare values. For example. Keep that in mind when you are debugging.54 Functions of the adjacent sides are a and b. . you get >> c = hypotenuse(3) ??? Input argument "b" is undefined. if you provide too few.

• Write a loop that enumerates values of a from 1 to 3.5. that are the lengths of the sides of a right triangle. call hypotenuse to compute c and display it. Here are the steps we will follow to develop the program incrementally. • Write a script named find triples and start with a simple statement like x=5. and displays them. In other words. in some cases the approximation is an integer but the actual value is not. like 3. we would like to find integral values a. but remember that floatingpoint values are only approximately right. we have to write our own logical function. • Inside the loop.7 An incremental development example Let’s say that we want to write a program to search for “Pythagorean triples:” sets of integral values. b and c such that a2 + b2 = c2 . which we’ll call isintegral: function res = isintegral(x) if round(x) == x res = 1. • Write a nested loop that enumerates values of b from 1 to 4. But that would be wrong. >> c = hypotenuse(3. • Use isintegral to check whether c is an integral value. 4 and 5. . end end This function is good enough for most applications. so very wrong. else res = 0. 4) c = 5 >> isinteger(c) ans = 0 To do that. isinteger checks whether a value belongs to one of the integer types (a topic we have not discussed). and displays them. 5. you might be tempted to use isinteger.7 An incremental development example 55 To check whether a value you have computed is an integer. it doesn’t check whether a floating-point value happens to be integral.

Here’s the second draft: for a=1:3 a end At each step.56 Functions • Use an if statement to print only the triples a. but if you start simple and add a little bit at a time. once for each value of a. So the first draft of this program is x=5. 5. • Generalize the function to take input variables that specify the range to search. you will avoid a lot of debugging.8 Nested loops The third draft contains a nested loop: for a=1:3 a for b=1:4 b end end The inner loop gets executed 3 times. b and c that pass the test. which might seem silly. • Transform the script into a function. the program is testable: it produces output (or another visible effect) that you can check. so here’s what the output loops like (I adjusted the spacing to make the structure clear): >> find_triples a = 1 b b b b b b b b b b b b = = = = = = = = = = = = 1 2 3 4 1 2 3 4 1 2 3 4 a = 2 a = 3 .

0000 3.0000 3 1.0000 1. b).0000 3. b.0000 2. b. 5. c] end end If you are following along. We can eliminate the extra work by adjusting the range of the second loop: for a=1:3 for b=a:4 c = hypotenuse(a.8284 3.2426 5 Sharp-eyed readers will notice that we are wasting some effort here. c] end end 57 To display the values of a. for a=1:3 .0000 2.9 Conditions and flags The next step is to check for integral values of c. b and c. [a. there is no point in checking a = 2 and b = 1. shows the three values on one line: >> find_triples ans ans ans ans ans ans ans ans ans ans ans ans = = = = = = = = = = = = 1. when it is displayed.6056 4.1623 3.0000 4 1.1231 2.0000 3.0000 1.0000 1.0000 2.6056 4. for a=1:3 for b=1:4 c = hypotenuse(a.9 Conditions and flags The next step is to compute c for each pair of values a and b.0000 2. This loop calls isintegral and prints the resulting logical value.4142 2.0000 4.0000 2.0000 2.4721 3. b). I am using a feature we haven’t seen before. run this version to make sure it has the expected effect. [a.0000 3.0000 3.0000 1.0000 4.2361 3.0000 3.2361 2.1623 4. After checking a = 1 and b = 2.5. The bracket operator creates a new matrix which.0000 2.0000 1.

58 for b=a:4 c = hypotenuse(a. but to contain at least one Pythagorean triple. [c.4142 0 ans = 2.2361 0 ans = 3. b.2426 0 ans = 5 1 I chose the ranges for a and b to be small (so the amount of output is manageable). if flag [a.8284 0 ans = 3.6056 0 ans = 4. By . c and flag. flag = isintegral(c). A constant challenge of debugging is to generate enough output to demonstrate that the code is working (or not) without being overwhelmed. c] end end end Now the output is elegant and simple: >> find_triples ans = 3 4 5 5.1231 0 ans = 2. b). >> find_triples ans = 1. b). The next step is to use flag to display only the successful triples: for a=1:3 for b=a:4 c = hypotenuse(a. this program has the side-effect of assigning values to a. b. flag] end Functions end By not displaying a and b I made it easy to scan the output to make sure that the values of c and flag look right.1623 0 ans = 4.4721 0 ans = 4.10 Encapsulation and generalization As a script. which would make it hard to use if any of those names were in use. flag = isintegral(c).

The MATLAB editor provides a shortcut for doing that. c] end end end end The empty parentheses in the signature are not strictly necessary. it never gets assigned a value. we can avoid name collisions. The natural generalization is to replace the constant values 3 and 4 with a variable so we can search an arbitrarily large range of values. flag = isintegral(c). if flag [a. this process is called encapsulation because it isolates this program from the workspace. I like to use parentheses to remind me that it is a function. But I put it there as a matter of habit. b. the Increase Indent command under the Text menu. if flag [a. function res = find_triples (n) for a=1:n for b=a:n c = hypotenuse(a. b.5. Similarly. flag = isintegral(c). not a script: >> find_triples() The output variable isn’t strictly necessary. In order to put the code we have written inside a function. and also so my function signatures all have the same structure. b). b). c] end end end end Here are the results for the range from 1 to 15: . but they make it apparent that there are no input variables. when I call the new function. we have to indent the whole thing. either. The next step is to generalize this function by adding input variables. Just don’t forget to unselect the text before you start typing! The first draft of the function takes no input variables: function res = find_triples () for a=1:3 for b=a:4 c = hypotenuse(a.10 Encapsulation and generalization 59 wrapping the code in a function.

but that doesn’t mean the program will do the right thing. suppose I decided to add a third input variable to hypotenuse: function res = hypotenuse(a. d) res = (a. you have to change all the places that call the function. 12. This is an example of a development technique that is sometimes useful: rather than search the program for all the places that use hypotenuse. 5 triangle we already knew.11 A misstep When you change the signature of a function. b. 13 and 8. . And that brings us to the Eighth Theorem of debugging: Error messages sometimes tell you what’s wrong. b). end When d is 2.^d) ^ (1/d). 17 are “new. If you do what you’re told. but they seldom tell you what to do (and when they try. 5. The triples 5.60 >> find_triples(15) Functions ans = 3 4 5 ans = 5 12 13 ans = 6 8 10 ans = 8 15 17 ans = 9 12 15 Some of these are more interesting than others. So that makes it pretty easy to find the error. Error in ==> find_triples at 7 c = hypotenuse(a. it’s just an example. too. you get: >> find_triples(20) ??? Input argument "d" is undefined. you might make the error message go away. There is no practical reason to generalize the function in this way. Error in ==> hypotenuse at 2 res = (a. they’re usually wrong).^d + b. For example. 4. but you should.^d) ^ (1/d). Now when you run find triples.” but the others are just multiples of the 3. this does the same thing it did before. 15.^d + b. you can run the program and use the error messages to guide you. especially if the error messages make suggestions about what to change. But this technique is risky. MATLAB doesn’t know what the program is supposed to do.

c] end end end end continue causes the program to end the current iteration immediately (without executing the rest of the body).12 continue 61 5. but the rule is to jump to the inner-most loop (which is what we wanted). then a and b share a common factor and we can use the continue statement to skip to the next pair: function res = find_triples (n) for a=1:n for b=a:n if gcd(a. If they do. since there are two loops. then dividing both by the common factor yields a smaller.5. it might not be obvious which loop to jump to. and not the multiples. I also simplified the program slightly by eliminating flag and using isintegral as the condition of the if statement. let’s modify the function so that it only displays the “lowest” of each Pythagorean triple. b). if isintegral(c) [a. b. In this case. similar triangle that has already been checked. The simplest way to eliminate the multiples is to check whether a and b share a common factor. Here are the results with n=40: >> find_triples(40) ans ans ans ans ans ans ans = 3 = 5 = 7 = 8 = 9 = 12 = 20 4 12 24 15 40 35 21 5 13 25 17 41 37 29 . MATLAB provides a gcd function that computes the greatest common divisor of two numbers. If the result is greater than 1.12 continue As one final improvement.b) > 1 continue end c = hypotenuse(a. jump to the top of the loop. and “continue” with the next iteration.

Exercise 5. The program resumes from where it left off. then 2 2 (Fn Fn+3 . in part because you expect that most MATLAB functions work. and go on to the next statement after the function call. in order. uses fibonacci2 to compute the first n Fibonacci numbers. . The function’s workspace is destroyed. there are two ways to interpret it: • You can think about the mechanism I just described. When you are reading a program and you come to a function call. Fn+1 + Fn+2 ) is a Pythagorean triple for all n ≥ 1. Before the function starts running. MATLAB evaluates each of the arguments and assigns the resulting values. The body of the code executes. 2.62 Functions There is an interesting connection between Fibonacci numbers and Pythagorean triples. If F is a Fibonacci sequence. The value of the function call is the value of the output variable. to the input variables (which live in the new workspace). it is natural to take the leap of faith. 5. 3. MATLAB creates a new workspace for it. the only thing that remains is the value of the output variable and any side effects the function had (like displaying values or creating a figure). 4. Somewhere in the body (often the last line) a value gets assigned to the output variable.1 Write a function named fib triple that takes an input variable n. or • You can take the “leap of faith”: assume that the function works correctly. 5. 2Fn+1 Fn+2 .13 Mechanism and leap of faith Let’s review the sequence of steps that occur when you call a function: 1. and follow the execution of the program into the function and back. and then checks whether this formula produces a Pythagorean triple for each number in the sequence. and in part because you don’t generally have access to the code in the body of the function. When you use built-in functions.

14 Glossary 63 But when you start writing your own functions. and then forgetting about the details of how it works.14 Glossary side-effect: An effect. when the function is called. from one of the arguments. testing it to make sure it works. or have any other side-effects. you should get more comfortable with the idea of writing a function. you will probably find yourself following the “flow of execution. abstraction: The process of ignoring the details of how a function works in order to focus on a simpler model of what the function does. . output variable: A variable in a function that is used to return a value from the function to the caller. and just assuming (after appropriate testing) that it works. 5. encapsulation: The process of wrapping part of a program in a function in order to limit interactions (including name collisions) between the function and the rest of the program. Forgetting about details is called abstraction. input variable: A variable in a function that gets its value.” This can be useful while you are learning. abstraction means forgetting about how a function works. generalization: Making a function more versatile by replacing specific values with input variables. name collision: The scenario where two scripts that use the same variable name interfere with each other. silent function: A function that doesn’t display anything or generate a figure. which specifies the names of the function. logical function: A function that returns a logical value (1 for “true” or 0 for “false”). signature: The first line of a function definition. that is not the primary purpose of a script. in the context of functions. the input variables and the output variables. like modifying the workspace. but as you gain experience.5.

encapsulate the code in an appropriately-named function. and generalize the function by adding one or more input variables. .2 Take any of the scripts you have written so far.64 Functions 5.15 Exercises Exercise 5. Make the function silent and then call it from the Command Window and confirm that you can display the output value.

so using functions helps avoid name collisions. • Once you have a function working.2 Maps In mathematics. in this chapter we will use fzero to find solutions of nonlinear equations. Later we will use ode45 to approximate solutions to differential equations. and then assemble a complete solution.1 Why functions? The previous chapter explained some of the benefits of functions. 6. including • Each function has its own workspace. a map is a correspondence between one set called the range and another set called the domain. . For each element of the range. the map specifies the corresponding element of the domain. and then generalize it by adding input variables. This process of abstraction is an important tool for managing the complexity of large programs. For example. work on the pieces one at a time. • Functions allow you to divide a large problem into small pieces. Another reason you should consider using functions is that many of the tools provided by MATLAB require you to write functions. you can forget about the details of how it works and concentrate on what it does.Chapter 6 Zero-finding 6. • Functions lend themselves to incremental development: you can debug the body of the function first (as a script). then encapsulate it as a function.

) 6. x. The problem is that f (x) is also used to mean the value of f that corresponds to a particular value of x.4 Nonlinear equations What does it mean to “solve” an equation? That may seem like an obvious question.66 Zero-finding You can think of a sequence as a map from positive integers to elements. You can also think of a function as a map from inputs to outputs. but all we know about it is the relationship x2 = a. .2*x -3. You can think of a vector as a map from indices to elements. starting with a simple example: let’s say that we want to know the value of a variable.” In MATLAB. 6. this would be expressed like this: function res = error_func(x) res = x^2 . So I don’t like this notation. I prefer f : x → x2 − 2x − 3 which means “f is the function that maps from x to x2 − 2x − 3. you have probably seen something like f (x) = x2 − 2x − 3 which is supposed to mean that f is a function that maps from x to x2 − 2x − 3. not just integers. Now. the set of floating-point numbers is discrete. In these cases the maps are discrete because the elements of the range are countable. but in this case the range is continuous because the inputs can take any value. end I’ll explain soon why this function is called error func. back to our regularly-scheduled programming. but I want to take a minute to think about it.3 A note on notation In this chapter I need to start talking about mathematical functions. but since floating-point numbers are meant to represent real numbers. we think of them as continuous. (Strictly speaking. and I am going to use a notation you might not have seen before. If you have studied functions in a math class.

which is what we are going to do next. But what have you really done? The relationship you derived is equivalent to the relationship you started with—they contain the same information about x—so why is the second one preferable to the first? There are two reasons. what they usually mean is something like “finding an equivalent relationship that is explicit in one of the variables. √ could start with x = 4 as an “initial We guess. we can compute the value of x for any value of a. consider the equation x2 − 2x = 3.1037 >> x = sqrt(2*x+3) x = 3. you probably know how to “solve” this equation: you √ take the square root of both sides and get x = a.” because x is all alone on the left side. To demonstrate a numerical solution.4 Nonlinear equations 67 If you have taken algebra. Alternatively. You could solve this analytically. One is that the relationship is now “explicit in x. Assuming that we know how to compute square roots. This equation is not explicit. with the satisfaction of a job well done. The other reason is that the recipe is written in terms of operations we know how to perform. Then.6. you could solve it numerically by rewriting it as x = 2x + 3. assuming that we know the value of a. x = 3 √ x = and −1. that’s what I will call an analytic solution.0344 . >> x = sqrt(2*x+3) x = 3. so it is not clear that this move did any good at all. either by factoring it or by using the quadratic equation. you move on to the next problem.” In the context of this book. But suppose that we had some reason to expect there to be a solution near 4. Here’s what would happen: >> x = 4. we can treat the right side as a recipe for computing x.” and then use the equation x = 2x + 3 iteratively to compute successive approximations of the solution.3166 >> x = sqrt(2*x+3) x = 3. and you would discover that there are two solutions. When people talk about solving an equation. since x appears on both sides. to distinguish it from a numerical solution.

We’ll see one of the more practical alternatives in a minute. x is closer to the correct answer.0038 Zero-finding After each iteration. the error function is f : x → x2 − 2x − 3 Any value of x that makes f (x) = 0 is also a solution of the original equation. or sometimes roots. Techniques that generate numerical solutions are called numerical methods. evaluated at various values of x. In this example. then we can be certain that there is at least one zero between x1 .68 >> x = sqrt(2*x+3) x = 3. To address this limitation. A value that makes it true is a solution. and it is not used very often in practice. if we can find two values x1 and x2 such that f (x1 ) > 0 and f (x2 ) < 0. any other value is a non-solution. 6.0114 >> x = sqrt(2*x+3) x = 3. it is useful to rewrite non-linear equations as zerofinding problems: • The first step is to define an “error function” that computes how far a given value of x is from being a solution. For example. Zero-finding lends itself to numerical solution because we can use the values of f . But for any given non-solution. there is no sense of whether it is close or far from a solution. The nice thing about the method I just demonstrated is that it is simple. • The next step is to find values of x that make f (x) = 0.5 Zero-finding A nonlinear equation like x2 − 2x = 3 is a statement of equality that is true for some values of x and false for others. to make reasonable inferences about where to look for zeros. which is good enough for most purposes. and after 5 iterations.1%. These values are called zeros of the function. but it doesn’t always work as well as it did in this example. or where we might look to find one. the relative error is about 0.

Finally.” then you are ready to go on to the next section. find the parabola that passes through all three points. you probably didn’t say that.6 fzero fzero is a built-in MATLAB function that combines the best features of several efficient and robust numerical methods. f(x2) If this was all you knew about f . and confirm that there are zeros at 3 and -1. In this case we would say that x1 and x2 bracket a zero.6 fzero 69 and x2 (provided that we know that f is continuous). We’ve already seen an example of an error function: function res = error_func(x) res = x^2 . end You can call error func from the Command Window.6. 6. . you have to define a MATLAB function that computes the error function you derived from the original nonlinear equation.2*x -3. where would you go looking for a zero? If you said “halfway between x1 and x2 .” then congratulations! You just invented the secant method! And if you said. well. “I would evaluate f at a third point.” then congratulations! You just invented a numerical method called bisection! If you said. “I would connect the dots with a straight line and compute the zero of the line.. In order to use fzero. if you said.. “I would use a built-in MATLAB function that combines the best features of several efficient and robust numerical methods. and compute the zeros of the parabola.” then. and you have to provide an initial guess at the location of a zero. f(x1) x2. Here’s what this scenario might look like on a graph: x1.

we get a different root (at least sometimes). and where.99997750209270 x = 3. The first argument is a function handle that names the M-file that evaluates the error function.75000000000000 x = 3.0000 Success! We found one of the zeros. -2) ans = -1 Alternatively. The @ symbol allows us to name the function without calling it. in fact. you can provide both: >> fzero(@error_func.4]) x = 2 x = 4 x = 2.00000000000000 x = 3 x = 3 ans = 3 . 4) ans = 3. we only know that one of them is near 4. Then we could call fzero like this: >> fzero(@error_func. You might be curious to know how many times fzero calls your function.4]) ans = 3 The second argument here is actually a vector that contains two elements.70 >> error_func(3) ans = 0 >> error_func(-1) ans = 0 Zero-finding But let’s pretend that we don’t know exactly where the roots are. The bracket operator is a convenient way (one of several) to create a new vector. [2. The second argument is the initial guess. if you know two values that bracket the root.00000000025200 x = 3. In turn. If you modify error func so that it displays the value of x every time it is called and then run fzero again.99755211623500 x = 2. you are just telling fzero where it is. fzero calls your error function—more than once. you get: >> fzero(@error_func. >> fzero(@error_func. If we provide a different initial guess. [2.03708133971292 x = 2. The interesting thing here is that you are not actually calling error func directly.

functions should always assign a value to the output variable.7 What could go wrong? 71 Not surprisingly. it starts by computing f (2) and f (4). The problem is that MATLAB treats the first argument as a function call. but MATLAB doesn’t enforce this rule. In general. 6. Error in ==> error_func at 2 x Which is a very confusing error message. but when the function ends. if you write: function res = error_func(x) y = x^2 .2*x -3 end and then call it from the Command Window: >> error_func(4) y = 5 It looks like it worked. [2. so it calls error func with no arguments. . y disappears along with the function’s workspace. and it displays the result. the message indicates that the input argument is “undefined. If you try to use it with fzero. so it is easy to forget. Another common problem is writing an error function that never assigns a value to the output variable. the interval that brackets the root gets smaller. In that case.4]) y = -3 ??? Error using ==> fzero FZERO cannot continue because user supplied function_handle ==> error_func failed with the error below.” although it might be clearer to say that you haven’t provided a value for it. you get something like: >> fzero(error_func.6.7 What could go wrong? The most common problem people have with fzero is leaving out the @. but don’t be fooled. you can tell fzero to give you a quicker.4]) ??? Input argument "x" is undefined. For example. [2. fzero stops when the interval is so small that the estimated zero is correct to 16 digits. This function assigns a value to y. you get >> fzero(@error_func. Since error func requires one argument. If you don’t need that much precision. dirtier answer (see the documentation for details). After each iteration.

You would have seen the same error message when you called error func from the interpreter.1]) ??? Error using ==> fzero The function values at the interval endpoints must differ in sign.72 Zero-finding Output argument "res" (and maybe others) not assigned during call to "/home/downey/error_func. there are exceptions. it is easy for mistakes to go undetected. so you may never have a problem. There is one other thing that can go wrong when you use fzero. If you read it carefully. • When you call a function.). fzero is generally pretty robust. When you write your own functions and use them yourself. But when you use your functions with MATLAB functions like fzero. but this one is less likely to be your fault. . you have to get it right! Yet another thing that can go wrong: if you provide an interval for the initial guess and it doesn’t actually contain a root. ok. 1 Well. this is a pretty good error message (with the quibble that “output argument” is not a good synonym for “output variable”). [0.” because they do something (like display values or generate a figure) but either don’t have an output variable or don’t make an assignment to it. It is possible that fzero won’t be able to find a root. Functions that don’t return a value are sometimes called “commands. you get >> fzero(@error_func. Even if you provide an interval that brackets a root. Error in ==> error_func at 2 y = x^2 . if only you had assigned the result to a variable: >> x = error_func(4) y = 5 ??? Output argument "res" (and maybe others) not assigned during call to "/home/downey/error_func. including find triples. things can still go wrong if the error function is discontinuous. etc.2*x -3 You can avoid all of this if you remember these two rules: • Functions should always assign values to their output variables1 .m (error_func)". but you should remember that there is no guarantee that fzero will work. you should always do something with the result (either assign it to a variable or use it as part of an expression.m (error_func)". especially if you provide a single value as an initial guess.

if you have a variable with the same name as a function. >> x = 5. and if there isn’t one.8 Finding an initial guess The better your initial guess (or interval) is. of course).8 Finding an initial guess 73 6. As a result. If you have a function. and then try to use the sin function. you might get an error: >> sin = 3. MATLAB starts by looking for a variable with that name. So you probably want to make your function silent before you plot it. like error func that takes a scalar input variable and returns a scalar output variable. Another approach is to plot the function and see if you can approximate the zeros visually. and a scalar is really a 1x1 matrix. .9 More name collisions Functions and variables occupy the same “name-space. or if the value of x was smaller. if there were more distance between the assignment and the “function call. Since the value of sin is a scalar. 6. >> sin(x) ??? Index exceeds matrix dimensions. In this example.6.” which means that whenever a name appears in an expression. If the value of sin was a vector.5]) The first argument is a function handle.” this message would be pretty confusing. it looks for a function. For example. you will usually have some intuition about the answer. the problem is clear. By default ezplot calls your function 100 times (each time with a different value of x. Of course. if you assign a value to sin. the variable shadows the function. and the fewer iterations it will need. you can plot it with ezplot: >> ezplot(@error_func. MATLAB tries to access the 5th element of the matrix and finds that there isn’t one. the second is the interval you want to plot the function in. you would really be in trouble. the more likely it is that fzero will work. [-2. This intuition is often enough to provide a good initial guess for zero-finding. But the only thing worse than getting an error message is not getting an error message. When you are solving problems in the real world.

A possible cause of this error is that you forgot to initialize the variable. At least. running: Experiment by making changes and running different versions. but sometimes you have to spend some time to build scaffolding. so that helps. and especially if you are working on a hard bug. ruminating: Take some time to think! What kind of error is it: syntax. the problem becomes obvious. or from the output of the program? What kind of error could cause the . If this happens inside a function. >> sin(1) ans = 3 Just to review. That’s why in Section 6. you get >> f = f+1 ??? Error: "f" previously appeared to be used as a function or command. runtime. but you can improve your chances by choosing variable names that don’t shadow existing functions. and by choosing function names that you are unlikely to use as variables. or you have initialized it implicitly using load or eval. read it back to yourself. that’s what you get if you are lucky. logical? What information can you get from the error messages.a There is no universal way to avoid these kind of collisions. I often give functions names that end in func. MATLAB tries to call f as a function.74 >> sin = 3. too. and you get this ??? Input argument "x" is undefined. the sine of 1 is not 3! Zero-finding The converse error can also happen if you try to access an undefined variable that also happens to be the name of a function. Error in ==> f at 3 y = x^2 . For example. and then try to increment a variable named f (and if you forget to initialize f). conflicting with its use here as the name of a variable.3 I called the error function error func rather than f. there are four things to try: reading: Examine your code. and check that it means what you meant to say. if you have a function named f. 6.10 Debugging in four acts When you are debugging a program. Often if you display the right thing at the right place in the program.

copy your program into another file before you start stripping it down. If you get stuck on one of these activities. reading your code might help if the problem is a typographical error. because they can’t stand to delete a line of code (even if it’s wrong). you will sometimes find the answer before you finish asking the question. But if you run experiments without thinking or reading your code. But even the best debugging techniques will fail if there are too many errors. Then you can starting rebuilding. . and then rebuild. Beginning programmers are often reluctant to retreat. To summarize. Then you can paste the pieces back in a little bit at a time. If it makes you feel better. random walk programming can take a long time. Debugging is like an experimental science. try to think of a test that would eliminate one of them. simple tests. until you get back to a program that works. So does talking. For example. you might fall into a pattern I call “random walk programming. and sometimes retreating. Beginning programmers sometimes get stuck on one of these activities and forget the others. Each activity comes with its own failure mode. because the error is in your head. running.10 Debugging in four acts 75 problem you’re seeing? What did you change last. the best thing to do is back off. here’s the Ninth Theorem of debugging: Finding a hard bug requires reading. ruminating.” which is the process of making random changes until the program does the right thing. If there are two or more possibilities. undoing recent changes. and that you understand. Taking a break sometimes helps with the thinking. The way out is to take more time to think.6. Sometimes the best option is to retreat. before the problem appeared? retreating: At some point. Needless to say. If you explain the problem to someone else (or even yourself). or if the code you are trying to fix is too big and complicated. especially if you run small. Running experiments can help. try the others. but not if the problem is a conceptual misunderstanding. You should have at least one hypothesis about what the problem is. you can read it 100 times and never see the error. If you don’t understand what your program does. simplifying the program until you get to something that works.

Use fzero to find as many different roots as you can.1 1. Estimate the location of any zeros in this range. You can think of floating-point numbers as a continuous set.1) 2. shadow: A kind of name collision in which a new definition causes an existing definition to become invisible. Does fzero always find the root that is closest to the initial guess? . It should take an input variable. x. zero (of a function): A value in the range of a function that maps to 0. discrete set: A set. like the integers. In MATLAB. often approximately. range: The set of values a map maps from. map: A correspondence between the elements of one set (the range) and the elements of another (the domain). and return 32x6 − 48x4 + 18x2 − 1 (6. whose elements are not countable.12 Exercises Exercise 6. Write a function called cheby6 that evaluates the 6th Chebyshev polynomial. domain: The set of values a map maps to. 3.11 Glossary analytic solution: A way of solving an equation by performing algebraic operations and deriving an explicit way to compute a value that is only known implicitly. variable names can shadow built-in functions (with hilarious results). Use ezplot to display a graph of this function in the interval from 0 to 1. continuous set: A set. numerical method: A method (or algorithm) for generating a numerical solution. You can think of sequences. 6. like the real numbers. vectors and functions as different kinds of maps.76 Zero-finding 6. numerical solution: A way of solving an equation by finding a numerical value that satisfies the equation. a function handle is a way of referring to a function by name (and passing it as an argument) without calling it. function handle: In MATLAB. whose elements are countable.

In particular. ρ. Addison-Wesley. • Check to make sure the result makes sense. the volume of the sphere below the water line is volume = π (3rd2 − d3 ) 3 as long as d < 2r An object floats at the level where the weight of the displaced water equals the total weight of the object. d and r. • Use fzero to find a root near d0 . check that d < 2r. • Make a guess about the value of d0 to use as a starting place. • Write a MATLAB function that evaluates this function. If a sphere with radius r is submerged in water to a depth d.3g/cm3 (0. because otherwise the volume equation doesn’t work! • Try different values of ρ and r and see if you get the effect you expect. Our goal is to find values of d that are roots of this equation. at what depth does a duck float? Here are some suggestions about how to proceed: • Write an equation relating ρ. Fourth Edition. Test it.6.3 times the density of water). then make it a quiet function.12 Exercises 77 Exercise 6. • Rearrange the equation so the right-hand side is zero. What happens as ρ increases? Goes to infinity? Goes to zero? What happens as r increases? Goes to infinity? Goes to zero? 2 This example is adapted from Gerald and Wheatley. . Assuming that a duck is a sphere with radius 10 cm. is 0. 4 The volume of a sphere2 with radius r is 3 πr3 . Applied Numerical Analysis. 1989.2 The density of a duck.

78 Zero-finding .

Chapter 7 Functions of vectors 7. keeping all the functions in one file is convenient. % density in g / cm^3 r = 10. To test error func I would call it from duck and then call duck from the Command Window. % radius in cm res = h. I often use the top-level function to develop and test my helper functions.m and start with a top-level function named duck that takes no input variables and returns no output value.2. For example. but it makes debugging difficult because you can’t call helper functions from the Command Window. but only the first one. end . I would create a file named duck. Then I would write a function named error func to evaluate the error function for fzero. To help with this problem.1 Functions and files So far we have only put one function in each file. It is also possible to put more than one function in a file. the top-level function can be called from the Command Window. to write a program for Exercise 6. Large programs almost always require more than one function. Here’s what my first draft might look like: function res = duck() error = error_func(10) end function res = error_func(h) rho = 0. The other helper functions can be called from anywhere inside the file.3. but not from any other file.

like a duck. the “duck problem. For this problem I might only need two functions. Other . Once I finished and tested error func. If you didn’t work on this exercise. Some of these decisions are justifiable. we took into account the density of the duck and the buoyancy of water. In this context.2 Physical modeling Most of the examples so far have been about mathematics.80 Functions of vectors The line res = h isn’t finished yet. but we ignored the buoyancy of the duck due to displacement of air and the dynamic effect of paddling feet. but if there were more. so the effect of buoyancy in air is probably small. Physical modeling is a process for making predictions about physical systems and explaining their behavior. The following figure shows the steps of this process: Model analysis simulation Prediction/ Explanation validation Physical System abstraction System Behavior A model is a simplified description of a physical system. in the duck problem. 7. The process of building a model is called abstraction. so it might be a good idea to explain what that is. We also simplified the geometry of the duck by assuming that the underwater parts of a duck are similar to a segment of a sphere. Exercise 6. in the same way that abstract art does not directly depict objects in the real world. The density of the duck is much higher than the density of air. For example. and then combine them into a working program. A realistic model is one that includes more details and corresponds more directly to the real world. you should at least go back and read it. I could write and test them one at a time. “abstract” is the opposite of “realistic. And we used coarse estimates of the size and weight of the duck.” an abstract model bears little direct resemblance to the physical system it models.2.” is the first example we have seen of a physical system. but this is enough code to test. I would modify duck to use fzero. A physical system is something in the real world that we are interested in. Abstraction involves making justified decisions about which factors to include in the model and which factors can be simplified or ignored. This book is supposed to be about physical modeling.

3 Vectors as input variables Since many of the built-in functions take vectors as arguments.3 Vectors as input variables 81 decisions. Models are useful because they can be analyzed mathematically and simulated computationally. Models that are too realistic might be difficult to simulate and impossible to analyze.7. like the spherical geometry. This is another example of a function that doesn’t actually have a return value. We have only seen one physical model so far. so parts of this discussion may not be clear yet. but very helpful. Checking whether a model is good enough is called validation. it just displays the value of the input variable: >> display_vector(1:3) X = 1 2 3 . If we need a more precise answer (for some reason) we might need a more realistic model. One is to compare multiple models of the same system. A model is successful if it is good enough for its purpose. Here’s a simple (silly) example: function res = display_vector(X) X end There’s nothing special about this function at all. that is an indication that (at least) one of them is wrong. the sphere model is good enough. If that is infeasible. are harder to justify. there are weaker forms of validation. but first we should learn more about vectors. The only difference from the scalar functions we’ve seen is that I used a capital letter to remind me that X is a vector. A more realistic model is not necessarily better. the sphere model makes it possible to generate an approximate answer without making detailed measurements of real ducks. If they are inconsistent. and the size of the discrepancy is a hint about the reliability of their predictions. We will come back to these topics later. The strongest form of validation is to make a measurement of an actual physical system and compare it to the prediction of a model. The actual geometry of a duck is complicated. If we only need a rough idea of the fraction of a duck that lies below the surface. it should come as no surprise that you can write functions that take vectors. 7.

end I called it mysum to avoid a collision with the built-in function sum. but I didn’t.1 Write a function named find target that encapsulates the code. 7.82 Functions of vectors Here’s a more interesting example that encapsulates the code from Section 4. from Section 4. end res = total. .4 Vectors as output variables There’s also nothing wrong with assigning a vector to an output variable.14. I made a point of assigning it to a variable. Here’s an example that encapsulates the code from Section 4. that finds the location of a target value in a vector.12 that adds up the elements of a vector: function res = mysum(X) total = 0. as a reminder that it is supposed to get a vector value. which does pretty much the same thing. Here’s how myapply works: >> V = myapply(1:3) V = 1 4 9 Exercise 7.13: function res = myapply(X) for i=1:length(X) Y(i) = X(i)^2 end res = Y end Ideally I would have changed the name of the output variable to Res. Here’s how you call it from the Command Window: >> total = mysum(1:3) total = 6 Because this function has a return value. for i=1:length(X) total = total + X(i).

here’s hypotenuse from Section 5.5 Vectorizing your functions Functions that work on vectors will almost always work on scalars as well. it might not work on vectors.5 Vectorizing your functions 83 7. For example. >> hypotenuse(1:3. But it might! If the operators and functions you use in the body of your function work on vectors.3818 1. 1:3) ??? Error using ==> mpower Matrix must be square.7. Some of the other functions we wrote don’t work on vectors. but they can be patched up with just a little effort. . >> mysum(17) ans = 17 >> myapply(9) ans = 81 Unfortunately. end This doesn’t work on vectors because the ^ operator tries to do matrix exponentiation. we are seeing features that show MATLAB’s strengths. here is the very first function we wrote: function res = myfunc (x) s = sin(x) c = cos(x) res = abs(s) + abs(c) end And lo! It turns out to work on vectors: >> Y = myfunc(1:3) Y = 1. If you write a function with scalar inputs in mind.5: function res = hypotenuse(a.3254 1. which only works on square matrices. because MATLAB considers a scalar to be a vector with length 1. But here.1311 At this point. then your function will probably work on vectors. because there are a number of features that I think make life harder than it needs to be for beginners. finally. b) res = sqrt(a^2 + b^2). the converse is not always true. I want to take a minute to acknowledge that I have been a little harsh in my presentation of MATLAB. For example.

2 Write a function named cumulative sum that uses a loop to compute the cumulative sum of the input vector. then the elements of the cumulative sum. In math notation. 7.84 Functions of vectors But if you replace ^ with the elementwise operator . respectively. it matches up corresponding elements from the two input vectors. then the new function will also work on vectors. so the elements of C are the hypotenuses of the pairs (3. In general. The inverse operation of cumsum is diff. which takes a vector as an input and computes a new vector that contains all of the partial sums of the original.6 Sums and differences Another common vector operation is cumulative sum. MATLAB provides a function named cumsum that computes cumulative sums: >> V = 1:5 V = 1 2 3 4 5 >> C = cumsum(V) C = 1 3 6 10 15 Exercise 7. >> B = [4.5. C. 15). which computes the difference between successive elements of the input vector. if you write a function using only elementwise operators and functions that work on vectors.12.8]. 4). >> C = hypotenuse(A. >> D = diff(C) D = 2 3 4 5 .^. 12) and (8.15]. it works! >> A = [3. are: i Ci = j=1 Vj In other words. the ith element of C is the sum of the first i elements from V . (5. B) C = 5 13 17 In this case. if V is the original vector.

and which would compute the ratio of successive elements of the input vector.3 Write a function named mydiff that computes the inverse of cumsum. which computes the cumulative product. or if you want to be clever. MATLAB’s version of diff is not exactly the inverse of cumsum. 2 3 4 7.4 Write a function named cumulative prod that uses a loop to compute the cumulative product of the input vector. which would be called ratio. so that cumprod(myratio(X)) and myratio(cumprod(X)) both return X.7. you can take advantage of the fact that eln a+ln b = ab. In math notation. that looks like: >> V = 1:5 V = 1 2 3 4 5 >> P = cumprod(V) P = 1 2 6 24 120 Exercise 7.7 Products and ratios 85 Notice that the output vector is shorter by one than the input vector. so that cumsum(mydiff(X)) and mydiff(cumsum(X)) both return X. You can use a loop. Exercise 7. As a result. then we would expect cumsum(diff(X)) to be X: >> cumsum(diff(V)) ans = 1 But it isn’t. .5 Write a function named myratio that computes the inverse of cumprod. Exercise 7.7 Products and ratios The multiplicative version of cumsum is cumprod. If it were. that’s: i Pi = j=1 Vj In MATLAB. MATLAB doesn’t provide the multiplicative version of diff.

6). (1 + √ 5)/2 (see Exercise 4. you might want to know if there are any positive elements. that means we didn’t find what we were looking for (because if we had.8 Existential quantification It is often useful to check the elements of a vector to see if there are any that satisfy a condition. which is known to logicians as universal quantification and denoted with the symbol ∀ which is pronounced “for all. and it is denoted with the symbol ∃. that returns 1 if there is such an element and 0 if there is not. you can confirm that the ratio of successive elements converges on the golden ratio. which is pronounced “there exists. return end end res = 0. like exists.” For example. “there exists some element x in the set S such that x > 0. this expression ∃x in S : x > 0 means. this condition is called existential quantification. we know the answer (it exists!) and we can end the function immediately without looking at the rest of the elements. not just the loop. If we exit at the end of the loop.” So this expression . That behavior is what we want here because as soon as we find a positive element. For example.9 Universal quantification Another common operation on vectors is to check whether all of the elements satisfy a condition. 7. it is similar to break except that it breaks out of the whole function. function res = exists(X) for i=1:length(X) if X(i) > 0 res = 1. 7. In logic. end We haven’t seen the return statement before.” In MATLAB it is natural to express this idea with a logical function.86 Functions of vectors If you apply myratio to a vector that contains Fibonacci numbers. we would have hit the return statement).

10 Logical vectors 87 ∀x in S : x > 0 means “for all elements. to rewrite ∀x in S : x > 0 as ∼ ∃x in S : x ≤ 0 Where ∼ ∃ means “does not exist. A better way is to reduce the problem to existential quantification. a vector whose elements are the logical values 1 and 0. Exercise 7.6 Write a function named forall that takes a vector and returns 1 if all of the elements are positive and 0 if there are any non-positive elements. x.” In other words. that is. the result is a logical vector. 7. L is a logical vector whose elements correspond to the elements of V. x > 0.” A slightly silly way to evaluate this expression in MATLAB is to count the number of elements that satisfy the condition. which takes a logical vector and returns a vector that contains the indices of the elements that are “true. Logical vectors can be used like flags to store the state of a condition. They are also often used with the find function. in the set S.7. For each positive element of V.10 Logical vectors When you apply a logical operator to a vector. >> V = -3:3 V = -3 >> L = V>0 L = 0 0 0 0 1 1 1 -2 -1 0 1 2 3 In this example. the corresponding element of L is 1. checking that all the elements are positive is the same as checking that there are no elements that are non-positive. that is.” Applying find to L yields .

physical system: Something in the real world that we are interested in studying. the result is an empty vector. abstraction: The process of building a model by making decisions about what factors to simplify or ignore. physical modeling: A process for making predictions about physical systems and explaining their behavior. it only be called from another function in the same file. validation: Checking whether a model is adequate for its purpose. 6 and 7 have the value 1. helper function: A function in an M-file that is not the top-level function. If there are no “true” elements. >> find(V>10) ans = Empty matrix: 1-by-0 This example computes the logical vector and passes it as an argument to find without assigning it to an intermediate variable. model : A simplified description of a physical system that lends itself to analysis or simulation.” We can also use find to write exists more concisely: function res = exists(X) L = find(X>0) res = length(L) > 0 end Exercise 7. You can read this version abstractly as “find the indices of elements of V that are greater than 10.7 Write a version of forall using find.11 Glossary top-level function: The first function in an M-file. 7.88 >> find(L) ans = 5 6 7 Functions of vectors which indicates that elements 5. . existential quantification: A logical condition that expresses the idea that “there exists” an element of a set with a certain property. it is the only function that can be called from the Command Window or from another file.

that contains logical values 1 and 0. .7.11 Glossary 89 universal quantification: A logical condition that expresses the idea that all elements of a set have a certain property. logical vector: A vector. usually the result of applying a logical operator to a vector.

90 Functions of vectors .

when bacteria grow in particularly bacteria-friendly conditions. let’s define f to be a function that maps from time. For example. t. but we can write a differential equation that describes it: df = af dt where a is a constant that characterizes how quickly the population increases. We don’t know what it is. If the equation related . “Solving a DE” means finding a function whose derivatives satisfy the equation. To say that two functions are equal is to say that their values are equal at all times.1 Differential equations A differential equation (DE) is an equation that describes the derivatives of an unknown function. In other words: ∀t : df (t) = af (t) dt This is an ordinary differential equation (ODE) because all the derivatives involved are taken with respect to the same variable. the rate of growth at any point in time is proportional to the current population. Toward that end.Chapter 8 Ordinary Differential Equations 8. What we might like to know is the population as a function of time. to population y. Notice that both sides of the equation are functions.

we can express the solution as a function of t. If you don’t believe me. and so on. Linear. If we know the population of bacteria at a particular point in time. but they all have this form: t → beat For any value of b. What do you think the population will be after some period of time h has elapsed? . Unfortunately. The alternative is to solve them numerically. For example. we can use that additional information to determine which of the infinite solutions is the (unique) one that describes a particular population over time. that is. r. first order ODEs can be solved analytically. this function satisfies the ODE. y. 8. if any of the terms involved products or powers of t. This equation is linear because each term involves t. This equation is first order because it involves only first derivatives. and the rate of change. Let’s say that you arrive at time t and measure the current population. it would be a partial differential equation. Here’s a test to see if you are as smart as Euler. That determines what we wanted to know: f : t → 5eat The extra bit of information that determines b is called the initial condition (although it isn’t always specified at t = 0). then we can write f (0) = 5 = bea0 and solve for b. most interesting physical systems are described by nonlinear DEs. This particular ODE has an infinite number of solutions. most of which can’t be solved analytically. take its derivative and check.2 Euler’s method The simplest numerical method for ODEs is Euler’s method. f and df /dt it would be nonlinear.92 Ordinary Differential Equations derivatives with respect to different variables (partial derivatives). If it involved second derivatives. which is 5. f or df /dt raised to the first power. it would be second order. if we know that f (0) = 5 billion cells.

and then use Equations 8. y)h (8.8.2 to compute values of Ti and Fi until Ti gets to the value of t we are interested in. but in general it’s not. y) dt where y = f (t) and g is some function that maps (t. that is. etc. their meanings. The interval h is called the time step. so we only expect the estimate to be good if r changes slowly and h is small. y : df (t) = g(t. The price of higher order methods is that they have to evaluate g more times per time step. they are probably accurate. For each index i. and F is the sequence of estimates. third-order drops by 8. known value). so I want to pause to review what we have so far. Then we can advance from one point in time to the next using these equations: Tn+1 = Tn + h Fn+1 = Fn + g(t.1) (8. it computes the rate of change. Euler’s method is first order. you expect the error to drop by a factor of 4. Assuming that we start at t = 0 and we have an initial condition f (0) = y0 (where y0 denotes a particular. given the time and current population. we would set T1 = 0 and F1 = y0 . cut the time step again. If the rate doesn’t change too fast and the time step isn’t too big. congratulations! You just invented Euler’s method (but you’re still not as smart as Euler).2) where T is a sequence of times where we estimate the value of f . Here are the variables. 8. Euler’s method is accurate enough for most purposes.3 Another note on notation 93 If you said y + rh.1 and 8. and their types: . y) onto r. With a secondorder method. which means that each time you cut the time step in half. If the results are the same. One way to check is to run it once with time step h and then run it again with time step h/2. Fi is an estimate of f (Ti ). But let’s assume (for now) that the ODE we are interested in can be written so that ∀t. otherwise.3 Another note on notation There’s a lot of math notation in this chapter. you expect the estimation error to drop by half. and some of it is non-standard. This estimate is based on the assumption that r is constant.

g is a “rate function” that computes the rate of change as a function of time and population. ft is more specific: it is the actual rate of change at time t. g is more general: it can compute the rate of change for any (hypothetical) population at any time. But some parts of the solution are harder to estimate than others. and if we assign f (t) to a variable. where we estimate f (t) a sequence of estimates for f (t) Type function t → y function t → r function t → r function t. Similarly. t. The ode stands for “ordinary differential equation [solver]. y → r scalar variable scalar variable scalar variable scalar constant sequence sequence t y r h T F So f is a function that computes the population as a function of time. but I have never liked it because it looks like a fraction. y. we call it r. . y) to a variable.” the 45 indicates that it uses a combination of 4th and 5th order formulas.94 Name f df /dt ft g Ordinary Differential Equations Meaning The unknown function specified. The first time derivative of f Alternative notation for the first time derivative of f A “rate function. which has the benefit of looking like a function. implicitly. Fortunately. I prefer ft . given that the population is f (t). we usually call that variable y. because the nice people at Mathworks have implemented it in a function called ode45. df /dt is the most common notation for the first derivative of f .” derived from the ODE. It is easy to get ft confused with g. you don’t have to know what that means. If we assign g(t. but notice that they are not even the same type. Methods that do that are called adaptive. time population rate of change time step a sequence of times. by an ODE. 8. it is doing more work than necessary on the easy parts. The ideal solution is to adjust the time step as you go along.4 ode45 A limitation of Euler’s method is that the time step is constant from one iteration to the next. that computes rate of change for any t. and one of the best adaptive methods is the Dormand-Prince pair of Runge-Kutta formulas. if the time step is small enough to get the hard parts right. f (t) is the function evaluated at a particular time.

2 we used parameters rho and r to quantify the density and radius of a duck. As an example. suppose that the rate of population growth for rats depends on the current population. y → ay [1 + sin(ωt)] This function is useful because we can use it with Euler’s method or ode45 to estimate values of f . in Exercise 6. In order to estimate values of f numerically.01. of f . The first step is to write the equation more explicitly. which varies over the course of the year. res = a * y * (1 + sin(omega * t)). we have to transform it into a rate function. but in some models they might vary in time. 1 . The governing equation might be something like ft = af [1 + sin(ωt)] where a is a parameter that characterizes the reproductive rate.01 and ω = 2π/365 (one cycle per year): function res = rats(t. which is the slope.8. For example. you have to write a MATLAB function that evaluates g as a function of t and y. or rate of change. and ω is the frequency of a periodic function that characterizes the effect of varying food supply on reproduction. y. and the availability of food. end 1 A parameter is a value that appears in a model to quantify some physical aspect of the scenario being modeled. Parameters are often constants. The next step is to introduce a variable. y. to say that two function are equal means that they are equal all all times. y) a = 0. In other words ∀t : ft (t) = af (t) [1 + sin(ωt)] where t is time in days. as another name for f (t) ∀t : ft (t) = ay [1 + sin(ωt)] This equation means that if we are given t and y. we can compute ft (t). All we have to do is write a function that evaluates g. Here’s what that looks like using the values a = 0. omega = 2 * pi / 365. This is an equation that specifies a relationship between a function and its derivative. The last step is to express that computation as a function called g: g : t.4 ode45 95 In order to use ode45.

2) The first argument is a handle for the function that computes g. the result is the rate of change (in units of rats per day): >> r = rats(0. 2) r = 0. The second argument is the interval we are interested in. The rate of growth is slow in the winter and summer.0200 So if there are two rats on January 1. but it also accelerates as the population grows. and faster in the spring and fall. we expect them to reproduce at a rate that would produce 2 more rats per hundred days. but that is exactly what ode45 does. one year. the y-axis shows the rat population. the rate has almost doubled: >> r = rats(120. which starts at 2 and grows to almost 80. 8. When you call ode45 without assigning the result to a variable.5 Multiple output variables ode45 is one of many MATLAB functions that return more than one output variable.0376 Since the rate is constantly changing. The third argument is the initial population. Here’s how you would use it: >> ode45(@rats.96 Ordinary Differential Equations You can test this function from the Command Window by calling it with different values of t and y. 2) r = 0. it is not easy to predict the future rat population. 365]. The syntax for calling it and saving the results is . f (0) = 2. [0. MATLAB displays the result in a figure: 80 70 60 50 40 30 20 10 0 0 50 100 150 200 250 300 350 400 The x-axis shows time from 0 to 365 days. But if we come back in April.

omega = 2 * pi / 365. you have to do it yourself: >> plot(T. The primary advantage is that you can compute numerical solutions to ODEs that don’t have analytic solutions.6 Analytic or numerical? When you solve an ODE analytically. you’ll see that the space between the points is not quite even. where ode45 estimated the population. To see the population at the end of the year. where ode45 evaluates g. Each element of T is a time. 2).0000 76. Y(end)] ans = 365. you can display the last element from each vector: >> [T(end). and “approximate” because each value Fi is only an estimate of the true value f (t). You can think of these vectors as a discrete approximation of the continuous function f : “discrete” because it is only defined for certain values of t. . y. If you are curious to know more about how ode45 works. t. If you assign the output values to variables. f (t). How much does the final population change if you double the initial population? How much does it change if you double the interval to two years? How much does it change if you double the value of a? 8. so Y(end-1) is the second-to-last element of Y. you can modify rats to display the points. They are closer together at the beginning of the interval and farther apart at the end. when it appears as an index. it means “the index of the last element.” You can use it in an expression.6 Analytic or numerical? >> [T. each element of Y is an estimate of f (t). When you solve an ODE numerically. [0. (t. you get two vectors. the result is a function. y) plot(t. that allows you to compute the population. for any value of t. Y] = ode45(@rats.01. which is the vast majority of nonlinear ODEs. ’bo’) a = 0. 97 The first return value is assigned to T. Y. ode45 doesn’t draw the figure. Here is a simple version: function res = rats(t. f . ’bo-’) If you plot the elements of T.8. So those are the limitations of numerical solutions.9530 end is a special word in MATLAB. 365]. y). the second is assigned to Y.

MATLAB treats the first argument as a function call. Fi ). but also to detect places where the errors are increasing so it can decrease the time step (or the other way around). zoomed in on the range from Day 100 to 170: 35 30 y (rat population) 25 20 15 10 90 100 110 120 130 t (days) 140 150 160 170 The circles show the points where ode45 called rats. and calls rats without providing arguments. You’ve been warned! . the error message is confusing. [0. >> clf.98 Ordinary Differential Equations res = a * y * (1 + sin(omega * t)). [0. 10]. in order to see all of the data points. Error in ==> rats at 4 res = a * y * (1 + sin(omega * t)). Notice that ode45 typically evaluates g several times for each estimate. for one thing. This figure shows part of the output. If you leave it out. The rectangles show the locations of the estimates (Ti . 2). end Each time rats is called.365]. Again. The lines through the circles show the slope (rate of change) calculated at each point. 2) ??? Input argument "y" is undefined. because it looks like the problem is in rats. This allows it to improve the estimates. 8. Y] = ode45(@rats. >> ode45(rats. hold on >> [T.7 What can go wrong? Don’t forget the @ on the function handle. it plots one data point. you have to use hold on.

m (rats)". it provides two arguments. tfinal. % WRONG .01. 2) ??? Output argument "res" (and maybe others) not assigned during call to "/home/downey/rats. If you only take one input variable.args{:}). next. r. y → ay You might be tempted to write this: function res = rate_func(y) a = 0.8. .1 res = a * y end % WRONG But that would be wrong.y0.01. you’ll get an error. ntspan. So very wrong. So you have to write a function that takes t as an input variable. t and y. tdir. you get >> ode45(@rats. Error in ==> rats at 2 a = 0. If you are working with a rate function like this: g : t. y) a = 0. Error in ==> funfun/private/odearguments at 110 f0 = feval(ode.. function res = rate_func(t.. t0. y) a = 0. f0. Error in ==> ode45 at 173 [neq. odeArgs. r = a * y * (1 + sin(omega * t)) end And then call it from ode45.7 What can go wrong? 99 Also. even if you don’t use it. remember that the function you write will be called by ode45.t0. y0. Why? Because when ode45 calls rate func. If you write something like this: function res = rats(t. odeFcn. omega = 2 * pi / 365.365]. tspan. in that order. [0.1 res = a * y end % RIGHT Another common error is to write a function that doesn’t make an assignment to the output variable. % ODE15I sets args{1} to yp0. which means it has to have the signature ode45 expects: it should take two input variables. and return one output variable.

Yet another mistake that people make with ode45 is leaving out the brackets on the second argument.com/company/newsletters/news_notes/clevescorner/may03_cleve.. f0. tspan. Again. MATLAB thinks there are four arguments. . which means that the computation takes a long time. t0.html . odeFcn. if you read the first line. tfinal. the tspan argument must have at least two elements. which we have been calling the interval). 365. you should see something like this: 2 The following discussion is based partly on an article from Mathworks available at http: //www.mathworks. you’ll get the idea. with δ = 0. In that case. but if you read the first line and ignore the rest. odeArgs. Here’s one example: ft = f 2 − f 3 If you solve this ODE with the initial condition f (0) = δ over the interval from 0 to 2/δ. ntspan.01. and you get >> ode45(@rats. 2) ??? Error using ==> funfun/private/odearguments When the first argument to ode45 is a function handle. it might not be your fault: the problem you are trying to solve might be stiff2 . next. you should be able to figure out the problem (tspan stands for “time span”. 8. 0.8 Stiffness There is yet another problem you might encounter. y0.100 Ordinary Differential Equations This might be a scary message. I won’t give a technical explanation of stiffness here.. Error in ==> ode45 at 173 [neq. but if it makes you feel better. except to say that for some problems (over some intervals with some initial conditions) the time step needed to control the error is very small. tdir.

but if the problem is stiffness. linear: A DE that includes no products or powers of the function and its derivatives.1 Write a rate function for this ODE and use ode45 to solve it with the given initial condition and interval.8. .6 0. In this case. Exercise 8. partial DE: A DE that includes derivatives with respect to more than one variable first order (ODE): A DE that includes only first derivatives. the situation is even worse. ordinary DE: A DE in which all derivatives are taken with respect to the same variable. the time step is very small and the computation goes slowly. If you get tired of waiting for a computation to complete.2 0 0 20 40 60 80 100 120 140 160 180 200 After the transition from 0 to 1.9 Glossary differential equation (DE): An equation that relates the derivatives of an unknown function.9 Glossary 1.2 1 0. In general. It won’t always solve the problem. Start with δ = 0. the improvement can be striking. the problem is easy to fix: instead of ode45 you can use ode23s.8 0. you might want to try one of the stiff solvers.4 0. For smaller values of δ. Now replace ode45 with ode23s and try again! 8.1 and decrease it by multiples of 10. you can press the Stop button in the Figure window or press Control-C in the Command Window. if you find that ode45 is taking a long time. an ODE solver that tends to perform well on stiff problems (that’s what the “s” stands for).4 101 1.

first order (numerical method): A method whose error is expected to halve when the time step is halved. write the rate function. g. we can use Newton’s Law of Cooling3 : ft = −r(f − e) where f is the temperature of the coffee as a function of time and ft is its time derivative. Some ODE solvers. you will have to model the cooling process of a hot liquid in air. then how long? To answer this question. 8.2 Suppose that you are given an 8 ounce cup of coffee at 90 ◦ C and a 1 ounce container of cream at room temperature. As a simplification. and that you would like to start drinking as soon as possible. Let’s assume that that has been done and r has been found to be 0.org/wiki/Heat_conduction . as a function of y. where y is the temperature of the coffee at a particular point in time.102 Ordinary Differential Equations time step: The interval in time between successive estimates in the numerical solution of a DE.001 in units of inverse seconds. and r is a parameter (also constant) that characterizes the rate of heat transfer. Hot coffee transfers heat to the environment by conduction. are designed to work on stiff problems. • Using mathematical notation. 1/s. which is 20 ◦ C. like ode23s. 3 http://en. e is the temperature of the environment.10 Exercises Exercise 8. It would be easy to estimate r for a given coffee cup by making a few measurements over time. stiffness: A characteristic of some ODEs that makes some ODE solvers run slowly (or generate bad estimates). You have learned from bitter experience that the hottest coffee you can drink comfortably is 60 ◦ C. Assuming that you take cream in your coffee.wikipedia. radiation. are you better off adding the cream immediately or waiting? And if you should wait. parameter: A value that appears in a model to quantify some physical aspect of the scenario being modeled. which is a constant in this case. adaptive: A method that adjusts the time step to control error. Quantifying these effects individually would be challenging and unnecessary to answer the question as posed. and evaporative cooling.

your function has to take t as the first input argument in order to work with ode45. It should take the volumes and temperatures of the liquids as parameters. Test your function by adding a line like rate func(0. • Use mix func and ode45 to compute the time until the coffee is drinkable if you add the cream immediately. then more slowly.90) working. how confident are you that this model can give a definitive answer to this question? What might you do to improve it? 4 http://en. and returns the temperature of the coffee after mixing. y). modify coffee to use ode45 to compute the temperature of the coffee (ignoring the cream) for 60 minutes. the final temperature of a mixture depends on the specific heat of the two substances4 . nevertheless. and y1 and y2 are their temperatures. • Once you get rate func(0. where v1 and v2 are the volumes of the liquids. the call coffee from the Command Window. Confirm that the coffee cools quickly at first. But if we make the simplifying assumption that coffee and cream have the same density and specific heat. Add code to coffee to test mix func. Notice that in this case g does not actually depend on t.8. and reaches room temperature (approximately) after about an hour. • Write a function called mix func that computes the final temperature of a mixture of two liquids.wikipedia. • Add a function called rate func that takes t and y and computes g(t. • Modify coffee so it takes an input variable t that determines how many seconds the coffee is allowed to cool before adding the cream. In general. • What do these results tell you about the answer to the original question? Is the answer what you expected? What simplifying assumptions does this answer depend on? Which of them do you think has the biggest effect? Do you think it is big enough to affect the outcome? Overall.10 Exercises 103 • Create an M-file named coffee and write a function called coffee that takes no input variables and returns no output value.org/wiki/Heat_capacity . • Use fzero to find the time t that causes the temperature of the coffee after mixing to be 60 ◦ C.90) to coffee. then the final temperature is (v1 y1 + v2 y2 )/(v1 + v2 ). Put a simple statement like x=5 in the body of the function and invoke coffee() from the Command Window.

104 Ordinary Differential Equations .

The difference is that the elements are arranged in rows and columns.Chapter 9 Systems of ODEs 9. which returns a vector: >> V = size(M) V = 3 3 The first element is the number of rows. you specify the row and column numbers: >> M(1. it contains elements that are identified by indices. To read an element of a matrix. Like a vector. One of many ways to create a matrix is the magic function. the second is the number of columns.1 Matrices A matrix is a two-dimensional version of a vector. so it takes two indices to identify an element. you can use whos to display it: >> whos Name M Size 3x3 Bytes 72 Class double array Or the size function.2) ans = 1 . which returns a “magic” matrix with the given size: >> M = magic(3) M = 8 3 4 1 5 9 6 7 2 If you don’t know the size of a matrix.

>> size(R) ans = 1 5 Well. everything is a matrix. column” to myself. >> size(x) ans = 1 1 And a vector is a matrix with only one row: >> R = 1:5.” or the abbreviation RC. Actually. 4. the other kind are column vectors.5. row or column.2 Row and column vectors Although it is useful to think in terms of scalars. like a mantra. where the elements are in a single column. I find it useful to repeat “row.106 Systems of ODEs >> M(2. because the elements are arranged in a row. from MATLAB’s point of view. it takes some effort to remember which index comes first. anyway. across. with semi-colons between rows: >> D = [1.2. A scalar is just a matrix that happens to have one row and one column: >> x = 5. vectors and matrices. there are two kind of vectors.1) ans = 3 When you are working with matrices. Another way to create a matrix is to enclose the elements in brackets. The ones we have seen so far are called row vectors. One way to create a column vector is to create a matrix with only one element per row: .6] D = 1 4 2 5 3 6 >> size(D) ans = 2 3 9. You might also find it helpful to remember “down.3 . some vectors.

column vectors.2. and scalars? .5.3 The transpose operator The transpose operator. you don’t have to know what kind it is: >> R(2) ans = 2 >> C(2) ans = 2 9. which is a new matrix that has all of the elements of the original. When you index the elements of a vector. but for most basic vector operations.2. 4. computes the transpose of a matrix.1 What effect does the transpose operator have on row vectors.6] D = 1 4 2 5 3 6 D has two rows. In this example: >> D = [1.9. so its transpose has two columns: >> Dt = D’ Dt = 1 2 3 4 5 6 Exercise 9. which looks remarkably like an apostrophe.3 The transpose operator >> C = [1. it doesn’t matter.3] C = 1 2 3 >> size(C) ans = 3 1 107 The difference between row and column vectors is important in linear algebra. but with each row transformed into a column (or you can think of it the other way around).3 .

= 0. ode45 can handle systems of equations. = 0. The model is governed by the following system of differential equations: Ft = ebRF − cF where • R is the population of rabbits. and the output is a matrix that contains one column for R and one for F .1. At first glance you might think you could solve these equations by calling ode45 once to solve for R as a function of time and once to solve for F .1. The problem is that each equation involves both variables. • c is the natural death rate of foxes in the absence of prey. • e is the efficiency of turning eaten rabbits into foxes. • a is the natural growth rate of rabbits in the absence of predation. A common example is rabbits and foxes.108 Systems of ODEs 9.2: function res = lotka(t.01. Fortunately. which is what makes this a system of equations and not just a list of unrelated equations. = 0. % a b c e set the parameters = 0. And here’s what the rate function looks like with the parameters a = 0. To solve a system. V) % unpack the elements of V r = V(1).1 and e = 0.4 Lotka-Voltera The Lotka-Voltera model describes the interactions between two species in an ecosystem. • F is the population of foxes. Rt = aR − bRF . • b is the death rate of rabbits per interaction with a fox. f = V(2).01. you have to solve the equations simultaneously.2. The difference is that the initial condition is a vector that contains initial values R(0) and F (0). a predator and its prey. b = 0. c = 0.1.

That is. the second is the time interval. and the characteristics of their interactions. The order of these elements (rabbits and foxes) is up to you. MATLAB doesn’t know what these values mean. [0. 365]. It also makes the third paragraph. where you unpack the input vector and repack the output vector. The second paragraph sets the parameters that describe the reproductive rates of rabbits and foxes. The body of the function includes four paragraphs. and the third is the initial condition. dfdt = e*b*r*f . dfdt]. it is up to you as the programmer to keep track. but giving names to these values helps me remember what’s what. the initial conditions you provide when you call ode45 have to be the same as the order. When ode45 calls this function. the first input variable is time. inside lotka.b*r*f. The first paragraph unpacks the vector by copying the elements into scalar variables. Sharp-eyed readers will notice something different about this line: res = [drdt. where we compute the derivatives. 10]) As always. resemble the mathematical equations we were given. The semi-colon between the elements of the vector is not an error. each explained by a comment. but for this example I chose values that yield interesting results. The initial condition is a vector: the first element is the number of rabbits at t = 0.4 Lotka-Voltera 109 % compute the derivatives drdt = a*r . R(t) and F (t). If we were studying a real system. which helps prevent errors. end As usual. The last paragraph packs the computed derivatives back into a vector. but you have to be consistent. % pack the derivatives into a vector res = [drdt. the first argument is a function handle. It is necessary in this case because ode45 requires the result of this function to be a column vector. This isn’t necessary. . The second input variable is a vector with two elements. I gave it a capital letter to remind me that it is a vector. Now we can run ode45 like this: ode45(@lotka. the second element is the number of foxes. dfdt]. [100. these values would come from observations of real animals.c*f. it provides a vector as input and expects to get a vector as output.9.

Another possible error is reversing the order of the elements in the initial conditions. t0. This result is one of several patterns this system can fall into.. Error in ==> ode45 at 173 [neq. tfinal.5 What can go wrong? The output vector from the rate function has to be a column vector. As an exercise.110 Systems of ODEs But if you get the order right. you should see something like this: 120 100 80 60 40 20 0 0 50 100 150 200 250 300 350 400 The x-axis is time in days. next. otherwise you get ??? Error using ==> funfun/private/odearguments LOTKA must return a column vector. f0. if you call ode45 without assigning the results to variables. It’s not clear why it needs to be a column vector. odeArgs. but that’s not our problem. or the vectors inside lotka. so it can’t catch errors like this. Here’s what that looks like: . the bottom curve shows foxes. 9. it plots the results. odeFcn. . If you assign the results to variables. tspan. MATLAB doesn’t know what the elements are supposed to mean. Again. tdir.6 Output matrices As we saw before. it will just produce incorrect results. try experimenting with different values. y0. depending on the starting conditions and the parameters. 9.. it suppresses the figure. Which is pretty good as error messages go. ntspan. the y-axis is population. The top curve shows the population of rabbits.

If you plot these vectors against each other. In this context. column 2.6 Output matrices >> [T. 2). the second output variable is a matrix containing one column for each variable (in this case. so M(:. R and F ) and one row for each time value. the colon represents the range from 1 to end. 111 As in previous examples. T is a vector of time values where ode45 made estimates. F) You get a phase plot that looks like this: 22 20 18 16 14 12 10 8 6 4 20 1 30 40 50 60 70 80 90 100 110 . 365]. 1). You can think of the left side of this assignment as a vector of variables. so if you do this: >> plot(T. M) MATLAB understands that it should plot each column from M versus T. You can copy the columns of M into other variables like this: >> R = M(:. >> size(M) ans = 185 2 This structure—one column per variable—is a common way to use matrices. >> F = M(:. 1) means “all the rows. But unlike previous examples. like this >> plot(R. plot understands this structure. 2) means “all the rows.9. 10]). column 1” and M(:. [0. [100. M] = ode45(@lotka.” >> size(R) ans = 185 >> size(F) ans = 185 1 So R and F are column vectors.

state: If a system can be described by a set of variables. paragraph: A chunk of code that makes up part of a function. This path is called a trajectory. If there are 3 variables in the system. transpose: An operation that transforms the rows of a matrix into columns (or the other way around. unpack: To copy the elements of a vector into a set of variables. Since the behavior of this system is periodic. you are on your own. system of equations: A set of equations written in terms of a set of variables such that the equations are intertangled. the resulting trajectory is a loop. the values of those variables are called the state of the system. but for 4 or more variables. column vector: A matrix that has only one column. a matrix that has only one row. trajectory: A path in a phase plot that shows how the state of a system changes over time. this figure shows the path traced by the state during the time interval. You can use plot3 to trace trajectories in 3 dimensions.7 Glossary row vector: In MATLAB. phase plot: A plot that shows the state of a system as point in the space of possible states. the state moves around the plane. pack: To copy values from a set of variables into a vector. we need 3 dimensions to show the state of the system. .112 Systems of ODEs Each point on this plot represents a certain number of rabbits (on the x axis) and a certain number of foxes (on the y axis). each point in this plane describes the complete state of the system. Since these are the only two variables in the system. Over time. if you prefer). so the trajectory is a 3-D curve. 9. usually with an explanatory comment.

9.8 Exercises

113

9.8

Exercises

Exercise 9.2 Based on the examples we have seen so far, you would think that all ODEs describe population as a function of time, but that’s not true. According to the Wikipedia1 , “The Lorenz attractor, introduced by Edward Lorenz in 1963, is a non-linear three-dimensional deterministic dynamical system derived from the simplified equations of convection rolls arising in the dynamical equations of the atmosphere. For a certain set of parameters the system exhibits chaotic behavior and displays what is today called a strange attractor...” The system is described by this system of differential equations: xt yt zt = σ(y − x) = xy − bz (9.1) (9.2) (9.3)

= x(r − z) − y

Common values for the parameters are σ = 10, b = 8/3 and r = 28. Use ode45 to estimate a solution to this system of equations. 1. The first step is to write a function named lorenz that takes t and V as input variables, where the components of V are understood to be the current values of x, y and z. It should compute the corresponding derivatives and return them in a single column vector. 2. The next step is to test your function by calling it from the command line with values like t = 0, x = 1, y = 2 and z = 3? Once you get your function working, you should make it a silent function before calling ode45. 3. Assuming that Step 2 works, you can use ode45 to estimate the solution for the time interval t0 = 0, te = 30 with the initial condition x = 1, y = 2 and z = 3. 4. Use plot3 to plot the trajectory of x, y and z.

1 http://en.wikipedia.org/wiki/Lorenz_attractor

114

Systems of ODEs

Chapter 10

Second-order systems
10.1 Nested functions

In the Section 7.1, we saw an example of an M-file with more than one function: function res = duck() error = error_func(10) end function res = error_func(h) rho = 0.3; % density in g / cm^3 r = 10; % radius in cm res = ... end Because the first function ends before the second begins, they are at the same level of indentation. Functions like these are parallel, as opposed to nested. A nested function is defined inside another, like this: function res = duck() error = error_func(10) function res = error_func(h) rho = 0.3; % density in g / cm^3 r = 10; % radius in cm res = ... end end The top-level function, duck, is the outer function and error func is an inner function.

and a is the resulting acceleration of the object.. Even more generally. as a function of time. 10. F and a are scalars.116 Second-order systems Nesting functions is useful because the variables of the outer function can be accessed from the inner function. In this example. end end Both rho and r can be accessed from error func.. how do you find the position of the object. error = error_func(10) function res = error_func(h) res = . if F and a vary in time. So a more explicit way to write Newton’s law is ∀t : F (t) = ma(t) The arrangement of this equation suggests that if you know m and a you can compute force. we made it easier to test duck with different parameter values. then they can be thought of as functions that return vectors. m is the mass of the object. Based on a physical model.2 Newtonian motion Newton’s second law of motion is often written like this F = ma where F is the net force acting on a object. a. and compute a. so we can write a differential equation ptt = a . By making rho an input argument. So if you know acceleration. p? Well. but in general they are vectors. function res = duck(rho) r = 10. that is. In a simple case where the object is moving along a straight line. F is a function and the result of evaluating F (t) is a vector that describes the net force at time t. This is not possible with parallel functions. but in most physical simulations it is the other way around. we know that acceleration is the second derivative of position. using a nested function makes it possible to move the parameters rho and r out of error func. which is true. you know F and m.

Near the surface of the earth. It gets t and X as input variables.10. the acceleration of gravity is g = −9. p. but by introducing a new variable.3 Freefall Let’s start with a simple example.3 Freefall 117 Where a and p are functions of time that return vectors. v). for velocity. % acceleration of gravity in m/s^2 res = g.8. res = [dpdt. the second says that the derivative of v is a. The return value % pack the results in a column vector . an object in freefall in a vacuum (where there’s no air resistance). pt vt = v = a The first equation says that the first derivative of p is v. v. So this will be a one-dimensional problem. end The first function is the rate function. % the second element is velocity dpdt = v. it is a second-order ODE. dvdt = acceleration(t. end function res = acceleration(t.8 m/s2 . X) p = X(1). altitude. at least for now. where the elements of X are understood to be position and velocity. % the first element is position v = X(2). ode45 can’t solve this equation in this form. If the object falls straight down (in the same direction as gravity). Because this equation includes a second derivative. dvdt]. v) g = -9. we can rewrite it as a system of first-order ODEs. and ptt is the second time derivative of p. p. we can describe its position with a scalar value. 10. Here is a rate function we can use with ode45 to solve this problem: function res = freefall(t. where the minus sign indicates that gravity pulls down.

the force due to air resistance. For large objects moving quickly through air. so we don’t really have to include all this information yet. So you can think of the “object” a a skydiver jumping out of an airplane at about 12. the second is the time interval (30 seconds) and the third is the initial condition: in this case. Computing pt is easy because we are given velocity as an element of X. we can add air resistance. Notice that ode45 doesn’t know where the ground is. 10. not a ballistic trajectory). called “drag. [0. Here’s how to run ode45 with this rate function: >> ode45(@freefall. 0]) As always. acceleration computes acceleration as a function of time. which are velocity and acceleration. respectively.” is proportional to v 2 : . Here’s what the result looks like: 4000 3500 3000 2500 2000 1500 1000 500 0 −500 0 5 10 15 20 25 30 The bottom line shows velocity starting at zero and dropping linearly. 30]. position and velocity. [4000. so the skydiver keeps going through zero into negative altitude. The top line shows position starting at 4000 m and dropping parabolically (but remember that this parabola is a function of time. the first argument is the function handle. the net acceleration is a constant.000 feet. the initial altitude is 4000 meters and the initial velocity is 0.4 Air resistance To make this simulation more realistic.118 Second-order systems from freefall is a (column) vector that contains the derivatives of position and velocity. but we will soon. We will address this issue later. which is what the second function does. In this example. The only thing we have to compute is acceleration.

known as “terminal velocity. % total acceleration end The sign of the drag force (and acceleration) is positive as long as the object is falling. p. % acceleration of gravity in m/s^2 c = 0. we can assign them to variables . the cross-sectional area of the object and the surface properties of the object. Be careful when you are working with forces and accelerations. we have to know mass. so let’s say that the skydiver (with equipment) weighs 75 kg. To examine the results more closely. In my code. let’s say that c = 0. To convert from force to acceleration. v) a_grav = -9. I use comments to remind myself what units the values are in. % drag constant m = 75. velocity is a constant. the direction of the drag force is up. velocity increases until the drag acceleration equals g. That helps me avoid nonsense like adding forces to accelerations. make sure you only add forces to forces or accelerations to accelerations. For purposes of this problem. The net acceleration is the sum of gravity and drag. Here’s what the result looks like with air resistance: 4000 3500 3000 2500 2000 1500 1000 500 0 −500 0 5 10 15 20 25 30 Big difference! With air resistance. % drag acceleration in m/s^2 res = a_grav + a_drag. Here’s a version of acceleration that takes air resistance into account (you don’t have to make any changes in freefall: function res = acceleration(t.2.4 Air resistance 119 Fdrag = cv 2 Where c is a drag constant that depends on the density of air. after that.2.10. % drag force in N a_drag = f_drag / m. % mass in kg f_drag = c * v^2.” and position decreases linearly (and much more slowly than it would in a vacuum).8.

org/wiki/Human_cannonball . This relationship is the source of the intuition that heavy objects fall faster.120 Second-order systems >> [T. 1 http://en.2) ans = -60. If a projectile stays in a plane.5 Parachute! In the previous section. in air. What is the terminal velocity now? How long (after deployment) does it take to reach the ground? 10. 30]. and the next logical example is a projectile. we can think of the system as two-dimensional.7.2 Modify acceleration so that after 30 seconds of free-fall the skydiver deploys a parachute. A “projectile” is an object propelled through space. That’s where parachutes come in. with x representing the horizontal distance traveled and y representing the height or altitude. a target. you would almost certainly be killed.wikipedia. M] = ode45(@freefall. The next logical step is a system of second-order equations. we saw that the terminal velocity of a 75kg skydiver is about 60 m/s. 0]). usually toward. which (almost) instantly increases the drag constant to 2.6143 % velocity in m/s % altitude in meters Exercise 10. and often to the detriment of. [0.4412e+03 >> M(end. and confirm that terminal velocity increases.1) ans = 2. Exercise 10. According to the Wikipedia1 . the record distance for a human cannonball is 56.1 Increase the mass of the skydiver.6 Two dimensions So far we have used ode45 for a system of first-order equations and for a single second-order equation. And then read the terminal position and velocity: >> M(end. think of a circus performer being fired out of a cannon. they do! 10.5 meters (almost 186 feet). If you hit the ground at that speed. [4000. which is about 130 mph. So now instead of a skydiver.

dPdt = V. end The second argument of the rate function is a vector. W. end function res = acceleration(t. P and V are vectors with elements for the x and y components. .8.3. dVdt]. res = [dPdt.10]. with four elements. [0. W) P = W(1:2). % acceleration of gravity in m/s^2 res = [0. [0. ignoring air resistance (for now). the acceleration in the x direction is 0. If we launch the human projectile from an initial height of 3 meters. which represents position. The first two are assigned to P. dVdt = acceleration(t. 40. 3. P.6 Two dimensions 121 Here is a general framework for computing the trajectory of a projectile in two dimensions using ode45: function res = projectile(t. the ode45 call looks like this: ode45(@projectile. Other than that. g]. 30]). V). It looks like the flight time is about 6 seconds. with velocities 40 m/s and 30 m/s in the x and y directions. V = W(3:4). The result from acceleration is also a vector. which represents velocity. the last two are assigned to V. in the y direction it’s g. V) g = -9. this code is similar to what we saw in Section 10. P.10. And the result looks like this: 300 250 200 150 100 50 0 −50 0 1 2 3 4 5 6 7 You might have to think a little to figure out which line is which.

What initial velocity is needed to achieve the record flight distance of 65.6 meters? Hint: what is the optimal launch angle? 10. probably has a drag constant closer to 0. y] z = 1 2 3 4 5 Inside brackets. To explain what that means.3) Y = 1 1 1 1 1 1 >> Z = [X. the comma operator performs horizontal catenation. but that was based on the assumption that the skydiver is falling flat. “Vertical catenation” joins the matrices by stacking them on top of each other. In the skydiver scenario.122 Second-order systems Exercise 10. flying head-first. “horizontal catenation” lays them side by side. Here is an example with matrices: >> X = zeros(2. Exercise 10.2.4 Add air resistance to this simulation. Y] . we estimated that the drag constant was 0. which is the operation of joining two matrices into a larger matrix. plot the trajectory of the projectile. The vertical catenation operator is the semi-colon.1.3 Extract the x and y components of position. I’ll start with catenation.3) X = 0 0 0 0 0 0 >> Y = ones(2. vertcat for one. Here’s an example of horizontal catenation with row vectors: >> x = 1:3 x = 1 2 3 >> y = 4:5 y = 4 5 >> z = [x.7 What could go wrong? What could go wrong? Well. A human cannonball. and estimate the distance traveled.

These operations are relevant to projectile because of the last line. and likewise with vertcat and vertical catenation. dVdt]. b] ??? Error using ==> horzcat All matrices on a row in the bracketed expression must have the same number of rows. end As long as both dPdt and dVdt are column vectors. so they can’t be catenated in either direction. a is a row vector and b is a column vector. dPdt = V. you probably guessed that horzcat is the function that performs horizontal catenation. If not. V). In this example. Reading the error messages. >> c = [a.7 What could go wrong? Z = 0 0 1 1 0 0 1 1 0 0 1 1 123 These operations only work if the matrices are the same size along the dimension where they are glued together. dVdt = acceleration(t. W) P = W(1:2). which packs dPdt and dVdt into the output variable: function res = projectile(t. the semi-colon performs . res = [dPdt. you get: >> a = 1:3 a = 1 >> b = a’ b = 1 2 3 2 3 >> c = [a. V = W(3:4). b] ??? Error using ==> vertcat All rows in the bracketed expression must have the same number of columns. P.10.

124 Second-order systems vertical catenation. In general.0042 m2 ). so if you are working with ode45. v ˆ is the magnitude of the velocity vector. The mass of the baseball is 0.3 kg/m3 at sea level). and V is a unit vector in the direction of the velocity vector. inner function: A function defined inside another function definition.9 Exercises Exercise 10. 10. outer function: A function that contains another function definition. see http: // en. nested function: A function defined inside another function. 10. the path of the baseball stays in a plane. The inner function can access the variables of the outer function. But if either of them is a row vector. drag due to air resistance. org/ wiki/ Drag_ ( physics) .8 Glossary parallel functions: Two or more functions defined side-by-side. so that one ends before the next begins.145 kg. Cd is the drag coefficient (0. . and the result is a column vector with four elements. catenation: The operation of joining two matrices end-to-end to form a new matrix. and Magnus force due to spin. For more information about drag. that’s trouble. use size to display the dimensions of the operands. wikipedia. ode45 expects the result from projectile to be a column vector. A simple model of the drag of a baseball is: Fd = − 1 ˆ ρ v 2 A Cd V 2 where Fd is a vector that represents the force on the baseball due to drag. ρ is the density of air (1. it is probably a good idea to make everything a column vector. and make sure you are clear on which way your vectors go.3 is a reasonable choice). so we can model it as a projectile in two dimensions. If we ignore wind and Magnus force. if you run into problems with horzcat and vertcat.5 The flight of a baseball is governed by three forces: gravity. A is the cross sectional area of the baseball (0.

you also might find information on the web. How big is the effect on your computed ranges? How big is the effect on the optimal angles? 2 Robert K. Either way. Colorado. What is the minimum speed a ball must leave the bat in order to clear the monster (assuming it goes off at the optimal angle)? Do you think it is possible for a person to stand on home plate and throw a ball over the Green Monster? • The actual drag on a baseball is more complicated than what is captured by our simple model. and returns the optimal angle and range as output variables. . uses ode45 to compute the trajectory.9 Exercises 125 • Write a function that takes the initial velocity of the baseball and the launch angle as input variables. and then use your simulation to test your prediction. In particular.10. How does the optimal angle vary with initial velocity? • When the Red Sox won the World Series in 2007. You can get some of the details from The Physics of Baseball2 . • Write a function that takes the initial velocity of the baseball as an input variable. the drag coefficient varies with velocity. computes the launch angle that maximizes the range. they played the Colorado Rockies at their home field in Denver. What effect does this have on drag? Make a prediction about what effect this will have on the optimal launch angle. 3rd Edition. • The Green Monster in Fenway Park is about 12 m high and about 97 m from home plate along the left field line. 2002. Find an estimate of the density of air in the Mile High City. Adair. Harper Paperbacks. specify a more realistic model of drag and modify your program to implement it. and returns the range (horizontal distance in flight) as an output variable.

126 Second-order systems .

direction = -1.1 ODE Events Normally when you call ode45 you have to specify a start time and an end time. 2. Fortunately MATLAB provides a mechanism for dealing with this problem. The function you provide has to take the same input variables as your rate function. % Stop the integration if height crosses zero. When ode45 runs. Here’s how it works: 1. For example.6 function [value. Before calling ode45 you use odeset to create an object called options that contains values that control how ode45 works: options = odeset(’Events’. here is an event function that would work with projectile from Section 10. You can call this function anything you want. The bad news is that it is a little awkward. @events).Chapter 11 Optimization and Interpolation 11.isterminal. you don’t know ahead of time when the simulation should end.direction] = events(t. % But only if the height is decreasing. But in many cases. % Extract the current height. In this case. isterminal = 1. but the name events is conventional.X) value = X(2). it will invoke events after each timestep. the name of the option is Events and the value is a function handle. end .

[0. options). Exercise 11. Although either definition would be good enough for most purposes.2 Optimization In Exercise 10. 30]. In this case the range of feasible values is between 0 degrees (parallel to the ground) and 90 degrees (straight up). For the Green Monster Problem—finding the optimal angle for hitting a home run in Fenway Park. you pass options as a fourth argument: ode45(@projectile. In this case value gets the second element of X. the simulation continues.10]. but ode45 does some additional work to make sure that the solution in the vicinity of the event is accurate. “Optimal” is a fancy was of saying “best. so maybe we want the angle that yields the longest range when the ball falls through 12m. but we might not be sure how far from 45 degrees to look. decreasing (direction=-1. we could start with the widest feasible range. But in this case we are trying to clear a 12m wall. which is understood to be the height of the projectile. [0. In this case the “optimal” angle is the one that yields the greatest height at the point where the ball reaches the wall. The simplest way to search for an optimal value is to run the simulation with a wide range of values and choose the one that yields the best result. and that one of the estimated values in the result is at the time of the event.” what that means depends on the problem. the event is “terminal” and the simulation stops. If isterminal=0. It is tempting to choose the angle that yields the longest range (distance from home plate when it lands). So the first step in any optimization problem is to define what “optimal” means. If isterminal=1. you were asked to find the optimal launch angle for a batted ball.128 Optimization and Interpolation events returns three output variables: value determines when an event occurs. When you call ode45. neither is quite right. 40. direction determines whether an event occurs when value is increasing (direction=1). To play it safe.5. which is 97m from home plate.1 How would you modify events to stop when the height of the projectile falls through 3m? 11. This method . We expect the optimal angle to be near 45 degrees. isterminal determines what happens when an event occurs. or both direction=0. The second step is to define a range of values where you want to search. 3. An “event” is a point in time when this value passes through 0. the meaning of “optimal” is not obvious. 3.

(y. Searching for an optimal value is similar. we can form a new pair. If y is positive. Either way the size of the bracket gets smaller. but we have to start with three values. and we want to find a root of f . between x1 and x2 and then evaluating y = f (x3 ). x2 . A better algorithm is a Golden Section Search. The algorithm proceeds by choosing a third value. x2 ). f .3 Golden section search To present the Golden Section Search. f(x1) x2. we had a picture like this: x1. If y is negative then the pair (x1 . that makes f (x1 ) positive and another value. that makes f (x2 ) negative. The basic idea is similar to the methods for zerofinding we saw in Section 6. In the case of zero-finding. that we can evaluate. y) brackets the root.5. f(x2) We are given a function. then there has to be a root in between (as long as f is continuous). x1 . especially in a case like this where computing the distance in flight is expensive.11. If we can find a value. I will start with a simplified version I’ll call a Silver Section Search. and the picture looks like this: x1 x2 x3 . that brackets the root. In this case we say that x1 and x2 “bracket” the root. x3 . so our estimate of the location of the root gets better. 11. that is. a value of x that makes f (x) = 0.3 Golden section search 129 is not very efficient.

I chose to bisect the bigger of the ranges (x1 . x2 = V(2). for i=1:50 if x3-x2 > x2-x1 x4 = (x2+x3) / 2. x4 . fx1 = height_func(x1).130 Optimization and Interpolation This diagram show that we have evaluated f in three places. x2 ) and (x2 . x4 . x3 = V(3). x4 ) brackets the maximum. end . x3 ) brackets the maximum. x2 and x3 . but some choices are better than others. x2 . and evaluate f (x4 ). fx4 = height_func(x4). x3 ) brackets a maximum. fx3 = fx4. In the example. fx1 = fx2. x2 . depending on whether f (x4 ) is greater than f (x2 ): x1 x2 x4 x3 x1 x2 x4 x3 If f (x4 ) is less than than f (x2 ) (shown on the left). then the new triple (x1 . Either way the range gets smaller and our estimate of the optimal value of x gets better. then there has to be at least one local maximum between x1 and x3 . x1 . else x3 = x4. if fx4 > fx2 x1 = x2. If f (x4 ) is greater than f (x2 ) (shown on the right). Here’s what that looks like in MATLAB: function res = optimize(V) x1 = V(1). fx2 = height_func(x2). There are two possible outcomes. This method works for almost any value of x4 . x2 = x4. x3 ). then (x2 . so we would say that the triple (x1 . and found that x2 yields the highest value. fx3 = height_func(x3). fx2 = fx4. The next step is to choose a fourth point. If f is continuous.

3 Golden section search else x4 = (x1+x2) / 2. Read the Wikipedia page about the Golden Section Search (http: // en. and then updates the triplet x1. else x1 = x4. x2 = x4. optimize starts by evaluating height func for each of the three values. just as fzero and ode45 do. In the worst case the loop executes 50 times. Exercise 11. it computes the range of the bracket. fx1 = fx4. passing pi as an argument. fx2 = fx4. end 131 The input variable is a vector that contains three values that bracket a maximum. function res = handle_func(func) func(pi) end You can call handle func from the Command Window and pass different function handles as arguments: >> handle_func(@sin) .2 I call this algorithm a Silver Section Search because it is almost as good as a Golden Section Search. fx4 = height_func(x4). We assume that height func returns the quantity we want to optimize. handle func takes a function handle called func and calls it. x2 and x3 according to the results. Each time through the for loop the function chooses a value of x4. If so. After the update. For example. end end if abs(x3-x1) < 1e-2 break end end res = [x1 x2 x3]. evaluates height func. for the Green Monster Problem it is the height of the ball when it reaches the wall. it breaks out of the loop and returns the current triplet as a result. in this case they are angles in degrees.11. and checks whether it is small enough. org/ wiki/ Golden_ section_ search ) and then modify this code to implement it. x3-x1. fx3 = fx2. if fx4 > fx2 x3 = x2.3 You can write functions that take function handles as input variables. Exercise 11. wikipedia.

in Section 8. which you can think of as a discrete map.132 Optimization and Interpolation ans = 0 >> handle_func(@cos) ans = -1 Modify optimize so that it takes a function handle as an input variable and uses it as the function to be optimized.4 Discrete and continuous maps When you solve an ODE analytically. end The result from ode45 is two vectors: >> [T. 365]. the result is a function. T contains the time values where ode45 estimated the population. We could search T for the value 180: >> find(T==180) ans = Empty matrix: 0-by-1 But there is no guarantee that any particular value appears in T. Y contains the population estimates. 2). you get two vectors (or a vector and a matrix). we used the following rate function to estimate the population of rats as a function of time: function res = rats(t. Now suppose we would like to know the population on the 180th day of the year. For example.4. I(1) ans = 23 . When you use an ODE solver. Read the documentation for fminsearch and use it to find the optimal launch angle of a baseball with a given velocity. Exercise 11.4 The MATLAB function fminsearch takes a function handle and searches for a local minimum. We can find the index where T crosses 180: >> I = find(T>180). Y] = ode45(@rats. which you can think of as a continuous map. 11. res = a * y * (1 + sin(omega * t)). omega = 2 * pi / 365.01. [0. y) a = 0.

180. which uses piecewise cubic Hermite interpolation. >> pop = interp1(T.6973 and 40. Other choices include ’spline’ which uses a spline curve to fit two points on either side. and MATLAB provides a function named interp1 that does it: >> pop = interp1(T. Then we find the corresponding value from Y: >> [T(23).11. that’s not a great choice because the time value we want is right in the middle.6486 >> pop = interp1(T.3742 That gives us a coarse estimate of the population on Day 180. Y.3451 40.3742. interp1 can also take a fourth argument that specifies what kind of interpolation you want. ’spline’) pop = 38. But where in this range is the best estimate? A simple option is to choose whichever time value is closer to 180 and use the corresponding population estimate. we could also find the last value before Day 180: >> [T(22). which does linear interpolation. 11.6233 The first two arguments specify a discrete map from the values in T to the values in Y.5 Interpolation 133 I gets the indices of all elements of T greater than 180. This process is called linear interpolation.6973 So the population on Day 180 was between 36. so I(1) is the index of the first one. The third argument is the time value where we want to interpolate. and ’cubic’. Y(23)] ans = 184. Y(22)] ans = 175.5 Interpolation A better option is to draw a straight line between the two points that bracket Day 180 and use the line to estimate the value in between. ’cubic’) pop = 38.2201 36.6491 . If we wanted to do a little better. The default is ’linear’. Y. 180. In the example. about halfway between the values that bracket it. 180) pop = 38. Y. The result is what we expected.

For time values near 365. but as we go farther into the “future. >> interp1(Y. 370. The following plot shows f (Y plotted as a function of T) and the inverse of f (T plotted as a function of Y).6 Interpolating the inverse function We have used interp1 to find population as a function of time.0000 76. 365*2. ’cubic’) pop = 80. they are not very different. Y. For example. we can also interpolate time as a function of population. ’cubic’) pop = -4. T. here is the estimate we get by extrapolating for a whole year: >> pop = interp1(T.8879e+03 And that’s wrong. 20) ans = 133.” we expect them to be less accurate. So very wrong. For example. But we have no reason to expect the spline to be more accurate than the cubic. Y(end)] ans = 365. because they use more of the data. . extrapolation may be reasonable.9971 This process is called extrapolation.4128 This use of interp1 might be confusing if you think of the arguments as x and y. We can also use interp1 to project the rat population out beyond the values in T: >> [T(end). and we know the function isn’t linear.9530 >> pop = interp1(T. 11. Fortunately. by reversing the roles of T and Y. You might find it helpful to think of them as the range and domain of a map (where the third argument is an element of the range). Y.134 Optimization and Interpolation In this case we expect the spline and cubic interpolations to be better than linear. we might want to know how long it takes the population to reach 20. or the other way around.

44. there are two possible answers.8.3833 % WRONG On Day 196.11. we get the wrong answer: >> interp1(Y. the population is actually 16. but if we ask on what day the population was 15.0309 So on Day 260. so interp1 isn’t even close! The problem is that T as a function of Y is a multivalued mapping. which means that for each value in the domain. If we try to use interp1. 260) ans = 15. 172. for some values . 15) ans = 196. we might see something like this: 18 400 16 350 14 300 12 250 10 200 Y 8 T 0 100 200 T 300 400 150 6 100 4 50 2 0 0 5 10 Y 15 20 We can still use interp1 to map from T to Y: >> interp1(T. If we reduce the food supply so that the rat population decreases during the winter. there is only one value in the range that maps to it. T.44 and 260. the population is about 15. Y.6 Interpolating the inverse function 400 135 80 350 70 300 60 250 50 200 40 Y T 150 30 100 20 50 10 0 0 20 40 Y 60 80 0 0 100 200 T 300 400 In this case we can use interp1 either way because f is a single-valued mapping.

this function uses a discrete map to implement a continuous map. 1 This example is adapted from Gerald and Wheatley.0070 0. we might only have discrete measurements: t 0 1 2 3 4 5 6 7 8 b(t) ---0.7 where t is time in months.7 Field mice As we’ve seen. Addison-Wesley. 1989. y is population. y → ay − b(t)y 1. I can’t find any documentation for this limitation. Fourth Edition. This causes interp1 to fail. we might not know b(t) for all t.0001 0. and b is a function of time that characterizes the effect of the food supply on the death rate. t). For example1 .0043 0. Instead. Applied Numerical Analysis. B.0036 0.136 Optimization and Interpolation in the range there are more than one values in the domain. one use of interpolation is to interpret the results of a numerical computation. then we don’t get to choose the values of t where the rate function (and therefore b) gets evaluated. end Abstractly. a is a parameter that characterizes population growth in the absence of limitations. suppose that the population of field mice is governed by this rate equation: g : t. 11. so that’s pretty bad.0011 0.0056 If we use ode45 to solve the differential equation. another is to fill in the gaps between discrete measurements. B = [70 36 11 1 4 13 28 43 56] * 1e-4. We need to provide a function that can evaluate b everywhere: function res = interpolate_b(t) T = 0:8. res = interp1(T.0028 0. .0004 0.0013 0. Although b appears in the equation as a continuous function.

2 as long as the ball is moving faster than 20 m/s. which is perpendicular to the axis of spin and the path of flight. 11. The coefficient of drag of a golf ball is about 0. which might increase the range. 2 See 3 See http://en.org/wiki/Golf_ball. multivalued mapping: A mapping where at least one value in the range maps to more than one value in the domain. 11. The coefficient of lift is proportional to the spin rate.9. but the energy that goes into generating spin probably comes at the cost of lower initial velocity.org/wiki/Magnus_effect. for a ball spinning at 3000 rpm it is about 0. .wikipedia.1.5 Write a rate function that uses interpolate b to evaluate g and then use ode45 to compute the population of field mice from t = 0 to t = 8 with an initial population of 100 and a = 0. single-valued mapping: A mapping where each value in the range maps to a single value in the domain.6 A golf ball2 hit with backspin generates lift.9 Exercises Exercise 11. The lift of a spinning ball is due to the Magnus force3 . http://en.wikipedia. Write a simulation of the flight of a golf ball and use it to find the launch angle and allocation of spin and initial velocity (for a fixed energy budget) that maximizes the horizontal range of the ball in the air. Then modify interpolate b to use spline interpolation and run ode45 again to see how much effect the interpolation has on the results.8 Glossary 137 Exercise 11.8 Glossary interpolation: Estimating the value of a function using known values on either side. extrapolation: Estimating the value of a function using known values that don’t bracket the desired value.11.

138 Optimization and Interpolation .

Chapter 12

Vectors as vectors
12.1 What’s a vector?

The word “vector” means different things to different people. In MATLAB, a vector is a matrix that has either one row or one column. So far we have used MATLAB vectors to represent sequences: A sequence is a set of values identified by integer indices; it is natural to store the elements of the sequence as elements of a MATLAB vector. state vectors: A state vector is a set of values that describes the state of a physical system. When you call ode45, you give it in the initial conditions in a state vector. Then when ode45 calls your rate function, it gives you a state vector. discrete maps: If you have two vectors with the same length, you can think of them as a mapping from the elements of one vector to the corresponding elements of the other. For example, in Section 8.5, the results from ode45 are vectors, T and Y, that represent a mapping from the time values in T to the population values in Y. In this chapter we will see another use of MATLAB vectors: representing spatial vectors. A spatial vector is a value that represents a multidimensional physical quantity like position, velocity, acceleration or force1 . These quantities cannot be described with a single number because they contain multiple components. For example, in a 3-dimensional Cartesian coordinate space, it takes three numbers to specify a position in space; they are usually
1 See

http://en.wikipedia.org/wiki/Vector_(spatial).

140

Vectors as vectors

called x, y and z coordinates. As another example, in 2-dimensional polar coordinates, you can specify a velocity with two numbers, a magnitude and an angle, often called r and θ. It is convenient to represent spatial vectors using MATLAB vectors because MATLAB knows how to perform most of the vector operations you need for physical modeling. For example, suppose that you are given the velocity of a baseball in the form of a MATLAB vector with two elements, vx and vy , which are the components of velocity in the x and y directions. >> V = [30, 40] % velocity in m/s And suppose you are asked to compute the total acceleration of the ball due to drag and gravity. In math notation, the force due to drag is Fd = − 1 ˆ ρ v 2 A Cd V 2

where V is a spatial vector representing velocity, v is the magnitude of the ˆ velocity (sometimes called “speed”), and V is a unit vector in the direction of the velocity vector. The other terms, ρ, A and Cd , are scalars. The magnitude of a vector is the square root of the sum of the squares of the elements. You could compute it with hypotenuse from Section 5.5, or you could use the MATLAB function norm (norm is another name2 for the magnitude of a vector): >> v = norm(V) v = 50 ˆ V is a unit vector, which means it should have norm 1, and it should point in the same direction as V . The simplest way to compute it is to divide V by its own norm. >> Vhat = V / v Vhat = 0.6 0.8

ˆ Then we can confirm that the norm of V is 1: >> norm(Vhat) ans = 1 ˆ To compute Fd we just multiply the scalar terms by V . Fd = - 1/2 * C * rho * A * v^2 * Vhat Similarly, we can compute acceleration by dividing the vector Fd by the scalar m.
2 Magnitude is also called “length” but I will avoid that term because it gets confused with the length function, which returns the number of elements in a MATLAB vector.

12.2 Dot and cross products

141

Ad = Fd / m To represent the acceleration of gravity, we create a vector with two components: Ag = [0; -9.8] The x component of gravity is 0; the y component is −9.8m/s2 . Finally we compute total acceleration by adding vector quantities: A = Ag + Ad; One nice thing about this computation is that we didn’t have to think much about the components of the vectors. By treating spatial vectors as basic quantities, we can express complex computations concisely.

12.2

Dot and cross products

Multiplying a vector by a scalar is a straightforward operation; so is adding two vectors. But multiplying two vectors is more subtle. It turns out that there are two vector operations that resemble multiplication: dot product and cross product. The dot product of vectors A and B is a scalar: d = ab cos θ where a is the magnitude of A, b is the magnitude of B, and θ is the angle between the vectors. We already know how to compute magnitudes, and you could probably figure out how to compute θ, but you don’t have to. MATLAB provides a function, dot, that computes dot products. d = dot(A, B) dot works in any number of dimensions, as long as A and B have the same number of elements. If one of the operands is a unit vector, you can use the dot product to compute the component of a vector A that is in the direction of a unit vector, ˆ i: s = dot(A, ihat) In this example, s is the scalar projection of A onto ˆ The vector projection i. is the vector that has magnitude s in the direction of ˆ i: V = dot(A, ihat) * ihat The cross product of vectors A and B is a vector whose direction is perpendicular to A and B and whose magnitude is c = ab sin θ where (again) a is the magnitude of A, b is the magnitude of B, and θ is the angle between the vectors. MATLAB provides a function, cross, that computes cross products.

We can compute relative direction by subtracting vectors. Imagine a star with mass m1 at a point in space described by the vector P1 . 3 See http://en. the result is a 3-dimensional vector. m1.1 Write a sequence of MATLAB statements that computes F12. a vector that represents the force on the star due to the planet. then the direction of R is from P1 to P2. and forces in Newtons. A common use of cross is to compute torques.3 Celestial mechanics Modeling celestial mechanics is a good opportunity to compute with spatial vectors. distances in meters. The distance between the planet and star is the length of R: r = norm(r) ˆ The direction of the force on the star is R: rhat = R / r Exercise 12. if we compute R = P2 P1.142 C = cross(A. Remember that this is the appropriate value of G only if the masses are in kilograms. If you represent a moment arm R and a force F as 3-dimensional vectors.wikipedia.2 Encapsulate these statements in a function named gravity force func that takes P1.67 × 1011 N m2 /kg 2 . F) If the components of R are in meters and the components of F are in Newtons. The magnitude of the gravitational force3 between them is m1 m2 r2 fg = G where r is the distance between them and G is the universal gravitational constant. then the torque is just Tau = cross(R. and F21. Exercise 12. 12.org/wiki/Gravity . P2. and a planet with mass m2 at point P2 . the force on the planet due to the star. B) Vectors as vectors cross only works for 3-dimensional vectors. then the torques in Tau are in Newton-meters. and m2 as input variables and returns F12. The direction of the force on the star at P1 is in the direction toward P2 . which is about 6.

2). x2. assuming that the % columns of M are x1. Y1 = M(:.X2]). animate func uses clf to clear the figure and axis to reset the axes. The mass of the Sun is about 2.Y2]). animation can make it obvious. 12. minmax is a vector of four elements which is used inside the loop to set the axes of the figure. max([Y1. Each time through the loop. If something is wrong. so X1 and Y1 get the coordinates of the Sun. drawnow. so the axes keep changing. y2.4).Y2])]. end end The input variables are the output from ode45. which makes the animation hard to watch. y1. This is necessary because otherwise MATLAB scales the figure each time through the loop. axis(minmax). Y2 = M(:. org/ wiki/ Jupiter .12. X2 and Y2 get the coordinates of Jupiter. wikipedia. You can get the mass of Jupiter. The columns of M are the positions and velocities of the Sun and Jupiter. minmax = [min([X1.4 Animation Animation is a useful tool for checking the results of a physical model.3 Write a simulation of the orbit of Jupiter around the Sun. One is to use getframe to capture a series of images and movie to play them back. X2(i). a vector T and a matrix M. There are two ways to do animation in MATLAB.0 × 1030 kg. min([Y1. Y2(i)). its distance from the Sun and orbital velocity from http: // en. for i=1:length(T) clf. Confirm that it takes about 4332 days for Jupiter to orbit the Sun. draw_func(X1(i). Y1(i). .4 Animation 143 Exercise 12.3: function animate_func(T. X1 = M(:. X2 = M(:.3). hold on. The more informal way is to draw a series of plots.1). hold on makes it possible to put more than one plot onto the same axes (otherwise MATLAB clears the figure each time you call plot). max([X1.M) % animate the positions of the planets. Here is an example I wrote for Exercise 12.X2]).

y2. A limitation of this method is that it ignores the time required to draw the figure. ’r. One limitation of this kind of animation is that the speed of the animation depends on how fast your computer can generate the plots.’. especially if the figure is complex or the time step is small. ’b.144 Vectors as vectors Each time through the loop. draw func uses plot to draw the Sun as a large red marker and Jupiter as a smaller blue one. Here is an example: end_time = 1000. ode45 still uses variable time steps to generate the estimates. . plot(x2. Since step is end time/200. pause(dt). x2. you can compute the time until the next frame and use pause to wait: dt = T(i+1) . After drawing each frame and calling drawnow. [0:step:end_time]. There are two ways to fix this problem: 1. 20). y1. Since the results from ode45 are usually not equally spaced in time. we have to call drawnow so that MATLAB actually displays each plot. The second argument is a range vector that goes from 0 to 1000 with a step size determined by step. W).4 To make sure you understand how animate func works. but then it interpolates them before returning the results. ’MarkerSize’. [T. M] = ode45(@rate_func. Otherwise it waits until you finish drawing all the figures and then updates the display. end The input variables are the position of the Sun and Jupiter. 50). This option does not affect the accuracy of the results.T(i). ’MarkerSize’. When you call ode45 you can give it a vector of points in time where it should generate estimates. Exercise 12. your animation might slow down where ode45 takes small time steps and speed up where the time step is larger. draw func is the function that actually makes the plot: function draw_func(x1. You can use pause to play the animation in real time. step = end_time/200.’. y1. there will be about 200 rows in T and M (201 to be precise). y2) plot(x1. try commenting out some of the lines to see what happens. so it tends to run slow. 2.

[T.5 Use animate func and draw func to vizualize your simulation of Jupiter. Exercise 12.6 What is a model for? In Section 7. Plot the result as a function of time and confirm that it decreases over the course of the simulation. The kinetic energy of a moving body is mv 2 /2. T and M.3 seconds.8 Run your simulation with one of the other ODE solvers MATLAB provides and see if any of them conserve energy. You can reduce the rate of energy loss by decreasing ode45’s tolerance option using odeset (see Section 11. the kinetic energy of a solar system is the total kinetic energy of the planets and sun.5 Conservation of Energy A useful way to check the accuracy of an ODE solver is to see whether it conserves energy. the rate of energy loss decreases. The potential energy of a sun with mass m1 and a planet with mass m2 and a distance r between them is U = −G m1 m2 r Exercise 12.7 Run ode45 with a range of values for RelTol and confirm that as the tolerance gets smaller. For planetary motion. 12. and said that a good model lends itself to analysis and simulation. the difference between the energy at the beginning and end. and . it turns out that ode45 does not.1): options = odeset(’RelTol’.5 Conservation of Energy 145 Exercise 12. Modify it so it shows one day of simulated time in 0. options). Exercise 12.001.2 I defined a “model” as a simplified description of a physical system. M] = ode45(@rate_func. and computes the total energy (kinetic and potential) of the system for each estimated position and velocity. The name of the option is RelTol for “relative tolerance. 12. 1e-5).12.001 seconds of real time—one revolution should take about 4. Your function should also compute the relative change in energy.” so it does more work to make the errors smaller. W. [0:step:end_time].6 Write a function called energy func that takes the output of your Jupiter simulation. as a percentage of the starting energy. Smaller values make ode45 less “tolerant.” The default value is 1e-3 or 0.

Sometimes called “length. the duck model in Exercise 6. used to indicate direction.4 offers a possible explanation of the dynamics of animal populations systems in terms of interactions between predator and prey species.146 Vectors as vectors makes predictions that are good enough for the intended purpose. velocity. At the other end of the spectrum. global climate models try to predict the weather tens or hundreds of years in the future.” but not to be confused with the number of elements in a MATLAB vector. prediction: Some models make predictions about physical systems.6 you were asked to design the golf swing with the perfect combination of launch angle. As a simple example. dot product: A scalar product of two vectors.2 predicts the level a duck floats at. the LotkaVolterra model in Section 9. explanation: Models can answer scientific questions. design: Models are useful for engineering design. and direction perpendicular to both. we have seen a number of examples. For example. The exercises at the end of this chapter include one model of each type. acceleration or force. For example. especially for testing the feasibility of a design and for optimization. cross product: A vector product of two vectors with norm proportional to the norms of the vectors and the sine of the angle between them. norm: The magnitude of a vector. in Exercise 11. 12. now we can say more about what models are for. proportional to the norms of the vectors and the cosine of the angle between them. Since then.7 Glossary spatial vector: A value that represents a multidimensional physical quantity like position. projection: The component of one vector that is in the direction of the other (might be used to mean “scalar projection” or “vector projection”). The goals of a model tend to fall into three categories. unit vector: A vector with norm 1. . velocity and spin.

In a binary system. Wiegert.11 A binary star system contains two stars orbiting each other and sometimes planets that orbit one or both stars4 .10 You have been asked to design a new skateboard ramp. “Long-Term Stability of Planets in Binary Systems. available from http: // citeseer. one at room temperature and one boiling. html . as in Holman. If they go fast enough.” Astronomical Journal 117. and to create a physical model of the system. and P. Exercise 12. Technical and artistic display will be assessed by the usual panel of talented judges. M. Exercise 12. this one is free to pivot about a support point.J. 4 See http://en. 1999. unlike a typical skateboard ramp. they are not allowed to put their feet down while on the ramp. ist. Simulation is a useful tool for investigating the nature of these orbits. psu.wikipedia. and an animation of the result. . some orbits are “stable” in the sense that a planet can stay in orbit without crashing into one of the stars or flying off into space. Read this paper and then modify your planetary simulation to replicate or extend the results. a simulation that computes the behavior of a rider on the ramp.8 Exercises Exercise 12. which one freezes first? Hint: you might want to do some research on the Mpemba effect.A. edu/ 358720.org/wiki/Binary_star.9 If you put two identical bowls of water into a freezer.8 Exercises 147 12. Your job is to design a ramp that will allow a rider to accomplish this feat.12. the ramp will rotate and they will gracefully ride down the rotating ramp. Skateboarders approach the ramp on a flat surface and then coast up the ramp.

Sign up to vote on this title
UsefulNot useful