Introduction to Matlab & Data Analysis Tutorial 6: Boolean Logic, Flow Control and the debugger Please change directory to directory E:\Matlab (cd E:\Matlab;) From the course website (http://www.weizmann.ac.il/midrasha/courses/MatlabIntro//course_outline.htm ) Download: debugExample.m, drawGasPrices.m, tryCatch.m, gas.mat, Shown on board: t6.m , trueOrFalse.m , rockPaperScissors.m, , estimatingEpsilon.m Weizmann 2010 © 1 Topics Boolean logic Relational and logical operators What is true and what is false Flow control: if-else-end constructions Switch-case-end constructions for loops while loops First Loops flow control: break continue try-catch retrun use of Matlab debugger 2 Lecture Reminder Weizmann 2010 © 3 What is true and what is false? Type “logical” True represented by 1 False represented by 0 Keywords: true, false. What is False? false 0 What is true? anything else … Special cases: Empty string ‘’ Array with false values [1 0 1] Empty matrix [] What About NaN? Not true and not false – NaN if (NaN) ??? NaN's cannot be converted to logicals. 4 Reminder - Relational operators < Less than > Greater than <= Less than or equal to >= Greater than or equal to Element by element: Similar dimensions Scalar expansion == Equal to ~= Not equal to 5 Reminder - Logical Operators Logical operator Description Logical operator Description && And (short-circuiting) & And || OR (short-circuiting) | OR ~ Not ~ Not x y X && Y x || y xor(x,y) 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 x ~x 0 1 1 0 Logical functions (column-wise) any(x) all(x) 6 Reminder - Flow Control Flow control: if-else-end constructions switch-Case constructions For loops While loops Loops flow control: If road == the_one_less_traveled_by Break continue disp(‘Made all the difference’); Return Else Try-Catch disp(‘Kept for another day’); end 7 Reminder - If-else-end constructions if (expression I) statement1a; statement1b; else statement2a; statement2b; end Use indentation! if (expression I) statement1a; statement1b; elseif (expression II) statement2a; statement2b; elseif (expression III) statement3a; statement3b; else statement4a; statement4b; end 8 Switch-Case constructions if (expression I) statement1a; statement1b; elseif (expression II) statement2a; statement2b; elseif (expression III) statement3a; statement4b; switch expression case test_exp1 statement1a; statement1b; case {test_exp2, test_exp3} statement1a; statement1b; end Scalar: expression == test_exp1 String: strcmp(expression, test_exp1) otherwise statement1a; statement1b; end 9 Example - Switch-Case day='Tue'; switch day case 'Mon' disp('Matlab class'); case {'Tue','Wed','Thu'} disp('Matlab tutorial'); otherwise disp('Free'); end 10 Reminder - For and While Loops for index = array while expression statement1; statement2; statement1; statement2; end In every iteration of the loop the index equals to one column of the array. end If the expression is true -> run another iteration Pitfall – endless loop 11 Reminder - Nested loops for index1 = array1 statement1; statement2; for index2 = array2 statement3; statement4; end end Indentation! for index1 = array1 statement1; statement2; while expression statement3; statement4; if expression1 statement5; end end end No limitations of nesting order and # levels 12 break – immediately breaks the loop continue – jump to the end statement. Does not break the loop return – returns control to the command line (or to the calling function). Anywhere Breaks only one loop Only inside loops! Reminder - Break, Continue and return affect the flow 13 End Of lecture Reminder Weizmann 2010 © 14 Boolean Logic Weizmann 2010 © 15 Boolean Logic - Pitfalls a = []; b = []; c = 1; a == b Empty array a == c Empty array Comparing to empty array gives empty array Use isempty(A) NaN == NaN NaN is not equal to itself. Use isnan. 2 = 2 Error Major Pitfall! = ~= == 16 Use Indentation & Parentheses x = 0; y = 1; z = 2; % The statement below is unclear x^2 - y == -1 && y*2 - z == 0 || z*2 - x == 5 % Use parentheses! % Use Indentation – % Do not split a logical expression into two lines ( (x^2 - y == -1) && … (y*2 - z == 0 ) ) || … (z*2 - x == 5) 17 Flow control Examples: if-else-end for loops while loops (break, continue) Weizmann 2010 © 18 Example - Rock-Paper- Scissors %%Paper-Rock-Scissors % we use How do we compute % P for Paper % R for Rock who won? Ideas? % S for Scissors Hint: use strcmp % get players hands clc; player1_hand = input('Player 1 hand:'); clc; player2_hand = input('Player 2 hand:'); clc; disp(['Player 1 hand is: ' player1_hand]); disp(['Player 2 hand is: ' player2_hand]); 19 If Example – Rock-Paper- Scissors %Calculate who won if ( ( strcmp(player1_hand,'P') && strcmp(player2_hand,'R') ) || ... ( strcmp(player1_hand,'R') && strcmp(player2_hand,'S') ) || ... ( strcmp(player1_hand,'S') && strcmp(player2_hand,'P') ) ) disp('Player 1 won!'); elseif ( ( strcmp(player2_hand,'P') && strcmp(player1_hand,'R') ) || ... ( strcmp(player2_hand,'R') && strcmp(player1_hand,'S') ) || ... ( strcmp(player2_hand,'S') && strcmp(player1_hand,'P') ) ) disp('Player 2 won!'); else disp('Draw'); end Notice the indentation rockPaperScissors.m 20 Simple For Loop Example – Using For Loops to Initiate Matrices Using a for loop create a 1x10 vector where each entry is the sum of its index and the square root of the previous element (the “zero” element value is 0) x = zeros(1,10); Allocating memory prev_num = 0; “end case”: i=1 variables naming: prev_, cur_ for i=1:10 x(i) = i + sqrt(prev_num); prev_num = x(i); end 21 Simple For Loop Example – Using For Loops to Initiate Matrices Alternative code: x = zeros(1,10); Using if-else-end to take care of end cases for i=1:10 if (i == 1) % end case first element x(i) = i; else x(i) = i + sqrt(x(i-1)); end end 22 Nested For Loop Example – Using For Loops to Initiate Matrices Using for loops initiate a 3x3 matrix such that: Each entry is the sum of its subscripts square A = zeros(3,3); % Don’t forget to allocate memory! A= 2 5 10 for n = 1:3 for m = 1:3 A(n,m) = n^2 + m^2; end end 5 10 8 13 13 18 23 While Loop Example – Estimating Epsilon Epsilon – the smallest number that can be added to 1 such that the result is greater than 1. Can we compute the last line inside the loop? my_eps= 1; my_eps = 1; while (my_eps+1) > 1 my_eps = my_eps/2; end while (my_eps+1) > 1 my_eps = my_eps/2; if (my_eps+1) <= 1 my_eps = my_eps*2; break; end end Is that ok? my_eps = my_eps*2; estimatingEpsilon.m 24 Efficiency And Readability Usually when operations can be performed by either loops or vector operation – the vector operations are more efficient and readable. Always allocate memory in advance. x = linspace(0,2*pi,1000); y = sin(x); == z = zeros(size(x)); for i=1:length(x) z(i) = sin(x(i)); end 25 The Debugger Weizmann 2010 © 26 Debugger Debugging – The process of discovering and correcting bugs in a program Matlab has a graphical debugger We use the debugger to follow a specific run of the control flow debugExample.m /2 A *2 B 27 Debugging Run Time Errors Open the example: edit debugExample.m; Debug buttons Debug menu Stop if errors / warn Break points – There are bugs Lets find them . . Red Gray Modifying a file 28 Coding Tips An “end case” – a relatively rare input that might cause bugs (NaN, Inf). Use indentation: Write the “end” before writing the content Cntl-I Use variables instead of numbers (avoid “hard coding”) 29 Throwing and Catching errors error(‘msg’); try – catch - end Weizmann 2010 © 30 Try-Catch try statement1; error statement2; … catch statement3; statement4; … Try to run the code in the “try” block If no error and reached the catch, go to the end statement. If an error occur, go to the catch statement. end 31 Try-Catch - Errors try statement1; error(‘error message’); statement2; … catch Many Matlab functions throw errors when something goes wrong You can throw error: error(‘error message’); You can also catch errors: statement3; error_string = lasterr; errorStr = lasterr; error = lasterror; disp(errorStr); Using Structure, the error error.message next tutorials… statement4; end rethrow(lasterror); 32 TryCatch.m Try and Catch Example try A = ones(3,3); x = input('Input a number by which A will be divided:'); if isnan(x) error(['NaN was entered: ' num2str(x)]); Input: 2 end A = A /x; A catch errorStr = lasterr; disp(errorStr); %rethrow(lasterror); end Try to uncomment A= 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 Input: nan Error using ==> TryCatch at 7 NaN was entered: NaN Input:[0, 1] Error using ==> mrdivide Matrix dimensions must agree. 33 Final Example – Drawing multiple plots File edit drawGasPrices.m you should have gas.mat in the same directory Reminder: Gasoline_prices – US gas prices at each month of the years 1976-2004 Years – 1976:2004 Months – char matrix. Each row contains a month 34 Final Example – Drawing multiple plots Goal: Get from the user at most five years Draw a figure with a subplot for every year The year subplot displays the prices of gas during this year as a function of the months. 1. Load the data Make sure the data is OK 2. Getting which 3. Draw the plot years to draw 35 Final Example – Drawing multiple plots Notice: Errors: Using while, return, break, continue to get input Using For loop: Throwing for error Try-catch to avoid error exit when the input is wrong Using the loop index to retrieve relevant data Using index to set current subplot Variables naming Use the debugger to go over the code 36 1. Load the data Drawing Multiple Plots – Throwing Error Make sure the data is OK clear; close all; load gas.mat; % checking that the data exist if (~exist('gasoline_prices','var') || ... ~exist('months','var') || ... ~exist('years','var') ) error('gasoline_prices ... not defined'); end 37 2. Getting which years to draw Drawing Multiple Plots – Displaying Instructions to the User % getting which years to draw years2draw = []; disp('Enter which year to draw') disp('Years should be between 1976 and 2004'); disp('Maximum five years are allowed.'); disp('When done enter D'); D while mean break disp('If you wish to quit without drawing enter Q'); Q while mean return 38 2. Getting which Drawing Multiple Plots – Quitting and Breaking a Loop years to draw while length(years2draw) < 5 … cur_year = [input('Year / D / Q :','s')]; if (strcmp(cur_year, 'Q')) disp('Bye!'); return; elseif (strcmp(cur_year, 'D')) break; end Use while … end to iterate until you get a satisfying input 39 2. Getting which Drawing Multiple Plots – Using Continue, for mal input years to while length(years2draw) < 5 … % getting the number cur_year = str2num(cur_year); cur_year = floor(cur_year); if ~isscalar(cur_year) disp('Input is not a number, try again.'); continue; end % year not in range if (cur_year < 1976 || cur_year > 2004) disp('Years are not … 1976-2004'); continue; end years2draw(end+1) = cur_year; end draw 40 2. Getting which years to draw Drawing Multiple Plots – Try-Catch Handling of unpredicted error while length(years2draw) < 5 … try <all the code of getting the input> % adding the year to the input years vector years2draw(end+1) = cur_year; catch We avoid exiting by catching the error error_str = lasterr; disp(['Bad input, try again:' error_str]); continue; end … end 41 3. Draw the plot Drawing Multiple Plots – Return if Nothing Need to be Done % end case: % if no year was entered we are done if (isempty(years2draw)) disp('No year was entered, exiting.'); return; end % opening a new figure figure; 42 3. Draw the plot Drawing Multiple Plots – For loop – Variables Naming for i = 1:length(years2draw) % getting the data cur_year = years2draw(i); cur_year_prices = gasoline_prices(find(years == cur_year),:); % setting the current subplot subplot(length(years2draw),1,i); % drawing plot(1:12,cur_year_prices, 'r-x','LineWidth',2) xlabel('Month', 'FontSize', 14); ylabel('$/Gallon', 'FontSize', 14); title(['Monthly Gas Prices during:' num2str(cur_year)], 'FontSize', 16) set(gca,'XTick',1:12, 'XTicklabel', months); grid; Variables naming: axis tight; end i for index cur_ for current (value is specific for this iteration) 43 Summary Boolean logic Relational and logical operators What is true and what is false Flow control: if-else-end constructions Switch-case-end constructions for loops while loops Loops flow control: break continue try-catch return First use of Matlab debugger 44 Extra examples Not shown in the tutorial Weizmann 2010 © 45 Boolean Logic Tips and Pitfalls quote = ['To err is human - and to blame' … 'it on a computer is even more so. ']; Sub_str1 = 'i am'; Sub_str2 = 'i'; Strings are char arrays: quote == sub_str1 ??? Error using ==> eq Matrix dimensions must agree. quote == sub_str2 [ 0 0 0 … 1 0 0 1 … 0 0] Should have equal sizes Scalar expansion String comparison – strcmp strncmp strcmpi strcmp(quote, sub_str1) 0 (“i” - not case sensitive) 46 Examples Which are similar? 1 || 2 && 0 1 || (2 && 0) (1 || 2) && 0 Notice the Precedence Arrays - Which are similar? [] [0, 1] [1, 1] any([0, 1]) all([0, 1]) TrueOrFalse.m 47 Use Logical Expressions for Array Indexing >> isnan([1, NaN]) [0, 1] >> v = 1:10; % Find all elements of v % that are product of 3 or equal 5 % (hint – use mod(v,3)): >> >> find(v == 5 | mod(v,3) == 0) [3, 5, 6, 9] 48