flow control and functions - university of california ...dmk/old-matlab-mini-course/notes... ·...

17
Flow Control and Functions Script files If's and For's Basics of writing functions Checking input arguments Variable input arguments Output arguments Documenting functions Profiling and Debugging

Upload: others

Post on 31-May-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Flow Control and Functions

� Script files

� If's and For's

� Basics of writing functions

� Checking input arguments

� Variable input arguments

� Output arguments

� Documenting functions

� Profiling and Debugging

Page 2: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Introduction

Today, we are going to explore the wonderful world of functions. Functionsare critical to efficiently using matlab. We are going to spend most of theclass working on a single function. In each step, we will add features to thisfunction while we learn. The end result will be a function that measuresEuclidean distance between sets of points in an arbitrary number ofdimensions.

Before starting, I would like everyone to change their working directory tothe Windows Desktop. You can either do this with the cd command, or(easier) by clicking on the “ ...” besides the “Current Directory” displayed atthe top of the Matlab Window and selecting the desktop. We will be savingand loading any and all files from the desktop during these classes.

Page 3: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Script FilesBefore beginning our function, we need a couple more matlab tools. In matlab, anyset of commands can be placed in a text file and run as a group from the CommandWindow. These are called script files. For example, place the following commandsinside a new text file:

% This is my script file[1 2 3]a = randn([2, 3])a .^ a %%% This raises a to the a %%%%

Save the file as myscript.m. All matlab script files must end in “.m”. To run thesecommands, just type the filename in the command window. Compare the following:

� myscript % Don' t need the .m here

� echo on

� myscript

� echo off

� a

echo on repeats all the commands in the script file as they are executed.

In many of the following pages, it will be more convenient to place the commandsinside scripts files and execute them all at once. Nevertheless, any command can beentered on the command line.

Page 4: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Flow Control: ifFlow control refers to any command that changes the execution order of the code.These include if, for, switch and while. if is used to make a logical test.

a = 4.1 * pi;if a > pi | a < �pi

b = mod( a, 2*pi ); % Between 0 and 2*pi.if b > pi, b = b – 2*pi; end % All in one line.

elseb = a;

end

Note the indentation. This is useful for reading, but not strictly necessary.

All flow control blocks in matlab must end with end. The commands any and allare useful for flow control. any checks is true if any element of the vector is true,all is true only if all elements of the vector are true.

a = [ 1 NaN 2];if any( isnan( a ) )

a( isnan(a) ) = �999;end

Page 5: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Flow Control: for & switchfor repeats a series of commands once for each element of an array.

a = 1:5for i = a

disp([ ' The square of ' int2str(i) ' is ' ...int2str(i^2) ' . ' ])

end

Note that i receives each of the values of a. disp is useful for displaying textualoutput.

switch is shorthand for various if statements. It is particularly useful withstrings.

loo.status = ' bad' ;switch loo.status

case ' bad'l oo. gr ade = 1;

case ' good'l oo. gr ade = 4;

otherwiseloo.grade = �999;

end

Page 6: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Function BasicsHere we are going to begin with functions. The basic form of a matlab function is:

function [out1,out2,...]=f_name(in1,in2,...)% Documentation(PUT YOUR CODE HERE)

where in and out are the input and output arguments. Functions are saved in m �

files with the same name as the function. They are used from the command windowin the same way one would use any matlab function (mean, size, ...).

Inside a matlab function, the only known variables are those in the function.Variables defined in the Command Window are absent inside the function.

Here is a simple example that divides one number by another and returns the integerdivisor and its remainder:

function [id,r] = divideme( n, d )% DIVIDEME% This function does division like you did in grammar% school.id = floor( n/d );r = n – id * d;

This function would be saved in a file with the name “divideme.m” and would becalled from the command line as divideme. Try it and see that it works.

Page 7: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Our FunctionAs promised, we are going to be creating our own function in this class. I wouldlike you to create a function that measures Euclidean distance between vectors ofpoints. For example, suppose you have measured the x,y �coordinates of threejetties, as well as the position of 20 different buoys, and you wish to know thedistance from any of the jetties to any of the buoys. The jetty positions would be a3x2 array (first column for x, second for y), the buoy positions would be a 20x2array. The result of the function is a 3x20 matrix with the distance from any jetty toany buoy.

Try to create this function. Begin with a function that expects coordinates in 2dimensions (2 column matrices). The function should begin something like:

function [ d ] = dist( coord1, coord2 )....

An efficient solution to the problem will probably use the transpose operator and thefunctions size and repmat. Don't hesitate to check out the help for thesefunctions. Use your matrix arithmetic. The formula for the Euclidean distancebetween a pair of points (x

1,y

1) and (x

2,y

2) is:

x 1

� x22 �

y 1

� y 22

