ENGINEERING SCIENCE INTRODUCTION TO ENGINEERING COMPUTATION AND SOFTWARE DEVELOPMENT ENGGEN131 COURSE BOOK, VOLUME 1 SC 2016 ENGGEN 131 SC Lab Sign Off Name: Username: (e.g. jsmi001) To get a lab signed off, complete ALL lab tasks before asking a tutor to check you off. Lab Tutor signature: Date: Lab 1 Lab 2 Lab 3 Lab 4 Lab 5 Lab 6 Remember: If you do not complete a lab within the allocated 2 hours you will need to complete it in your own time and have it ready to be checked off at the START of the next week. 2 MATLAB Course Manual Contents ENGGEN 131 Course Outline ....................................................................................................................... 1 Chapter 1: An Introduction to MATLAB ................................................................................................11 Chapter 2: 1D Arrays, Problem Solving .................................................................................................27 Chapter 3: Functions, Problem Solving and Debugging ..................................................................41 Chapter 4: Logical operators and conditional statements .............................................................57 Chapter 5: Loops ............................................................................................................................................79 Chapter 6: 2D and 3D Arrays ....................................................................................................................93 Chapter 7: Advanced Graphics .............................................................................................................. 113 Chapter 8: Strings....................................................................................................................................... 135 Chapter 9: Files ........................................................................................................................................... 153 Chapter 10: Linear Equations and Linear Algebra ......................................................................... 167 Chapter 11: Differential Equations and "Function" Functions .................................................. 181 Laboratory 1: An introduction to MATLAB ....................................................................................... 191 Laboratory 2: Debugging, Functions and Problem Solving ......................................................... 213 Laboratory 3: Logical Operators, Conditional Statements and Loops..................................... 227 Laboratory 4: Graphics and Image Processing ................................................................................ 247 Laboratory 5: Strings and Files ............................................................................................................. 257 Laboratory 6: Linear equations and differential equations ....................................................... 265 Appendix: Style Summary ....................................................................................................................... 275 Appendix: Flowcharts............................................................................................................................... 277 Appendix: MATLAB Command Reference ......................................................................................... 281 The complete course outline is available at canvas.auckland.ac.nz Please report any typos you spot by posting to the "Typos" thread on the class Piazza forum. The forum is accessible via Canvas. ENGGEN 131 Course Outline This course is divided into two halves. The first half will introduce you to programming using the software package MATLAB. The second half will introduce you to the high level programming language C Summary Information Semester Second semester, Year 1, 2016 Points value 15 points Pre-requisites No prior programming knowledge is assumed. It is however strongly recommended that you have taken a first year university mathematics course. Staff Course Coordinator Peter Bier Room 231, level 2, 70 Symonds St (Uniservices House) Email: p.bier@auckland.ac.nz Phone: 3737599 xtn. 83014 Matlab Lecturers Prof. Rosalind Archer (Lecturer for weeks 1-3) Email r.archer@auckland.ac.nz Prof. Nic Smith (Lecturer for weeks 1-3) Email np.smith@auckland.ac.nz Peter Bier (Lecturer for weeks 4-6) Email: p.bier@auckland.ac.nz C Lecturer Paul Denny (Lecturer for weeks 7-12) Room 465, level 4, Computer Science Building (Building 303) Email: p.denny@auckland.ac.nz Phone: 3737599 xtn. 87087 Teaching Assistant Dustin Philip Email: dphi038@aucklanduni.ac.nz Class schedule Each week there are three hour long lectures plus a two hour lab. Learning continuity In the event of an unexpected disruption we undertake to maintain the continuity and standard of teaching and learning in all your courses throughout the year. If there are unexpected disruptions the University has contingency plans to ensure that access to your course continues and your assessment is fair, and not compromised. Some adjustments may need to be made in emergencies. You will be kept fully informed by your course co-ordinator, and if disruption occurs you should refer to the University Website for information about how to proceed. 1 Course content Calendar description Introduction to problem solving in engineering through the use of the software package MATLAB, and the high level programming language C. Learning Objectives Introduction to Matlab: Comprehend how to write and execute a simple Matlab program that takes user input and displays output. Matlab Functions, Problem Solving and Debugging: Application of a problem solving methodology to develop an algorithm and then translate it into Matlab code. Application of debugging skills to locate and fix software bugs. Application of writing of software functions. Matlab Logical operators, conditional statements and loops: Application of Matlab programming skills to control program flow by using logical operators, conditionals and loops. Matlab graphics and image processing: Application of Matlab programming to produce plots of 1D and 2D data. Application of Matlab programming to manipulate and process images. Matlab strings and files: Application of Matlab programming to allow for file input/output and the manipulation of string data. Matlab tools for solving linear algebra problems and differential equations: Application of Matlab programming to: solving engineering linear algebra problems, solving first order differential equations and programming to write functions that can use other functions as inputs. An introduction to visual studio: Comprehend the C compilation process. Comprehend why there are different data types and explain how this effects values assigned to them. Application of C programming to write and execute programs. C Conditionals, Loops, Arrays and Structures: Application of C programming to: control program flow by using logical operators, conditionals and loops, create and manipulate structures and manipulate images via library routines. C file IO and Functions: Application of C code to open a file, read or write formatted data to it and then close it. Application of C code to writing functions. C pointers and strings: Application of C programming to create and manipulate string data. Application of C programming to create and manipulate pointers, including an understanding of how pointers are used with arrays. Recursion and software engineering: Application of C programming to write recursive functions. Define software engineering. 2 Inclusive learning Students are urged to discuss privately any impairment-related requirements face-to-face and/or in written form with the course convenor/lecturer and/or tutor. Learning Resources Electronic learning resources: Files required for the labs, lecture recordings and pdfs of the course manuals will all be available from https://canvas.auckland.ac.nz The class discussion forum can be accessed via Canvas or directly at: https://piazza.com/aucklanduni.ac.nz/semester22016/enggen131/home Hardcopy learning resources The recommended textbook for the Matlab half is “A Concise Introduction to Matlab” by William J Palm III (1st edition). This is available for purchase from the university book shop and is also available on desk copy from the Engineering Library. Note that “Introduction to MATLAB 7 for Engineers” by William J Palm III (2nd edition) contains essentially the same material (plus some extra chapters). It is also available on desk copy from the Engineering Library. Recommended readings for both texts are given at the end of each chapter. Software (Programming environments) In the labs, we will be using two pieces of software: • • MATLAB (for the first half of the course) Microsoft Visual Studio (for the second half of the course). You may wish do download and install these two pieces of software so that you can work from home. Detailed instructions on how to do this are provided on Canvas. Please note that a student license for MATLAB costs around $60 to $100 (depending on what version you opt for) whereas it is possible to download Visual Studio for free. 3 Assessment information Academic integrity The University of Auckland will not tolerate cheating, or assisting others to cheat, and views cheating in coursework as a serious academic offence. The work that a student submits for grading must be the student's own work, reflecting his or her learning. Where work from other sources is used, it must be properly acknowledged and referenced. This requirement also applies to sources on the world-wide web. A student's assessed work may be reviewed against electronic source material using computerised detection mechanisms. Upon reasonable request, students may be required to provide an electronic version of their work for computerised review. All students enrolled at the University of Auckland are required to complete a compulsory Academic Integrity course, usually in their first semester/year of enrolment. This can be accessed via https://www.academicintegrity.auckland.ac.nz/ The University of Auckland’s full guidelines on procedures and penalties for academic dishonesty are available online (the academic integrity site above includes a link). Coursework Labs (12% of final grade). There are weekly labs (twelve in total). Each lab is worth 1% of your final grade. • Labs 1-6 cover Matlab programming. • Labs 7-12 cover C programming. Assignments (4% of final grade). There are two short assignments, each worth 2% of your final grade. Assignment 1 (on Matlab) requires students to contribute to a repository of multichoice questions. You will be assigned to either group A or group B. • Assignment 1 Group A must submit their questions by Sunday 7th August. • Assignment 1 Group B must submit their questions by Sunday 21st August. • Assignment 2 (on C programming) is due Tuesday 4th October. Projects (24% of final grade). There are two large projects, each worth 12% of your final grade. • Project 1 (on Matlab programming) is due Sunday 11th September. • Project 1 also includes a peer review component which is due Sunday 18th September • Project 2 (on C programming) is due Monday 17th October.. A late penalty will be applied to projects submitted after the due date. • • Projects submitted up to 24 hours late will have a 25 percent penalty applied. Projects submitted between 24 and 48 hours late will have a 50 percent penalty applied. Late projects will not be accepted beyond 48 hours past the due date. 4 Tests (10% of final grade). There are three multichoice tests in total. Test 1 and 2 are on Matlab. Your BEST result from the two Matlab tests counts towards 5% of your final grade. Test 3 covers C programming and is worth 5% of your final grade. Test details are as follows: • • • Test 1 (Matlab). 30 minute test held on the evening of Thursday 11th of August, covering material taught in the preceding weeks. Assemble at 6.15pm. Test 2 (Matlab). 30 minute test held during your usual lecture time on Wednesday 24th August, covering material taught since the start of semester. Assemble outside your usual lecture theatre. Test 3 (C). 90 minute test held on the evening of Thursday 6th of October, covering C material taught in the proceeding weeks. Assemble at 6.15pm. Exam (50% of final grade) The final exam contributes 50% to your final grade. Half the exam is on MATLAB and half the exam is on C, with an emphasis on the material covered in the labs and the project. Final Mark Calculation Neither internal coursework nor exam may raise the average by more than 10 percentage points. Your final mark will be calculated as the minimum of: • • • Coursework % + 10 Exam % + 10 ½ x (Coursework % + Exam %) For example, if you scored 100% in your internal and 40% in your exam your final mark would be the minimum of the values [110, 50, 70]. This would give you a final mark of 50%. DO YOUR OWN COURSEWORK, otherwise you will not know what you are doing in the exam and you will fail. Assessment summary The assessment for all aspects of the course are as follows: Assessment MATLAB C Total Labs 6% 6% 12% Tests 5% 5% 10% Assignments Projects Course work total Exam 2% 2% 12% 12% 25% 25% 25% 25% 5 4% 24% 50% 50% IMPORTANT: we have automated software that checks for copying, do NOT cheat, you will be caught. If a student provides work to another student who then copies part of it then at a minimum both students will receive a mark of zero for that item and your names will be recorded in a misconduct register held by the Faculty. 6 Timetable The following timetable gives an overview of the MATLAB half of the course. Week Lectures Week 1 Chapter 1 Introduction to MATLAB Chapter 2 Problem Solving and 1D Arrays Lab 1 Introduction to MATLAB Week 2 Chapter 3 Functions, Workspaces and Debugging Chapter 4 Logical Operators and Conditional Statements Lab 2 Functions, Problem Solving and Debugging. Week 3 Chapter 5 Loops Chapter 6 2D and 3D arrays, Image Processing Lab 3 Logical Operators, Conditional Statements and Loops Assignment 1 Group A Complete by Sunday 7th August Week 4 Chapter 7 Advanced Graphics Chapter 8 Strings Lab 4 Graphics and Image Processing Test 1 6.15pm Thursday 11th August Week 5 Chapter 9 Files Chapter 10 Linear Equations and Linear Algebra Lab 5 Strings and Files Assignment 1 Group B Complete by Sunday 21st August Week 6 Chapter 11 Differential Equations Test Lab 6 Linear Equations and Differential Equations Test 2 In class Wednesday 24th August Midsemester break Lab Assessment Project 1 Complete by Sunday 11th September Week 7 Project 1 peer review Complete by Sunday 18th September 7 Laboratories You will attend one 2 hour laboratory every week. They are a key part of the course. A lead tutor and graduate student tutors will be available to help you with lab work and answer your questions. Lab resources You should bring this manual to every lab for the first half of the course. The lab material is contained at the rear of this course manual. In addition, labs will require you to view the class Piazza forum and download files from Canas. You may need to refer back to sections of the manual covered during lectures when attempting lab tasks. Lab attendance You will need to attend your allocated lab session (the one you enrolled into on SSO) in order to get your lab tasks signed off. It is recommended you arrive on time to make the most of the two hour lab period (where you have access to tutor help, if required). Lab tasks The lab tasks are designed to be worked through in order. You will receive credit for completing the compulsory lab tasks and getting them signed off (1% per lab). If you do not finish the tasks within your two hour lab then the expectation is that you will complete the lab tasks during the week, so that they are ready for sign off at the START of the next lab. Lab sign off Once you have completed all required tasks for a lab you should open all required script files and then show them to one of your tutors so that you can get the lab signed off in your book (we record sign off at the front of your book and on our record sheets). As well as checking your code your tutors will check that you understand what you have written by asking you a few questions. Note that you will NOT get your lab signed off unless: • You have completed ALL compulsory lab tasks for that lab • You have adequately commented ALL script files you wrote for the lab • You can demonstrate that you understand the code you have written It is important you keep up with the course material. If you don’t complete a lab in the allocated week, you will need to work on the material in your own time, so that it is ready to get checked off at the START of your next week’s lab session. Tutors will only sign off the previous week’s lab during the first hour of the following week’s lab session. You may also get signed off one week ahead. As an example, you could get signed off for the Lab 3 tasks at any time during your week two lab session, any time during your week three lab session or during the first hour only of your week four lab session. 8 Lab locations Please check SSO to find out which lab room you are enrolled in. If you are unsure where your lab is, refer to the map below and allow plenty of time to get to your first lab. • • • Engineering Level 3 (401.311/401.312 and 401.307) - near Student Services Stall Engineering Level 4 (403.409) - Symonds St level Science Teaching Labs (303S.B75, 303S.G75, 303S.175, 303S.279) 303 labs 401.311/ & 401.307 403.409 9 10 Chapter 1: An Introduction to MATLAB MATLAB is a an extremely useful piece of mathematical software that is used by engineers to help them solve problems. MATLAB is short for MATrix LABoratory. MATLAB can be used as an advanced calculator and graphing tool for engineering computation. It can also be used as a programming language to develop software and it has great support for manipulation of matrices. Learning outcomes After working through this chapter, you should be able to: • • • • • • • • Understand why you are taking this course Understand why we are teaching you MATLAB Use MATLAB as a calculator Create and use variables Write a script file Get input from the user and display output Understand the importance of commenting Write simple comments Why learn to program? Computers are important tools for modern-day engineering. Computers allow engineers to perform time consuming tasks quickly and hence solve a wide range of interesting problems. Computers also make it possible for us to visualise our models, allowing us to interpret our results. If no existing software is able to help you solve your problem you may need to develop your own software by writing computer programs. Writing computer programs is an important skill that is relevant to all branches of engineering. Computer programs can be used to: • Solve engineering problems Visualise the solutions Image: Pressure in an oil reservoir 11 An illustration: solving equations To illustrate how important computers can be to solving engineering problems, consider the relatively simple task of solving a system of simultaneous equations. You are likely familiar with several methods for solving simultaneous equations by hand. If you have taken MM1 you will have encountered solving by both Gaussian elimination and Matrix methods. Two equations Consider the task of solving the following equations: 2x + y = 4 x − y = −1 You should easily be able to solve these by hand to get x = 1, y = 2 Three equations Consider the task of solving the following equations: 2x x +y −y +2z −z = 4 = −1 y −2z = 4 With a little more effort we can solve these by hand to get x = 1.2, y = 2.8,z = −0.6 Ten equations Now consider the task of solving the following equations: 2x1 x1 3x1 2x1 3x1 x1 x1 3x1 −x1 −x1 −x 2 +3x 2 +3x 2 −x 2 + x2 + x2 +2x 2 +2x 2 + x3 −x 3 +3x 3 −x 3 −x 3 −x 3 + x3 +3x 4 +3x 4 −x 4 +2x 4 + x4 + x4 +3x 4 + x4 +3x 4 +2x 5 +2x 5 + x5 +2x 5 +2x 5 −x 5 −x 5 +3x 5 −x 5 −x 6 + x6 +3x 6 +2x 6 −x 6 + x6 +3x 6 −x 6 +3x 6 +2x 7 −x 7 + x7 + x7 −x 7 + x7 +2x 8 +3x 9 +3x 9 +3x 9 +3x 8 +3x 8 +2x 8 + x9 −x 9 + x9 + x7 + x8 −x 8 −x 9 −x 9 + x10 −x10 + x10 + x10 +2x10 +2x10 +2x10 −x10 −x10 = 1 = 2 = 1 = 3 = 2 = 3 = 1 = 0 = −1 = 2 Could you solve these by hand? In theory it is possible but it would take a long time and you would need to be extremely careful as the chances of making a simple arithmetic error in the resulting pages of algebra is quite high. 12 Solving equations with a computer This system can be solved with relatively little effort in MATLAB. Even more equations Sometimes engineers need to solve not 10 or even 100 equations, but systems with 10,000 or 100,000 equations. This can be done very quickly using a computer. Solving systems of linear equations is a common problem in many branches of engineering, for example you will need to solve systems of linear equations for problems related to: • • • • Operations research Mechanics and dynamics Electrical Circuits Chemical reactions Quickly solving large systems of equations is just one of the many tasks that MATLAB can accomplish with very little effort from the programmer. 13 Why use MATLAB? There are a large range of different programming languages available to choose from. We have chosen to introduce you to MATLAB first for a number of reasons: • • • • MATLAB is an easy introduction language for learning how to program. MATLAB provides a “quick-and-easy” development environment. MATLAB is very useful in many engineering contexts. MATLAB is used in industry. Programming with MATLAB Programming is a transferable skill. Basic programming concepts are common to almost all programming languages. The syntax may change but is usually similar. Learning to program in MATLAB will make it much easier to pick up just about any other language. MATLAB is platform independent. You can write the software once for several different operating systems including both Windows and Mac platforms. If you rely only on the core functionality of MATLAB you will also be able to run your programs under Linux, using Octave. MATLAB can be linked to other software. For example it can be used with programs written in other popular languages such as C/C++, Java or Fortran. MATLAB in your degree In Mathematical Modelling 2 and 3 you will need to use MATLAB to solve applied mathematical models. Other courses in structural analysis, electrical circuits and systems and control also use MATLAB. In MM2, MM3 and many other courses you may like to use MATLAB to check your calculations and plot results. Many students use MATLAB to write programs for their 4th year project. MATLAB is a marketable skill Engineering job advertisements can and do mention MATLAB as a required skill. Computer programming experience is also often mentioned as a required or desirable skill. 14 MATLAB as a calculator MATLAB can be used in a wide range of ways to help you solve engineering problems. We will begin by using MATLAB as an advanced calculator. In particular we will learn: • • • To express mathematics in a form suitable for MATLAB. To use built-in mathematical functions in calculations. To use variables in calculations This is the window that appears when you start MATLAB. This is the menu bar This window shows the current directory This is the This window shows the workspace command window – we use this as our calculator Entering commands You can enter expressions at the command line in the command window and evaluate them right away. Previous command Next command >> 3 + 5 * 8 ans = 43 >> 3 * (4 + 2) ans = 18 The >> symbols indicate the command prompt, where commands are typed. 15 Mathematical Operators Operator MATLAB Algebra + + 5 + 4 = 9 − - 5 - 4 = 1 × * 5 * 4 = 20 ÷ / 5 / 4 = 1.25 ab a^b 5^4 = 625 Order of operations MATLAB follows the usual BEDMAS order of operations when performing calculations. B = Brackets E = Exponentials D = Division M = Multiplication A = Addition S = Subtraction >> 3 * 4 + 2 ans = 14 >> 3 * (4 + 2) ans = 18 Be careful using brackets - check that opening and closing brackets are matched up correctly. Built-in functions Like a calculator, MATLAB has many built-in mathematical functions. The MATLAB command reference at the rear of this manual lists some of the functions available. To call a function is simple: >> sqrt(4) ans = 2 >> abs(-3) ans = 3 Note the use of brackets around the function’s input argument. There should be no spaces between the function name and the opening bracket. Function names are case sensitive and all built-in functions should be called using lower case letters, even though MATLAB help files show the function name in capitals. You can search for and find out more about the available functions by using MATLAB’s help. 16 >> help gives command line help >> help log >> doc gives graphical user interface (GUI) help >> doc exp 17 Variables Programming Task 1.1: Task: Solution: Example: Use Matlab to convert temperatures from degrees Fahrenheit to degrees Celsius. The formula for the conversion is 5 c = ( f − 32) × 9 f = 100 ⇒ c = 37.8 f = 32 ⇒ c = 0 In algebra we use variables so calculations are easily represented. We can also use variables with MATLAB. MATLAB >> f = 100 f = 100 >> c = (f-32)*5/9 c = 37.7778 >> f = 32 f = 32 >> c = (f-32)*5/9 c = 0 You can think of variables as named locations in the computer's memory in which a number can be stored. It may help to think of your computer memory as a large set of “boxes” in which numbers can be stored. Boxes can be labeled with a variable name and the values placed in the boxes can be inspected and changed. >> a = 3 a = 3 18 Assigning variables a value The equals sign is used to assign values to variables. Variable assignment either creates the variable OR, if it already exists, changes the variable value. >> a = 2 a = 2 Assignment is always left to right: >> a = >> 3 = a ??? 3 = a | Error: … some expression Naming variables Variable names may only use alphanumeric characters and the underscore. They should not begin with a number and cannot include spaces. If using a single letter to identify a variable then use a lower case name for scalar values. We will reserve upper case letters for matrices, to be consistent with standard mathematical notation. It is a good programming practice to give variables descriptive names, so that it is possible to tell at a glance what a variable contains. If using word(s), the first letter should be lower case, and the first letter of subsequent words should be upper case: numberOfStudents = 750; taxRate = 0.33; This makes variable names easier to read. Special variables MATLAB has some special variables: • • • • • ans is the result of the last calculation pi represents π Inf represents infinity NaN stands for not-a-number and occurs when an expression is undefined e.g. division by zero i, j represent the square root of -1 (necessary for complex numbers) 19 Calculations with variables Suppose we want to calculate the volume of a cylinder. Programming Task 1.2: Task: Solution: Example: Calculate the volume and surface area of a cylinder. The formula for calculating volume of a cylinder of radius r and height h is v = π r 2h The formula for surface area is a = 2π rh + 2π r 2 r = 5, h = 10 ⇒ v = 785.34, a = 471.24 Radius and height are stored as variables in memory with sensible names (such as radius and height). >> radius = 5 radius = 5 >> height = 10 radius = 10 We can then calculate the volume in MATLAB as follows: >> volume = pi * radius^2 * height volume = 785.3982 Visually: Script Files You can save a sequence of commands so that you may reuse them. To save commands we place them in a script file. When a script file is run each line of the file is executed in turn. This has the same effect as typing each line in the command window. Script files need to be saved with the file extension “.m”. Script file names can only use letters, numbers and the underscore character. Eg vol_surf.m is a valid name. There are some important limitations to be aware of when naming your files. 20 File names should NOT: • include spaces • start with a number • use the same name as an existing command If you do any of the above you will get unusual errors when you try and run your script. MATLAB includes an editor for working on script files: Once you have saved a script file you can can run the sequence of commands from the file by typing the filename, without the “.m” extension. E.g. >> vol_surf radius = 5 height = 10 volume = 785.3982 area = 471.2389 >> Commenting Lines that start with the % character are not executed by MATLAB. This means you can add comment lines to your file which explain the purpose of various commands. Comments are VERY IMPORTANT. They help people understand what the code is doing and why. Your code may make sense to you now but it is important to realise that you may not be the only person who needs to understand your code. Most code written in the real world will need to be modified by either yourself or someone else at some point in the future. These modifications are usually done to improve performance, add extra functionality or fix errors. A program written months or years ago can be very hard to understand without good commenting, even when you were the person who originally wrote it! Note: All script files MUST be commented. Lab tasks will NOT be checked off if you have not commented your files. 21 Header comments Every script file should have a header comment at the top of the file which indicates the purpose of the file and who wrote it. % vol_surf calculates volume and surface area of a cylinder % for a cylinder of radius 5 and height 10 % Author: Andrea Raith Including the author’s name is important as if someone else is trying to use your code they then know who to ask for help. MATLAB uses this header comment to generate help. Typing help and your filename will display your header comments. E.g. >> help vol_surf vol_surf calculates volume and surface area of a cylinder for a cylinder of radius 5 and height 10 Author: Andrea Raith Other comments You should add comments to any sections of code which are not straight forward to understand. This may include comments that explain what is being done or relate to how to use MATLAB functions you are not very familiar with. Aim to write useful comments. The following is an example of useless commenting and poor choice of variable names: % x % y set x to 100 = 100 calculate y = (x – 32) * 5 / 9 The above comments do not really help you understand anything about the code. We can already see that x is being set to 100 and that y is being calculated. We are also given no clues what x and y represent. The following is far more useful and actually helps a reader understand what the code is doing: % Convert 100 degrees Fahrenheit to Celsius f = 100 c = (f - 32) * 5 / 9 % Convert 32 degrees Fahrenheit to Celsius f = 32 c = (f - 32) * 5 / 9 From these comments it is obvious what the variables c and f are meant to represent and it is clear what the calculation of c is achieving. 22 The complete script file is as follows: % ConvertTemp converts 100 and 32 degrees Fahrenheit (f) to % Celsius (c) % Author: Andrea Raith % Convert 100 degrees Fahrenheit to Celsius f = 100 c = (f - 32) * 5 / 9 % Convert 32 degrees Fahrenheit to Celsius f = 32 c = (f - 32) * 5 / 9 Basic user interaction: Input/Output Script files are more useful if they can interact with users, prompting them to enter values and then displaying relevant results. We want to be able to get input from the user and then display the appropriate output. Programming Task 1.3: Task: Solution: Example: Prompt user to enter height and width of rectangle and calculate its area. Input: Obtain user input: height (h) and width (w) The formula for rectangle area is a = h w Display calculated area h = 3, w = 4 ⇒ a = 12 This is easy to do using the built-in input and disp commands. % CalculateRectArea.m calculates the area for % a rectangle with dimensions provided by the user % Author: Spongebob Squarepants % prompt user to enter height and width height = input('Enter the height of the rectangle: ') width = input('Enter the width of the rectangle: ') % note the semi-colon on the end of the line % this supresses the output of the command, the command is % executed but the result of the calculation is not displayed area = height * width; disp('The area of the rectangle is') disp(area) Note that the input function takes as an argument a string of characters enclosed in single quotes. This string of characters could include words, numbers and punctuation characters. When MATLAB executes an input command the entire contents of this string are printed to the screen and then the computer will wait for the user to type something and press enter. 23 The disp function can either take a string of characters enclosed in single quotes OR a variable. If it is called with a string of characters the characters enclosed in quotes are printed to the screen. If it is called with a variable then the value of the variable is displayed. When this program is run it produces the following output: >> CalculateRectArea Enter the height of the rectangle: 3 height = 3 Enter the width of the rectangle: 4 width = 4 The area of the rectangle is 12 Chapter 1 Summary Program We can now write commented simple script files that get input from a user, use MATLAB as a calculator and then display results back to the user. For example, the following program calculates the final mark for a 131 student based on their internal course work and exam marks. Programming Task 1.4: Task: Solution: Example: Prompt user to enter 131 internal course work and exam mark. Calculate final mark and display it. Input: Obtain user internal coursework and exam mark Your final mark will be calculated as the minimum of: • Coursework % + 10 • Exam % + 10 • ½ x (Coursework % + Exam %) Display final mark c = 38, e = 62 ⇒ f = 48 c = 60, e = 55 ⇒ f = 57.5 24 Command window solution (without prompting user for input and nice output): >> c = 90; >> e = 20; >> f = min([c + 10, e + 10, (c + e) / 2]) f = 30 Script with comments: % % % % Calculate131Result.m calculates the final result for a student with an internal course work and final exam mark entered by the user Author: Peter Bier % get course and exam mark from user c = input('Please enter the course work mark: ') e = input('Please enter the exam mark: ') courseAverage = 1 / 2 * (c + e) % Neither coursework nor exam mark may raise the average by % more than 10 percent, so the course work and exam marks % set an upper limit on the possible mark that can be achieved % calculate upper limits cmax = c + 10 emax = e + 10 % the final mark cannot be above either of the upper limits, % so it will be the minimum of the course average and the % two upper limits % We use the min function to calculate the minimum of these % three values. The input argument for the min function is % a list of values enclosed in square brackets and separated % by commas. % note we have supressed the output of the min function % calculation with a semi-colon on the end final_mark = min([courseAverage, cmax, emax]); disp('Final mark is ') disp(final_mark) 25 An example of running this program is shown below (user input is in bold): >> Calculate131Result Please enter the course work mark: 38 c = 38 Please enter the exam mark: 62 e = 62 courseAverage = 50 cmax = 48 emax = 72 Final mark is 48 Recommended reading Chapter 1 An Introduction to Matlab Topic Using Matlab as a calculator Menus and the toolbar Script Files Input/Output Help Help Introduction to Matlab 7 for Engineers (2nd ed) Section Pages 1.1 6-17 A Concise Introduction to Matlab (1st ed) Section Pages 1.1 2-13 1.2 1.4 1.4 1.5 1.2 1.4 1.4 1.5 1.6 17-19 29-32 36-38 38-43 26 13-15 23-26 26-28 28-31 32 Chapter 2: 1D Arrays, Problem Solving In this chapter we introduce the basics of working with 1D arrays. An array is a variable that can hold multiple values. Recall that the reason we are learning how to develop software is so that we may write computer programs to solve problems. When confronted with a new problem it can be tricky to know how to approach it so we will outline a simple five step method that can be used to help develop a computer program to solve a problem. Learning outcomes After working through this chapter, you should be able to: • • • • • • Explain the concept of a 1D array Create and manipulate 1D arrays Draw plots of 1D arrays Use 1D arrays in programs Outline the five steps for problem solving Use the five steps to solve a problem 1D arrays So far we have dealt with MATLAB variables that hold a single value. We can also create MATLAB arrays that hold multiple values. Arrays are useful for storing lists of values (1D arrays) or tables of values (2D arrays). They are also ideal for representing vectors (1D arrays) and matrices (2D arrays) If a scalar variable (for a single value) is like a cardboard box, then a 1D array variable is like a filing cabinet. Each drawer of the filing cabinet can store a value. >> B=[3, 7, 2, 1] B = 3 7 2 1 27 Programming Task 2.1: Task: Using an array of daily temperature lows and highs over a week understand how to use and manipulate arrays. Creating 1D arrays To create an array we can assign a list of values to a variable. The values need to be enclosed by square brackets and separated by a comma or a space. >> dailyHighs = [10, 11, 13, 12, 19, 18, 17] dailyHighs = 10 11 13 12 19 18 17 >> dailyLows = [3 2 dailyLows = 3 2 4 1 5 6 4 4 1 5 6 4] Accessing array elements You can access or change a particular array element using round brackets. >> dailyHighs dailyHighs = 10 11 13 12 19 18 >> dailyHighs(2) ans = 11 >> dailyHighs(2) = 14 dailyHighs = 10 14 13 12 19 18 17 17 Extending arrays You can add extra elements by creating them directly using round brackets or by concatenating them (adding them onto the end). >> dailyHighs dailyHighs = 10 14 13 12 19 18 17 >> dailyHighs(8) = 12 dailyHighs = 10 14 13 12 19 18 17 12 >> dailyHighs = [dailyHighs, 14] dailyHighs = 10 14 13 12 19 18 17 12 14 28 Default array elements If you don’t assign array elements, MATLAB gives them a default value of 0 >> dailyHighs dailyHighs = 10 14 13 12 19 18 >> dailyHighs(12) = 10 dailyHighs = 10 14 13 12 19 18 17 12 14 17 12 14 0 0 10 Using arrays in programming The main use for arrays in programming is data storage. Rather than creating a large number of variables to store related values, we can use a single array to store the values. Some examples of where you would use an array for data storage are as follows: • • • keeping track of the trajectory of a basketball storing the stress along a beam storing pressures inside the heart Using Arrays in MATLAB MATLAB was originally written for use with arrays and subsequently it is very good at dealing with them. MATLAB provides lots of special array functionality to make it easier to create and manipulate arrays. Using arrays and MATLAB functions allows repetitive calculations to be done quickly. It also allows us to write compact programs. Automatic 1D Arrays There are a number of ways to create 1D arrays automatically. The colon operator and the linspace function are particularly useful Using the colon operator, you can specify an array that contains a sequence of increasing or decreasing values. A start and stop value are required. >> x = 0:10 x = 0 1 2 3 4 5 6 7 8 9 10 The colon operator creates an array of elements beginning with the start value and ending with the stop value. By default the values will increase by a step size of 1. You can specify a different step size if you prefer as follows: >> x = 0:2:10 x = 0 2 4 6 8 10 29 The linspace function is a convenient function for creating an array that contains a sequence with a specific number of elements. The input arguments for the linspace function are the start value, stop value and number of elements to create. When passing inputs to a function the order is important, so you must pass in first the start value then the stop value and finally the number of elements: >> t = linspace(0,10,7) t = 0 1.6667 3.3333 5.0000 >> 6.6667 8.3333 10.0000 The above command has created a list of 7 points spaced evenly between 0 and 10. Array Slicing It is possible to access several elements of an array at once using array slicing. Instead of using a single value to index the array we can use another array. For example to pull out the 2nd, 4th and 6th elements of the dailyHighs array we can do the following: >> dailyHighs dailyHighs = 10 14 13 12 19 18 >> dailyHighs([2,4,6]) dailyHighs = 14 12 18 17 12 14 0 0 10 The colon operator can be particularly handy when you wish to pull out a sequential slice of an array: >> dailyHighs dailyHighs = 10 14 13 12 19 >> dailyHighs(3:5) dailyHighs = 13 12 19 18 17 12 14 0 0 10 In the above example we are displaying the 3rd, 4th and 5th elements, as the colon operator has been used to create the array [3, 4, 5]. Array Arithmetic Arrays of the same length can be added or subtracted to each other. Arrays can also be multiplied by scalar constants. >> dailyHighs = [10, 11, 13, 12, 19, 18, 17]; >> dailyLows = [ 3, 2, 4, 1, 5, 6, 4]; >> dailyRange = dailyHighs - dailyLows dailyRange = 7 9 9 11 14 12 13 >> dailyAverage = 0.5 * (dailyHighs + dailyLows) dailyAverage = 6.5 6.5 8.5 6.5 12 12 10.5 30 It is possible to multiply the elements in one array by the corresponding elements in another array. Here is an example of element by element multiplication: >> heights = [9, 8, 4, 6]; >> widths = [3, 2, 1, 5]; >> areas = heights .* widths areas = 27 16 4 30 Note the use of the dot before the multiplication symbol. The dot operator means MATLAB will perform element by element multiplication rather than attempting matrix multiplication. Element by element division is also available: >> heights = [9, 8, 4, 6]; >> widths = [3, 2, 1, 5]; >> ratios = heights ./ widths ratios = 3 4 4 1.2 It is also possible to raise every number in an array by a particular power, using element by element exponentiation. >> heights = [9, 8, 4, 6]; >> square = heights.^2 square= 81 64 16 36 Again notice the use of the dot operator. A common error is to forget to use a dot when manipulating arrays. If you leave the dot off then MATLAB will attempt to do Matrix multiplication or exponentiation and will generate an error. The error is because MATLAB is attempting a matrix multiplication of the two vectors, which is not valid. >> heights = [9, 8, 4, 6]; >> widths = [3, 2, 1, 5]; >> areas = heights * widths Error using * Inner matrix dimensions must agree. 31 Array Functions Standard mathematical functions (sin, cos, exp, log, etc) can apply to arrays as well as scalars. This has the same effect as applying the function to each of the elements in turn. >> x = [1, 2, 3]; >> y = sin(x); y is now [sin(1), sin(2), sin(3)] When writing functions later in the course remember that your input variables might be arrays The following example shows how we can use the sin function on an array to produce a plot of this function. >> x = linspace(0, 2*pi,9) x = 0 0.7854 1.5708 2.3562 3.1416 6.2832 >> y = sin(x) y = 0 0.7071 1.0000 0.7071 0.0000 0.0000 >> plot(x,y) The result of running this code is the following plot: Notice that the curve is not very smooth as we have only used 9 points. If we increase our number of points we get a smoother curve: 32 3.9270 -0.7071 4.7124 -1.0000 5.4978 -0.7071 We have been a bit naughty leaving our graph unlabelled. You should give all graphs a title and label the axes. Fortunately this is very easy in MATLAB. We simply use the title, xlabel and ylabel functions, passing in the labels between single quotes: >> title('y = sin(x)'); >> xlabel('x values'); >> ylabel('y values'); Special Array Functions Some functions are specialised for use with 1D arrays: • • • • length(array) gives the number of elements in array min(array) gives the minimum value in array max(array) gives the maximum value in array sum(array) gives the sum of values in array 33 Five steps for problem solving There are many different problem solving methodologies available. The following five steps provide a simple framework which can help you approach a problem. 1. 2. 3. 4. 5. State the problem clearly Describe the input and output information Work the problem by hand (or with a calculator) for a simple set of data Develop a solution and convert it to a computer program Test the solution with a variety of data We will be using these five steps through out this course. Problem solving worked example Programming Task 2.2: Task: Write Matlab code to compute the distance between two points in a plane, where the points are given by the user and the result should be displayed to the user. Solution: Detailed working shown below. Example: Detailed working shown below. We want to compute the distance between two points in a plane Step 1: State the problem clearly Compute the straight-line distance between two points in a plane. Step 2: Describe the input and output information Our inputs are the information given that we require to solve the problem. Note that sometimes we will be given irrelevant information, so not all given information may be required. Our outputs are the values we need to compute. It is often helpful to draw an I/O diagram. I/O = Input/Output 34 Step 3: Work the problem by hand Working the problem by hand is a very important step. Use a calculator if necessary. Don’t skip this step, even for a simple problem. If you cannot do this step: • Read the problem again • Consult reference material • Diagrams can be useful Working the problem by hand will help you understand what steps need to be taken to solve the problem. It will also give you a known solution value for a simple data set, which you can use later to test your program. distance = (side1 ) 2 + (side 2 ) 2 = (6 − 2) 2 + (4 −1) 2 = 4 2 + 32 = 16 + 9 = 25 =5 Step 4: Develop a solution and convert it to a computer program Decompose the problem into a set of steps and write pseudocode or a flowchart for code. Then write the code. Simple problems give simple steps. Complex problems give complex steps. If we are dealing with a complex problem we still decompose the problem into a series of steps. Each complex step may also require the problem solving process. We will discuss how to create pseudocode and flowcharts for complex problems later in the course. Pseudocode 1. 2. 3. 4. Get x- and y-values for two points Compute length of two sides of right angle triangle generated by points Use hypotenuse calculation to get distance Display the distance 35 Computer Program script file % CalculateDistance.m calculates the distance between two % points p1 and p2 on a plane % get x and y values for x1 = input('Please enter y1 = input('Please enter x2 = input('Please enter y2 = input('Please enter two the the the the points x coord y coord x coord y coord of of of of point point point point 1: 1: 2: 2: '); '); '); '); % compute length of two sides of right angle triangle % generated by points side1 = x2 - x1; side2 = y2 - y1; % Use hypotenuse calculation to get distance d = sqrt(side1^2 + side2^2); % Display the distance disp('The distance between the two points is'); disp(d); Step 5: Test the solution with a variety of data Test using hand worked example. Also test with other data. We need to verify that our code works correctly by testing it with a range of data. >> CalculateDistance Please enter the x coord Please enter the y coord Please enter the x coord Please enter the y coord The distance between the 5 of point 1: 2 of point 1: 1 of point 2: 6 of point 2: 4 two points is >> CalculateDistance Please enter the x coord Please enter the y coord Please enter the x coord Please enter the y coord The distance between the 1.4142 of point 1: 0 of point 1: 0 of point 2: 1 of point 2: 1 two points is 36 Space for notes 37 Chapter 2 Summary Program We can now write programs that use 1D arrays and apply the five steps of problem solving. Programming Task 2.3: Task: Implement the rectangle method to calculate an approximate value of the integral: π /4 ∫ sin2 (x) − cos2 (x)dx . 0 Prompt the user for the number of points to use in the approximation Solution: Left to reader Example: Left to reader The following program calculates an approximate value for the integral ∫ π /4 0 sin 2 (x) − cos2 (x)dx by using the rectangle method. % % % % % % IntegrateWithRectangleMethod.m calculates an approximate value for the integral of sin(x)^2 - cos(x)^2, between the limits 0 and pi/4. The rectangle method is used, ie A = h(y_1 + y_2 + ... + y_(n-1) ) Author: Peter Bier % get number of points to use to represent the function over % the specified range n = input('Please enter the number of points to use: '); % set up a range of x values from 0 through to pi/4 x = linspace(0,pi/4,n); % calculate the value of the function for each x value y = sin(x).^2 - cos(x).^2; % determine the width of the rectangles we will use to % approximate the area h = x(2) - x(1); % calculate area of all the little rectangles % notice we drop the last y value by using array slicing rectangles = h * y(1:n-1); % sum all the little rectangles to get our area approximation area = sum(rectangles); % display the area value disp('The approximate value of the definite integral is'); disp(area); 38 Some examples of this program running are given below (user input is in bold): >> IntegrateWithRectangleMethod Please enter the number of points to use: 10 The approximate value of the definite integral is -0.54236 >> IntegrateWithRectangleMethod Please enter the number of points to use: 1000 The approximate value of the definite integral is -0.50039 It can be shown analytically that the solution is -0.5, so our approximation is pretty good. Recommended reading Chapter 2 1D Arrays, Problem Solving Topic Arrays Arrays Element by element operations Problem Solving Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 1.3 2.1 2.3 Pages 19-20 70-81 83-97 Section 1.3 2.1 2.3 1.7 52-60 39 Pages 16-17 38-48 49-57 40 Chapter 3: Functions, Problem Solving and Debugging MATLAB has many built-in functions, such as the trigonometric functions and the functions for processing arrays that we have already met. The MATLAB command reference appendix lists more of the built-in functions available. In addition we can define our own functions in a function file and use them in just the same way as the built-in functions. Writing functions is a key part of software development and will allow you to write code that is shorter, easier to understand and easier to maintain. Learning outcomes After working through this chapter, you should be able to: • • • • • Explain the concept of a function Call functions from your own programs Define your own functions Examine the function and command workspaces Debug script files and functions What is a function? A function is one of the basic building blocks of software development. Generally a function takes some input value(s), processes them and returns some output value(s). We are already familiar with mathematical functions, which take an input value and transform it into an output value. You will have encountered the following notation for mathematical functions: y = f (x) The function f takes an input value x and returns an output value y. We will also refer to the input value as the argument of the function f. As we have already seen, MATLAB functions use the same notation when called. Mathematical functions: y = sin(x) y = ln(x ) y= x MATLAB functions: y = sin(x) y = log(x) y = sqrt(x) 41 Here are a few more examples of some functions you have already encountered: largestValue = max(x) y = exp(x) a = linspace(-pi, pi, 10) Note that the linspace function takes not one but three input arguments. It is possible for a function to have many input arguments. Depending on the function the input argument(s) may be scalars or arrays. It is also possible for a function to have no input arguments, eg the following function can be called to return a random number between 0 and 1: x = rand() Why use functions? There are several excellent reasons for using functions. Functions enable us to use a “divide and conquer” strategy. A complex programming task can be broken into smaller manageable tasks, with a function written for each task. The functions do not even need to be written by the same person, allowing several people to work on the same project at the same time. Functions allow us to reuse code. The same function may be useful for many problems Rather than repeating the same lines of code several times in order to do a common task, we can write a function to do that task and then simply call it. This not only saves us from writing lots of extra code, it enables us to write easier to understand programs. Functions make code easier to maintain. A function has well defined behaviour. We know that given certain inputs it should return certain outputs. It is easy to check that the right outputs are being returned for possible inputs. If there is a problem with our code we can test each function to help us pinpoint the piece of problem code. Functions allow us to hide implementation. Once a function has been written we don't need to look at its code to use it. The only interaction is via inputs and outputs. How the function is written (the implementation) is hidden inside the function. Behaviour of a function • • • Functions should be well commented (users must be able to find out how a function works) Functions should be well defined (given inputs should give known outputs) Functions should be well tested (inputs should always give correct outputs) 42 Calling functions We can call functions from the command line or a script file. In either case they are called in the same way. To call a function we need to know the name of the function, what input(s) it takes and what output(s) it returns. Inputs can be either numbers or variables. Eg: y = sin(3); y = min([3, 5, 1]) x = 3; y = sin(x); a = [3, 5, 1] y = min(a) For built-in functions the information we need to call the function can be found using the MATLAB help. This is very handy when we meet a new function and need to learn how to use it for the first time. Let's look at the size function for arrays: Function input(s) Function output(s) 43 After reading through the help we now have some idea of how the size function works. We could call the size function to find out the size of a Matlab array. We know it takes one or two inputs and returns one or more outputs. Here is an example of a call to size to find the number of entries (columns) in array xRange: >> xRange = -2:.2:2 >> [S] = size(xRange,2) Note that the name of the function is in lower case even though the help shows it written in uppercase. Function names are case sensitive, which means that size(x), Size(x) and SIZE(x) would be interpreted as three different functions. Input argument(s) are passed to the function by placing them inside the parentheses following the function name. If there is more than one argument we separate them by commas. Note that there is no space between the function name and the opening parentheses. Also note that the order of the input arguments is very important. When calling a function with several inputs it is the order of the arguments that is used to tell which is which, rather than the name. The input arguments do NOT need to have the same name as those shown in the help file. We usually assign the output of a function to a variable so that it can be used. Some functions return more than one output value. If more than one variable is returned we assign the output variables by using a list of variables inside square brackets. The output arguments do NOT need to have the same name as those shown in the help file. If there is only one output we can omit the square brackets: >> y = atan(x) >> a = atan(0.5) IMPORTANT: If a function returns several outputs but you forget the square brackets and only assign the result to one variable, it will contain only the first output returned. The other outputs will be thrown away. This is a common programming error that beginner programmers make. Some functions print information to the screen or draw images on the screen rather than returning a value. In this case there is no need to store the output of the function as a variable: >> plot(x,y) >> disp('Hello') 44 Writing functions Let’s start by writing a very simple function that will square a number for us. The mathematical definition of this function looks like this: y( x) = x 2 To define this function in Matlab you could type the following into a file: function y = Square(x) y = x^2; end The keyword “function” lets Matlab know we are writing a function. Next is the output variable, which must be assigned a value before the function returns. Following the equals sign is the function name, which is case sensitive. Following the name is the function input, in brackets. The function “body” contains a single line that is used to calculate the output value for our given input. Finally the keyword “end” tells Matlab the function is finished. Once this file was saved with the name square.m we can call our function, just as we would call any other Matlab functions: >> fourSquared = Square(4) Let’s have a look at a slightly more complicated example, a function that converts polar coordinates into Cartesian coordinates (more on this later): “function” keyword Output variable(s): Must be assigned a value in function body Function name File name Input variable(s) or arguments: These are the only variables whose values the function can access End statement: signifies the end of the function Function body Can be one line or hundreds of lines 45 The PolarToCartesian function is an example of the most general case of a function, as it takes multiple input arguments and produces multiple outputs. It is possible for a function to have multiple inputs, one input or no inputs. It is also possible for a function to have multiple outputs, one output or no outputs. The first line of your file varies in each case. Multiple outputs • • • No inputs One input Multiple inputs function [o1, o2, ...] = MyFunc() function [o1, o2, ...] = MyFunc(i1) function [o1, o2, ...] = MyFunc(i1, i2,...) One output • • • No inputs One input Multiple inputs function [o1] = MyFunc() function [o1] = MyFunc(i1) function [o1] = MyFunc(i1, i2, ...) For a function with one output value the square brackets around the output argument are optional and may be left off if you desire, as was done with our Square function. No outputs • • • No inputs One input Multiple inputs function [] = MyFunc() function [] = MyFunc(i1) function [] = MyFunc(i1, i2, ...) For a function with no output value the square brackets and equals sign are optional and may be left off if you desire (you need to leave off BOTH if you wish to do this). Function filenames Functions must be saved to a file with a .m extension, using exactly the same filename as the function name. As with standard script files there are some important limitations when naming functions. Function names should NOT: • • • include spaces start with a number use the same name as an existing command (check to see if it is in use by typing help followed by the name) You may only use alphanumeric characters and the underscore when naming functions. One convention is to use an upper case letter for the first letter of the name and for the first letter of subsequent words, eg PolarToCartesian. Another popular convention to follow when naming functions is to use underscores to separate words in a function name, eg polar_to_cartesian. These conventions helps to distinguish function names from variable names. It also helps distinguish from built-in functions which are named using lower case letters only. 46 You may use whichever convention you prefer. In general this course manual will follow the latter convention of using an upper case letter for the first letter of the name and for the first letter of subsequent word. We’ll use the other convention occasionally too, so that you remember it. In practice it makes for easier to read code if you stick to one of the conventions. Function headers Every function file should have a header comment at the top of the file, just beneath the function definition. This header should describe the function's input(s) and output(s), the purpose of the function and who wrote it. function [ c ] = ConvertFahrenheitToCelsius( f ) % ConvertFahrenheitToCelsius (f) converts temperature in % degrees Fahrenheit (f) into Celsius (c) % Author: Andrea Raith c = (f - 32) * 5 / 9 end Typing help and your function name will display your header comments. Eg >> help ConvertFahrenheitToCelsius ConvertFahrenheitToCelsius (f) converts temperature in degrees Fahrenheit (f) into Celsius (c) Author: Andrea Raith 47 Writing functions: Polar to cartesian example Let’s revisit the PolarToCartesian function, only this time we will develop it from scratch and include a detailed function header and comments. Recall that polar coordinates are useful for describing circular shapes.We need to convert to Cartesian coordinates for plotting Programming Task 3.1: Task: Write a function that converts from polar coordinates to Cartesian coordinates Solution: Recall that polar coordinates are useful for describing circular shapes.We need to convert to Cartesian coordinates for plotting. The diagram illustrates how Cartesian coordinates are derived from polar coordinates. y = r sin θ Pseudocode INPUTS: r and θ Calculate x value as x = r cos θ Calculate y value as y = r sin θ OUTPUTS: x and y Example: < left to the reader > 48 Code function [x, y] = PolarToCartesian(r, theta) % PolarToCartesian transforms r and theta from polar % coordinates into (x,y) cartesian coordinates % Inputs: r = radial distance % theta = radial angle % Outputs: x = cartesian x coordinate % y = cartesian y coordinate % Author: Peter Bier % % % % % x y we use the dot operator so that our code will also work if r and theta are arrays. Note the use of the semi-colon to suppress output, otherwise our function will print out the x and y values when calculating them = r .* cos(theta); = r .* sin(theta); end Remember that the function must be saved using the function name as the filename, eg PolarToCartesian.m Using our function Programming Task 3.2: Task: Write a matlab script that draws a spiral Solution: Using polar coordinates it is easy to draw a spiral: • create array of θ -values that describe a full 360 degree (or 2π) turn • create array of r-values ranging from zero to the maximum extension of the spiral (say 10) • Now the combination of r and θ values represents points on the spiral Now plot the spiral: • To be able to plot, convert to Cartesian coordinates - Example: % spiral.m draws a spiral using polar coordinates. % Author: Peter Bier % our array of 20 radius values will range from 0 to 10 spiralRs = linspace(0,10,20); % our array of 20 theta values will range from 0 to 2pi, % ie a full circle spiralThetas = linspace(0, 2*pi, 20); [x, y] = PolarToCartesian(spiralRs, spiralThetas); plot(x,y); Saving this code as spiral.m and running it produces the following plot: 49 50 Workspaces The MATLAB workspace When you create variables in MATLAB via the command window or in script files, MATLAB stores them in the “workspace”. You can view the contents of the workspace under the Workspace tab. The MATLAB workspace can be cleared by either restarting MATLAB or by using the clear command. 51 Function workspaces Functions create their own workspaces Function inputs are also created in the workspace when a function starts. A function doesn’t know about any variables in any other workspace, it only has access to the input values and any variables it creates. Function outputs are copied from workspace when function ends. The MATLAB workspace knows nothing about any of the other variables a function might use in its own workspace. Function workspaces are destroyed after functions end. This means that any variables created in a function “disappear” when the function ends. Debugging Often when we write a computer program it is "buggy". The program runs but it does not do what it is supposed to. The problem may be as simple as an incorrect sign in a formula or it may be quite subtle and hard to detect. We will practice “debugging” (removing bugs) during the labs. MATLAB provides a debugger to allow us to step through each line of code and examine the value of the workspace variables as we go. By checking whether each line does what we expect it is usually possible to track down the problem line (or lines). A debugger can be a great help when working on a large file. We can set a "break-point" on a particular line which means the program will run as normal until it reaches the break point. We can then step through line by line until we have found the problem. Using a break point is a much better idea than having to step through every single line, as often we know the problem occurs after a lot of other code (which we don't want to spend time stepping through). Debugging and functions When stepping through each line of a piece of code in a file you have a choice of what to do when you come to a line which calls a function. You can step "over" the function, in which case the debugger just goes on to the next line of code in your current file. You can also step "into" the function, in which case the debugger goes to the first line of code inside your function (which will open up a different file). Once inside a function you can choose to step through every single line or at some point you may like to "step out", back to your original file you were debugging. 52 Space for notes 53 Chapter 3 Summary Program We can now define functions and write programs that use those functions. The following function uses numerical differentiation to calculate the derivatives for a set of points that are passed in as inputs. Programming Task 3.3: Task: Use numerical differentiation to calculate derivatives for an array of points given by their x-values and corresponding function values f(x). Solution: < to do: using 5 steps of problem solving > Example: Try it with a function whose derivative you know such as sin(x). function [dfdx] = NumericalDerivative(x,fx) % NumericalDerivative uses numerical differentiation to find % the derivative at each point for a set of discrete points % passed to it that represent a mathematical function. % Inputs: x A 1D array of x values % fx A 1D array of values corresponding to a % mathematical function f applied to each of % the x values, ie f(x) % Outputs: dfdx A 1D array of derivative values, 1 for each % of the x values % Author: Peter Bier n = length(x); h = x(2) - x(1); % find the number of elements in the array % determine the step size; % use a forward difference to calculate the derivative of the % first element (as we have no backwards points) dfdx(1) = (fx(2) - fx(1))/h; % % % % % % % use a central difference to calculate the derivatives of the middle elements since we have points to the left and right and a central difference is more accurate Note we could do the second element by itself as follows: dfdx(2) = (fx(3) - fx(1))/(2*h) and the second to last element could be done as follows: dfdx(n-1) = (fx(n) - fx(n-2))/(2*h) % Using array slicing we can be a little cunning and do all the % middle elements at once by subtracting an array of % all bar the last two elements from an array of % all bar the first two elements and then dividing by 2h. dfdx(2:n-1) = (fx(3:n) - fx(1:n-2)) / (2*h); % use a backward difference to calculate the derivative of the % last element (as we have no point forward of it) dfdx(n) = (fx(n) - fx(n-1))/h; end 54 Below is a script file that uses this function to create a plot of the derivative of y=sin(x). % plot the derivative of the sin function x = linspace(0, 2*pi, 50); y = sin(x); dydx = NumericalDerivative(x,y); plot(x,dydx); title('Plot of numerical derivative of sin function'); xlabel('x'); ylabel('derivative'); The result of running this script is a graph of the cos function. Recommended reading Chapter 3 Functions, Problem Solving and Debugging Topic Debugging Workspaces Debugging Writing functions Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 1.4 2.1 4.7 3.2 Section 1.4 1.2 4.6 1.4 Pages 32-34 80-81 228-233 148-152 55 Pages 25-26 47-48 184-188 126-130 56 Chapter 4: Logical operators and conditional statements Part of the power of computer programming comes from the ability to test if certain conditions are met and then perform different actions depending on the result. Relational and logical operators allow us to test relationships between variables and determine if expressions are true or false. Conditional statements then allow us to control what code gets executed, based on whether a condition is true or not. Learning outcomes After this chapter, you should be able to: • • • • • Use pseudocode and flow charts to describe programs Understand relational and logical operators Understand conditional statements Create and use boolean variables Control program flow with conditional statements and boolean variables Controlling your computer A computer program is a sequence of simple steps. Each step does one thing. Pseudocode and Flowcharts Before writing a program in any computer language it is often a very good idea to write out a plan, which will outline the steps in the program. This allows us to focus on what the program will do, without worrying about exactly how to write the code. Armed with a plan it is then much quicker to write the code. There are two common methods used for describing a program: pseudocode and flowcharts. 57 Pseudocode is a text description of program steps. It may contain fragments of code but doesn’t contain the nitty-gritty details. It is similar to a recipe. Flowcharts use geometric symbols to describe program steps. The resulting chart captures the “flow” of the program Being able to plan programs by writing psuedocode or drawing flowcharts is a very handy skill no matter what programming language you are working with. Flowchart Elements The following table details some of the geometric elements used in flow charts. Notice how different shapes are used for different kinds of behaviour. Beginning of algorithm (or function) Computation End of algorithm (or function) Output Input Comparison 58 Here is an example of a flowchart from a popular web comic called xkcd. Note that the comic artist wouldn’t get full marks in an exam for their flowchart, as they forgot to use the correct shape for their start and stop points! For more xkcd comics see xkcd.com 59 Flow charting functions Below is the flow chart for the polarToCartesian function: Note that we use a parallogram to show the inputs and outputs for the function. 60 Programming Example We can plan out a program that will calculate your final percentage given your coursework and exam percentages. Reminder: Programming Task 4.1: Task: Solution: Example: Prompt user to enter 131 course work and exam mark. Calculate final mark and display it. Input: Obtain user coursework and exam mark Your final mark will be calculated as the minimum of: • Coursework % + 10% • Exam % + 10% • ½ x (Coursework % + Exam %) Display final mark c = 38, e = 62 ⇒ f = 48 c = 60, e = 55 ⇒ f = 57.5 Pseudocode1 1. 2. 3. 4. 5. 6. Get coursework percentage C Get exam percentage E Calculate C + 10 Calculate E + 10 Calculate (C + E) / 2 Set final percentage F to be minimum of C + 10, E + 10, (C + E) / 2 61 Flowchart Once we have our plan we can then choose a language to write our program in. 62 MATLAB program 63 C program 64 Implementing Min What if min was not an in-built function? We could write our own to perform the same task, which would need both comparisons and logic. Programming Task 4.2: Task: Write Matlab code to determine the minimum of the three values Cinc, Einc and Avg, without using Matlab’s built-in min function. Solution: Pseudocode 1.F = Cinc 2.If Einc < F, set F = Einc 3.If Avg < F, set F = Avg Variable F now contains the minimum of the three values. Example: Cinc = 100, Einc = 30, Avg = 65 ⇒ F = 30 Cin = 70, Einc = 65, Avg = 57.5 ⇒ f = 57.5 Flowchart Before we can write our own min function we will need a way of comparing relationships between values and a way of determining which commands to run based on that comparison. Relational operators Relational operators test relationships between variables. A == B A ~= B A<B A>B A <= B A >= B tests whether A equals B tests whether A does not equal B tests whether A is less than B tests whether A is greater than B tests whether A is less than or equal to B tests whether A is greater than or equal to B Each of the above tests returns either false or true for two given variables A and B. 65 Using relational operators >> a=3; >> b=4; >> a==b ans = 0 >> a>b ans = 0 >> a<=b ans = 1 >> a>=b ans = 0 >> a~=b ans = 1 >> a<b ans = 1 Each of the above tests leads to either false (ans = 0) or true (ans = 1). Logical Operators Logical operators test conditions, usually expressed as relationships between variables or expressions. A value is false if it is 0 and true otherwise (any non-zero value is considered true by Matlab). The value of a logical operator is either true or false, represented as 1 or 0 respectively. Common logical operators are: ~p p&q p|q true if p is not true true if both p and q are true true if either p or q are true Using Logical Operators >> a=3; >> b=4; >> ~(a==b) ans = 1 >> a | b ans = 1 >> c=5; >> (a<b) & (b<c) ans = 1 >> (a>b) | (a>c) ans = 0 >> (a>b) | (b<c) ans = 1 66 Conditional statements A conditional statement has two parts to it, a condition and a dependent: “If it is sunny outside then I will cycle to university.” condition dependent •“If I get more than 90% in the final exam then I will buy myself an iPhone .” condition dependent Using MATLAB if examMark > 90 then disp('Time to buy an iPhone') end condition dependent if...end Syntax if condition some commands end dependent The word end lets MATLAB know when the conditional statement is finished. It is usual to use the indentation shown above. This makes it simple to spot where the end of the if occurs. Pseudocode 1.If condition, some commands Alternative Pseudocode 1. If condition a) Some commands Flowchart 67 Programming Task 4.3: Task: Write a Matlab script that defines variables a and b, and then displays a if the value of a is less than the value of b. Solution: • • Set a and b If a < b o Display a See pseudocode and flowchart below. Example: a = 2, b = 5 ⇒ output : 2 a = 5, b = 2 ⇒ no output Describing myIf.m Pseudocode Flowchart 1.Set a = 2 2.Set b = 5 3.If a < b a)Display a Matlab script: File: myIf.m a=2; b=5; if a<b disp(a) end MATLAB command prompt >> myIf 2 >> 68 if...else...end Syntax if condition some commands else some other commands end This section is OPTIONAL Remember that the word end lets MATLAB know when the conditional statement is finished. It is important not to forget it! Pseudocode 1. If condition a) Some commands 2. Else a) Some other commands Flowchart Programming Task 4.4: Task: Solution: Write a Matlab script that defines variables a and b, and then displays the smaller of the two. • • • Example: Set a and b If a < b o display a Else o display b See pseudocode and flowchart below. a = 5, b = 4 ⇒ output : 4 a = 2, b = 5 ⇒ output : 2 69 Describing myIfElse.m Pseudocode Flowchart 1.Set a = 5 2.Set b = 4 3.If a < b a)Display a 4.Else a)Display b Matlab code File: myIfElse.m a=5; b=4; if a<b disp(a) else disp(b) end MATLAB command prompt >> myIfElse 4 >> 70 if...elseif...else...end Syntax if condition some commands elseif another condition some different commands else some other commands end This section is OPTIONAL Pseudocode 1. If condition a) Some commands 2. Else If another condition a) Some different commands 3. Else a) some other commands Programming Task 4.5: Task: Solution: Write a Matlab script that defines variables a and b, and then displays the smaller of the two, or both if they are equal. • • • • Example: Set a and b If a == b o bisplay a and b Else If a < b o display a Else o display b See pseudocode and flowchart below. a = 5, b = 4 ⇒ output : 4 a = 2, b = 2 ⇒ output : 2 and 2 71 Describing myIfElseIfElse.m Pseudocode Flowchart 1.Set a = 5 2.Set b = 4 3.If a == b a)Display a and b 4.Else if a < b a)Display a 5.Else a)Display b Example File: myIfElseIfElse.m a=5; b=4; if a==b, disp(a) disp(b) elseif a<b, disp(a) else disp(b) end MATLAB command prompt >> myIfElseIfElse 4 >> 72 Testing multiple conditions Suppose we want to check if a < b < c and then do something depending on the result. You might be tempted to try a = 2 b = 1 c = 3 if (a < b < c) disp('b is between a and c') end This is NOT the correct way to test if b is between a and c. MATLAB's precedence means that it will first evaluate a < b, which is false and so is given the value 0. It will then check to see if 0 < c, which is true, so the entire expression evaluates to true. Hence running the above code will display the message 'b is between a and c' even though that is clearly not the case. To test if b is between a and c we need to test two relationships: a < b and b < c We should test whether both are true: if (a<b) & (b<c) disp('b is between a and c') end Note the use of “&” to test whether both conditions are true. More on precedence Care must be taken when checking multiple conditions, as it is easy to write code which does not do what you expect. This is because certain operations take precedence over others. Suppose we want to check if a is less than b and c. This statement is ambiguous and can be interpreted in a few different ways. For example it could be interpreted to mean: test that the value of a is less than b AND that the value of a is less than c (a < b) & (a < c) find the value of b & c and test to see if a is less than this a < (b & c) find the value of a < b and see if both this value and c are true (a < b) & c 73 Notice that the only difference between the MATLAB code for the second and third options is the placement of the brackets. What happens if we leave off the brackets? Which interpretation does MATLAB use? a=2 b=3 c=1 if (a < b & c) disp('a is less than b and end c') MATLAB's precedence is that < will be evaluated before &. First 2<3 is evaluated which is true. Then 1 & 1 is evaluated, which is also true, so the message is displayed. Omitting the brackets had the same effect as using (a<b) & c When testing multiple conditions it is a good idea to always put in brackets, even if you don't think you need them. Brackets make your code easier to read and understand. They also help to avoid bugs which can result from using the default evaluation order of logical and relational operators, when it checks something different from what you actually wanted. For more detail on operator precedence see the Matlab help (Search for “operator precedence”). Implementing Min Again We now have the tools to be able to write our own min function. % myMin - finds min(Cinc, Einc, Avg) % If Cinc < Einc and Avg, set F = Cinc if (Cinc < Einc) & (Cinc < Avg), F = Cinc; % If Einc < Cinc and Avg, set F = Einc elseif (Einc < Cinc) & (Einc < Avg), F = Einc; % If Avg < Cinc and Einc, set F = Avg else % Must be true by default F = Avg; end; 74 Boolean variables Boolean variables are used to store “true” and “false” values. They are very useful when working with relational operators and conditional statements. MATLAB uses: • a value of 1 to represent true (actually any NONZERO value is treated as true) • a value of 0 to represent false MATLAB also has two special variables that are useful when dealing with booleans • true which has the value 1 • false which has the value 0 You can create boolean variables just like other variables: % set isSuccessful to true and finished to false isSuccessful = 1; finished = 0; Or equivalently: isSuccessful = true; finished = false; It is common to use boolean variables to store an answer to some “question” that controls a conditional statement or while loop. if (isSuccessful) disp('Time to celebrate!'); end Naming boolean variables It is good programming practice to choose a variable name that indicates the type of the variable. One common naming convention for boolean variables is to start every name with the word "is". This makes it clear how to interpret a value of true or false. For example the name isSuccessful is much more meaningful than a variable called status. Try to write statements that read well. Consider which of the following reads better: if isSuccessful do something end if ~isFailure do something end 75 If you do not want to use names which start with "is" then it is a good idea to use a yes/no or true/false question as the name. This helps you write readable code. eg: if( atUniversity & stillAStudent ) needMoreMoney = 1; end Chapter 4 Summary Program Programming Task 4.6: Task: Write a Matlab script that asks the user to specify carry-on baggage dimensions and weight, and checked baggage weight. The script checks whether baggage dimensions and weight are acceptable or not, and informs the user. Assume checked baggage can weigh up to 20kg, carry-on 7kg, and carry-on dimensions must be so that length + width + height are at most 115cm. Solution: Write pseudocode or draw flowchart. Example: See examples below 76 % % % % % % This program requests information on a passenger's luggage and determines if their luggage is acceptable for air travel Maximum Dimensions of Carry-on Luggage: 115 linear cm (length + width + height) Maximum weight of carry-on luggage is 7 kg Maximum weight of checked luggage is 20kg % get passenger luggage information carryonLength = input('Enter carry on length:'); carryonWidth = input('Enter carry on width:'); carryonHeight = input('Enter carry on height:'); carryonWeight = input('Enter carry on weight:'); checkedWeight = input('Enter checked bag weight:'); linearDimensions = carryonLength + carryonWidth + carryonHeight; luggageIsAcceptable = 1; % determine if carry on is acceptable if( linearDimensions <= 115 & carryonWeight <= 7) disp('Carry on bag acceptable') else % carry on not acceptable luggageIsAcceptable = 0; % display reason(s) why carry on not accepted if (linearDimensions > 115) disp('Carry on too big'); end if( carryonWeight > 7) disp('Carry on too heavy'); end end % determine if checked bag is acceptable if (checkedWeight <= 20) disp('Checked bag acceptable') else disp('Checked bag too heavy'); luggageIsAcceptable = 0; end if( luggageIsAcceptable ) disp('You may now board your flight'); end 77 Some examples of this program running are given below (user input is in bold): Enter Enter Enter Enter Enter carry on length: 30 carry on width: 40 carry on height: 50 carry on weight: 4 checked bag weight: 21 Carry on too big Checked bag too heavy Enter Enter Enter Enter Enter carry on length: 30 carry on width: 40 carry on height: 20 carry on weight: 8 checked bag weight: 19 Carry on too heavy Checked bag acceptable Enter Enter Enter Enter Enter carry on length: 30 carry on width: 40 carry on height: 20 carry on weight: 5 checked bag weight: 19 Carry on acceptable Checked bag acceptable You may now board your flight Recommended reading Chapter 4 Logical operators and conditional statements Topic Relational operators and conditional statements Relational operators Logical operators Conditionals Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 1.6 Pages 44-48 Section Pages 4.2 4.3 4.4 191-192 194-197 201-208 4.1 4.2 4.3 153-155 156-160 163-167 78 Chapter 5: Loops Often when writing computer programs we will want to run the same (or very similar) piece of code several times. MATLAB provides commands that allow us to “loop” over a piece of code and run it multiple times. We may need to keep looping until some condition is met, in which case we use a while loop. We may know how many times you want to loop over a section of code, in which case we use a for loop. Remember, if you find yourself writing the same lines of code more than a couple of times in a row, chances are you should be using a loop. Using loops will save you some typing and also make your program easier to read and maintain. Learning outcomes After working through this chapter, you should be able to: • • • • • • Explain the concept of a while loop Use while loops in a program Explain the concept of a for loop Use for loops in programs Manipulate 1D arrays using a for loop Describe loops using flowcharts and pseudocode While loops While loops are used when you need to keep looping while some condition remains true. They are very similar to if statements. An if statement checks the truth of a condition and then executes a piece of code if the condition is true. A while statement checks the truth of a condition and while the condition remains true repeatedly loops over a piece of code, executing it again and again. Suppose you wanted to write out the square of an integer, only if the value squared was less than 50. It would be easy to come up with an if statement to do this: i = input('Enter an integer'); if i^2 <= 50 disp(i^2) end 79 Suppose that we now wanted to write out the squares of all integers less than 50. Programming Task 5.1: Task: Write out the square of all integers less than 50. Solution: One way to do this would be as follows: Display 12 Display 22 … Display 72 - Example: File: squares.m disp(1^2); disp(2^2); disp(3^2); disp(4^2); disp(5^2); disp(6^2); disp(7^2); MATLAB command prompt >> squares 1 4 9 16 25 36 49 >> It is pretty inefficient to type out seven nearly identical lines. The situation would be even worse if we had wanted to write out all the squares less than 1,000,000. Notice how each line is almost identical, with only one number changing each time. In fact we can make each display command call the same, by using a variable to hold the number we are squaring: Solution: File: squares2.m i= 1 disp(i^2) i= 2 disp(i^2) i =3 disp(i^2) i =4 disp(i^2) i = 5 disp(i^2) i = 6 disp(i^2) i = 7; disp(i^2) Another way to do this would be as follows: i = 1, Display i2 i = 2, Display i2 … i = 7, Display i2 MATLAB command prompt >> squares2 1 4 9 16 25 36 49 >> 80 Unfortunately this has made our code even longer! Fortunately MATLAB provides us a way of "looping" over the command disp(i^2) and executing it while i^2 < 50 We can represent what we want to do using pseudocode or a flowchart Solution: Much better way to print the squares of integers up to 50 is using a while loop: Pseudocode i=1 while i2 <= 50 display i2 i=i+1 end Flowchart display i2 To achieve this sort of behaviour we use a while loop. MATLAB while loop example File: squares3.m i = 1; while i^2 <= 50 disp(i^2) i = i + 1; end MATLAB command prompt >> squares3 1 4 9 16 25 36 49 IMPORTANT: Note that for the while loop to work, we need to make sure the variable i increases (by one each time), as otherwise the value of i will stay the same and consequently the value of i2 will never change. To make sure that the value of i changes, the following line is executed each time we go through the loop i=i+1 Note how this has the effect of increasing the value of i by one. Think about what would happen if we left out this line. 81 General form of a while loop Pseudocode initialise while condition some commands update end Flowchart The update step is very important. If it is omitted or not done correctly you may get stuck in an infinite loop. Infinite loops An “Infinite loop” is a piece of code that will execute again and again and again ... without ever ending. Possible reasons for infinite loops: • getting the conditional statement wrong • forgetting the update step ' If you are in an infinite loop then ctrl-c stops MATLAB executing your program File: infinite_loop.m i = 1; while i >= 0 disp(i) i = i + 1; end MATLAB command prompt >> infinite_loop 1 2 3 4 LOTS MORE NUMBERS 6824 6825 AND SO ON, until ctrl-C REMEMBER: use CTRL-C to break out of an infinite loop. 82 An example of a scenario that could create an infinite loop, from xkcd.com Booleans and while loops Using a boolean variable to control a while loop allows us to write more readable code. Syntax stillLooping = true; while stillLooping some commands if some conditions stillLooping = false; end end Boolean while Example iPhoneCost = 979; needMoreMoney = true; while(needMoreMoney) moneySaved = input('How much money have you saved?'); if( moneySaved >= iPhoneCost ) disp('You do not need to save any more money'); needMoreMoney = false; else disp('Keep saving'); end end 83 For loops Recall that when we wanted to write out the squares of all integers less than 50, we used a while loop i = 1; while i^2 <= 50 disp(i^2) i = i + 1; end We could just as easily used the following while loop to achieve the same task i = 1; while i <= 7 disp(i^2) i = i + 1; end Here the condition has been changed, so that we are checking if the variable i is less than 7. This loop will be run exactly seven times, with the body of the loop being run for each of the numbers 1, 2, 3, 4, 5, 6 and 7. MATLAB provides another way of "looping" over the commands called a for loop. For loops can be more convenient to use than while loops in many cases (although you can always achieve the same thing with an appropriate while loop). The convenience of a for loop lies in the fact that they take care of the update step for us. For loops are particularly useful when we know exactly how many times we want to loop through a piece of code or we wish to execute a loop a number of times for a given list of values. In the example above we wish to display the square of i for each of the values from 1 to 7. The syntax of the appropriate for loop looks like this: File: squares4.m for i=1:7 disp(i^2) end MATLAB command prompt >> squares4 1 4 9 16 25 36 49 >> The for loop allows us to execute the disp command for each of the values from 1 to 7. The first time through the loop, i has the value 2. The second time i has the value 3 and so on, until the very last time when i has the value 7. Recall that 1:7 is another way of writing the array [1,2,3,4,5,6,7]. We can think of a for loop as a loop that executes a given piece of code for each element in an array. 84 Pseudocode for our squares example for i = 1 to 7 by 1 display i2 end If we wanted to print out all the squares of integers from 1 to 100, instead of 1 to 7, just a small change is necessary: for i = 1:100 disp(i^2) end Flowchart for our squared example display i2 Notice this flowchart is very similar to the one for the while loop that did the equivalent task. This shouldn’t be a surprise as the task can be accomplished using either kind of loop. More on for loops At the heart of a for loop is a loop variable, often given the name i. The first time through the loop the variable i has a start value. Each subsequent time the value of i is increased by a step value (usually 1). We continue looping until we reach the finish value. The commands inside the for loop will often use the loop variable (but they don't have to). Pseudocode for i = start to finish by step some commands end 85 Flowchart Syntax for variable = start:step:finish some commands end If no step is specified it is assumed to be 1. Note that while pseudocode and Matlab code of a for loop does not require to specify an update of the loop variable (the update step is included in the for loop statement start:step:finish), this update step must be included in the flow chart like it is done for a while loop. Some examples File: count_to_five.m for i=1:5 disp(i) end MATLAB command prompt >> count_to_five 1 2 3 4 5 >> File: triple_greeting.m for i=1:3 disp('Hello') end MATLAB command prompt >> triple_greeting Hello Hello Hello >> 86 Different step values File: count_time.m for time=0:0.1:0.5 disp(time) end MATLAB command prompt >> count_time 0 0.1000 0.2000 0.3000 0.4000 0.5000 >> File: countdown.m for i=5:-1:1 disp(i) end disp('blastoff!') MATLAB command prompt >> countdown 5 4 3 2 1 blastoff! >> Note that the for loop stops as soon as the finish value is exceeded. File: count_odd.m for i=1:2:10 disp(i) end MATLAB command prompt >> count_odd 1 3 5 7 9 >> 87 For Loops and arrays For loops are ideal for processing arrays. The loop variable can be used as an array index. This allows us to use the same piece of code but run it on each element in an array in turn. File: check_weights.m bagWeights = [4.5, 3.4, 5.0, 7.2, 10.0, 4.9, 8.6]; for i=1:length(bagWeights) if (bagWeights(i) > 7) disp(['Bag ', num2str(i), ' too heavy!']); bagIsTooHeavy(i) = true; else bagIsTooHeavy(i) = false; end end MATLAB command prompt >> check_weights Bag 4 too heavy! Bag 5 too heavy! Bag 7 too heavy! >> The array bagIsTooHeavy will also have been populated >> bagIsTooHeavy bagIsTooHeavy = 0 0 0 1 1 0 1 Notice how the loop variable has been used as an index into our bagWeights and bagIsTooHeavy arrays. A common programming error is to create a for loop attempts to access elements of an array that do not exist. This will occur if i happens to be zero, have a negative value or have a fractional value. Array indices in Matlab can only be positive integers. 88 Space for notes 89 Chapter 5 Summary Program We can now write programs that use loops. Programming Task 5.2: Task: Write a script that asks the user to enter internal and exam marks for 131 students and then calculates their final mark. Solution: • • • Example: While there are students to process o ask user for student ID, internal and exam mark and store each in an array For all elements of the student ID array o Calculate final mark of students and store it in an array Display student IDs and corresponding final marks See below % this script file lets a user enter internal and examination % marks for the students in a class and then calculates their % final marks. % index keeps track of which student we are up to i = 0; % boolean variable which is true while there are more students % to process moreStudentsToProcess = 1; while( moreStudentsToProcess ) % increment student number i = i + 1; % ask user to enter internal and exam marks for student id(i) = input('Enter student id number:'); internalMark(i) = input('Enter the internal mark:'); examMark(i) = input('Enter exam mark:'); disp('Are there more students to process?') response = input('Enter 1 for yes, 0 for no:'); % response of 0 means no more students to process if( response == 0) moreStudentsToProcess = 0; end end 90 % summary program continued % calculate final exam mark for each student for j=1:length(id) coursework = internalMark(j); exam = examMark(j); cmax = coursework + 10; emax = exam + 10; avg = (coursework + exam)/2; finalMark(j) = min([cmax,emax,avg]); end disp('Student ids are'); disp(id); disp('Final marks are'); disp(finalMark); An example of this program running is shown below, with user input in bold. Enter student id number:123 Enter the internal mark:12 Enter exam mark:56 Are there more students to process? Enter 1 for yes, 0 for no:1 Enter student id number:234 Enter the internal mark:56 Enter exam mark:78 Are there more students to process? Enter 1 for yes, 0 for no:1 Enter student id number:565 Enter the internal mark:67 Enter exam mark:69 Are there more students to process? Enter 1 for yes, 0 for no:0 Student ids are 123 234 565 Final marks are 22 66 68 Recommended reading Chapter 5 Loops Topic Loops For loops While loops Introduction to Matlab 7 for Engineers (2nd ed) Section Pages 1.6 48-51 4.5 211-213 4.5 221-225 91 A Concise Introduction to Matlab (1st ed) Section Pages 4.4 4.4 170-174 178-180 92 Chapter 6: 2D and 3D Arrays As well as support for 1D arrays, MATLAB allows you to create and manipulate 2D and 3D arrays. It is also possible to use MATLAB to manipulate images, by reading the colour values into a 3D array and then changing the colour values. Learning outcomes After working through this chapter, you should be able to: • • • • • • Explain what a 2D array is Create and manipulate 2D arrays Draw plots of 2D arrays Perform calculations with 2D arrays Manipulate 2D arrays using for loops Manipulate RGB images via 3D arrays 2D arrays Variables so far have been scalars (single value) and 1D arrays (lists of values). Some types of data are suited to being stored in 2D arrays. For example: • • • data which corresponds to an underlying physical “grid” data from a table data representing the elements of a matrix If a 1D array is like a filing cabinet, a 2D array is like a set of cubby holes A = [1, 2, 3; 2, 4, 6; -1, 0, 1] A = 1 2 2 4 -1 0 3 6 1 93 Creating 2D arrays Creating a 2D array is very similar to the way we create a 1D array. We enclose numbers within square brackets and values on the same row are separated by a comma or space. A semi colon is used to indicate the start of a new row: >> A = [1 2 3; 6 5 4] A = 1 6 2 5 3 4 Programming Task 6.1: Task: Using a 2D array of quarterly production understand how to use and manipulate arrays. The rows of the array represent years, and its columns represent production in the corresponding quarter. >> QuarterlyProd = [42, 52, 48, 47; 41, 48, 50, 42; 51, 38, 40, 41] QuarterlyProd = 42 52 48 41 48 50 51 38 40 47 42 41 Accessing array elements You can access a particular value in an array by using round brackets and two indices separated by a comma. These indices specify which row and column to look at: For example, the array element in row 2 and column 3 of the QuarterlyProd array has the value 50, therefore production in the third quarter of year two was 50. >> QuarterlyProd(2,3) ans = 50 If we want, we can change a particular array value: >> QuarterlyProd(2,3) = 35 QuarterlyProd = 42 41 51 52 48 38 48 35 40 47 42 41 94 Extending arrays You can add extra elements by creating them directly using round brackets, or by concatenating them (adding them onto the end). When extra elements are added MATLAB fills in any gaps with 0. >> QuarterlyProd = [42, 52, 48, 47; 41, 48, 50, 42; 51, 38, 40, 41] QuarterlyProd = 42 52 48 47 41 48 50 42 51 38 40 41 >> QuarterlyProd(4, 1) = 45 QuarterlyProd = 42 41 51 45 52 48 38 0 48 50 40 0 47 42 41 0 When concatenating you need to make sure the dimensions of the arrays being used are compatible. >> A = [8, 9; 1 2] >> D = [A; B] A = D = 8 1 >> B = [4 5] 8 1 4 >> E = [A, B = E = 4 9 2 5 8 1 9 2 5 C] 9 2 3 5 >> C = [3; 5] >> F = [A, C; B, 12] C = F = 3 5 8 1 4 95 9 2 5 3 5 12 2D array functions Standard mathematical functions can be applied to 2D arrays too. >> x = [1, 2, 3; 4, 5, 6]; >> y = sin(x) y = 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 Special array functions The size function returns the number of rows and columns in an array. The syntax is: [m, n] = size(A) Where m = number of rows, n = number of columns The transpose operator ' swaps the rows and columns in an array. Be careful as it is easy to miss the transpose operator, since it is so small. >> A = [1 2 3; 4 5 6]; >> [m,n] = size(A) m = 2 n = 3 >> B = A' B = 1 2 3 4 5 6 96 Automatic 2D arrays There are a number of useful functions for creating 2D arrays: zeros, ones, rand, eye and meshgrid. The zeros function takes a number of rows and columns and creates an array of the specified size filled with zeros. The ones function is similar but creates an array full of ones. The rand function is also similar but fills the array with random values between 0 and 1. The eye function takes a number of rows and creates a square array with ones on the diagonal and zeros everywhere else. The eye function is handy for generating identity matrices. >> zeros(2, 4) ans = 0 0 0 0 >> ones(3, 2) ans = 1 1 1 0 0 0 0 1 1 1 >> eye(3) ans = 1 0 0 0 1 0 0 0 1 The meshgrid command will be covered in later chapters. Drawing 2D arrays The data in a 2D array can be represented as a surface in 3D by using the surf command. >> M = [3 4 5; 2 3 4; 1 2 3] M = 3 2 1 4 3 2 5 4 3 >> surf(M) We can add labels in with the xlabel, 97 ylabel and zlabel commands. You might expect the first index (the row index) to correspond to the x axis, but by default it actually corresponds to the y axis. In the example above M(1,3) is equal to 5 and presents the value at the point (3,1). Arithmetic with 2D arrays Two 2D arrays can be added or subtracted using the + and - operators, as long as the arrays have same size. This is identical to matrix addition or subtraction. Hint Use the size command to find out how big an array is, or check in the workspace window Two 2D arrays can be multiplied with the * operator. This performs matrix multiplication. As with all matrix multiplication, the first array must have same number of columns as the second array has rows. You can check how many rows or columns an array has with the size command: • size(A, 1) gives number of rows of A • size(A, 2) gives number of columns of A >> A = [3 1 0; 1 -2 4]; 98 C = A×B (3 × 2) + (1× 4) + (0 ×1) = (1× 2) + (−2 × 4) + (4 ×1) 10 = −2 >> B = [2; 4; 1]; >> C = A * B C = 10 -2 Element by element operations In mathematically based work matrix multiplication is very useful. However in some applications we want to perform an element-wise multiplication, ie we want to multiply each element in the first array by the corresponding element in the second array. For this to work the two arrays must be the same size. To perform multiplication element-wise use a . before the operator >> A = [3 1 0; 1 -2 4]; >> B = [4 2 -1; 0 1 3]; >> C = A .* B C = A.*B (3 × 4) (1× 2) (0 × −1) = (1× 0) (−2 ×1) (4 × 3) 12 2 0 = 0 −2 12 C = 12 0 2 -2 0 12 The dot operator can also be applied with other mathematical operations, just as we did with 1D arrays: • Using .^ 2 squares elements in the array term by term instead of multiplying the whole array by itself • Using ./ divides the array element by element >> denom = [2, 3, 4, 5, 6]; >> numer = [1, 2, 3, 4, 5]; >> fracs = numer ./ denom fracs = 0.5000 0.6667 0.7500 99 0.8000 0.8333 Subranges We can select any submatrix using 1D arrays of indices. This is similar to taking a slice of an array. >> A = [1 4 5 6; 8 3 2 8; 0 6 7 9]; >> B = A(2:3, 2:4) B = 3 6 2 7 8 9 >> C = A([2 1], [1 3 4]) C = 8 1 2 5 8 6 Colon operator Using a colon : instead of an index array refers to ALL rows or columns of the array >> A = [1 4 8 3 0 6 >> B = A(2, 5 6; 2 8; 7 9]; :) >> C = A(:, 2) C = 4 3 6 B = 8 3 2 8 >> D = A(1:2, :) D = 1 8 100 4 3 5 2 6 8 2D arrays and nested for loops We have seen how to use a for loop to loop through the contents of a 1D array. In order to loop through all elements of a 2D array we can use two for loops, with one inside the other. This is called a nested for loop. A general nested for loop has the following form (but could have more levels) for i = i_start:i_step:i_finish for j = j_start:j_step:j_finish some commands end end Programming Task 6.2: Task: Solution: Example: Use a nested for loop to loop through the elements of a 2D array A. Draw a flow chart for this. Determine rows and cols: the number of rows and columns of A. for i = 0 to rows (step size of 1) for j = 0 to cols (step size of 1) perform some commands with A(i,j), the element in row i, column j of A. end end - You will draw in the flow chart for a nested for loop on the next page: 101 For loop flow chart We will draw this in class. 102 Creating a times table array Programming Task 6.3: Task: Solution: Example: Display a 5 x 10 array containing the basic time table facts up to the 5 times table. Row 1 will contain the 1 times table, row 2 the 2 times tables and so on. Loop through all of the 5 rows of the array (row index i) and loop through all of the 10 columns of the array (column index j) using two nested for loops. Set the value for row i, column j to i*j Display the array - % Create an array containing the basic time table facts % the upper left corner is black % the lower right corner is white % cycle through each row for i = 1:5 % cycle through each column for j = 1:10 % set the array value for row i, column j timestable(i,j) = i*j; end; end; % display the array disp(timestable); This will display the following array: 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25 6 12 18 24 30 7 14 21 28 35 8 16 24 32 40 9 18 27 36 45 10 20 30 40 50; Editing a greyscale image A greyscale image is made up of lots of tiny pixels, with each pixel having an intensity value representing how light or dark that point on the image is. We can use intensity values ranging from 0 to 255 to represent different shades of grey (0 being black and 255 being white). Integer values in this range are commonly used when working with both greyscale and colour images and are typically stored in a special type of variable called an unsigned 8 bit integer (uint8 for short). Images that use unsigned 8 bit integers to represent colour information are called 8 bit images. The intensity value for a pixel in row m and column n of an image can then be stored in a 2D array. To make a pixel in row 2, column 3 of an image a nice shade of grey we could use: myPic(2,3) = 128 103 To make a pixel in row 4, column 5 white we would use myPic(4,5) = 255 It would take a long time to make an interesting picture setting each pixel value in turn, so we will use a nested for loop to create an image with the upper left corner black and the lower right corner white: Programming Task 6.4: Task: Solution: Example: Create a 100 x 200 rectangular greyscale image whose color changes gradually from a black upper left corner to a white lower right corner. Loop through all of the 100 rows of the image (row index i) and loop through all of the 200 columns of the image (column index j) using two nested for loops. Set the pixel value for row i, column j to 255(i+j)/300 (255 is white, 0 is black, values in between are different shades of grey) Display the image Write the image to a file. - % Create a rectangular image 100x200 pixels in size % the upper left corner is black % the lower right corner is white % cycle through each row for i = 1:100 % cycle through each column for j = 1:200 % set the pixel value for row i, column j image(i,j) = 255*(i+j)/300; end; end; % before displaying image need to conver to unsigned 8 bit format image = uint8(image) % display the image imshow(image) % write the image to a file imwrite(image,'greyRectangle.jpg'); This produces the following image: 104 3D arrays and image processing Arrays in MATLAB can be three dimensional. If a 2D array is like a cubby hole a 3D array is like layering several cubby holes on top of each other. This means to identify a single item in a 3D array we use three indices. You can think of these as a row number, a column number and a "layer" (ie which cubby hole to use). One use of 3D arrays is to describe values for data that vary over three dimensions (eg temperature in a room). The three indices describe which point we are dealing with (remember they must be whole numbers though) 3D arrays and images 3D arrays are very useful for graphics applications, as colour images can be nicely represented using 3D arrays. A 2D image is made up of lots of pixels. Each pixel is a tiny square of colour. In the RGB (red-green-blue) colour scheme the pixel colour is stored by recording three colour intensities for the red, green and blue intensities. This means every pixel in a 2D image has three separate values (one for red, one for green and one for blue). 8 bit image formats use a value between 0 and 255 to represent each intensity (0 means none of that colour, while 255 means lots of it). With a single colour value we are limited to 256 shades whereas with just 3 colour values (each between 0 and 255) we can represent over 16 million different colours. To work with images we can store all the colour intensities for all the pixels in a 3D array. Our three indices for the array are: the row, the column and the colour (1 = red, 2 = green, 3 = blue). 105 For example to set the amount of red for a pixel in row 2, column 3 of our image we would use % some red myPic(2,3,1) = 128 We could also set the amount of blue and green % lots of green myPic(2,3,2) = 255 % no blue myPic(2,3,3) = 0 Red and green mix to make yellow so this pixel will be a greeny shade of yellow. Programming Task 6.5: Task: Solution: Create a 30 x 40 color image that is purple. Initialise 30 x 40 3D array For purple color: for all pixels mix red and blue (set to 150 for each pixel on blue and red layer), and set green layer to 0. Show image To make a small 30x40 purple image we need to mix red and blue, i.e. we could do the following: % create a 3D array with 30 rows, 40 columns and 3 "layers" % (one for each colour) % Note the 'uint8' which ensures the resulting 3D array will be % correctly interpreted as a color picture by imshow. % Alternatively we could have used the uint8 function myPic = zeros(30,40,3, 'uint8'); % set all values in layer 1 (red) to be 150 myPic(:,:,1) = 150; % all values in layer 2 (green) remain at 0 % set all values in layer 3 (blue) to be 150 myPic(:,:,3) = 150; We can display our image nicely using the imshow function: imshow(myPic) NOTE: you can only use the imshow function if you have the Matlab Image Processing Toolkit installed (it is available in the labs but may but only a certain number of people can use it at once). If you do not have access to the Matlab Image Processsing Toolkit you can still display the image using the image function (but you’ll need to follow it by a command to set up the axes to display an image, or it will look funny): image(myPic) axis image 106 If we wanted to add in a few rows (rows 5-10) of bright yellow we can do the following % change red intensity to 255 for all pixels in rows 5 to 10. myPic(5:10,:,1) = 255; % change green intensity to 255 for all pixels in rows 5 to 10. myPic(5:10,:,2) = 255; % change blue intensity to 0 for all pixels in rows 5 to 10. myPic(5:10,:,3) = 0; All pixels rows 5 to 10 now have lots of red, lots of green but no blue. Mixing red and green creates yellow, so these rows will be yellow. Reading and manipulating an image To read an existing image into MATLAB we use the imread function, which takes as input the filename of an image enclosed in single quotes: myPicture = imread('photo.jpg') This command will create a 3D array called myPicture which contains the image intensity values for the image contained in the named file. We can determine the number of rows and columns in the image by using the size command. size(myPicture) ans = 314 213 3 The 3D array has 314 rows, 213 columns and 3 layers (1 layer for each colour). We can use nested for loops to loop through all colour values for all pixels and modify them. The resulting image can then be written out using the imwrite command. Programming Task 6.6: Task: Solution: Create negative of image ‘photo.jpg’. Read color photo.jpg, resulting in 3D array. Identify number of rows, columns and layers of image Use nested for loop (loop through rows, colums and layers) Invert each pixel by replacing its original value by (255 – value). Show image Write image to file Example: - 107 The following program will create a negative of a photo, by inverting the colour. % create negative image from a photo % read in image myPicture = imread('photo.jpg') [rows,cols,colours] = size(myPicture); for i=1:rows for j=1:cols for k=1:3 myPicture(i,j,k) = 255 - myPicture(i,j,k); end end end imshow(myPicture); imwrite(myPicture,'negative.jpg'); Source: Image by Andrea Raith (Dept of Engineering Science) 108 Space for notes 109 Chapter 6 Summary Programs We can now write programs that use 2D and 3D arrays. Programming Task 6.7: Task: Solution: Example: Flip greyscale image ‘greyscalePhoto.jpg’ upside down and add black border. Read image resulting in 2D array and obtain dimensions Use nested for loop (loop through rows and colums): For i = 1:floor(rows/2) For j = 1:columns Swap entry in row i with entry in row (rows – i + 1) Add border by setting pixels of first / last three rows / columns of image to 0 Show image and write it to file - For example, the following program reads in a greyscale image, flips the image upside down and then adds a black border to it. % flip greyscale image upside down and add a black border % read in image myPicture = imread('greyscalePhoto.jpg'); [rows,cols] = size(myPicture); % % % % % % % flip image first half we want to row 1 with row 2 with row 3 with row i with by swapping rows. We only need to loop through the of the rows in order to swap them all. swap: the last row, last row - 1, last row - 2, last row + 1 - i for i=1:floor(rows/2) for j=1:cols % store the old pixel value from the top half % before we over write it oldpixel = myPicture(i,j); % replace the pixel value on the top half with one from % the bottom half of the image myPicture(i,j) = myPicture(rows + 1 - i,j); % set the pixel of the bottom half to what was in the top myPicture(rows+1-i,j) = oldpixel; end end 110 % summary program continued % add border myPicture(:,1:3) = 0; myPicture(:,(cols-2):cols) = 0; myPicture(1:3,:) = 0; myPicture((rows-2):rows,:) = 0; imshow(myPicture); imwrite(myPicture,'flipped.jpg'); An example of this program running is given below: Source: Image by Andrea Raith (Dept of Engineering Science) Recommended reading Chapter 6 2D and 3D Arrays Topic Multidimensional Arrays Nested for loops Plotting surfaces Introduction to Matlab 7 for Engineers (2nd ed) Section Pages 2.2 81-83 4.5 211-212 5.8 335-338 111 A Concise Introduction to Matlab (1st ed) Section Pages 2.2 49 4.4 172-173 5.7 251-254 112 Chapter 7: Advanced Graphics You have already encountered the plot function, for creating simple xy plots. MATLAB provides a large number of other graphics functions for more advanced plotting. Learning outcomes After working through this chapter, you should be able to: • • • • • • • • Label your plots Plot several sets of data on the same graph Control line types, axis types and colours on 1D plots Create several figures at the same time Create subplots Create different types of 1D data plots (log graphs, bar graphs and polar plots) Create different types of 2D data plots (surface maps, contour plots and quiver plots) Make MATLAB movies Labelling plots The purpose of a plot is to communicate information. That information cannot be communicated effectively unless the plot is labelled. It is very important that you label your plots. Labels can be added by using the insert menu on a figure window but it is often more convenient to use the MATLAB labelling functions. Title The title function allows us to create a title for our plot. Make sure your title is meaningful and describes what is being plotted. The title command takes as input some words enclosed in single quotes and writes these out as the plot title. title('Vertical movement of an anchored boat'); Labels for the x and y axes You should label BOTH axes, indicating the name of the quantity being plotted and the units used. The xlabel and ylabel functions are used to label the x and y axes. As with the title command, they take as input some words enclosed in single quotes and write these out as the labels. xlabel('time (hours)') ylabel('displacement (metres)'); Note that the title, xlabel and ylabel commands need to be called after the plot function. 113 x = linspace(0,4*pi,100); y = 3 * sin(0.5*x); plot(x,y); title('Vertical movement of an anchored boat'); xlabel('time (hours)') ylabel('displacement (metres)'); Plotting multiple data sets The plot command can be used to plot several lines on the same graph, eg: % plot multiple data sets on the on the same graph x = 0 : 2*pi/100 : 2*pi; y1 = sin(x); y2 = cos(x); y3 = sin(x) + cos(x); plot(x,y1,x,y2,x,y3) xlabel('x') ylabel('y') title('Example plot - multiple data sets') 114 An alternative method to plotting several sets of data on the same plot is to use the hold command. The hold command allows you to hold on to your current plot, so that subsequent plot commands are performed on the current plot, rather than creating a new plot. % plot multiple data sets on the on the same graph using hold on x = 0 : 2*pi/100 : 2*pi; y1 = sin(x); y2 = cos(x); y3 = sin(x) + cos(x); plot(x,y1) hold on plot(x,y2) plot(x,y3) xlabel('x') ylabel('y') title('Example plot - multiple data sets') Note that if we do NOT use the hold on command, each time the plot function is called any previous plot is thrown away and replaced by the latest one. To stop holding on to a plot use the hold off command. 115 Controlling 1D plots Line colours, types and symbols. By default 1D plots use a solid blue line. You can specify other colours and line styles, if you prefer. For many data sets it makes more sense to plot individual points rather than a line. You can specify to plot a symbol at each data point. Generally measured data is plotted using individual points while functions are plotted using a line. Sometimes it is a good idea to do both. To control line colours, types and symbols we pass in an optional third argument to the plot command. This argument is a sequence of control characters enclosed in single quotes. Here are a few examples of how to specify line colours, types and plot symbols: Plot the data using a red dashed line. plot(x,y,'r--') Plot the data using just green circles at each point (and no line) plot(x,y,'go') Plot the data using a dotted cyan line and a plus symbol at each data point plot(x,y,'c:+') A summary of some of the control characters is given in the table below: Colour r red g green b blue c cyan m magenta y yellow k black Symbol . point o circle x cross + plus * star Line style solid : dotted -. dashdot -- dashed You can specify an element from any or all of these three columns. The order is not important but you cannot have more than one element from each column. % plot multiple data sets on the on the same graph using different % line types and colours x = 0 : 2*pi/100 : 2*pi; y1 = sin(x); y2 = cos(x); y3 = sin(x) + cos(x); plot(x,y1,'r-.',x,y2,'go',x,y3,'b+') xlabel('x') ylabel('y') title('Example plot - multiple data sets') 116 For full details on all available colours, symbols and line styles see the MATLAB help for the plot function. Legends If more than one set of data has been plotted on the same graph it is important to add a legend, so that we can tell what each line represents. It is a good idea to use different line types as well as colours, since that makes it easier to distinguish each line if the plot is printed out in black and white. This can be done with the legend command. Once it has been added you can move the position of the legend on the figure with the mouse. legend('sin(x)', 'cos(x)', 'sin(x) + cos(x)') 117 Axes MATLAB will automatically determine the maximum and minimum values for the axes. To override these use the axis function. The axis function takes as input a four element array which specifies the axes limits in the following order: [xmin, xmax, ymin, ymax]. The x axis will then range from xmin to xmax, while the y axis will range from ymin to ymax. axis([ 0, 9, -2, 2 ]) Grid lines If you like grid lines on your plots you can add them using the grid on command. grid on 118 Creating additional figures What happens if you enter the following? x = 0 : 2*pi/100 : 2*pi; y1 = sin(x); y2 = cos(x); plot(x,y1) title('Example plot #1') plot(x,y2) title('Example plot #2') As we have NOT used the hold on command, MATLAB will create a figure for the the first plot and then it will overwrite the first plot with the second plot. We end up with only one figure, containing a plot of y=cos(x). If we wanted to view the two plots at the same time we can place each one in its own figure. We do this by creating an additional figure window before making the second plot. plot(x,y1) title('Example plot #1') figure plot(x,y2) title('Example plot #2') Note that the second figure may be sitting on top of the first, so you may need to move it to the see the figure underneath. MATLAB automatically numbers each new figure with a new number. An even better option than just using the figure command is to create numbered figure windows for each plot: figure(1) plot(x,y1) title('Example plot #1') figure(2) plot(x,y2) title('Example plot #2') Explicitly numbering figures makes it easier to tell what data we are dealing with in any given figure. Subplots Sometimes it makes sense to present data as a set of plots contained inside the same figure, this can be done with the subplot(m,n,p) command. 119 The subplot command specifies the number of rows (m) and the number of columns (n) in the subplot. The plot number (p) indicates what position to plot the data at. Note that you do not have to use up every position. subplot(2,2,1) plot(x,y1,'r-.') title('y = sin(x)') subplot(2,2,2) plot(x,y2,'go') title('y = cos(x)') subplot(2,2,3) plot(x,y3,'b+') title('y = sin(x) + cos(x)') You may want to resize the figure window with the mouse if you are using subplots. 120 Other Types of 1D plots As well as basic xy plots MATLAB supports a number of other common plot types. Log graphs You can create line graphs with log scaling on either or both axes by using the commands semilogx, semilogy and loglog. These commands use the same syntax as the plot function. semilogx(x,y) semilogy(x,y) loglog(x,y) Log graphs can be useful when you are deciding on what kind of model to fit to a data set (eg power model or exponential model). To determine which model is appropriate, you investigate which graph results in the plotted data falling on a straight line. y = mx + c y = m log(cx) y = ecemx y = cx m 121 Bar graphs You can create bar graphs with the bar function. The syntax is the same as plot function: bar(x,y) For each x value a bar is drawn with the corresponding y value used as the height. You must make sure that there are no duplicates in the x array. Here is a plot of some hourly observations of an anchored boat moving with the tide. Polar graphs In some applications we need to depict data that has an angle dependence. For example, if you were designing navigational software for a yacht you would need to know how often the wind blows from each direction. A polar plot is one way to depict angle dependent data. The syntax of the MATLAB function for producing polar plots is: polar(angleData, plotData). The angleData is an array of angles (in radians). The plotData is an array containing the corresponding data values for each angle. 122 Here is a plot of wind directions in Evansville, IN. Function plotting •Note that you can also plot functions directly (instead of building arrays with the function values and plotting them). To do so use the ezplot command. The ezplot function takes a function in single quotes and a two element array that specifies the domain of the function: ezplot('x^2-x',[0,2]) 123 Plotting 2D arrays Suppose we have a 2D array containing the depths to the top of an oil reservoir. It would be more useful to visualize this data in 2 or 3 dimensions. Surface plots We can create a 3d visualisation of the top of the oil reservoir by using the surf command to generate a surface from the depth data (adding a label to the z axis and a colour bar to show what depth each colour represents). Note the American spelling of color for the colorbar command. surf(resTop) zlabel(‘Depth, ft’) colorbar 124 Note that the numerical values shown on the x and y axes simply correspond to the column and row indices of our array data. This is the default behavior if we do not pass the surf command any data on x and y coordinate values. We will learn shortly how to construct meaningful x and y values to pass as additional parameters to the surf comand. IMPORTANT NOTE: If no x and y values are passed to the surf command the value storerd in restop(1,2) will have x coordinate 2 and y coordinate 1. This is a potentical source of confusion as we are used to the first value in a pair representing the x coordinate and the second value representing the y coordinate. When plotting surfaces Matlab uses the second index value for the x coordinate. There is a logical reason for this. Traditionally we think of the x directon as being horizontal and the y direction being vertical. The first index of a 2D array is the row index (i.e. the “vertical” location within the array). For this reason the first index is associated with the y direction. You can view the data in a surface plot from other angles by rotating the plot using the mouse (choose Tools->Rotate 3D from the figure menu). Notice how after rotating our surface the value stored in row 1, column 1 of our array is now on the bottom left. If you want to create a 2D plot which views the surface from directly above you can use pcolor instead of surf. 125 Contour plots A contour plot is also a useful way to represent this kind of data. MATLAB’s contour command will create contour plots from data in a 2D array. contour(resTop) To fill the area between the contours with a color use contourf. Using for loops to plot a surface Consider the task of creating a plot of the surface described by z = f (x, y) = 5x 2 + y 3 To generate plots of 3D polynomials we first need to generate height values (z values) for a range of (x,y) points and store these heights in a 2D array. We can then use surf to visualise the surface described by this data. Usually we use (x,y) points selected from a regular rectangular grid, or mesh. 2D arrays are a very convenient way to store information about a mesh. For example we can use a 2D array to store the x co-ordinates at each point on a mesh (call this array X). Another 2D array could be used to store the y co-ordinates at each point on a mesh (call this Y). Yet another 2D array could be used to store the height at each point on the mesh (call this Z). The last array is the one we must construct to plot the surface, although we also need to pass on the information about the x and y coordinates. Nested for loops provide an excellent way of iterating through all elements in a 2D array and can also be used to calculate elements in a 2D array. 126 Remember that MATLAB follows the convention that when describing a position in a matrix, the first value is treated as the row number (vertical position) while the second value is treated as the column number (horizontal position). When thinking about points in a mesh this means the vertical position (y axis) corresponds to the first index, while the horizontal position corresponds to the second index. The height of the point shown on the grid below would therefore be stored as Z(2,3) x axis y axis If you visualise sitting the entries of a 3x4 matrix containing heights on top of this grid, then the value at each position would correspond to the height at that position. IMPORTANT – note how the first index corresponds to the y axis position NOT the x axis position. In practice we use more than 3 rows and 4 columns in a grid, to ensure a smoother surface. If we want to label the surface with the correct x and y values, we also need to construct 2D arrays containing the x and y values for each point on the mesh, as shown below: x = 0:5; y = -5:5; % create grid for i = 1:length(x) for j = 1:length(y) % i is being used to step along the x axis % j is being used to step along the y axis % Note the ORDER of i and j when indexing X(j,i) = x(i); % store x position Y(j,i) = y(j); % store y position end end % calculate the heights for all points on the the grid Z = 5 * X.^2 + Y.^3; surf(X,Y,Z) xlabel('x') ylabel('y') zlabel('height') title('5x^2+y^3') 127 Note how we passed three arguments into the surf function: surf(X,Y,Z) Omitting the X and Y information means that index numbers are used instead of the actual x and y values. See how the y axis is different in the example below. 128 Using meshgrid to create a mesh and plot a surface As we have seen, labeled 3D plots need 2D arrays of x and y values that describe a mesh. The meshgrid function allows us to easily generate these 2D arrays from 1D arrays, without having to use for loops. Consider the following code. x = [ 1 2 3 4]; y = [0 0.5 1]; [X,Y] = meshgrid(x,y) This Creates: X = 1 1 1 2 2 2 3 3 3 4 4 4 Y = 0 0.5000 1.0000 0 0.5000 1.0000 0 0.5000 1.0000 0 0.5000 1.0000 Together these two arrays desribe 12 points on a mesh. You can visualise the mesh as follows: 1 2 3 4 0 0.5 1.0 Note how the x values go across while the y values go down. Notice how if we overlaid the X array onto this mesh, it contains the x values for each point on the mesh. If we overlaid the Y array onto this mesh it contains the y values for each point on the mesh. We can find the x and y values of any point in the mesh by looking up the values from the appropriate row and column of our 2D mesh arrays. E.g. The point shown in row 2 and column 3 of the mesh has x value 3 and y value 0.5. 129 X(2,3) Y(2,3) ans = ans = 3 0.5 The 2D arrays representing the mesh can be used by surf and some other functions for plotting 2D arrays. In the case of the oil reservoir example, we could use meshgrid to easily create 2D arrays that describe the physical position of each depth measurement, to give meaningful x and y data. The meshgrid command makes it very easy to generate plots of 3D polynomials. Here is an example of plotting the surface described by z = f (x, y) = 5x 2 + y 3 that we previously did using for loops. x = y = [X, Z = 0:5; -5:5; Y] = meshgrid(x, y); 5 * X .^ 2 + Y .^ 3; % No loops needed! surf(X,Y,Z) xlabel('x') ylabel('y') zlabel('height') title('5x^2+y^3') 130 Quiver plots Quiver plots are another useful way to represent many kinds of engineering data. These plots are useful for displaying vector quantities (e.g. velocity, electric or magnetic fields etc.) with arrows indicating both direction and magnitude. Quiver plots are often combined with surface plots and/or contour plots. A quiver plot requires four 2D arrays. The first two arrays describe the x and y coordinates of a mesh (eg an X and Y array). The second two arrays describe the two components of a vector at each point in the mesh. We often refer to these as the U and V arrays. Assume we have a grid described by an X and Y array on which a magnet sits. Assume that the strength and direction of the magnetic field at each point is described by two arrays U and V. Given this information we could generate a quiver plot as follows: quiver(X,Y,U,V) The arrows on the quiver plot are vectors with components (u,v) which describe the direction and strength of the magnetic field. 131 Putting plots into documents If you want to put your plot into another document (such as a Microsoft Word document) first choose Edit->Copy Figure from the menu on the figure. The figure can then be pasted into the other document. Alternatively you can choose File>Save As from the menu on the figure and then select an image file type such as jpg, bmp or eps. These image files can then be imported into word or displayed on a web page. Animating plots Animation is quite simple in MATLAB. We just plot data repeatedly on a single figure, with a slight pause between each plot. For example to plot the function y=sin(x+t) over the x range 0 to 2pi and the time range 0 to 5 we can do the following: x = 0:2*pi/100:2*pi; for t=0:0.05:5 y=sin(x+t); plot(x,y) pause(0.2) end To export this animation we can create a movie file that can be viewed by media players such as quick time. To create a movie we "grab" a sequence of frames, storing each frame in an array and then writing the frame data out as an .avi file. nFrame = 1; x = 0:2*pi/100:2*pi; for t=0:0.05:5 y=sin(x+t); plot(x,y) movieData(nFrame) = getFrame nFrame = nFrame + 1; end movie2avi(movieData,'animation'); 132 Chapter 7 Summary Program We can now write programs that produce a variety of 2D and 3D plots % this program plots two functions of one variable, % combines them to produce a function of two variables % and then plots this function as a surface in 3D. % set up x and y values which will define a grid x=linspace(0,pi,100); y=linspace(0,2,100); % calculate values for 2D functions fx = sin(x); gy = exp(y); % set up grid and calculate values for 3D surface function [X,Y] = meshgrid(x,y); Z = sin(X) .* exp(Y); % first plot the 2D functions, on separate axes but the % same figure figure(1); subplot(2,1,1); plot(x,fx); title('sine wave'); xlabel('x'); ylabel('sin(x)'); subplot(2,1,2); plot(x,gy); title('exponential function'); xlabel('x'); ylabel('exp(x)'); % now plot the 3D surface on a second figure figure(2); surf(X,Y,Z); title('An interesting surface formed from sin(x)*exp(y)'); xlabel('x axis'); ylabel('y axis'); zlabel('height'); 133 Recommended reading Chapter 7 Graphics and Image Processing Topic Plotting basics Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 5.1 Section 5.1 Subplots and hold 5.2 Log graphs Polar plots Surfaces and contour plots Animation 5.3 5.3 5.8 B.1 Pages 259-265 269-271 271-276 279-280 282-285 290-291 335-385 661-663 134 5.2 Pages 205-207 209-211 211-216 5.2 5.2 5.7 217-219 220-221 251-254 Chapter 8: Strings So far we have dealt mainly with variables that contain numbers. Variables can also contain "strings" of characters. A string is an array of characters. Strings are useful for storing text based data and for displaying messages to users. Learning outcomes After working through this chapter, you should be able to: • • • • • • • • • Explain what a string is Create strings and string variables Use and manipulate strings and strings variables Compare strings Search for substrings Format strings using sprint Insert special characters into a string (e.g. quotes, new lines, tabs, slashes) Extract values from strings using sscanf Create and access cell arrays. What are strings? The scalars, vectors and matrices we have created to contain variables have generally contained numbers. It is also possible to create arrays that contain characters. MATLAB uses Unicode to store characters. Each character on your keyboard is represented using a special value. Unicode is a character encoding scheme that includes not only English characters but nearly all characters from every major world language, both past and present. It is capable of describing over a million different characters. You should also be aware of the older ASCII code for storing characters that is based on the order of the English alphabet. ASCII uses only 7 bits to represent a character and can only store 127 values. This is enough to describe all the characters on a standard English keyboard and it was commonly used to store characters before Unicode was created. You can think of ASCII as a very small subset of Unicode (but a useful one since we primarily deal with the English alphabet). To represent a word or a sentence we can create an array of characters. This is called a string. MATLAB uses row arrays of characters to represent strings. 135 ASCII ASCII stands for the American Standard Code for Information Interchange. The values 0 through to 31 are reserved for control characters (which were originally intended to control devices such as printers). E.g. the code value 8 represents a backspace (bs), which would cause a printer head to move back one space. The printable characters start at 32 (with the space character) and continue from there through to 126. 127 is the code for delete. Code 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Char (nul) (soh) (stx) (etx) (eot) (enq) (ack) (bel) (bs) (ht) (nl) (vt) (np) (cr) (so) (si) (dle) (dc1) (dc2) (dc3) (dc4) (nak) (syn) (etb) (can) (em) (sub) (esc) (fs) (gs) (rs) (us) Code 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Char (sp) ! " # $ % & ' ( ) * + , . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? Code 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 Char @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ Code 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 Char ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ (del) A word like “Hello” can be represented using the numerical code values: 72, 101, 108, 108, 111. 136 ASCII Art (just for fun) In the earlier days of computing, the only way to produce graphics was to use the printable ASCII characters to create images. This lead to the rise of ASCII art. Here are a few quick examples to illustrate the idea. ///"\ |6 6| \ - / .@@@. __) (__ @6 6@/ \./ \ @ = @ : : : \ _) (_'| : |) ) /' \./ '\ : |_/ / /\ _ /\ \=o==|) \ \ ) (/ /%|%%' '7/ \7%%|%%' | |`%%|%%' | |`%%|%%' | | %%|%% |_.._| /_|_\ pjb _ + . . . + /.-' . + . /.\ + . () + /. .\ // . v_____v // + __ # o o # // / +\ #\_O_/# _ -e// \__/| '-.___.-'-@@@-'-.___.-' |_eE \e-| . . . @ . . .| | . _.-. . . .-._ . | |.-' | . . | '-.| | . . . | |===@===| | . | / . . \ / . . \ _.-' . . . '-._ ------------------------- pjb __ {0O} \__/ /^/ ( ( \_\_____ (_______) pjb (_________()Oo (O) (O) || (O) || .----. || || || / O O\ / \ || / \ ' O ' : : / \ : : \ / | | : : | | __`----'______________________________\__/__| |__\__/____pjb \__/ 137 Creating strings String variables are named just like numerical variables. They are assigned values by using either other string variables or string constants. A string constant is a sequence of characters between single quotes. Here is an example of creating a string using a string constant: message = 'Hello World'; This string is an array of 11 characters. We can check this with the size command size(message) ans = 1 11 The 11 characters (including the space) have been stored in a 1x11 row array. We can access individual array elements, to see what letter is stored there. message(2) message(7) ans = ans = e W We can also create a second string variable as follows: sameMessage = message; sameMessage is a second string that will also contain the 11 characters 'Hello World'. We can also create strings from numerical values using functions like num2str and int2str and char. These functions convert a numerical value into the equivalent string. It is important to realize the difference between the number 123 and the string '123'. The number can be used in numerical calculations, where as the string consists of the 3 characters '1', '2' and '3' and it is used for displaying the characters '123' rather than for calculations. The following program illustrates the difference between the two kinds of variables: numbers = 123; letters = '123'; disp(numbers+10) disp(letters+10) Running this results in: 133 59 60 61 138 Adding 10 to the letters string resulted in a value of 10 being added to each of the 3 characters stored in the string. The character '1' is represented in Unicode by using the value 49, hence the first value in the array was printed out as 59. Likewise '2' is represented using the value 50 and '3' the value 51. To see what Unicode character is represented by the value 59 we could use the char function, which converts positive integers into the equivalent character: char(59) The value 59 represents the semi-colon character. ans = ; Confusing numerical values and strings can produce very unusual errors in your programs. To create the string '123' from the number 123, simply use the num2str function: letters = num2str(123) We can also create strings using the input command. If we wish to interpret what the user types as a string rather than a numerical value, the optional 's' argument must be passed to the input function: name = input('Please enter your name:','s'); The 's' tells the input function to interpret whatever is typed as a string. String variables are useful for preloading strings we may wish to use in a range of different situations. eg: • Input commands to the user • Messages for display • Plot titles, labels etc Storing text in strings is also often useful as we can then use functions to search through our strings and look up text information. Manipulating strings As strings are simply character arrays we can use many of MATLAB's methods for handling arrays with them. Accessing individual elements Individual characters can be accessed, just as we access individual elements of an array: department = 'engsci' c = department(1) c = 'e' 139 We can also assign new values to existing elements of an array: department(1)='E'; department(4)='S' department = 'EngSci' Obtaining subranges department = 'EngSci' department(1:3) % corresponds to the string 'Eng' department(4:6) % corresponds to the string 'Sci' Concatenation We can concatenate strings together, just as we can concatenate normal arrays together. Concatenation works on both string variables and string constants. department = 'EngSci' task = 'problem solving' totalMessage = [department ' equals ' task] Will prduce the result: totalMessage = 'EngSci equals problem solving' Note that we get strange results when we concatenate an array of characters with an array of numerical values. Consider the following code: message = ['value of 10 squared is ' 10^2] It is likely the programmer intended to create a string called message containing the message: 'value of 10 squared is 100' Instead, what is actually created is the string 'value of 10 squared is d' This is because we are attempting to concatenate the array 'value of 10 squared is ' with the numerical value 100. Before concatenating, MATLAB automatically converts the numerical value 100 into a string by interpreting it as a character (100 is the number that corresponds to the Unicode character 'd'). If we want 100 to be displayed on the end, rather than a 'd' we must first convert the numerical value of 100 to the string '100' by using the num2str function: message = ['value of 10 squared is ' num2str(10^2)]; 140 Changing case Strings are case-sensitive. 'a' is not equal to 'A'. All characters in a string can be converted to lower or upper case by using the lower or upper functions. department = 'EngSci'; display(lower(department)); display(upper(department)); Running the above code produces the output: engsci ENGSCI Comparing strings Two strings are equal if they contain exactly identical characters in each position, including characters such as spaces. This means they need to be exactly the same length. Comparing two strings is very useful for checking what text a user has typed in (eg if they are prompted to type 'yes' or 'no' to a question we can compare the string entered with the 'yes' and 'no' strings and then take appropriate action). String comparison is also handy when you wish to search through a cell array of strings, to find one particular string that matches up with a string the user has entered. This allows us to do things like search through lists of names until we find the correct person. There are several functions for comparing two strings strcmp strncmp strcmpi Compare two strings Compare first n positions Compare ignoring case The strcmp takes two strings as inputs and returns 1 if they are identical and 0 otherwise. Strings are case sensitive, so the string 'Hello' is NOT the same as the string 'hello'. The strncmp takes two strings as inputs and an integer n. strncmp returns 1 if the first n positions of the two strings match exactly. Otherwise 0 is returned. strncmp is case sensitive. The strcmpi function takes two strings as inputs and returns 1 if they are identical, ignoring case. Otherwise 0 is returned. 141 String comparison examples string1 = 'engsci' string2 = 'EngSci' strcmp(string1,string2) strcmp(string1,'engsci') ans = ans = 0 1 strncmp('engsci','Engsci',3) strncmp(string2,'Engsci',3) ans = ans = 0 1 strcmpi(string1,string2) strcmp(string1,'engsc') ans = ans = 1 0 The strcmpi function is particularly handy when comparing user input, as if a user answered yes to a question we don't care whether they typed 'YES', 'yes' or 'Yes'. ansr = input('Does strcmpi ignore case when comparing strings?','s') if (strcmpi('yes',ansr)) disp('Excellent answer!'); else disp('Sorry, you are wrong'); end Regardless of what case the user types the word yes in, the text 'Excellent answer!' will be displayed. An alternative to using the strcmpi function is to convert all strings to the same case before comparing them, eg: ansr = input('Is there more than one string compare function?','s') if (strcmp('no',lower(ansr)) disp('Wrong! There are several.'); else disp('Correct'); end 142 Searching for substrings Sometimes instead of comparing two strings to see if they are identical we wish to see if a small "substring" occurs in a larger string, and if so where it occurs. The strfind function allows us to search a string for occurrences of a shorter string. It takes as inputs the string and a shorter pattern string to search for. The output is an array that contains the starting index of each occurrence of the pattern. If the pattern was not found then the array will be empty (which means it has zero length). strfind('Bananarama','ana') ans = 2 4 dept = 'Engineering Science' strfind(dept,'ng') ans = 2 10 strfind(dept,'science') ans = [] Note the word science was not found, as strfind is case sensitive. If we wanted to search for the substring 'science' regardless of case we could have done: strfind(lower(dept),'science') ans = 13 If all you care about is whether a substring was found or not you can simply examine the length of the array to determine how many times the substring was found. phrase = input('Enter a sentence:','s'); theLocations = strfind(lower(phrase),'the'); if (length(theLocations) == 0 ) disp('Your sentence did not contain the letters "the"'); else disp('Your sentence contained the letters "the"'); end 143 Formating with sprintf The sprintf command allows us to create nicely formatted strings for display to users, or to use with string commands. The syntax of the sprintf command is: s = sprintf(format, variables); The first argument is a format string that includes special characters, which define how to write out the data. Following the format string are the variables to write out. The output from sprintf is the format string with each format specifier replaced by one of the formatted variables. Variables are processed in order, so that the first format specifier is replaced by the value of the first variable, the second specifier by the second variable and so forth. A simple example will help to make things clearer. name = 'Bob'; mark = 98; s = sprintf('%s scored a mark of %i out of 100',name,mark) s = Bob scored a mark of 98 out of 100 The first specifier is '%s', which specifies a string value. The first variable, name, is inserted as a string in place of the '%s'. The second specifier is the '%i', which specifies an integer value. The second variable, mark, is inserted as an integer in place of the '%i'. The result is a nicely formatted string that is stored in s. There is a wide range of specifiers available. Here are some of the more common ones: specifier %s %c %d or %i %e %f %g output string character decimal integer scientific notation decimal floating point the shorter of e or f example hello c -23 1.2345e+10 23.1234 Inserting a number between the % character and the specifier allows you to specify the minimum width to reserve for displaying the value. This is handy when wanting to format output in columns. string = sprintf('The sqrt of %5d is %3d',1,1); disp(string); string = sprintf('The sqrt of %5d is %3d',100,10); disp(string); string = sprintf('The sqrt of %5d is %3d',10000,100); disp(string); The sqrt of 1 is 1 The sqrt of 100 is 10 The sqrt of 10000 is 100 144 Notice how 5 characters are set aside for the first value and spaces are added to make sure the value takes up 5 characters worth of space. When formatting numerical values you can control the number of decimal places to use. Insert a decimal point followed by a number between the % character and the specifier to indicate how many decimal places to use: s = sprintf('1/900 with 4dp and scientific notation is %.4e',1/900) Running this results in: s = 1/900 with 4dp and scientific notation is 1.1111e-003 Note that the variables passed in can either be just a variable or an expression that MATLAB will calculate before formatting: s = sprintf('pi with 2dp is: %.2f and pi squared is: %.2f',pi,pi^2) Running this results in: s = pi with 2dp is: 3.14 and pi squared is: 9.87 If necessary you can control both the minimum width and the number of decimal places to use: s = sprintf('pi with 2dp is: %6.2f',pi); disp(s); s = sprintf('pi with 3dp is: %6.3f',pi); disp(s); s = sprintf('pi with 4dp is: %6.4f',pi); disp(s); Running this results in: pi with 2dp is: 3.14 pi with 3dp is: 3.142 pi with 4dp is: 3.1416 Note the rounding 145 Special characters Most characters you will deal with are either letters, numbers or punctuation symbols. There are however some special characters used to describe the layout of text on a page. When you type a document using a word processor, every key stroke is stored as a character. This includes things like when you hit the tab key or the enter key. Hitting tab in a word processor will insert a single “tab” character while hitting the enter key will insert a “newline” character. If we wish to insert a tab or new line character into a MATLAB string that will be processed by sprintf, we use a backslash followed by a special character code to do so. The backslash is sometimes referred to as an escape character, as it escapes normal character entry and allows us to enter a special character. For example a tab character can be inserted using \t while a newline character can be inserted using \n. As the backslash is used for entering special characters, if you ever want to enter a backslash you need to use the special character code \\. >> message = 'We use a \\n character to \nmove to a new line'; >> sprintf(message) ans = We use a \n character to move to a new line One other character which is tricky to enter in a string is the single quote character, as this is used to signal the end of a string. If you do want to enter a single quote character, enter two single quote characters in a row. This works both for strings passed to sprintf and the disp command. >> message = 'Peter''s tip on entering single quotes, use two!'; >> disp(message) Peter's tip on entering single quotes, use two! 146 Processing with sscanf We can also use format specifiers to help us scan strings for formatted data. The sscanf function keeps reading data of a specified format from a string until the end of the string is reached or it runs out of compatible data. The syntax of the sscanf command is as follows: data = sscanf(s, format, size); The variable s is the string to scan. The format is a string detailing the format of the data we wish to read. The same format specifiers are available as those that we met when using sprintf. The size argument is optional. If it is left off the sscanf command will attempt to read all values of the specified format until the end of the string is reached or incompatible data is found. If a size is specified it will attempt to read enough data to fill an array of the specified size. The data read by sscanf is returned as an array. string = 'e is approx 2.7183'; e = sscanf(string,'e is approx %f'); e = 2.7183 The variable e is a 1x1 array containing an approximate value of the constant e. string = 'x = 2.3 y = 1.5'; point = sscanf(string,'x = %f y = %f'); point = 2.3000 1.5000 The variable point is a 2 element array which contains the x and y coordinates of the point. 147 Cell Arrays Strings are arrays of characters. Sometimes we wish to work with arrays of strings. Using 2D arrays is one possibility but every row in a 2D array has the same length. Strings often have different lengths so instead of using a standard 2D array MATLAB provides us with a special kind of array where each element of the array is a string. These arrays are called Cell arrays. They are created and indexed with curly braces: message = { 'hello', 'world' }; message is a two element cell array. It has length two. If we had used square brackets instead of curly braces, MATLAB would have concatenated the two strings into one. The length of this array would have been ten as 'helloworld' has ten characters. You must use curly braces if you want to create a cell array. We can access the first string in the array using curly braces: greetingString = message{1}; greetingString now contains the string 'hello'. Note that using round brackets results in something quite different: greetingCellArray = message(1); greetingCellArray now contains a 1x1 cell array, which has one string as it's element. When working with cell arrays it is very important to remember to use curly braces. If you use round brackets to try and index a cell array, you will get a 1x1 cell array back rather than a string. This can be very confusing if you do not spot your error. Some MATLAB string functions will also work on cell arrays but the results can be rather confusing. If working with a cell array it is often a good idea to use a for loop to work through your cell array, allowing you to work on one string at a time. myMessage = { 'Remember', 'to', 'use', 'curly', 'braces' } for i = 1:length(myMessage) word = myMessage{i}; if (strcmp('curly',word)) disp(['curly is word ' num2str(i)]); end end Running this will result in the output: curly is word 4 In the next chapter we will learn about importing data from files into MATLAB. When importing a file into MATLAB it is quite common for a cell array to be created. 148 Space for notes 149 Chapter 8 Summary Program We can now write programs that manipulate strings. For example, the following program searches for the exam result of a student name that is entered by the user. % search for a student and display their exam results % normally we would import some examination data from a file % for this example we will just create a cell array of names % and an array of marks name = {'Adam Blogs','Adam Smith','John Smith'}; mark = [67, 42, 91]; searchName = input('Please enter a student name:','s'); % total number of students n = length(mark); studentFound = 0; i = 0; % search until student found or we run out of students while (~studentFound & i < n ) % i is the index into the student mark arrays. i = i + 1; % get name from cell array, note curly braces studentName = name{i}; locations = strfind(lower(studentName),lower(searchName)); % check if search name found in one or more locations % of the student name string if (length(locations) > 0) disp(['Found student ' studentName]) response = input('Is this the correct student?','s'); % check if first letter of reponse is y or Y if( strcmpi('Y',response(1)) ) % use ... to spread this command over 2 lines display([studentName ' got a mark of ' ... num2str(mark(i))]); studentFound = 1; end end end 150 % summary program continued if (studentFound == 0) message = sprintf('%d students were scanned',n); disp(message); message = sprintf('Student %s was not found',searchName); disp(message); end Examples of this program running are given below (user input is in bold): Please enter a student name:adam Found student Adam Blogs Is this the correct student?n Found student Adam Smith Is this the correct student?y Adam Smith got a mark of 42 Please enter a student name:smith Found student Adam Smith Is this the correct student?no Found student John Smith Is this the correct student?no 3 students were scanned Student smith was not found Recommended reading Chapter 8 Strings Topic String variables Strings Introduction to Matlab 7 for Engineers (2nd ed) Section Pages 1.4 37 4.4 209-210 151 A Concise Introduction to Matlab (1st ed) Section Pages 1.4 27 4.3 168 152 Chapter 9: Files MATLAB commands are not the only thing we want to be able to store in files. Often we wish to manipulate some data in order to calculate a result. Usually this data is stored in a file. It is important to be able to get that data from the file into MATLAB, in a format that MATLAB can work with. We also may wish to write out the results of a calculation to a data file. Learning outcomes After working through this chapter, you should be able to: • • • • Load and save data to a MAT file Use the import wizard to import data from files Use the MATLAB file commands for reading data directly from a file Use the MATLAB file commands for writing data out to a file MAT files MATLAB has a file format designed for saving variables from the MATLAB workspace. Variables can then be loaded back into the workspace from the file. These files are called MAT files and they have a .mat extension. By default the files are not human readable, which means that you cannot view the values of the variables by opening a MAT file in a text editor. We use the save and load commands to save and load variables in the workspace. Saving variables Once we have created some variables in the workspace it is then possible to save them to a file for later use. For example: A = [1 2; 3 4] b = [1; 0] time = 3; save example A b time The save command will create a file called example.mat and save the contents of variables A, b and time to the file. If we do not specify which variables to save, MATLAB will save all variables in the workspace to the file. If you want to create a human readable data file you can save the data as ascii characters (strings) by using the -ascii option: save example -ascii A b time The file created can then be read by humans but it will take up more space on your computer's hard disk. 153 Loading variables If we clear all our variables out (either by restarting MATLAB or using the clear command) it is now still possible to get one or more of our saved variables back again by using the load command: load example A b This loads variables A and b into the workspace from our file example.mat. Note that if wanted to load just the variable A we could type: load example A If we want to load everything stored in the file example.mat we would type: load example Importing data from files using the wizard MAT files are ideal for saving the value of variables that were created using MATLAB. Sometimes we need to read in values from files that were created by other applications such as excel. MATLAB provides an import wizard, which helps you to read data from other file formats. To start the import wizard select "Import Data" from the menu bar: 154 You will then be prompted to select a file to import data from. This could be a txt file, a spreadsheet or some other kind of file. For example, we may wish to import the data contained in the following text file: This file contains temperature and humidity data for a weather station on Waiheke island. The import wizard will attempt to read the data into arrays. Notice that the very first row contains headings for our three columns. The first column of our data file is a string specifying the time while the other two columns contain numerical values (temperature in Fahrenheit and humidity). When we use the import wizard to open a file, the wizard will attempt to read data and create arrays to hold that data. It will create a preview of the arrays that will be created. 155 You may need to specify the character used to separate columns, if the import wizard has not picked the correct character. In this case the tab character was successfully used: 156 The default mode for the data import wizard is to import each column from your data file as a separate vector. In this case, there are three columns, so the wizard will create three vectors. The wizard has also identified the first row as a header row, and named the vectors Time, TemperatureF, and Humidity accordingly. Since the file is 84 lines long, containing one header row and 83 rows of data, each vector will have size 83x1. If a different form is more appropriate for the data, you could select a different output mode. For example, you could import the data as a cell array, which would result in an array of size 84x3, containing all of the data from the file (including the header row): Once you have finished importing the data, the variables will be created in the workspace. 157 File I/O Unfortunately sometimes the import Wizard fails to import our data correctly and we need another way of reading data from files. Note that it is impossible for MATLAB to understand all file formats, as people create new formats all the time, so it is important that we have ways of dealing with unusual file formats. Fortunately we can write our own MATLAB code to read formatted files. We can also use MATLAB to write out nicely formatted files, allowing us to create our own file formats for storing our data. MATLAB provides a number of I/O (Input/Output) functions that can be used for reading input from files and writing output to files. The I/O functions are based on the standard C library functions for reading and writing to files. You will encounter these C library functions in the C part of the course. Before reading or writing a file you need to open the file. After working with a file you should always close it. Opening and closing files To work with a file we need to first open it and get an identifier for the file. It is possible to have several files open at once and the file identifier provides an id we can use to tell MATLAB which file to read or write from. To open a file we use the fopen command: fid = fopen(filename, permission); The filename is a string containing the name of the filename to open. The permission variable is a string which tells the fopen command what kind of access we want to the file (eg permission to read or permission to write). Some possible values for the permission string are listed in the table below. 'r' 'w' 'r+' 'a' Reading only Writing only Reading and writing Appending only (adding on to the end of a file) If the fopen command successfully opens a file it will return an integer file id. If the file fails to open it will return the value -1. A file may fail to open if the incorrect file name has been provided or if the file is being used by some other application. It is a good idea to check the value of the file id and display an error message if the file failed to open. To open a file called mydata.dat for reading we would use the following command: fid = fopen('mydata.dat','r'); 158 It is a good idea to check if the file opened successfully by testing the fid value: if fid == -1 disp('Error opening file') end Once we have finished reading or writing to a file it is important to tidy up after ourselves and close the file. A file that is still open may not be able to be used by other applications. Closing the file also frees up some computer memory. To close the file we use the fclose command, passing in the file id of the file to close: status = fclose(fid); The fclose command returns a status variable that indicates whether or not the file was closed successfully. If the file closed successfully a value of 0 is returned. If there was a problem closing the file a value of -1 is returned. Reading from files There are two possible functions to use when reading files. The fscanf function allows you to potentially read the contents of an entire file with just one command. You can also use it to read a set number of values from a file. It is very convenient when the file format is very simple. The fgetl command allows you to read a file line by line. For more complicated file formats this is useful as you can then use string processing to extract data from each line in turn. fscanf The fscanf function keeps reading data of a specified format until the file is finished or it runs out of compatible data. The syntax of the fscanf command is as follows: data = fscanf(fid, format, size); The fid is the identifier of the file we are reading from. The format is a string detailing the format of the data we wish to read. The same format specifiers are available as those that we met when reading and writing strings. It may help to remember that fscanf is very similar to sscanf, the difference being that it scans a file instead of a string. Here is a reminder of some of the more common format options. specifier %s %c %d or %i %e %f %g output string character decimal integer scientific notation decimal floating point the shorter of e or f 159 example hello c -23 1.2345e+10 23.1234 The size argument is optional. If it is left off the fscanf command will attempt to read all values of the specified format until the end of the file is reached or incompatible data is found. If a size is specified it will attempt to read enough data to fill an array of the specified size. The data read by fscanf is returned as an array. The following code opens a file and then reads in as many real numbers from a file as it can: fid = fopen('mydata.dat','r'); data = fscanf(fid, '%f'); fclose(fid); The following code opens a file and then reads in only the first 5 integer values from the file: fid = fopen('mydata.dat','r'); data = fscanf(fid, '%i', 5); fclose(fid); The following code opens a file and then reads the first eight numbers into a 2x4 array: fid = fopen('messy.dat','r'); data = fscanf(fid, '%d', [2,4]) fclose(fid); Note that the values are read from the file row by row (going across) but data is written column by column. If the contents of messy.dat is as follows: 123 45 6789 10 11 12 13 When we use the above code we get the following result: 160 fgetl The fgetl commands gets a single line from a file and stores the line as a string. The string can then be processed using the various string functions we have already encountered such as sscanf or str2num. The syntax of the fgetl command is as follows: line = fgetl(fid) The fgetl commands returns the next line of the file associated with file identifier fid. The MATLAB string returned does NOT include the end of line character '\n'. If the end of file is encountered then the value -1 is returned. Here is an example of using fgetl to read a line from our messy.dat file: fid=fopen('messy.dat','r'); % get first line from the file line = fgetl(fid); % read three integers from the string into an array values = sscanf(line,'%d %d %d'); fclose(fid); It is common to use a while loop to loop through a file and process each line one at a time. This can be done as follows: % Open the file for reading fid=fopen('messy.dat','r'); if( fid == -1) disp('Error opening the file'); else % get first line from the file line = fgetl(fid); % loop through the file until we run out of lines while (ischar(line)) % check if line contains characters % display contents of line string, could process it instead disp(['Line read was:' line]) % get next line line = fgetl(fid); end % close the file once we are finished with it fclose(fid); end 161 Writing to files Just as for reading from files, we need to first open a file before we can write to it, only this time we need to open it with write permission, using 'w'. fid = fopen('squares.txt','w'); To write to a file we use the fprintf command. This is very similar to the sprintf command, except that instead of returning a string, the string is written to the file. The syntax of the fprintf command is: fprintf(fid, format, variables); It writes out the variables using the specified format until all values of the specified format have been written. The format specifiers are the usual specifiers we use with the fscanf, sscanf and sprintf commands. If the variables include arrays then the values are written out column by column. % This script writes out the first 10 square numbers % to a file x = 1:10 squares = x.^2; % open the file for writing to myfid = fopen('squares.txt','w'); if( myfid == -1) disp('Error opening the file'); else % write out array to file, one value per line fprintf(myfid,'%d\n',squares); % close the file once we are finished with it fclose(myfid); end Why does my file not have newlines when viewed in Notepad? If you open the file squares.txt on a Windows machine using Microsoft Notepad all the data will appear to be on one line, whereas using Microsoft Wordpad or Microsoft Word the file views correctly. Read the next page for the reason why and how to avoid this problem. 162 Using text mode (or a brief history of newlines) When a typist used a manual type writer the paper was held by a device called a “carriage” and as you typed the carriage moved the paper sidewise. Before the typist could add a new line of text they had to do TWO things: 1) Return the “carriage” so that they would be back typing on the left hand side of the paper 2) Feed the paper up one line (a line feed) Early computers often used a system called teletype, where a mechanical typewriter was part of the user interface. To type a new line on paper required a teletype device to do exactly the same two things typists did. Two control characters were used to tell the teletype device what to do: 1) A carriage return, ASCII value 13, abbreivated to cr and represented by \r 2) A line feed, ASCII value 10, abbreviated to nl and represented by \n As operating systems were developed, operating system programmers needed to make a choice about how to represent a new line in a text file. Different programmers went with different choices: - Windows went with representing a newline the same way as was used with teletype, using two characters; a carriage return followed by a line feed, i.e. \r\n Mac went with representing a newline with the single control character \r Unix (and Linux) went with representing a newline with the single control character \n The Mac operating system was eventually redesigned and they moved to using \n from OSX onwards. The consequences of these choices made in the long distant past are still with us today and moving text files between operating systems can cause much frustration (why don’t my newlines work, why, Why, WHY!) When writing text files for a Mac or Linux machine you can just use \n to represent a newline. When writing text files for a Windows system you should represent a newline with two characters, i.e. \r\n to ensure that all Windows applications can display the text file correctly. It is a pain to have to add the \r in front of the \n every time you want a newline. Fortunately you don’t have to if you use the Matlab “text mode” when writing to a file. To use the text mode include the letter t when opening, e.g: myfid = fopen('squares.txt','wt'); On a Windows machine using text mode will mean a carriage return will be automatically inserted in front of any line feed. That is \n characters are actually written out as \r\n This saves you the hassle of having to do it yourself. You can also use text mode to read in text from a file, in which case the carriage returns are removed for you as text is read in. To open in read mode add the letter t when opening, e.g: fid=fopen('messy.dat','rt'); 163 Chapter 9 Summary Program We can now read data from files and write data to files. For example, the following program writes some exponential data to a file and the second program reads that data back in. % This script writes data to exponential.txt % each line consists of an exponent and the value % of e to that exponent % calculate data to write x = 0:.1:1; y = [x; exp(x)]; % open the file for writing to myfid = fopen('exponential.txt','w'); if( myfid == -1) disp('Error opening the file'); else % write out array to file, column by column fprintf(myfid,'%6.2f %12.8f\n',y); % close the file once we are finished with it fclose(myfid); end 164 % This script reads the data from exponential.txt % one line at a time % Open the file for reading filename = 'exponential.txt'; fid=fopen(filename,'r'); if( fid == -1) disp(['Error opening file ' filename]); else % get first line from the file line = fgetl(fid); % loop through the file until we run out of lines while (ischar(line)) % read two values from the line into a 2 element array values = sscanf(line,'%f %f'); message = sprintf('e to the power of %g is %g',values); disp(message); % get next line line = fgetl(fid); end % close the file once we are finished with it fclose(fid); end Recommended reading Chapter 9 Files Topic Data files Introduction to Matlab 7 for Engineers (2nd ed) Section Pages 3.4 172-176 165 A Concise Introduction to Matlab (1st ed) Section Pages 3.4 145-147 166 Chapter 10: Linear Equations and Linear Algebra MATLAB has very good support for working with both vectors and matrices. This makes it an ideal tool for solving linear algebra problems. In particular is is very easy to solve systems of linear equations that are written in Matrix form. Learning outcomes After working through this chapter, you should be able to: • • • • Solve systems of linear equations using MATLAB Solve basic linear algebra problems with MATLAB Use matrix transformations (rotation, translation, scaling, shearing) Apply transition matrices Solving systems of linear equations Systems of linear equations appear in many different branches of engineering. In MM1 you were introduced to solving equations using Gaussian elimination. You will also have learnt how to use matrix algebra to solve systems of linear equations in matrix form. MATLAB supports both methods. Solving a linear equation in 3 lines Consider the following system of linear equations: x1 + 2x 2 + 3x 3 = 1 2x1 + 5x 2 + 3x 3 = 6 + 8x 3 = −6 x1 + This system of linear equations can be written in matrix form as: 1 2 3 x1 1 2 5 3 x 2 = 6 1 0 8 x 3 −6 1 x1 1 2 3 which is of the general form: Ax = b where A = 2 5 3 x = x 2 b = 6 −6 x 3 1 0 8 The solution of Ax = b is x = A −1 b , ie x is the inverse of A multiplied by b. 167 To solve this equation in MATLAB we simply type the following: A = [1 2 3; 2 5 3; 1 0 8]; b = [1; 6; -6]; x = inv(A) * b The result is: x = 2.0000 1.0000 -1.0000 Note that MATLAB displays only 4 decimal places by default. The 4 zeros tell us that the first value, as calculated by MATLAB is close to but not exactly 2. Similarly the second and third values are not exactly whole numbers. This is due to difficulties in representing decimal numbers accurately. We can use the "left division" operator to find a solution using a method based on using Gaussian elimination: A = [1 2 3; 2 5 3; 1 0 8]; b = [1; 6; -6]; x = A \ b The result is: x = 2 1 -1 MATLAB does all the hard work for us and the solution by Gaussian elimination matches exactly the real solution, so the left division operator seems like a better method to use. In general the left division method is more accurate. (Note we can always check our solution by calculating A*x to see if we get b) Some background theory In MM1 you were introduced to the matrix form of systems of linear equations: Ax = b . Recall that if the matrix A has an inverse you can multiply both sides of the equation by the inverse of A to get: A −1 Ax = A −1 b Ix = A −1 b That is, the solution is the inverse of A multiplied by b. x = A −1 b 168 Remember that this method only works if A has an inverse. A matrix has an inverse if, and only if, the determinant of the matrix is nonzero. To find the determinant of a square matrix A we can use the det command: det(A) If the determinant is nonzero then the inv command can be used to calculate the inverse. Once the matrix A and the column vector b have been assigned values it only takes one line of code to solve the system. x = inv(A) * b MATLAB also supplies the left division method, which performs the equivalent to Gaussian elimination but is very quick to type: x = A\b The left division method is preferred as computing the inverse of a matrix and then performing a matrix multiplication takes more time than performing Gaussian elimination. Also the left divison method is less likely to introduce errors due to rounding. It can still be worth checking the determinant of A is nonzero, to check whether our equations have a solution. A traffic flow example Consider the problem of determining how many cars per hour travel through two sections of street. We know how many cars go into and out of Main St. We also know how many cars go into Brown St and how many come out of King St. We would like to determine how many cars per hour come into King St and how many travel on the small section of Main St between Brown and King St. This particular problem is easy to solve by hand but we can use the same principles to determine traffic flow in much larger road networks. 169 Recall the fives steps for problem solving 1. 2. 3. 4. 5. State the problem clearly Describe the input and output information Work the problem by hand (or with a calculator) for a simple set of data Develop a solution and convert it to a computer program Test the solution with a variety of data State the problem clearly Determine x1 and x2 using the known traffic flows of 400, 500, 600 and 700 cars/hour on segments of Main St, King St and Brown St (which are one way streets). Describe the input and output information Input: • • • • Main St (north of intersection 1), 500 cars/hour King St (west of intersection 1), 700 cars/hour Brown St, 400 cars/hour Main St (south of intersection 2), 600 cars/ hour Output: • x1 cars per hour travelling on King St (east of intersection 1) • x2 cars per hour travelling on Main St (between intersection 1 and intersection 2) Work the problem by hand (or with a calculator) for a simple set of data Balance the flow of cars into and out of each intersection. Intersection 1 x1 + x 2 = 500 + 700 Intersection 2 x 2 = 600 + 400 Clearly x2 is equal to 1000 cars/hour, so x1 + 1000 = 1200 ⇒ x1 = 200 Develop a solution and convert it to a computer program The two equations we need to solve can be expressed as 1 1 x1 1200 = 0 1 x 2 1000 170 To solve this problem in MATLAB we can use the “left division” operator A = [1, 1; 0, 1]; b = [1200; 1000]; x = A\b x = 200 1000 Test the solution with a variety of data To test our solution we verify that A*x is equal to b. A*x ans = 1200 1000 171 Solving basic linear algebra problems Much of the drudgery of working with vectors can be removed by using MATLAB functions. The table below lists some of the key functions available for working with vectors Function norm dot cross Use Length of a vector Dot product (scalar product) Cross product (vector product) Example norm(a) dot(a,b) cross(a,b) Armed with these functions we can easily solve a range of linear algebra problems. Find the angle between two vectors 1 3 Find the angle between the two vectors: a = 2 b = 2 3 1 Recall that a • b = a b cosθ Hence that angle theta is given by: θ = arccos a •b where arccos is the inverse cosine function ab Using MATLAB we can find theta as follows: a = [1; 2; 3]; b = [3; 2; 1]; theta = acos( dot(a,b) / (norm(a)*norm(b)) ) theta = 0.7752 172 Find the projection of one vector onto another 1 1 Find the projection of vector u onto vector v: u = 2 v = 0 3 1 Recall that p = u• v v v• v Using MATLAB we can find the projection as follows: u = [1; 2; 3]; v = [1; 0; 1]; p = ( dot(u,v)/dot(v,v) ) * v p = 2 0 2 Find the area of a triangle defined by two vectors 1 3 Find the area of the triangle defined by the two vectors: a = 2 b = 2 3 1 Recall that a × b = a b sin θ nˆ The cross product creates a vector that is normal to both a and b, with magnitude a b sin θ , ie the area of a parallelogram with sides a and b. The area of a triangle with sides a and b is half that of the parallelogram. Hence: Area = a ×b 2 a = [1; 2; 3]; b = [3; 2; 1]; area = norm(cross(a,b))/2 area = 4.8990 173 Find the equation of a plane containing three points 1 1 0 Find the plane that passes through the three points: p = 2 q = 0 r = 2 3 1 1 The lines pq and pr define two vectors in the plane. We can use the cross product of these two vectors to create a normal for the plane. The equation of a plane with normal n, through a point p is given by x •n = p•n We can find n and p • n using MATLAB p = [1; 2; 3]; q = [1; 0; 1]; r = [0; 2; 1]; pq = q - p; pr = r - p; n = cross(pq,pr) n = 4 2 -2 rhs = dot(p,n) rhs = 2 The equation of the plane is: 4 x • 2 = 2 or − 2 4x + 2 y − 2z = 2 174 Matrix Transformations A point (or points) can be transformed by using a square matrix. It is possible to create matrices representing stretches, enlargements, reflections and rotation. To transform a point we perform a matrix multiplication with the transformation matrix and the point. This is easily done in MATLAB. For example, we can easily transform the unit square as follows: Stretch the x direction by 3, reflect in the y axis and then rotate by 45 degrees. The transformation matrices required are: x stretch by 3 reflection in y axis rotation by 45 degrees 3 0 X= 0 1 −1 0 Y= 0 1 cos(π /4) −sin(π /4) R= sin(π /4) cos(π /4) The MATLAB code to transform the unit square is as follows: % matrix representing the unit square S = [0 1 1 0; 0 0 1 1] % plot square fill( S(1,:), S(2,:), 'r'); title('Unit square transformed'); axis equal % X % Y % R matrix to stretch x axis by a factor of 3 = [3 0; 0 1] matrix to reflect in y axis = [-1 0; 0 1] matrix to rotate by pi/4 radians (45 degrees) = [cos(pi/4) -sin(pi/4); sin(pi/4) cos(pi/4)] % perform transformations T = R * Y * X *S % plot transformed square hold on fill( T(1,:), T(2,:), 'b'); 175 176 Transition Matrices MATLAB is particularly useful when working with transition matrices. Consider the following problem. A taxi company has 200 taxis and studies them travelling between Auckland airport and Auckland city centre. At the start of the week (Monday 9am) it has 60 taxis at the airport and 140 in the city. Over each hour it observes that 20% of the airport taxis come into the city, and 30% of the city taxis move out to the airport. 1. How many taxis are there at the airport after one hour? 2. How many taxis are there at the airport after five hours? 3. What is the steady state distribution of taxis? First we need the transition matrix for the Markov chain: to airport to city from airport from city 0.8 0.3 T= 0.2 0.7 How many taxis are there at the airport after one hour? We need to perform the calculation 0.8 0.3 60 0.2 0.7 140 T = [0.8 0.3; 0.2 0.7]; xinit = [60; 140]; afterOneHourState = T*xinit afterOneHourState = 90 110 This means that 90 taxis are at the airport and 110 are at the city. How many taxis are there at the airport after five hours? 0.8 0.3 60 We need to perform the calculation 0.2 0.7 140 5 T = [0.8 0.3; 0.2 0.7]; xinit = [60; 140]; afterFiveHoursState = T^5*xinit afterFiveHoursState = 118.1250 81.8750 This means that approximately 118 taxis are at the airport and 82 are at the city. 177 What is the steady state distribution of taxis? We need to solve 0.8 0.3 x1 x1 = ie Tx = x 0.2 0.7 x 2 x 2 Tx = x Tx = Ix Tx − Ix = 0 (T − I)x = 0 0.8 0.3 1 0 x1 0 = − 0.2 0.7 0 1 x 2 0 −0.2 0.3 x1 0 = 0.2 −0.3 x 2 0 Note that two equations represented in the matrix are essentially identical (one is a scalar multiple of the other), so we can remove one of them. We also have the constraint that x1 + x 2 = 200 Hence we wish to solve: −0.2 0.3 x1 0 = 1 x 2 200 1 T = [-0.2 0.3; 1 1]; b = [0; 200]; steadyState = T\b steadyState = 120 80 Note that another alternative to this method is to simply see what happens in the long term, as markov chains tend to settle down to a steady state fairly quickly. eg we could see what happens after one day: T = [0.8 0.3; 0.2 0.7]; xinit = [60; 140]; afterOneDayState = T^24*xinit afterOneDayState = 120.0000 80.0000 178 Chapter 10 Summary Programs We can now write programs to solve linear alegbra problems. For example, the following program finds the intersection of two lines: x1 + 2x 2 = 1 2x1 + 5x 2 = 0 % find the intersection of two lines: % x_1 + 2x_2 = 1 and 2x_1 + 5x_2 = 0 A = [1 2; 2 5]; b = [1; 0]; if (det(A) == 0) message = 'No solution'; else x = A\b; message = sprintf('Intersection is (%g,%g)',x(1),x(2)); end; disp(message); An example of this program running is given below: Intersection is (5,-2) 179 The following program finds the area enclosed by three points p q, r and the angle at point q. % find the area enclosed by three points p, q, r % p q r define three points in space = [1; 2; 2]; = [1; 2; 3]; = [0; 0; 3]; % construct a vector from p to q pq = q - p; % construct a vector from p to r pr = r - p; % angle between pq and pr theta = acos( dot(pq,pr) / (norm(pq)*norm(pr)) ); % area of triangle area = norm(cross(pq,pr))/2; message = sprintf('Angle is %f and area is %f',theta,area); disp(message); An example of this program running is given below: Angle is 1.15026 and area is 1.11803 Recommended reading Chapter 10 Linear Equations and Linear Algebra Topic Matrix and vector operations Solving linear equations Linear equations with matrices Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 2.4 Pages 97-107 Section 2.4 Pages 57-69 6.1 6.2 359-376 365-376 2.5 69-77 180 Chapter 11: Differential Equations and "Function" Functions Ordinary differential equations arise in many branches of engineering. MATLAB can be used to find numerical solutions to differential equations. This is very useful when you meet a differential equation which is difficult or even impossible to solve analytically. To solve a differential equation we use one of MATLAB's "solver" functions (eg ode45 or ode23). These functions are a little unusual in that one of the inputs into the function is itself a function. There are several other useful functions which also take a function as an input. Learning outcomes After working through this chapter, you should be able to: • • • • Explain what a "function" function is Use fzero to find the root of a function Use ode45 to solve a first order differential equation Use feval to write your own "function" functions What is a "function" function? Until now we have dealt with functions that take one or more variables as inputs. Some special functions take a function as an input (so that they can use that function). There are quite a number of scenarios where a "function" function is useful. Consider a function that models the velocity of a rocket at any given time. To find the distance travelled by our rocket we would like to be able to integrate our function. Rather than having to write specific code to numerically integrate our function it would be great if we had a function called "Integrate" which could be passed the function to integrate and the limits of integration. Another common problem is that of finding the roots of a function (ie the input values for the function that give zero). A MATLAB function called fzero can be used to do this. Finding roots with fzero The fzero function allows us to find x values for any function f (x), such that f (x) = 0. These x values are called roots. Consider the problem of solving the equation: x 2 − x −12 = 0 This can be done by hand but it is also easy to solve using MATLAB. 181 First we write a function to represent our polynomial function px = MyPolynomial(x) px = x.^2 - x - 12; end We can now use the fzero function to find the roots of our polynomial close to a given x value. The fzero function takes two inputs • • The "address" of the function, so that fzero knows where to find the function An x value around which we want to search for roots. For example to look for roots near x=5 we use root = fzero(@MyPolynomial, 5) This will produce the following output: root = 4 To find the other root we need to start looking from a different value: root = fzero(@MyPolynomial, -5) This will produce the following output: root = -3 Notice that our function name has been prceceeded by the @ symbol. You will be familiar with the @ symbol from email addresses. The @ symbol is used in a similar way here to indicate we are passing the "address" of a function. As a result of passing in the address of MyPolynomial to fzero it knows where the function "lives" in memory and can call it. The @ symbol is a good reminder that the input being passed in is another function, not a variable. An alternative method of passing a function to another function is to pass in the function name as a string: fzero('MyPolynomial', 5) This approach is not quite as obvious as using the @ symbol. Also if you forget the quotes MATLAB will assume MyPolynomial is a variable. It will then attempt to use the contents of the variable MyPolynomial as a function, which is likely to generate an error. You may use either quotes or the @ symbol when passing functions. For consistency with the MATLAB help files we will use the @ notation to pass functions into other functions. 182 Solving ODEs in MATLAB MATLAB has some very powerful tools for solving ODEs. With very little effort you can find a numerical solution to a complicated first order differential equation, even if it is impossible to solve analytically. In MM2 you will also learn how to use MATLAB to solve second order and higher order differential equations that you meet in engineering problems. It can also be used to solve systems of differential equations such as you will meet in MM3. In this course we introduce you to using MATLAB to find numerical solutions for ODEs that can be written in the following form: dy = f (t, y) dt ie the derivative can be written as some function of the independent variable and dependent variable. In many cases the derivative will only depend on one of the variables but MATLAB can handle functions that depend on both. We will demonstrate how to use MATLAB to solve a simple ODE: Solving ODEs numerically In MM1 you were introduced to Euler's method for finding a numerical solution to first order differential equations. In order to use use Euler's method you needed three pieces of information: • • • A formula for the derivative A time interval (start time and finish time) An initial value at the start time (initial condition) The same three pieces of information are needed for any other numerical method. We will need to pass all three pieces of information to our MATLAB solver function. To do this we need: • • • A MATLAB function that calculates the derivative for any given values of the independent and dependent variables A time span array containing two values (a start time and finish time) An initial value We can then pass these three inputs into one of the MATLAB ODE solvers. The solver will call our derivative function many times to find a sequence of values for the given time span and initial conditions. The output from the solver will be two arrays, one containing values for the independent variable and the other containing the corresponding dependent variable values. Note that the solvers require the derivative function to take both the independent and dependent variables as inputs (even if one or the other may not be used). The independent variable must be the first input and the dependent the second. The output for the function must be the derivative for the given inputs. 183 A simple ODE Consider the problem of determining the volume of muddy water left in a 1000 litre tank, which began leaking at 1am. We know that the rate of flow out of the tank will be proportional to the volume left in the tank. dv ∝v dt We also know that as time goes by the mud will gradually coat the hole, reducing the amount of fluid that can flow out. Hence the rate of flow is inversely proportional to time. dv 1 ∝ dt t Putting this together we have the following model: dv kv =− dt t v (1) = 1000 Where k is determined by experiment to have the value k = 3 Note that our dependent variable is v as it depends on time. Our independent variable is t. Recall that the MATLAB solver functions need: • • • A MATLAB function that calculates the derivative for any given values of the independent and dependent variables A time span array containing two values (a start time and finish time) An initial value It will produce two outputs: • • An array of time values (the independent variable) An array of corresponding solution values (the dependent variable) Representing our ODE with a function We can now write a function that represents our ODE. It will take as inputs our independent variable and our dependent variable. (Note the order, the independent variable comes first). function dvdt = MuddyTankFlowRate(t,v) % calculate the flow rate out of a muddy tank of water % inputs: v the volume of water % t the time since the start of the flow % output: dvdt the flow rate k = 3; dvdt = -k * v / t; end 184 This function allows us to calculate the flow rate for any given time and volume. Using a solver There are quite a number of ODE solvers to choose from: ode45, ode23, ode113, ode15s, ode23s, ode23t, or ode23tb. In general ode45 is a good solver to try first. The others can be useful if ode45 does not work well for your problem. We can now write a short script to solve our ODE % Script to solve the volume of fluid left in a muddy tank % that contains a hole % set up a time span of 6 hours (t is measured in hours) timeSpan = [1, 7] % the initial volume at time t=0 is 1000 litres vInit = 1000 % solve our ODE [t,v] = ode45(@MuddyTankFlowRate, timeSpan, vInit); % plot result plot(t,v) title('Plot of fluid level in tank of muddy water') xlabel('time (hours)'); ylabel('volume (litres)') Running our script will produce a plot of the solution 185 Using feval to write our own function functions If we want to write our own "function" functions we need a way of being able to call a function that has been passed in as an input. The feval function allows us to do this. Consider evaluating our polynomial function introduced earlier. function px = MyPolynomial(x) px = x.^2 - x - 12; end To find out the value of our polynomial at x = 2 we can type: p = MyPolynomial(2) p = -10 186 Another way of evaluating the function is by using feval p = feval(@MyPolynomial,2) p = -10 If we want to get a little trickier we can even do the following % create a variable to contain the address of our function myFunctionAddress = @MyPolynomial; p = feval(myFunctionAddress,2) This gives us a way of evaluating functions that have been stored in variables. With this ability we can now write our own "function" functions. For example, the following function calculates the derivative of a given input function at a specified point. function dfdx = NumericalDerivative(f,x) % calculate the derivative of a function f at a given value x % using a central difference to estimate the derivative value % ie df/dx is approximated by ( f(x+h) - f(x-h) ) / (2h) % inputs: f the address of the function to differentiate % x the value to calculate the derivative at % output: dfdx the derivative of myFunction at x. % % % h set h to be a very small value, using the special MATLAB variable eps. We multiply by 1000 so that h is big enough that we get a difference when evaluating to the left and right of x = 1000*eps; dfdx = ( feval(f,x+h) - feval(f,x-h) ) / (2*h); end We can use our NumericalDerivative function in the same way that we used fzero: deriv = NumericalDerivative(@MyPolynomial,1) deriv = 1 187 Chapter 11 Summary Programs We can now write programs that use functions which take other functions as inputs. For example, the following function will classify a stationary point. function pointType = ClassifyStationaryPoint(derivative,point) % classify a stationary point for a function, given the % derivative of the function % inputs: derivative The derivative function which must have % only ONE input value % point x value of the stationary point % output: pointType a string describing the type of point % set up delta, a small positive number % eps is a special variable which contains a very small % positive number delta = 1000 * eps; % calculate the derivative just to the left of the point leftDerivative = feval(derivative, point - delta); % calculate the derivative just to the right of the point rightDerivative = feval(derivative, point + delta); if (leftDerivative > 0 & rightDerivative < 0) pointType = 'maximum'; elseif (leftDerivative < 0 & rightDerivative > 0) pointType = 'minimum'; else pointType = 'point of inflection'; end end dy = 2t −1 y(0) = 0 dt Solve for the displacement for 0 ≤ t ≤ 2 and also locate and classify the stationary points of y. The velocity in metres per second of an object is given by To solve an ODE we need a derivative function that takes TWO inputs (the independent and dependent variables). function dydt = DisplacementDerivative(t,y) % calculates the value of dy/dt = 2t - 1 % inputs: y The dependent variable % t The independent variable % output: dydt The rate of change dy/dt dydt = 2 * t - 1; end 188 To use fzero and our ClassifySationaryPoint function we need a function that takes only ONE input function v = Velocity(t) % calculates the value of v(t) = 2t - 1 % input: t The independent variable % output: v The value of v v = 2 * t - 1; end We can now solve our ODE and classify the stationary point. % This script solves the equation dy/dt = 2t - 1 with initial % condition y(0) = 0 for the range t = 0 to 2 % it also locates and classifies a stationary point % start and end value for time interval timeSpan = [0 2]; % at t = 0, y = 0 yInit = 0; % solve the ode using the ode45 solver [t,y] = ode45(@DisplacementDerivative,timeSpan,yInit); % % % % p stationary points occur when the first derivative is zero use fzero to locate a stationary point near t=1 Note we cannot use the DisplacementDerivative function as it has two inputs rather than one. = fzero(@Velocity,1); % use our classification function to classify the point pointType = ClassifyStationaryPoint(@Velocity,p); % plot the solution plot(t,y) % create a nicely formatted title string for the plot header = sprintf('Solution for y with a %s at %f',pointType,p); title(header); xlabel('t (seconds)'); ylabel('y (metres)'); Recommended reading Chapter 11 Differential Equations and “Function” Functions Topic Using fzero Solving ODEs Introduction to Matlab 7 for Engineers (2nd ed) A Concise Introduction to Matlab (1st ed) Section 3.2 8.5 Section 3.2 Pages 156-157 498-505 189 Pages 131-132 190 ENGGEN 131 Engineering Computation and Software Development Laboratory 1: An introduction to MATLAB The Department of Engineering Science The University of Auckland 191 Laboratory 1 GETTING STARTED Your Tutor will show you how to login to the Network if you are not familiar with it. Most of the applications you will use reside on File Servers rather than on the local hard drive of your computer. You have also been allocated an ec (Electronic Campus) home directory (H drive), in which you can save your work. If your computer is switched off (you can tell this by the absence of a light on the front of the computer) you should press the Power on the computer’s front panel. Do not switch the monitor on or off at any time! If the light is already on, you can simply restart the login sequence by holding down the Ctrl and the Alt keys and pressing the Delete key. GENERAL LAB DIRECTIONS You should work your way through the tutorials reading everything. Interaction with the computer takes place throughout the lab. The sections are not stand-alone so you must work through them in order. There are a number of lab tasks throughout the Lab that will be checked by your tutor when you have completed the whole lab. Any MATLAB commands for you to type are shown as they would appear in MATLAB. Other MATLAB terms in a body of text will be bolded to make it easy to see. Please feel free to help your fellow students understand the concepts and never hesitate to ask questions of the tutors. Some labs include optional exercises at the end. While completion of optional tasks is not required to get signed off for the lab, it is recommended you try them when time permits. The material presented in the optional exercises will increase your understanding of MATLAB and are HIGHLY recommended to help you prepare for the final exam, so when you have a chance do give these exercises a go. Be sure to look out for TASK There is a lab task to complete. TIP There is a handy tip to help you with MATLAB. Star There is a description of good programming practice. If you follow these tried and true conventions you will be a programming star! Stop There is a “roadblock to understanding”. Make sure you ask a tutor for clarification if you don’t understand what MATLAB is doing. 192 CLASS FORUM We are using Piazzza as a question and answer forum for the class. This is the best place for you to ask questions and discuss the course content. You will have been sent an email with a link to use to activate your Piazza account. TASK 1 Activate your Piazza account if you have not already done so. Go to the class forum, either by using the link on Canvas or by typing in the follow url: https://piazza.com/aucklanduni.ac.nz/semester22016/enggen131/home Read the post on lab 1 and follow the instructions given there. TIP Get help when you need it If you don't understand something try reading through your notes or the recommended text. If you still don't understand then get some help. There are many possible sources of help: During the lab you can • Ask a tutor • Ask a friend, • Post a question on the forum. Outise of lab times you can • Ask a friend • Post a question on the forum • Visit the lecturers • Pop into the part 1 assistance centre Do NOT leave it to the last minute to get help on things like assignments and projects. One very good reason to start assignments and projects early is that if you run into problems you will have much more time to seek help. 193 INTRODUCTION TO MATLAB MATLAB (MATrix LABoratory) is an interactive software system for numerical computations and graphics. As the name suggests, MATLAB is especially designed for matrix computations: solving systems of linear equations, performing matrix transformations, factoring matrices, and so forth. In addition, it has a variety of graphical capabilities, and can be extended through programs written in its own programming language. MATLAB is supported on Unix, Macintosh, and Windows environments. A student version of MATLAB for Macintosh or Windows may be purchased from the Science Student Resource Centre, which you can install on your own computer. MATLAB Advantages It simplifies the analysis of mathematical models It frees you from coding in lower-level languages (saves a lot of time - with some computational speed penalties) Provides an extensible programming/visualization environment Provides professional looking graphs MATLAB Disadvantages It is an interpreted (i.e., not pre-compiled) language, so it can be slow. GETTING STARTED Double click on the MATLAB icon. The MATLAB window should come up on your screen. It looks like this: 194 Finding Your Way Around the Windows The main window in the centre is called the Command Window. This is the window in which you interact with MATLAB. Once the MATLAB prompt >> is displayed, all MATLAB commands are executed from this window. In the figure, you can see that we execute the command: >> a = 7 In the top right corner you can view the Workspace window, and in the top left you can view the Current Directory window. Note that when you first start up MATLAB, the workspace window is empty. However, as you execute commands in the Command window, the Workspace window will show all variables that you create in your current MATLAB session. In this example, the workspace contains the variable a. If you enable the Command History window, it will be visible in the bottom right. This window simply gives a chronological list of all MATLAB commands that you used. During the MATLAB sessions you will create files to store programs or workspaces. Therefore create an appropriate folder to store the lab files. Set the current directory to be your H drive by clicking on the Browse button next to the Current Directory path. Go to My Computer (at the top), click on the + and select H. 195 Find the New folder button on the menu and name the new folder as Lab1. Now double click the Lab1 folder you just created so that MATLAB will automatically save files in this folder. Note that the current directory (or folder - folder and directory mean the same thing) is also displayed in the top right corner next to the main menu. You will get to know the various buttons and menus on the MATLAB window in the next few labs. We will not discuss all of them. Therefore, play around and familiarise yourself! 196 THE MATLAB HELP SYSTEM MATLAB’s help system provides information to assist you while using MATLAB. Select Help → MATLAB Help to open the help system. You can then browse the commands via the Contents window, look through the Index of commands or Search for keywords or phrases within the documentation. This is the most comprehensive documentation for MATLAB and is the best place to find out what you need. You can also start the MATLAB Help using the helpwin command. A faster way to find out information about commands is via the help command. If you just type help and hit return, you will be presented with a menu of help options. If you type help <command>, MATLAB will provide help for that particular command. For example, help hist will call up information on the hist command, which produces histograms. Note that the help command only displays a short summary of how to use the command you are interested in. For more detailed help documentation, use the doc command. For example, doc hist will display the full documentation of the hist command, including examples of how to use it and sample output. Another very useful MATLAB command is the lookfor command. This will also search for commands related to a keyword. Find out which MATLAB commands are available for plotting using the command lookfor plot in the command window. It may take a bit of time to get all commands on the screen. You can stop the search at any time by typing ctrl-c (the ctrl and the c key simultaneously). A list of the most basic MATLAB commands and functions is supplied in the appendix of your Course Manual. 197 WORKING AT THE COMMAND LINE Our initial use of MATLAB was as a calculator. Refer to chapter 1 to see what the mathematical operators are and to remind yourself what BEDMAS stands for. Let’s try some of the basic operations. Try typing the following: >> 5 + 4 ans = 9 >> 5 - 4 ans = 1 >> 5 * 4 ans = 20 >> 5 / 4 ans = 1.2500 >> 5^4 ans = 625 >> 34^16 ans = 3.1891e+024 The last ans (the result of the last calculation) is a quantity expressed in scientific notation. MATLAB uses scientific notation for very large numbers and very small numbers. MATLAB has a special way of representing this: 3416 = 3.1891× 10 24 >> 34^16 ans = 3.1891e+024 Note that as you type commands they are added to the command history window, giving you a record of everything you have typed for this MATLAB session. The first two tasks require you to type some simple MATLAB commands at the command prompt. When you have finished all the lab tasks you will need to show a tutor these commands to prove you have done the tasks. You may like to handwrite the answers for these first two tasks in your lab book to show your tutor later. Alternatively you can simply scroll back through the command history to show your tutor the commands you typed. Note that if you close down MATLAB your command history is erased. 198 TASK 2 Using MATLAB Help Below is a table containing some expressions you could use a calculator to compute. To familiarise yourself with entering expressions into MATLAB, complete the table. Use MATLAB Help to look up any functions you don’t know, e.g., >> lookfor log or >> help log Remember that ln(x) is the natural logarithm and that the function e x is called the exponential function. Also, notice that the last expression produces a complex number (which MATLAB represents using the special variable i for the imaginary part). Expression MATLAB Expression MATLAB Result 1 / sqrt(2 * pi) 1 2π 5 × 10 9 + 3 × 10 8 5e9 + 3e8 log10 72 1.8573 cos π -1 e1 2.7183 ln(sin(π 2 )) -0.8433 + 3.1416i TIP Getting tasks signed off Remember that you must complete ALL the lab tasks before getting your tutor to sign you off. Continue with the remainder of the lab before asking your tutor to check your tasks. For all most tasks you will be creating files. Remember to open ALL the files you have written before asking your tutor to check you off. When you are being checked off you can expect that your tutors will ask you some questions about the tasks, to check your understanding of the lab material. As you work through the labs make sure you understand what you are doing and please ask questions if you are confused. Note that your tutor may refuse to sign you off if it is obvious you do not understand the material. In that case you may need to reread some of the course notes and repeat parts of the lab until you have learnt the material. 199 Now that you have become used to the MATLAB Command Line, let’s use it to do some basic electrical engineering calculations. TASK 3 Basic Electrical Circuits If 2 resistors (resistance R1 and R2 measured in ohms) are placed in series in a circuit, they may be represented as a single resistor (resistance R, also in ohms) where R1 R2 R = R1 + R2 If 2 resistors (resistance R1 and R2) are placed in parallel in a circuit, they may be represented as a single resistor (resistance R) where R1 R2 1 1 1 = + R R1 R2 Now, use MATLAB to calculate the resistance of the following configuration of resistors 5Ω 2Ω 10 Ω You may like to write the commands you use below, so that you can show them to your tutor. (Alternatively you can show them where you typed them by using the history window). 200 MATLAB VARIABLES As we discussed, MATLAB stands for 'MATrix LABoratory'. This title is appropriate because the structure for the storage of all data in MATLAB is a matrix. We talk more about this in upcoming lectures. Right now we will only work with scalar variables. MATLAB stores these as matrix variables with 1 row and 1 column. These variables show in your workspace is shown as 1x1 matrices. Assigning Variables To create a (scalar) variable in MATLAB simply enter a valid variable name at the command line and assign it a value using =. Once a variable has been assigned a value it is added to the MATLAB Workspace and will be displayed in the Workspace window. For example, after entering: >> height = 5 height = 5 >> width = 4 width = 4 the Workspace window will contain both height and width as scalars: We should NOT use length as a variable name as this is a built-in MATLAB function. TIP Rules on Variable Names There are a number of rules as to the variable names you can use: 1. 2. 3. 4. 5. must start with a letter, followed by letters, digits, or underscores. X12, rate_const, Flow_rate are all acceptable variable names but not vector-A (since - is a reserved character); are case sensitive, e.g., FLOW, flow, Flow, FlOw are all different variables; must not be longer than 31 characters; must not be a reserved word (i.e., special names which are part of MATLAB language); must not contain punctuation characters; Be careful not to confuse the number 1 with the letter l, or the number 0 with the letter O. 201 Star Naming Variables You should choose variable names that indicate quantities they represent, e.g., width, cableLength, water_flow. You can use multiple words in the same variable name either by capitalizing the first letter of each word after the first one, e.g., cableLength, or by putting underscores between words, e.g., water_flow. At the rear of the course manual is a style guide which indicates the naming conventions we recommend you follow for this course. Not all the code in this course manual follows these conventions as we wish to expose you to a range of conventions. This is important since you may need to read or use code written using different styles. You may also prefer using a different convention. If we do (accidentally) use length (or another built-in function name) as a variable name we must remove it from the MATLAB Workspace to restore the built-in function. TIP Some MATLAB Workspace Functions You can see the variables in your workspace by looking at the Workspace window or by using the whos command: >> whos Name area height width Size Bytes 1x1 1x1 1x1 8 8 8 Class Attributes double double double If you want to remove a variable from the MATLAB you can use the clear command, e.g., >> clear width removes width from the workspace. If you want to get rid of all the variables in your workspace just type: >> clear Calculations with Variables Once you have added variables to the MATLAB Workspace, you can use them within calculations (just like you have used the special variable pi in Task 1). For example, to calculate the area of a 5 x 4 rectangle you could enter: >> height = 5 >> width = 4 >> area = height * width 202 ERROR MESSAGES If your command is invalid MATLAB gives you explanatory error messages (luckily!). Read them carefully. Normally MATLAB points to the exact position of where things went wrong. Enter: >> height* = 5 The result will be: ??? height* = 5 | Error: The expression to the left of the equals sign is not a valid target for an assignment. | The command has failed. MATLAB attempts to explain how/why the command failed. Stop Invalid Expression Make sure you know why the command failed in MATLAB. Ask a tutor if you are unsure. FINDING OLD COMMANDS Suppose you want to repeat or edit an earlier command. If you dislike typing it all back in, then there is good news for you: MATLAB lets you search through your previous commands using the up-arrow and down-arrow keys. This is a very convenient facility, which can save a considerable amount of time. Example. Clear the height of the rectangle in the earlier example: >> clear height and look at the Workspace window: Now you want it back! Press the up-arrow key until the earlier command: >> height = 5 appears in the Command Window (the down-arrow key can be used if you go back too far). Now press enter. Now height is back to what it was originally. 203 You can speed up the scroll if you remember the first letters of the command you are interested in. For example, if you quickly want to jump back to the command: >> height = 5 just type h and then press the up-arrow key. MATLAB will display the most recent command starting with h. Alternatively, you can use Copy and Paste under Edit. You can also use the Command History window to jump to a previous command. Go to the Command History window and double-click on the line height = 5: The command: >> height = 5 will appear in the Command Window and be carried out immediately. SUPPRESSION OF OUTPUT Up till now you have always seen the results of each command on the screen. This is often not required or even desirable; the output might clutter up the screen, or be long and take a long time to print. MATLAB suppresses the output of a command if you finish the command with a semi-colon ;. Enter: >> height = 5 You will notice that MATLAB prints out the result of this command after you press enter: height = 5 Now enter: >> height = 7; MATLAB will not print the result of the command. With scalar variables this doesn’t make much difference - but it can make a great deal of difference when dealing with large lists of numbers. 204 If you look at height in your Workspace window you will see its value has changed to 7: SAVING YOUR WORK - SCRIPT FILES So far all your work has been at the command line. This is useful for quick calculations. For calculations that are more complex, or that you are likely to perform often it is much more useful to save your work in script files. We will use script files from here onwards in the course. To create a new script file (also called an M-file) choose File→New→M-File from the MATLAB menu bar. This will open a blank script editor window. You can enter commands into this window using the same syntax as you would at the MATLAB command line. These commands can be saved, repeated and edited. Let’s start by creating a script file to calculate the area of a rectangle (one of our earlier examples). In the script file window enter: height = 5 width = 4 area = height * width Now save your script file by choosing File→Save from the menu in the script file editor. Give your script file a name, such as area_calc.m. The .m extension is used to denote MATLAB script files. The file will be saved in the working directory you set earlier in the lab. Stop Invalid Filenames Filenames cannot include spaces. They also cannot start with a number or include punctuation characters (other than the underscore). If you use an invalid filename you will get some unusual errors when you try to run your script. You should also avoid using reserved MATLAB commands as filenames. If you are unsure about whether a filename is a reserved MATLAB command, try typing the word help followed by the filename you wish to use (if it is reserved you’ll see an explanation of what that command or function does). Check your filename now to see if it is valid. 205 Now go back to the MATLAB command line (you can click on the MATLAB icon in the bar at the bottom of the screen or use Alt-Tab to get there). First, clear the workspace. Now, at the command prompt enter: >> area_calc You will see the height, width and area variables appear with their values. TIP Long Lines in Script Files If you have a very long command in your script file, it can be difficult to see the whole command at once, e.g., You can split the command into multiple lines, but you must add three dots, i.e., ..., to make sure MATLAB knows it is all one command, e,.g., Errors in Script Files If you make a mistake in a script file MATLAB will let you know with an error message. It will also let you jump to the (likely) source of the error by clicking on the error text. error Click on underlined text to jump to error Error message 206 Change area_calc.m so the area calculation has an error: height = 5 width = 4 area = height x width and run the script file again: >> area_calc You should get an error: ??? Error: File: area_calc.m Line: 3 Column: 15 Unexpected MATLAB expression. By clicking on the underlined text you will jump to height x width (and the error): Stop Script File Error Make sure you know why MATLAB gave an error. Ask a tutor if you are unsure. COMMENTING One of the most important facets of programming is documenting your program, or commenting. Comments lines begin with the % character and turn green in the MATLAB editor. Comments allow you to document your program to make it clear what steps you are taking. Throughout this course you are expected to have useful comments throughout your code. The expectation is that another person could rewrite (most of) your program starting only with the comments. TIP Comments as Help The first block of comments in a script file are shown if the command help filename is entered in the Command Window. For more information search for “Help Text” in the MATLAB Help. 207 Star Good Commenting Your initial commenting block should have a brief description of the script file functionality and also clearly define the input and output for the script file. You should also indicate the author of the script. For example here is the contents of the file area_calc.m % % % % % % This script calculates the area of a rectangle given its height and width Input: height = rectangle height width = rectangle width Output: area = rectangle area Author: Bilbo Baggins height = 5 width = 4 area = height * width The initial commenting block becomes part of the help system, so that you can find information about a script by typing the word help followed by the script name: >> help area_calc This script calculates the area of a rectangle given its height and width Input: height = rectangle height width = rectangle width Output: area = rectangle area You should also have (at least) one line of commenting for any command in your script file that is non-trivial. The above example is so simple it probably doesn’t merit any further commenting but as you progress to harder tasks you will want to add comments to the body of your function. For example: % % % % % % This script calculates the area of a rectangle given its height and width Input: height = rectangle height width = rectangle width Output: area = rectangle area Author: Bilbo Baggins height = 5 width = 4 % An insightful comment could go here, on a line of its own area = height * width % Alternatively you can add comments at the end of a line 208 TASK 4 Consider the following electrical circuit: R1 R3 R2 V The current through the circuit (in amps) is determined by the voltage through the circuit (in volts) divided by the resistance (in ohms) through the circuit. Write a script file to calculate the current through the circuit for any combination of R1, R2, R3 and V. Test your script file using: R1 = 5 Ω, R2 = 10 Ω, R3 = 2 Ω and V = 6 V (the current is 1.125 A). Be sure to choose an appropriate name for your script file and make sure you comment it. Stop Commenting is vital! Did you remember to comment your script file? We won’t sign your lab off unless all script files are commented. Check you have a comment at the top of the file that provides description of what your file does AND includes your name as the author of the file. BASIC USER INTERACTION Basic User Input Script files are more useful if they can interact with users. One simple way to do this is via the input command. You can use it to prompt the user for a value to assign to a variable. For example, rather than editing area_calc.m each time the values for height and width change you could use height = input('Enter the height of the rectangle: ') width = input('Enter the width of the rectangle: ') Try this out by opening your area_calc.m script file and saving it as area_calc_input.m. Now replace height = 5 width = 4 with the input commands given above. 209 Now enter area_calc_input at the MATLAB command prompt >> area_calc_input Enter the height of the rectangle: 3 height = 3 Enter the width of the rectangle: 6 width = 6 area = 18 You can use ;’s to suppress the output, e.g., height = input('Enter the height of the rectangle: '); width = input('Enter the width of the rectangle: '); so now only the result of the area calculation is displayed >> area_calc_input Enter the height of the rectangle: 4 Enter the width of the rectangle: 3 area = 12 Basic Formatted Output MATLAB’s basic output is ok for inspecting the value of variables, but it is not very informative. You can control your output more using the disp command. Once you have calculated area you can suppress MATLAB’s output and then write its value along with some extra information area = height * width; disp('The area of the rectangle is: ') disp(area) Using disp this way and entering 5 and 4 for height and width gives the following output >> area_calc_input Enter the height of the rectangle: 5 Enter the width of the rectangle: 4 The area of the rectangle is: 20 If you want to put the value of area on the same line as the text you can use the basic formatting function num2str and concatenate the text and the formatted area together. disp(['The area of the rectangle is: ' num2str(area)]) We’ll learn more about why this works later in the course. 210 TASK 5 Make a copy of your script file from Task 4 and save it using a different file name. Modify this copy to get user input for R1, R2, R3 and V. Display the total resistance of the circuit and current through the circuit using disp. Your output should look something like this: The total resistance for the circuit (in ohms) is: 5.3333 The total current through the circuit (in amps) is: 1.1250 Test your script file using: R1 = 5 Ω, R2 = 10 Ω, R3 = 2 Ω and V = 6 V (the current is 1.125 A) and: R1 = 8 Ω, R2 = 4 Ω, R3 = 5 Ω and V = 9 V (the current is 1.1739 A). TIP Get help when you need it If you don't understand something try reading through your notes or the recommended text. If you still don't understand then get some help. There are many possible sources of help: • • • • • Post a question on the forum. Ask a friend Ask a tutor Visit the lecturers in their office hours Pop into the part one assistance centre (in the Leech) Do NOT leave it to the last minute to get help on things like assignments and projects. One very good reason to start assignments and projects early is that if you run into problems you will have much more time to seek help. 211 COMPULSORY LAB TASKS END HERE You may now get your lab tasks checked off. Remember to open up ALL files you created for the lab tasks (which for this lab are the files for task 4 and task 5). Once you have opened up those files put up your hand and ask for a tutor to sign you off. While you wait, as an optional exercise you may wish to explore some of the other capabilities of MATLAB that we will not cover in class. This material is not examinable. You can see more examples of MATLAB’s capabilities by typing help demos at the command line. You can run any of them by entering the name of the demo at the command line. Some of the demos that we recommend looking at are truss, travel, ballode, graf2d. If you are looking for something less serious see xpbombs (This is an implementation of Minesweeper, which for many years was one of the only games that came as standard with the windows operating system). 212 ENGGEN 131 Engineering Computation and Software Development Laboratory 2: Debugging, Functions and Problem Solving The Department of Engineering Science The University of Auckland 213 Laboratory 2 TASK 0 Read the lab notes Go to Piazza and read the pinned post for Lab 2. It details some useful information you should read before starting this lab. DEBUGGING Debugging is a vital skill and one we will practice in each lab. There are two main categories of things that can go wrong. Your code may have syntax errors (which prevent it from running at all) or it may have bugs (which means that although it might run, it does not product the desired results). Syntax errors are a little easier to track down, as MATLAB will helpfully point out lines that generate syntax errors (including an informative message that will help you understand what caused the problem, once you get used to interpreting the sometimes cryptic sounding language). When dealing with syntax errors make sure you read the error message before trying to fix the line, as it will often give you a vital clue on what the problem is. In lectures you saw how MATLAB helps you find bugs in your code. Using the Matlab debugger (called M-Lint), you can identify errors while you edit code. There is also the Debug menu for stepping through your programs to identify and fix errors. Stepping through a section of code line by line can be an invaluable tool when trying to spot the problem. Remember you can view the variables in the workspace while doing this, so that you can track whether or not they match what you expect them to be. TASK 1 Debugging the Final Percentage Example Download the scrip file FinalPercentage.m from Canvas: http://canvas.auckland.ac.nz/ When downloading any script files from Canvas make sure you check that the filename is correct (including the .m extension) and then place the file into an appropriate directory. Open this script in the MATLAB Editor, fix any bugs and use it to calculate your final percentage for the following three scenarios: - you achieved 90% for your coursework and 70% for your exam. - you achieved 100% for your coursework and 38% for your exam. - if you achieved 50% for your coursework and 98% for your exam. 214 FUNCTIONS Consider the task of writing a function to convert a metric measurement (in metres) to an imperial measurement in feet and inches. Generally it is much easier to work with metric measurements but sometimes people want results given to them in imperial format. A conversion function could be used by any program which needs to display output in imperial format. Recall The 5 steps for problem solving: 1. State the problem clearly 2. Describe the input and output information 3. Work the problem by hand (or with a calculator) for a simple set of data 4. Develop a solution and convert it to a computer program 5. Test the solution with a variety of data We will work through our five steps to develop a function that converts metric measurements to imperial measurements. Step 1: State the problem clearly Write a function to convert a metric measurement (in metres) to an imperial measurement (in feet and inches). Step 2: Describe the input and output information Fill in the missing labels on the I/O diagram Step 3: Work the problem by hand for a simple set of data We will convert 2 metres to the imperial equivalent. We know that there are 12 inches to a foot and that one inch is the equivalent of 2.54 cms. 2 metres is 200 cm. Now calculate the number of inches: 200 / 2.54 = 78.7402 Now figure out how many feet we have by dividing the total number of inches by 12: 78.7402 / 12 = 6.5617 We have 6 feet. To calculate the number of inches remaining we will need to subtract off the number of inches in 6ft from the total number of inches: 78.7402 − 6 × 12 = 6.7402 So 2 metres is 6 feet 6.7402 inches. 215 Stop Make sure you understand the hand worked example Before continuing make sure you have understood how we converted 2 metres to 6 feet 6.7402 inches. You may find it helpful to work through another example by hand. Try converting 1.5 metres to feet and inches to get the answer. Step 4: Develop a solution and convert it to a computer program Our pseudocode is as follows: INPUTS: m • Calculate the total number of cms • Convert number of cms to the total number of inches • Calculate the total number of feet, ignoring the value after the decimal point • Find the remaining number of inches OUTPUTS: ft and in TIP Pseudocode can be used as comments Often it can be helpful to begin your code by writing comments that describe what you want to do. You can then fill in the required code. In many cases you can simply use your pseudocode as comments. Download the MetricToImperial.m file from Canvas. function [ft,in] = MetricToImperial(m) % This function converts a metric measurement (in metres) % to an imperial measurement (in feet and inches) % Input: m = measurement in metres % Outputs: ft = number of feet % in = number of inches % Author: Gandalf the Grey % Calculate the total number of cms cm = m * 100; % Calculate the total number of inches totalInches = cm/2.54; % Calculate the total number of feet, ignoring the value % after the decimal point % the floor command rounds down to the nearest whole number ft = floor(totalInches/12); % Find the remaining number of inches in = totalInches - 12*ft; end 216 Check that you have saved the downloaded file as MetricToImperial.m Star Naming functions You should choose functions names that give an indication of what the function does. You can use multiple words in the same variable name either by capitalizing the first letter of each word, e.g., MetricToImperial, or by putting underscores between words, e.g., metric_to_imperial. At the rear of the course manual is a style guide which indicates the naming conventions we recommend you follow for this course. For user defined functions we recommend the convention of capitalizing the first letter of each word. This helps to distinguish them from MATLAB built-in functions which use lowercase only. Step 5: Test the solution with a variety of data Try running the MetricToImperial function and testing it with a number of values. In particular try using an input value of 2 metres and confirm the results match that of our hand worked example. IMPORTANT: remember that the MetricToImperial function returns TWO values. If you want to store both values in variables, you must assign BOTH outputs to a variable, by typing the following (or similar) at the Matlab command window. [feet,inches] = MetricToImperial(1) Star Testing your code It is VERY important that you test that your code works, using a number of values. People often make the mistake of testing their code with only one value and then assume it works because it gives the answer expected in that one case. It is easy to write code that works for one value but gives the wrong result in other cases. Good programmers always test their code on a range of values to ensure it is working as expected. TASK 2 Imperial to metric function Use the five steps for problem solving to write a function to convert an imperial measurement (in feet and inches) to a metric measurement (in metres). Remember to comment your function. You should fill out the template below when completing this task. 217 Step 1: State the problem clearly Give a one sentence description of the problem. Step 2: Describe the input and output information Either write down the inputs and outputs OR draw an I/O diagram. Step 3: Work the problem by hand for a simple set of data You may like to work through the problem by hand for several different values, to give you a range of values you can use to test that your function works as expected. 218 Step 4: Develop a solution and convert it to a computer program Either write pseudocode OR draw flowchart below. Then write your code. 219 Stop Make sure you have written a function and not a script file The task asked you to write a function. Have you used the keyword function? Stop Make sure your function name is valid Remember that your function name must match your filename exactly. Your function name cannot include spaces. It also cannot start with a number, include punctuation characters (other than the underscore) or use a reserved MATLAB command. If you use an invalid filename you will get some unusual errors when you try to run your script. Check your filename now to see if it is valid and that it matches your function name. Step 5: Test the solution with a variety of data You need to have tested that your function works. You can (and should) test that your function works by calling it from the command line. You should also write a script file that uses your function. TASK 3 Imperial to metric function test script For step 5 write a script file that tests your function by calling it with a variety of data, including the problem you worked by hand in step 3. Remember to comment your test script. Star Writing test scripts FIRST Some programmers follow the practice of writing their test scripts first BEFORE they write the code that will be tested. This can be a very good approach to use, as once your tests pass you have some confidence that you’ve written your code correctly. 220 PROBLEM SOLVING The following problem is taken from page 128, “Introduction to MATLAB 7 for Engineers”, William J. Palm III): The potential energy stored in a spring is kx 2 2 where k is the spring constant and x is the compression in the spring. The force required to compress the spring is kx. The following table gives the data for five springs: Spring Force (N) Spring constant k (N/m) 1 11 1000 2 7 800 3 8 900 4 10 1200 TASK 4 Compression and potential energy for springs 5 9 700 We wish to be able to find the compression and potential energy for any given spring. Use the five steps for problem solving to write a function that will find the compression and potential energy for any given spring. Remember to comment your function. You should fill out the template below when completing this task. Step 1: State the problem clearly Give a one sentence description of the problem. Step 2: Describe the input and output information Either write down the inputs and outputs OR draw an I/O diagram. 221 Step 3: Work the problem by hand for a simple set of data You may like to work through the problem by hand for several different values, to give you a range of values you can use to test that your function works as expected. 222 Step 4: Develop a solution and convert it to a computer program Either write pseudocode OR draw flowchart below. Then write your code. 223 Stop When testing your function recall that it returns two outputs You will need to assign both your outputs to variables when testing your function, otherwise you will only see one output. Step 5: Test the solution with a variety of data TASK 5 Compression and potential energy test script For step 5 write a script file that tests your function by calling it with a variety of data, including the problem you worked by hand in step 3. Remember to comment your test script. COMPULSORY LAB TASKS END HERE Remember to open all the files you wrote for the lab tasks before asking a tutor to sign you off. This will include both the functions you wrote and the scripts to test them. Once you have completed the compulsory tasks it is recommended that you try the exam practice task (overleaf) which is designed to help prepare you for the final exam. The exam practice tasks give you a good indication of the kinds of questions you are expected to be able to handle in the final exam. 224 EXAM PRACTICE The standard normal distribution is described by the function: s(x) = 1 −x 2 / 2 e 2π The probability of randomly selecting a value within the range −α to α is then given by: α α −α 0 p = ∫ s( x ) dx = 2 ∫ s( x ) dx Unfortunately this integral cannot be calculated analytically. Write a MATLAB function which takes a single input value x and returns the value s(x). Write your function so that it will work on 1D arrays. Write a second MATLAB function which takes a single input value α and returns the probability p, of obtaining a value in the range −α to α . Your function should use the trapezium method to numerically integrate s(x). Recall that the trapezium method approximates the area under a curve by summing up a number of thin trapeziums, as illustrated in the diagram below. Pseudocode for the second function is provided over the page. 225 create an array of 100 x values from 0 to alpha width = x(2) - x(1) Heights = s(x) LeftHeights = Heights array with the last element removed RightHeights = Heights array with the first element removed Areas = (LeftHeights + RightHeights)/2 * width Total Area = sum the Areas p = 2 time the total area 226 ENGGEN 131 Engineering Computation and Software Development Laboratory 3: Logical Operators, Conditional Statements and Loops The Department of Engineering Science The University of Auckland 227 Laboratory 3 TASK 0 Read the lab notes Go to Piazza and read the pinned post for Lab 3. It details some useful information you should read before starting this lab. RELATIONAL AND LOGICAL OPERATORS In lectures we introduced relational operators and logical operators. These can be used in expressions to compare values. These operators are: Relational Operators equal to not equal to greater than less than greater than or equal to less than or equal to == ~= > < >= <= Logical Operators not and or ~ & | Enter the following commands into MATLAB: >> >> >> >> >> >> a = 1; b = 2; (a == 1) (a == 2) (b == 2) (a == b) Remember that 0 indicates false and any non-zero value (usually 1) indicates true. Do you get the results you expect? 228 Now try a few more: >> >> >> >> >> >> >> >> (a == 1) & (b == 2) (a == 2) & (b == 2) (a == 2) | (b == 2) a & b ~a c = 0; ~c (~b) | (~c) Do these statements give the results you expect? Stop Output from Expressions If you’re not sure about the output from the statements above, make sure you ask a tutor to clarify things. CONDITIONAL STATEMENTS Relational and logical operators can be used to test conditions in if statements. The syntax of the simplest form of an if statement is: if condition Do something end; The syntax of an if statement can be expanded so that if the condition is not true something else is done instead: if condition Do something else Do something else end; The if statement can be further expanded by the inclusion of one or more elseif sections: if condition Do something elseif another condition Do a different thing elseif yet another condition Do a different thing else Do something else end; 229 Let’s use an if statement to write out the correct value of a number. Save the following if statement in the script file testnum.m if (number == 1) disp('The number is 1'); end; Now try the following commands: >> >> >> >> number = 1; testnum number = 3; testnum Does MATLAB do what you expect? Notice that we are only displayed a message if the number is one. Let us extend our if statement so that we get a useful message regardless of what the number is. Edit testnum.m to read as follows if (number == 1) disp('The number is 1'); else disp('The number is not 1'); end; Now try the following commands: >> >> >> >> >> >> number = 1; testnum number = 3; testnum number = 2; testnum Does MATLAB do what you expect? Try stepping through testnum.m for each of the different values for number. Finally we will extend our if statement so that it also tells us if our number is 2. Edit testnum.m to read as follows: if (number == 1) disp('The number is 1'); elseif (number == 2) disp('The number is 2'); else disp('The number is not 1 or 2'); end; 230 Now try the following commands: >> >> >> >> >> >> number = 1; testnum number = 3; testnum number = 2; testnum Does MATLAB do what you expect? Try stepping through testnum.m for each of the different values for number. TIP Be careful to use == when checking for equality To check if number was equal to 1 we used TWO equals signs. A very common programming error is to accidently use one equals sign when you wanted to check for equality. In MATLAB this will result in an error. Star Indenting If you properly indent your script files it makes them much easier to read and debug. If you enclose commands within a statement (conditional, loop) you should indent the commands (usually by 2-4 spaces or by using the tab). Commands at the same level should have the same indentation. Correct indentation often helps you identify if you have left end out of your conditional statements or loops. TIP Smart Indenting Indenting is very important to get right. MATLAB helps by giving the Smart Indent option in the Text menu (the shortcut is ctrl-i) . This will indent any selected text. You should use this in your script files to ensure the indenting is correct. If you wish to use smart indent on your entire file the shortcut for selecting all text is ctrl-a. Remember: use ctrl-a followed by ctrl-i to ensure indenting is correct. 231 TIP Be careful of precedence when using logical operators To check if a number is equal to 7 or 11 you might be tempted to use: number == 7 | 11 This will NOT do what you might expect. This is because without brackets MATLAB will first evaluate number == 7, giving true or false and it will then or this with the value 11. As 11 is always interpreted as true the conditional will always evaluate to true. The following will not work either: number == (7 | 11) MATLAB will first evaluate 7 | 11, (interpreting both values as true and giving a result of 1). It will then check to see if number is equal to 1. This conditional will only ever be true if number is equal to 1. If number was 7 it would return false. The way to achieve what we want is to use: (number == 7) | (number == 11) In this case the brackets could be omitted but it is a good idea to include them to clarify what is being done and to avoid any problems with precedence. TASK 1 Debugging Conditionals Download WhatToWearForTheWeather.m and HowManyLayers.m from Canvas Open both the script and function in the MATLAB Editor, read the header comment to understand what the files should do and the fix any bugs so that you can run the WhatToWearForTheWeather script correctly (note this script calls the HowManyLayers function). Conditional bugs can be quite tricky to spot. Be on the lookout for examples where a single equals sign is used to check equality (rather than the required two) and make sure you think carefully about precedence (see the note above). Remember you can use the debugger to step through line by line (and you can step into a function), so that you can see how each line of code changes the variables in the workspace. 232 TASK 2 Types of quadratic roots You will be familiar with the following formula for finding the roots of a quadratic −b ± b 2 − 4ac x= 2a The term under the square root is called the discriminant and can be used to determine the type of roots the quadratic has. If the discriminant is positive then the polynomial has two real roots; If the discriminant is zero that the polynomial has one repeated root; Otherwise the discriminant is negative and the polynomial has two complex roots. Knowing how many real roots a quadratic equation has can have important consequences. For example when solving 2nd order linear homogenous ODES with constant coefficients, you obtain a characteristic equation which is a quadratic equation. Determining how many really roots your characteristic equation has tells you important information about he nature of the solution to the ODE. Write a function that takes as inputs the coefficients a,b and c and returns to the user the number of real roots a quadratic equation has. An example of using your function is shown below. >> n = NumberOfRealRootsForQuadratic(1,3,2) After running this function you would expect n to have assigned the number of real roots for the quadratic x 2 + 3 x + 2 = 0 (in this case n would be assigned the value 2) IMPORTANT: your function should not ASK you for the inputs using the input command, instead you should be passing values into your function, as shown in the function call above). Also your function should not display the number of real roots, it should return that value as an output. Use the template given on the next few pages to develop your function. 233 Step 1: State the problem clearly Give a one sentence description of the problem. Step 2: Describe the input and output information Either write down the inputs and outputs OR draw an I/O diagram. Step 3: Work the problem by hand for a simple set of data You may like to work through the problem by hand for several different values, to give you a range of values you can use to test that your function works as expected. 234 Step 4: Develop a solution and convert it to a computer program Draw a flowchart below. You may need to refer to the flowchart appendix. Then write your code. 235 Stop Check your function doesn’t use the input or disp commands. The idea behind a function is that values are passed into it when it is called (either from the command line or from within a .m file) When called with a set of inputs the function returns the desired result as an input. Generally speaking functions don’t ask the user to enter a value (that is usually done in scripts). This means your function should not ASK you to enter inputs using the input command, instead you should be passing values into your function when you call it. If you use the input command within a function to assign a value to an input, you will be overwriting whatever value was passed into the function when it was called. Your function should also not display anything. This is because someone may wish to call your function thousands of times (and it will take significantly longer for their code to run if your function displays values each time it runs). Step 5: Test the solution with a variety of data TASK 3 Testing of your quadratic roots function For step 5 write a script file called TestQuadraticRootsFunction that allows you to test your function with a variety of data, including the problem you worked by hand in step 3. Your script file should ask the user to enter the coefficients a, b and c, call your function and then display an appropriate message based on the result returned by the function, e.g: >> TestQuadraticRootsFunction Finding the number of roots for ax^2 + bx + c = 0 Enter the coefficient a: 1 Enter the coefficient b: 3 Enter the coefficient c: 2 The equation has 2 real roots Stop Check your test script calls your function. It isn’t going to test your function very well if it does not call it! 236 LOOPS While Loops While statements repeatedly execute a piece of code while a given condition is true. The syntax of a while statement is: while condition do something end For example, we can use MATLAB’s isprime function to write a script called FirstTenPrimes to print out the first 10 prime numbers: count = 0; i = 1; while count < 10 if isprime(i) disp(i); count = count + 1; end; i = i + 1; end; 237 Running FirstTenPrimes would produce the following output: 2 3 5 7 11 13 17 19 23 29 An example of an infinite loop, from xkcd.com. TIP Use Ctrl-C to break out of an infinite loop When you begin working with loops it is likely at some point that you will accidentally create an infinite loop. You can stop the code from running by holding down the control key and the c key at the same time. Remember: use ctrl-c to break out of an infinite loop 238 TASK 4 I will survive? Some activities carry with them a relatively high risk of death. For example around 4% of climbers who attempt to summit Everest die. The physicist Richard Feynman estimated that the chances of failure of a space shuttle mission with loss of vehicle and life were roughly 1%. Tragically two shuttles were lost. This raises the question of how many shuttle missions could NASA have expected to launch before losing a shuttle. Use a while loop to predict how many flights NASA could have made before losing a shuttle (assuming a 1% chance of failure). For every flight we will need to determine whether it is successful or not. To do this we will compare a randomly generated value (between 0 and 100) to see if it is in the range 0 to 1 (a value in this range will be deemed to be a failed mission). When your while loop has finished your script file should write a message telling NASA how many successful missions they made. Sample output: >> task3 You completed 12 successful missions before losing a shuttle Hint: You can generate a random number between 0 and 100 using the rand function which generates a value between 0 and 1 and then multiplying it by 100: 100*rand xkcd.com 239 For Loops For statements repetitively execute a piece of code a given number of times. The syntax of a for statement is: for counter = start:step:stop do something end This loop works by setting counter = start, doing something, adding step to counter, doing something, adding step to counter, etc until counter reaches (or passes) stop. Remember that if the step is not specified it is assumed to be 1. The following commands write out the numbers from 1 to 10: >> for i = 1:10 disp(i) end 1 2 3 4 5 6 7 8 9 10 The following commands write out the square of the numbers from 1 to 10: >> for i = 1:10 disp(i^2) end 1 4 9 16 25 36 49 64 81 100 240 TIP For loop counter names It is very common for programmers to use the letter i or j as a counter variable name. This is a good habit to get into. If, however, you are working with complex numbers it is a good idea to use a different counter name to avoid confusion with the special MATLAB variables used to represent the square root of negative 1. Any valid variable name can be used for your array counter If you want to write out the odd numbers between 1 and 10 (in increasing order) you would use these commands: >> for i = 1:2:10 disp(i) end 1 3 5 7 9 Notice that even though 10 is the stop value, it is not written out. This is because the loop stops after the stop value has been passed, even if the counter variable doesn’t take this value. If you want to write out the numbers from 10 to 1 you would use the following commands: >> for i = 10:-1:1 disp(i) end 10 9 8 7 6 5 4 3 2 1 Stop For Loops How could you write out the odd numbers between 1 and 10 in decreasing order? If you’re not sure, ask a tutor to clarify things. 241 For Loops and 1D Arrays A for loop is one way to populate a 1D array (which is essentially just a list of values). 1D arrays are often used as data structures for plotting. For example, if I wanted to draw y = x2 between 1 and 5, I could use the following code: >> for i = 1:5 x(i) = i; y(i) = x(i)^2; end; >> plot(x, y) Note that plot(x, y) draws x vs y. Enter this code into MATLAB to get the following plot: Examining x and y shows how the for loop works: >> x, y x = 1 y = 1 2 3 4 5 4 9 16 25 If I want to create a “high definition” plot of a more complex function, e.g., y = e − x cos(5 x),0 ≤ x ≤ 2π one way to do it would be to use a for loop to move through a list of x values and calculate the corresponding y value (there are other ways, e.g. you could use element by element operations). >> x = linspace(0, 2 * pi, 100); >> for i = 1:length(x) y(i) = exp(-x(i)) * cos(5 * x(i)); end; >> plot(x,y) 242 TASK 5 Monte Carlo simulation using for loops When dealing with processes that have uncertainty involved in them (like task 4) we are often interested in the most likely outcome. Running the code once only produces a single value but how do we know whether this value was likely or not? For example if we were told we ran 100 successful space shuttle missions were we lucky or unlucky to have made it to that many missions? One way to determine this outcome is via Monte Carlo simulation. We simulate the process a large number of times and store all the outcomes (in this case the number of successful missions). The list of outcomes can be then be studied statistically. Modify your script file from task 4 to ask the user how many simulations they would like to run and then use a for loop to perform the required number of simulations. For each simulation store the number of successful missions in a 1D array called successful_missions. This modification only requires that a few extra lines are added to your script file from task 4. To investigate the distribution for the number of successful missions use the hist command to draw a histogram of the number of missions, i.e.: hist(successful_missions) Try running your script several times, entering a different number of simulations each time to get a feel for how many simulations are required to get an accurate picture of the distribution. COMPULSORY LAB TASKS END HERE 243 EXAM PRACTICE A carbon fibre tiller is being trialled for use on a Team New Zealand boat at the next America’s Cup. Under the most extreme conditions likely to be experienced, this component will be subjected to a 2D strain given by the strain matrix: exx exy 0.230 −0.009 = e = exy eyy −0.009 −0.080 This matrix is simply a way of representing the normal and shear strains experienced by the component in 2 dimensions. Applying these strains to the component generates stresses in the material. You are tasked with finding the angle of orientation of fibres in the material which minimizes the maximum shear stress experienced within the component. To do this, you must first download GetMaxShearStress.m and strainData.mat from Canvas. Use the command: >> load strainData.mat to load the variables e and C into the workspace. e is the strain matrix given above, and C (a ‘compliance matrix’) contains information on the mechanical properties of the material. Using the function GetMaxShearStress.m (for which commenting has been provided), write a script that uses a for loop to determine the angle of orientation which minimizes the maximum shear stress in the component for the given applied strain. Your function should calculate an array of maximum shear stress values for 1000 angles starting at 0 and going through to pi/2. It should then determine which angle minimizes the maximum shear stress and display a message: The fibre angle that minimises the shear stress is ? radians (where ? is replaced by the value) Hint: You may find the min function useful. Use Matlab help to investigate how to use it. 244 EXAM PRACTICE The following algorithm, given in pseudocode, is used to find a root of a mathematical function f(x), ie the input value for a function that gives zero. Get initial guess, x, from user Get tolerance from user fx = f(x) h = 0.000001 while |fx| > tolerance fx = f(x) dfdx = (f(x+h)-f(x-h))/2h x = x - fx / dfdx end display value for root, x Write a MATLAB script that implements the above algorithm to find a root of the sin function when given an initial guess and tolerance. A sample session of your script running is shown below: Please enter the initial guess: 3 Please enter the tolerance: 0.001 Root of sin(x) is 3.142 IMPORTANT: Remember to comment your script file. HINT: The absolute value function in Matlab is called abs. 245 246 ENGGEN 131 Engineering Computation and Software Development Laboratory 4: Graphics and Image Processing The Department of Engineering Science The University of Auckland 247 Laboratory 4 TASK 0 Read the lab notes Go to Piazza and read the pinned post for Lab 4. It details some useful information you should read before starting this lab. PLOTTING BASICS Remember that all plots should include a title and labels (with units if appropriate). You can easily add a title and label your axes using the appropriate functions: t = linspace(0,10,100); plot(t,t.^2); title('Graph of rocket path'); xlabel('time (seconds)'); ylabel('distance (metres)'); TIP Extra Figure Windows If you want to save the figure you have created and start work on a new figure just use the figure command. This creates a new figure window for drawing on. You can choose to draw on existing figure window Figure n by using the command: >> figure(n) For more information look up figure in the MATLAB Help i.e., >> doc figure 248 PLOTTING MULTIPLE DATA SETS When plotting multiple data on the same set of axes you should use different colours/line styles and include a legend. You should refer back to your lecture notes to make sure you know how to modify line colours and styles, then proceed with the following task. TASK 1 Plotting more than one set of data on the same figure Electrocardiography (ECG) is a technique used to record the electrical activity of the heart and determine the rate and regularity of a test subject’s heartbeat. The data is measured using electrodes attached to the skin’s surface, which detect electrical impulses generated by the heart and display them as a waveform. Often, the signal provided by these electrodes suffers from electrical noise. Signal processing techniques can be used to reduce this noise, and provide data that suffers from less uncertainty. In this task, you are required to apply a smoothing function to an ECG signal and compare the unprocessed signal with the processed signal. First, download signal.mat and ThreePointSmooth.m from Canvas and place them in the folder you are working in. Use the command: >> load signal.mat to load two variables, y and t, into the workspace. y is an array of values giving the measurements taken by the electrodes, and t is an array of the corresponding times at which they were taken. Examine the documentation included in the ThreePointSmooth.m function to determine how it works and the required arguments. Write a single script file which produces TWO figures: Figure 1: a single set of axes showing the unprocessed signal (in green) and a processed signal (in dashed red) after 100 passes of the smoothing function (i.e. applying the function to the entire signal 100 times). Include a legend. Figure 2: 3 sets of axis showing the unprocessed signal, the signal after 1 pass of the function, and the signal after 100 passes of the filter. Use solid black lines for each of these plots. Before starting read the tip below. TIP If you need to loop over complicated code consider writing a function When looping over multiple lines of code, moving the code from the body of the loop into a function can dramatically improve the readability of your code. To complete task 1 you will need to smooth a signal once and then a further 99 times. It may be useful to write a SmoothSignal function that takes as input an array of any length and returns the smoothed signal that results from one pass of the three point smooth. You can then call your SmoothSignal function 100 times, replacing the previous signal with the new smoothed signal each time. 249 Figure 1 should look like this: Figure 2 should look like this: Stop Make sure you wrote a single script file and that it generates two figures Remember to follow instructions. If we request a single script file, we want a single file, not two. 250 DRAWING SURFACES The meshgrid function Use the MATLAB Help to find out more about meshgrid. What is the output of the following commands? >> x = [0.1 0.2 0.3]; >> y = [1.5 2.0 2.5 3.0]; >>[X, Y] = meshgrid(x, y) Why is this useful for drawing surfaces? Stop Meshgrid If you’re not sure how meshgrid works or why it is important make sure you ask a tutor to clarify things. TASK 2 Drawing Surfaces Write a SINGLE script file that uses two different methods to draw the surface f ( x, y ) = x 2 y ( y − 1)( y + 1) over the domain . − 1 ≤ x ≤ 1 and − 2 ≤ y ≤ 2 Method 1 1. Divide the interval for each dimension into 10 points. 2. Use a nested for loop to create the surface. Draw the surface. Method 2 Use meshgrid and the dot operator to create the surface. Draw the surface in a separate figure. Make sure that your surfaces look the same. Try increasing the number of points to 100 in each direction and see what happens to your surfaces. 251 IMAGE PROCESSING MATLAB allows you to display many different types of image files using the imread and image functions. For example, you can read the supplied xray.jpg file (available for download from Canvas) using the command >> xray_RGB = imread('xray.jpg', 'JPG'); The variable xray_RGB is a 3-dimensional variable of unsigned 8-bit integers (integers that take values between 0 and 255). Unsigned 8-bit integers can not store negative numbers, fractions or values larger than 255. Attempting to assign values that cannot be represented as unsigned 8-bit integers to an array of unsigned 8-bit integers can produce unexpected results. Depending on what you want to do with the contents of the array, you may first need to create an array of standard numerical values (doubles), using the double function. If needed you could always convert back to unsigned 8-bit images using the uint8 function. The first two dimensions represent the location of pixels in the image and the third dimension identifies whethere we are dealing with the amount or red, blue or green. MATLAB represents images using the RGB colouring for the pixels. >> size(xray_RGB) ans = 1024 745 3 Thus, pixel (i, j) has red content xray_RGB(i, j, 1), green content xray_RGB(i, j, 2) and blue content xray_RGB(i, j, 3). As an example of RGB colours, consider the following Colors Dialog Box for choosing colours in Microsoft Word: 252 To display an image represented by an m × n × 3 matrix of unsigned 8-bit integers you simply input the matrix into the image function. To ensure each pixel is square set the axis to be equal. >> image(xray_RGB) >> axis equal If you have read in the supplied image, Try typing the above commands to see what the image looks like. Note that this image is used under the licensing terms CC BY 2.5 and can be found here: https://en.wikipedia.org/wiki/X-ray_generator#/media/File:Xray-verkehrshaus.jpg IMPORTANT: remember that to draw an image, you need to make sure the array passed into the image fuction contains data stored as unsigned 8-bit integers. If need be you can create an array of unsigned 8-bit integers from a standard array of numerical values by using the uint8 function. TASK 3 Write a function to test if a pixel is blue Airport security staff use x-ray imaging to scan luggage and detect dangerous objects such as weapons. Metal objects are inorganic and typically show up as blue on airport x-rays. This means that being able to dectect blue pixels is important. Your friend told you that a pixel with RGB value (r, g, b) is considered to be blue if r < 128 and g < 128 and b ≥ 128 Write a function called PixelIsBlue that recognizes if a pixel is blue by examining its red, green and blue values. Your function should take in three inputs (the amount of red, green and blue) and return a single output (true or false, depending on whether the pixel is blue or not). Test your function. Your tests should include trying the following calls: PixelIsBlue(10,20,200) (should return 1, ie true) PixelIsBlue(120,180,0) (should return 0, ie false) 253 TASK 4 Debugging BlueCount.m Being able to count the number of blue pixels in an image would give security staff a tool for flagging which bags need more attention. A script has been written to count blue pixels but has bugs. Download BlueCount.m from Canvas: Open this script in the MATLAB Editor, read the header comment to understand what the file should do and the fix any bugs so that it runs correctly. Remember you can use the debugger to step through line by line, so that you can see how each line of code changes the variables in the workspace. TASK 5 Create a filtered image For this task you need to create a filtered image to aid airport security staff, replacing all pixels EXCEPT the blue ones with the colour white. The RGB values for white are (255, 255, 255). Write a script file that filters the xray image to make the inorganic material more noticable. Make sure to read and display the image before filtering it. You will then need to examine each pixel in turn and replace it with a white one if it is NOT blue. You should use the PixelIsBlue function that you wrote in Task 3 to determine if pixels are blue or not. Also be sure to display the final filtered image in a separate figure. Does your filter work completely? If not why not? Explain why or why not to a tutor. COMPULSORY LAB TASKS END HERE 254 EXAM PRACTICE To convert a colour RGB image into a grayscale image, the values of red, green and blue for each pixel must be replaced by a value representing the luminance for that pixel. The formula for calculating the luminance value for a given r,g,b pixel is lum = 0.3r + 0.59g + 0.11b Setting the r, g and b values all to be lum will result in a shade of grey. Write a function called luminance that will calculate the luminance value for a given colour. Your function should take as inputs three values (representing the amount of red, green and blue) and return the luminance value. Write a second function called ConvertToGrayscale which will convert a colour RGB image into a grayscale image by using your luminance function. ConvertToGrayscale should take as input a 3D array describing a colour image and then return a 3D array describing the equivalent grayscale image. IMPORTANT: Remember to comment your function files. EXAM PRACTICE Write a script file called halveImage that scales the size of an image down by a factor of 2 and then draws it to the screen. Your script should work by replacing each 2x2 square of pixels in the old image by a single pixel in the new image. The RGB values for the new pixel will be the average of the RGB values for the 4 pixels from the 2x2 square. You may assume that your image is an even number of pixels wide and high. IMPORTANT: Remember to comment your file. HINT: You are likely to need to use the double function and the uint8 function. 255 256 ENGGEN 131 Engineering Computation and Software Development Laboratory 5: Strings and Files The Department of Engineering Science The University of Auckland 257 Laboratory 5 TASK 0 Read the lab notes Go to Piazza and read the pinned post for Lab 5. It details some useful information you should read before starting this lab. STRINGS Recall that there are a number of useful functions for comparing strings. strcmp strncmp strcmpi strfind Compare two strings Compare the first n positions of two strings Compare two strings ignoring case Search for occurrences of a shorter string in a longer string Try typing the following and check that you understand the result of each string comparison str1 = 'banana' str2 = 'baNANA' strcmp(str1,str2) strcmp(str1,lower(str2)) strncmp(str1,str2,2) strcmpi(str1,str2) strcmp(str1,'bandana') strncmp(str1,'bandana',3) strncmp('banana','bandana',4) Stop Check your understanding Make sure you know why the above commands evaluated to either true or false. Ask a tutor if you are unsure. The strfind function is useful for searching a string for occurrences of a shorter string and returning the location(s) of that pattern. The strfind function returns an array listing the location(s) of that pattern. If the pattern is NOT found then the array will be empty. 258 To easily check if a pattern is found we can simply check if the length of the array containing the locations is 0 or not. str1 = 'banana' strfind(str1,'ana') length(strfind(str1,'ana')) strfind(str1,'skin') length(strfind(str1,'skin')) CELL ARRAYS Sometimes we wish to work with a special kind of array where each element of the array is a string. These arrays have a special name in MATLAB, they are called Cell arrays. They are created and indexed with curly braces: helloWorld = { 'hello', 'world' } length(helloWorld) disp( helloWorld{1} ) upper( helloWorld{2} ) When importing a file into MATLAB it is quite common for a cell array to be created. TIP Remember to use curly braces with cell arrays If you use square brackets to try and create a cell array you will not create a cell array, instead you will just end up with a concatenation of the individual strings. If you use round brackets to try and index a cell array you will get a 1x1 cell array back rather than a string. This can be very confusing if you do not spot your error. MATLAB string functions will also work on cell arrays but the results can be rather confusing. If working with a cell array it is often a good idea to use a for loop to work through your cell array, allowing you to work on one string at a time. Try saving the following code to a script file and running it myMessage = { 'Remember', 'to', 'use', 'curly', 'braces' } for i = 1:length(myMessage) str = myMessage{i}; len = length(str); disp ( ['length of ' str, ' is ', num2str(len)] ) end 259 STRINGS AND USER INPUT/OUTPUT By default the input command expects users to enter a numerical value. If you want to interpret the entered value as a string the input command needs to be passed the letter s as a second argument: name = input('Enter your name:', 's') The sprintf command is very useful for creating a nicely formatted string of characters which can then be displayed with the disp command. It supports a wider range of kinds of outputs. Here is a reminder of some of the more common outputs. specifier s c d or i e f g Output String Character decimal integer scientific notation decimal floating point The shorter of e or f example hello c -23 1.2345e+10 23.1234 The sprintf command takes a format string which usually includes one or more % signs followed by optional control flags and a specifier. Other arguments passed into the sprintf command are inserted in order in place of the specifiers, using the specified format. Try typing in the following commands, leaving off the semi-colon so that you can see what string is created: x = 10 sprintf('The value of x is %d and x cubed is %e',x,x^3) name = input('Enter your name:','s'); sprintf('Hello %s, how are you?',name) sprintf('The value of pi is: %f',pi) sprintf('Pi with scientific notation is: %e',pi) Inserting a decimal and a number between the % character and the specifier allows you to specify how many decimal places to use sprintf('Pi with 2dp is: %.2f',pi) sprintf('Pi with 8dp and scientific notation is : %.8e',pi) Inserting just a number between the % character and the specifier allows you to specify the minimum width to reserve for displaying the value. This is handy when wanting to format output in columns. Try typing the following and running it: for i=0:10:100 string = sprintf('The sqrt of %3d is %7.4f',i,sqrt(i)); disp(string); end 260 TASK 1 Debugging strings Download FindPhoneNumber.m from Canvas. Open this script in the MATLAB Editor, read the header comment to understand what the file should do and the fix any bugs so that it runs correctly. Remember you can use the debugger to step through line by line, so that you can see how each line of code changes the variables in the workspace. TASK 2 Processing strings Open the DNAString.mat file. It contains a long string of a DNA sequence gathered from a newly discovered species. To analyse the genetic nature of this new species, you must compare its DNA string with a number of known DNA strings. These strings are: Sequence 1a: ‘AGTCACT’ Sequence 1b: ‘AcgT’ Sequence 2a: ‘TACTga' The underlined letters are case insensitive – so for example, an occurrence of ‘taCTga’ would count as a match for sequence 2a, but ‘tACTgA’ would not. Write a script that counts the number of occurrences of each sequence in the DNA contained in DNAString.mat, and then prints the results to the screen. Your output should look similar to the following (but with different numbers): Sequence 1: a: 17 b: 34 Sequence 2: a: 7 Total: Total: 51 1 Note how the columns line up. You will need to use sprintf commands to achieve this. FILE I/O MATLAB provides an import wizard which can be used to import data files. Download the gasData.txt file from Canvas. Now try using the file import command to import the data contained in the file (go to File > Import Data) Sometimes the import wizard fails and we need to write code which will read in data from a file. Also if you wish to process many files at a time it is much more convenient to be able to use commands to read the contents of a file. 261 Instead of using the import wizard we will read in the contents of the gasData.txt file using file commands. See the chapter on file I/O for a reminder on how to do this. Remember that you must open the file for reading using fopen before reading from it. You should close your file using fclose when finished. TASK 3 Reading from a file Download the file named gasData.txt from Canvas. This file contains experimental data on the volume (V) and temperature (T) of 2 moles (n) of a particular gas. These measurements can be used to calculate the pressure (P) of the gas (which is the data that is required in this situation), using the universal gas constant (R) of 8.314 and the relationship: PV = nRT Write a script that reads data in from the file and calculates the pressure for each pair of temperature and volume measurements. TASK 4 Writing to a file Extend your script from task 2 so that the pressure measurements are written to a file called pressureData.txt, with each measurement on a new line. Your file should look something like: Pressure (Pa) 10.468417 10.412572 10.585964 10.484070 10.778068 10.915212 ... TIP If working on a windows machine use “Text” mode” when writing to a file A file can be opend for writing in text mode by adding a t next to the w, e.g. myfid = fopen('squares.txt','wt'); If you use text mode on a windows machine, carriage return characters will automatically be inserted in front of any line feed (\n) characters, meaning your file will display correctly when opened in Microsoft Notepad. See Using text mode (or a brief history of newlines) at the end of Chapter 9 for more detail. COMPULSORY LAB TASKS END HERE 262 EXAM PRACTICE (PART A) You are interested in catching people who have been copying each other’s project files. Write a function called CheckSimilarity that will take as input two file names and then check to see how similar the first file is to the second file. Your function will do this by counting how many corresponding lines are identical. i.e. if line 2 of file1.txt matches line 2 of file2.txt then the count of identical lines is increased. Note that for simplicity we will only count matches for corresponding lines, so if line 2 from file1.txt matches line 3 of file2.txt, the count of identical lines is NOT increased. It will also calculate a percentage similarity figure using the formula: Number of identical lines / number of lines in shortest file * 100 Your function should return two output values: the number of identical lines, the percentage similarity between the two files (a value between 0 and 100) IMPORTANT: Remember to comment your file. EXAM PRACTICE (PART B) You are interested in catching people who have been copying each other’s project files. Write a script file that will check to see how similar a given file is to all other files in the same directory. You should use the CheckSimilarity function you wrote in part A, which given two file names will return the number of identical lines and a similarity score. You will need to download the function GetFileNames from Canvas. GetFileNames returns a cell array containing a list of all filenames in the current Matlab directory. Your script file should ask the user to enter a file name to check and then it should write out a file called similarityReport.txt similarityReport.txt should contain a summary of how similar each file in the directory is to the entered file. It should use the format shown below: Similarity Check for file: file1.txt Filename file1.txt file2.txt file3.txt file4.txt Lines the same 10 5 5 1 %similar 100.0 50.0 100.0 5.0 IMPORTANT: Remember to comment your file 263 264 ENGGEN 131 Engineering Computation and Software Development Laboratory 6: Linear equations and differential equations The Department of Engineering Science The University of Auckland 265 Laboratory 6 TASK 0 Read the lab notes Go to Piazza and read the pinned post for Lab 6. It details some useful information you should read before starting this lab. LINEAR EQUATIONS Systems of linear equations appear in many different branches of engineering. It is easy to solve a system of linear equations using MATLAB and only requires writing a few lines of code once the system has been written in matrix form. Consider the problem of finding the intersection of the following two lines: 1 x +1 2 y = −x + 4 y= Replacing x with x1 and y with x 2 we can rearrange these two lines to get the following system −x1 + 2x 2 = 2 x1 + x 2 = 4 This system of linear equations can be written in matrix form as: −1 2 x1 2 = 1 1 x 2 4 −1 2 2 x1 which is of the general form: Ax = b where A = , , x = b = 4 1 1 x 2 In MM1 you will have learnt how to solve matrix equations of the form Ax = b . Recall that if A has an inverse you can multiply both sides of the equation by the inverse of A to get: A −1 Ax = A −1 b Ix = A −1 b That is, the solution is the inverse of A multiplied by b. x = A −1 b 266 In MATLAB it is easy to find the inverse of square matrices and to perform matrix multiplication. To find the solution we can simply type the following: A = [-1 2;1 1] b = [2;4] x = inv(A) * b Check the accuracy of your solution by typing A*x and verifying that we get b (or close to it) Once the matrix A and the column vector b have been assigned values it only took one line of code to solve the system. MATLAB also supplies the left division method, which is equivalent to Gaussian elimination and generally gives a more accurate solution. Try typing the following: x = A\b Verify that you get similar solution values. Check the accuracy of your solution by typing A*x and verifying that we get b (or close to it) Both of those methods ONLY work if A has an inverse. This can be checked before hand. Recall that a matrix has an inverse if, and only if, the determinant of the matrix is nonzero. To find the determinant of a matrix we can use the det command. Find the determinant of our matrix A by typing: det(A) Verify that it is nonzero. Recall that if your determinant is zero then the system of equations has no solution. This also means that the inv command would generate an error as the inverse does not exist. TASK 1 Solving a system of linear equations Consider the following electrical circuit, where we are interested in determining the current flowing along each branch: 267 Applying Kirchoff’s current law at each of the nodes (black dots), and using the current directions indicated by the arrows, we get the following system of equations: i1 − i2 = 0 i2 + i3 − i4 = 0 i4 − i3 − i5 = 0 i5 − i1 = 0 Applying Kirchoff’s voltage law around the three loops in the circuit, we get the equations: V1 − i2 R2 − i4 R4 − i5 R5 = 0 V1 − i2 R2 − V3 − i5 R5 = 0 V3 − i4 R4 = 0 This gives 7 equations for 5 unknowns (the currents). From this point on, we drop the final equation from each group. PART 1: Write a script that puts these equations into matrix form. Then solve the equations to find the current through each branch for the following parameters: V1 = 10V R2 = 3Ω V3 = 4V R4 = 4Ω R5 = 3Ω PART 2: We now want to find by how much we can increase the voltage at V1 before melting a wire (which occurs when more than 5A of current passes through any of them). Using the appropriate type of loop and a step size of 0.1V, increase the voltage at V1 until the maximum current flowing through any of the wires exceeds 5A. Then print the largest acceptable value of V1 to the screen, in the form: The maximum voltage that can be applied is ? volts. Where ? is replaced by the number of volts. 268 SOLVING ODES Ordinary differential equations arise in many branches of engineering. It is relatively easy to find numerical solutions for ODEs using MATLAB if they can be written in the following form: dy = f (y,t) dt i.e. the derivative can be written as some function of the dependent variable and independent variable. In many cases the derivative will only depend on one of the variables but MATLAB can handle functions which depend on both. Consider the following differential equation. dy = cosωt dt with initial condition y(0) = 0 This can easily be solved by direct integration to give y = 1 ω sin ωt Investigate the graph of this solution for time 0 to 1 seconds and an angular frequency of 2π by using the following script (available from Canvas): % calculate the analytic solution of the ODE % dy/dt = cos(omega * t); % omega is the angular frequency omega = 2*pi; % our time range is from 0 to 1 t = linspace(0,1,100); yAnalytic = 1 / omega * sin(omega * t); plot(t,yAnalytic) Now we will solve the same equation in MATLAB and compare it against the numerical solution. To calculate a numerical solution the solver needs three things: • • • A formula for the derivative (in the form of a function) A time interval (start time and finish time stored in an array) An initial value at the start time (initial condition) First we need to write a MATLAB function that calculates the derivative for any given values of t and y. This function will then be called many times by our solver to find our numerical solution. We can choose any valid function name for our derivative but as always it is a good idea to give the function a meaningful name. Note that the solvers require the derivative function to take both the independent and dependent variables as inputs (even if one or the other may not be used). The independent variable must be the 269 first input and the dependent the second. The output for the function must be the derivative for the given inputs. We can now write this function as follows: function [dydt] = SinusoidDerivative(t,y) % calculate the derivative dy/dt for the equation % dy/dt = cos(omega * t) % inputs: t, the independent variable representing time % y, the dependent variable representing displacement % output: dydt, the derivative of y with respect to t % omega is the angular frequency omega = 2 * pi; dydt = cos(omega * t); end Download this function from Canvas and save it as SinusoidDerivative.m. Try testing the function with a few values of y and t and verify that it gives you the correct derivative value for the following inputs: t = 0, y = 0 t = 0.25, y = 1 t = 0.5, y = 0 t = 1, y = 1 Now we are ready to write a script file to solve our ODE: % calculate the numerical solution of the ODE % dydt = cos(omega * t); % set up an array containing the start time and finish time % we will calculate solution values for this time range % we only need to specify TWO values (the start and finish) timeInterval = [0 1]; % our initial condition is y(0)=0 yinit = 0; % solve our ODE, the solver expects three arguments in the % the following order % - the name of the derivative function (in quotes) % - the time interval to solve for (a two element row vector) % - the value at the start time [t,y] = ode45('SinusoidDerivative', timeInterval, yinit); plot(t,y) Download this file from Canvas and run it. Compare your plot with the analytical solution. 270 A ROCKET-PROPELLED SLED (Adapted from an example on page 535 of “Introduction to MATLAB 7 for Engineers”, William J. Palm III.) Newton’s law gives the equation of motion for a rocket-propelled sled as: dv m = −cv dt where m is the sled mass (in kg) and c is the air resistance coefficient (N s/m). We know the initial velocity v(0) of the sled and want to find v(t). Finding v(t) Analytically Using our MM1 knowledge we know we can solve this ODE using Separation of Variables. Solve m dv = −cv given v(0) is known. dt Step 0 : Separate the variables to different sides dv m = −c dt v Step 1: Integrate dv ∫ m v = ∫ − c dt m ln v = −ct + k Note that k is a constant. Step 2: Make v the subject m ln v = −ct + k − ct + k ln v = m v=e − ct + k m Step 3: Rework the constant −c v = Ae m t where A = e k m Step 4: Evaluate the constant −c v(0) = Ae m A = v(0) 0 Step 5: Answer the question −c v(t ) = v(0)e m 271 t TASK 2 Plot the Analytic Solution Given a mass of 1000kg, an initial velocity of 5 m/s and air resistance coefficient of 500 N s/m, plot the rocket-propelled sled’s velocity over the time interval 0 ≤ t ≤ 10 . TASK 3 Plot the Numerical Solution Now we want to solve the ODE numerically. dv . dt Write a script file that uses ode45 to numerically solve the ODE and then produces a plot of velocity vs time. Write a function that returns the derivative Use the MATLAB Help if needed. COMPULSORY LAB TASKS END HERE EXAM PRACTICE Write a function called euler that will numerically solve ODEs of the form: dy = f ( y, t ) dt by using Euler’s method. Recall that in Euler’s method subsequent y values are given by: yn +1 = yn + h f ( yn , tn ) where h is the stepsize. If you need more information about Euler’s method see your MM1 notes or Wikipedia. Your function will need to take 3 inputs: - the name of the derivative function (in quotes) - the time interval to solve for (a two element row vector) - the value at the start time It should return two outputs: - a list of time values - a list of corresponding solution values An example of calling your function is as follows: timeInterval = [0 1]; yinit = 0; [t,y] = euler('SinusoidDerivative', timeInterval, yinit); plot(t,y) Use your function to solve the Rocket Propelled sled problem and compare your solution with the analytic solution and that obtained from ode45. 272 EXAM PRACTICE The following algorithm calculates increasingly accurate approximations to pi using vector algebra: Set a to [0 1 0] and b to [1 0 0] For n = 1 to the number of iterations 1 Set b to (a + b) 2 b Normalise b: b = b Calculate an approximation of pi using: pi = 2 n +1 a × b end Write a MATLAB script that asks the user to specifiy the number of iterations to use and then calculates a sequence of approximations to pi using the alogrithm described above. For every iteration your script should display the iteration number and the value of the approximation to 8 decimal places as shown in the sample output below: Value Value Value Value Value Value Value of of of of of of of pi pi pi pi pi pi pi for for for for for for for iteration iteration iteration iteration iteration iteration iteration 1 2 3 4 5 6 7 IMPORTANT: Remember to comment your file. 273 is is is is is is is 2.82842712 3.06146746 3.12144515 3.13654849 3.14033116 3.14127725 3.14151380 274 Appendix: Style Summary The following are recommended guidelines for the programming style that you should follow for this course. Commenting All code MUST be commented. Every script or function file should have a header comment at the top of the file which indicates the purpose of the file. It is a good idea to also include who the author is. % % % % % Lab 1, Task 3 This file calculates the current for an electrical circuit with two resistors in parallel (r1 and r2) and a third in series (r3) Author: Peter Bier You should comment any sections of code which are not straight forward to understand. Variable identifiers If using a single letter name then scalars and vectors should use lower case while matrices should use upper case: x = 5; y = [1,0,0]; A = [1,2; 3,4]; If using word(s) the first letter should be lower case, and the first letter of subsequent words should be upper case: numberOfStudents = 570; taxRate = 0.33; Function identifiers Identifiers for standard MATLAB functions are entirely in lower case. For functions that we define, the first letter should be upper case, as should the first letter of subsequent words: function [a] = CalculateArea(h,w) Indentation All statements enclosed by a conditional or loop should be indented using one tab character: if x > 0 y = log(x); else y = 0; end Note that you can get Matlab to do indentation of your code for you. Press Ctrl-A to select your code and then Cntrl-I to indent it (or select the Smart Indent option from the Text menu. 275 276 Appendix: Flowcharts Basic Elements Beginning of algorithm (or function) Both the start and end of an algorithm (or function) are shown inside a rectangular shape with rounded corners Input Both input and output elements are shown using parallelograms End of algorithm (or function) Output Computation Basic computation and other commands are shown inside a rectangle Comparison Decisions are shown inside a diamond, with the two paths indicated. 277 Functions Script files Function inputs are shown in a parallelogram on entry to the function. Function outputs are shown in a parallelogram just before exit. Conditionals if ... end 278 if ... else ..end if ... elseif ... end 279 For loop While loop 280 Appendix: MATLAB Command Reference There are many MATLAB features that are not included in the lecture and lab notes. Listed below are some of the MATLAB functions and operators available, grouped by subject area. Use the on-line help facility for more detailed information on the functions. General help demo who what size length clear computer ^C exit quit Disk Files help facility run demonstrations list variables in memory list M-files on disk row and column dimensions vector length clear workspace type of computer local abort exit MATLAB same as exit chdir delete diary dir load save type what fprintf change current directory delete file diary of the session directory of files on disk load variables from file save variables to file list function or file show M-files on disk write to a file Matrix/Array Operators Matrix Operators Array Operators (Element wise) -----------------------------------------------------------------------------------------------------------+ addition + addition subtraction subtraction * multiplication .* multiplication / right division ./ right division \ left division .\ left division ^ power .^ power ' conjugate transpose .' transpose Relational and Logical Operators < <= > >= == ~= & | ~ less than less than or equal greater than greater than or equal equal not equal and or not Control Flow if elseif else end for while break return pause 281 conditionally execute statements used with if used with if terminate if, for, while or end a function repeat statements a number of times do while break out of for and while loops return from functions pause until key pressed Special Values ans pi inf NaN clock date answer when expression not assigned pi infinity Not-a-Number wall clock date Special Characters = [ ] ( ) . ... , ; % : ! assignment statement used to form vectors and matrices see [ arithmetic expression precedence see ( decimal point continue statement to next line separate subscripts and function arguments end rows, suppress printing comments subscripting, vector generation execute operating system command Programming and M-files input keyboard error function eval feval echo exist etime global startup getenv menu get numbers from keyboard call keyboard as M-file display error message define function interpret text in variables evaluate function given by string enable command echoing check if variables exist elapsed time define global variables startup M-file get environment string select item from menu Special Matrices diag eye magic ones rand zeros diagonal identity magic square constant random elements zero Trigonometric Functions sin cos tan asin acos atan atan2 sine cosine tangent arcsine arccosine arctangent four quadrant arctangent sinh cosh tanh asinh acosh atanh hyperbolic sine hyperbolic cosine hyperbolic tangent hyperbolic arcsine hyperbolic arccosine hyperbolic arctangent Elementary Math Functions abs angle sqrt real imag conj round fix floor ceil sign rem exp log log10 282 absolute value or complex magnitude phase angle square root real part Imaginary part complex conjugate round to nearest integer round toward zero round toward -infinity round toward infinity signum function remainder exponential base e natural logarithm log base 10 Command Window clc format disp fprintf clear command screen set output display format display matrix or text print formatted number Graph Paper plot loglog semilogx semilogy polar mesh contour meshgrid bar stairs errorbar linear X-Y plot loglog X-Y plot semi-log X-Y plot semi-log X-Y plot polar plot 3-dimensional mesh surface contour plot domain for mesh plots bar charts stairstep graph add error bars Cholesky factorization eigenvalues and eigenvectors Hessenberg form inverse factors from Gaussian elimination Nonlinear Equations and Optimisation fmin fmins fsolve fzero title xlabel ylabel grid hold minimum of a function of one variable minimum of a multivariable function max maximum value min minimum value mean mean value median median value std standard deviation sort sorting sum sum of elements prod product of elements cumsum cumulative sum of elements cumprod cumulative product of elements hist histograms Elementary Matrix Functions expm logm sqrtm poly det matrix exponential matrix logarithm matrix square root characteristic polynomial determinant Differential Equation Solution ode23 ode45 solution of a system of nonlinear equations zero of a function of one variable File formats (used with fscanf, fprintf etc) %c %d %e, %f, %g %i %o %s %u %x plot title x-axis label y-axis label draw grid lines hold plot on screen Column-wise Data Analysis Decompositions and Factorisations chol eig hess inv lu Graph Annotation characters decimal numbers floating-point numbers signed integer signed octal integer series of non-white-space characters signed decimal integer signed hexadecimal integer 283 2nd/3rd order Runge-Kutta method 4th/5th order Runge-Kutta-Fehlberg method 284 A 285 286 B 287 288 C 289 290 D 291