Page 8: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Solution 1

Please try to work this problem out on your own. If you are really having problems,click here for a solution to the problem as this stage of development. If this linkdoes not work, try at the end of the page.

Page 9: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Checking Input ArgumentsTypically in a function you want to make sure that the correct type of arguments arepassed to the functions. In our example, you want to make sure that the first andsecond arguments have the same number of columns, and that that number is 2. Ifnot, you should return an error.

...if (size(coord1,2) ~= size(coord2,2)) | ...

(size(coord1,2) ~= 2)

er r or ( ' Wr ong si ze. ' )

end

. . .

The error exits the function immediately and displays the given string. Add theselines to your function and see how they work.

You can also place return anywhere in your function to exit the function earlywithout an error.

Page 10: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Variable Input ArgumentsMatlab does not automatically complain if the number of input arguments given to afunction is less than the number expected. Matlab simply leaves the extra inputvariables undefined. This is useful for allowing variable numbers of inputarguments.

Inside a matlab function, there is a predefined variable, nargin, which tells youhow many input variables were actually given. Try using the following functionwith several different numbers of input arguments:

function r = test( a, b, c, varargin )r = nargin;

Note the use of varargin. This allows you to have any number of inputarguments. All extra input arguments are placed in a cell array called varargin.In the above function, varargin{1} would be the fourth input argument,varargin{2} would be the fifth, etc.

Try adding the following to your function so that it works with only one inputargument:

if nargin < 2, coord2 = coord1; end

Page 11: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Our Function 2

You now have the necessary information to expand your function to acceptcoordinates in an arbitrary number of dimensions. coord1 and coord2 will nolonger have two columns, but rather an arbitrary (but equal) number of columns.

There are probably many solutions to this problem, but the two most straightforwardare either to use a for loop, or to use repmat and shiftdim and work with 3dimensional matrices.

Don't forget to check your arguments and allow for only one input argument.

Page 12: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Solution 2

Click here for a solution to the problem as this stage of development. If this linkdoes not work, try at the end of the page.

Page 13: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Output Arguments

Much of what has been said about input arguments can also be said about outputarguments. You can check how many output arguments the user requested usingnargout. Large numbers of output arguments can be accommodated usingvarargout.

Change the dist function as follows so that it will, if desired, return a secondoutput argument with the dimension of the input vectors:

function [d, dim]=dist(coord1,coord2)...if nargout > 1, dim = size(coord1,2); end

Test the function with zero, one and two output arguments.

Page 14: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Documenting Functions

Creating help documentation for personal functions in matlab is extremely easyand useful. All you have to do is include comment lines right after the functionline. Change the beginning of your function so that it looks as follows:

function [d, dim]=dist(coord1,coord2)% DIST – a function that measures distances%% Usage: d = dist( coords1, coords2 )% [d, dim] = dist( coords1, coords2 )% If coords1 is a MxN matrix and coords2 is a PxN matrix,% then the result is an MxP matrix of Euclidean distances% between the vectors in R^N given in coords1 and coords2

Now try the following from the command window:

� help dist

� which dist

Page 15: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Subfunctions

Matlab functions can contain their own private subfunctions simply be tacking thesesubfunctions onto the end of the file. For example, one rather clean way to solve thedistance function problem in arbitrary dimensions is to use a subfunction thatcomputes the distance squared in one dimension and then use a for loop to pass overeach dimension. It would look something as follows:

function [d, dim]=dist(coord1,coord2)...

d = d + dist1sq(coord1(:,i),coord2(:,i));

...d = sqrt(d)

...

function d = dist1sq(c1,c2)

...

Page 16: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Final Solution

Click here for the final version of the function as I would have written it. If this linkdoesn't work, look for a link at the end of the slide.

Again, this is only one possible way to solve the problem. Yours might look totallydifferent but function all the same. My version has the benefit of being reasonablyfast while minimizing memory usage in higher dimensions.

Page 17: Flow Control and Functions - University of California ...dmk/old-matlab-mini-course/notes... · Script Files Before beginning our function, we need a couple more matlab tools. In

Debugging and ProfilingMatlab makes it fairly easy to debug functions. Debugging begins with the errormessages it prints out on failure, but goes far beyond that. It is a fairly complextopic, so I won't say much.

The simplest tool you can use is the keyboard command. This command, whenplaced inside a function, temporarily exits the function and allows the user toexamine variables inside the function, step through the function (see dbstep) andcontinue when desired (see return).

Another useful and entertaining thing to do is profile a function. This is a way ofkeeping track of how much time matlab spends in different parts of your function.In this way, you can see what parts of the function take the longest and concentrateyour efforts on improving those parts.

Try the following:

� a = randn( 1000, 2 );

� b = randn( 1000, 2 );

� profile on

� dist( a, b );

� profile report