Extending MATLAB Write your own scripts andor functions
Extending MATLAB Write your own scripts and/or functions Scripts and functions are plain text files with extension. m (m-files) To execute commands contained in m-files, MATLAB needs to know where they are! store in working directory store in any directory, add to MATLAB's path
Reminders To check/change working directory pwd, cd, ls, dir menu bar current directory window To check/modify path addpath, rmpath, savepath File >> Set Path. . .
Scripts No input/output Operate on pre-defined workspace variables and variables defined in script Variables created during script are saved in workspace (side effects) Kind of like macros, relatively inflexible → good for executing repeated long/complicated sequences of commands on same data
How to execute a script Save list of commands, variable definitions, etc in plain text file 'script. Ex. m' Make sure 'script. Ex. m' is saved in wd, OR, its directory is added to path type 'script. Ex' at command prompt (no quotes) Be aware of side effects
Functions Basically, scripts that take input and create some output Operate on input variables and variables defined in function Variables created during function call only exist as long as function is running can be saved to workspace if defined as output → good for performing general tasks with optional parameters on different datasets
How to call your function (1) Write it (we'll get to that), and save as plain text file 'function. Ex. m' Make sure 'function. Ex. m' is saved in wd, OR, its directory is added to path Let's assume your function has 2 input arguments, these could be input data or parameters to pass to function body Examples. . .
How to call your function (2) Arg 1 is data stored as workspace variable, Arg 2 is file containing data, or could be a file to create for output >> function. Ex(x, 'filename. txt') Arg 1 is another function, Arg 2 is scalar parameter >> function. Ex(@func, 1000) >> function. Ex('func', 1000)
Defining your function First line must contain the following 'function' command name(s) of output, if any name of function, should be same as name of m-file name(s) of input parameters/arguments function output = user. Func(arg 1, arg 2) function [ ] = user. Func(arg 1, arg 2, arg 3) function [out 1, out 2] = user. Func(arg 1)
What about lines 2, 3, 4, . . . ? Function body can contain anything, as long as it's a valid MATLAB statement/command Any text preceded by a % is not executed → % this is a comment If function definition on line 1 is followed by block of commented lines, comments will be printed as help file when user types >> help user. Func
Programming basics Loops for loop → perform command(s) for some predetermined amount of times while loop → perform command(s) as long as some condition is met If-then statements if some condition is met → perform command(s) else and elseif
For loop While loop for index = 1: n while condition do something end for i = 1: 5 j = 1; i while j <= 5 end j j = j+1; end
For loops Avoid hogging memory, use vector alternatives in MATLAB vec = [2: 2: 10] for i = 1: length(vec) vec(i) = vec(i) + 10; end vec = 12 14 16 18 20 vec = vec + 10
How to loop through a matrix m = [1: 4; 5: 8; 9: 12]; % 1: 12 [rows cols] = size(m); for rowstep = 1: rows for colstep = 1: cols % create 3 x 4 matrix, values % % store # of rows and columns in variables loop through rows loop through columns rowstep % print current row colstep % print current column m(rowstep, colstep) % print value at current % position end % close column loop end % close row loop
Turn that script into a function. . . function [] = read_matrix(m) % % HELPFILE for trivial function 'read_matrix. m' % % 'm' is a matrix % elements of 'm' will be read starting with [1, 1] % % at each step, indices and their corresponding value % will be printed to the screen % START CODE [rows cols] = size(m); variables % store # of rows and columns in for rowstep = 1: rows for colstep = 1: cols % loop through row numbers % loop through column numbers rowstep % print current row colstep % print current column m(rowstep, colstep) % print value at current position end % close column loop % close row loop
If statements if condition do something end -------if condition do something else do something end val = m(3, 2) if val < 5 val = 0; elseif val > 5 val = val * 10; else end val = val^2;
File handling >>help iofun >>help fileformats load dlmread, dlmwrite xlsread, xlswrite urlread, urlwrite unzip, untar
More file handling, C style fopen, fclose fgetl, fscanf, fseek, ftell fid = fopen('mean. m'); % open file for reading while 1 % start loop, basically will loop % forever unless it is stopped % get next line in 'fid' line = fgetl(fid); end if ~ischar(line) break end % if 'line' is empty break loop disp(line) % print the current line fclose(fid); % close file
Let's put this all to use. . .
Example: transition probabilities Probabilistic sequence of events We have multiple examples of this sequence Given a particular event, how reliably can we predict the next event (including the end)? Assume sequence is always same number of events long Represent each event with a number Ex. Sequence: 1 – 2 – 3 – 3 – 1 – 4 – 4
Basic idea Represent each sequence as series of integers Collect a bunch of these sequences and put them in a matrix where each row is one example of the sequence We'll write code that will take the matrix and two of the events as arguments Code will return a probability: How often one event follows the other
Some sequences 2 1 1 1 2 1 1 1 2 3 2 2 2 1 2 2 2 3 4 3 3 3 3 3 4 6 4 4 4 2 4 4 4 6 7 6 6 6 3 6 6 6 7 6 6 6 5 6 7
Example: transition probabilities Givens A matrix 'data' containing events/numbers, each row is a sequence two events, 'leader' and 'follower' Tasks Compute how often 'follower' immediately follows 'leader' Compute how often 'leader' ends the sequence, i. e. is the last number in its row
Strategy Loop through matrix, looking for 'leader' Check to see if it is at the end of the row Check to see if the next element is 'follower' if yes, tally 1 Count total number of times 'leader' occurs Total up the tallies and divide each by the total occurrences of 'leader'
Implement in a function [prob term_prob] = trans. Prob. EXAMPLE(filename, leader, follower) % % 'filename' is plain text file containing sequences stored in a matrix % % 'leader' and 'follower' are events/numbers of interest % % This function will compute transition probability from 'leader' to % 'follower' % i. e. how often 'leader' is immediately followed by 'follower' % % returns 'prob' - 'leader' -> 'follower' transition probability % 'term_prob' - probability that 'leader' is last element % in its row
read in data and define variables. . . data = dlmread(filename); % pass info in 'filename' to variable 'data' % initialize empty counting vectors track_trans = []; % for tracking instances when 'leader' is % followed by 'follower' track_terms = []; % for tracking instances when 'leader' % terminates the line [data_row, data_col] = size(data); % save dimensions of 'data' % to use for looping
do the work. . . % loop over 'data' rows for row = 1: data_row % loop over 'data' columns for col = 1: data_col % look for instances of 'leader' if data(row, col) == leader % check if 'leader' terminates line if col == data_col % if yes, add 1 to counting vector track_terms = [track_terms 1]; % see if next element is 'follower' elseif data(row, col + 1) == follower % if yes, add 1 to counting vector track_trans = [track_trans 1]; end end
do the work. . . % loop over 'data' rows for row = 1: data_row % loop over 'data' columns for col = 1: data_col % look for instances of 'leader' if data(row, col) == leader % check if 'leader' terminates line if col == data_col % if yes, add 1 to counting vector track_terms = [track_terms 1]; % see if next element is 'follower' elseif data(row, col + 1) == follower % if yes, add 1 to counting vector track_trans = [track_trans 1]; end end
do the work. . . % loop over 'data' rows for row = 1: data_row % loop over 'data' columns for col = 1: data_col % look for instances of 'leader' if data(row, col) == leader % check if 'leader' terminates line if col == data_col % if yes, add 1 to counting vector track_terms = [track_terms 1]; % see if next element is 'follower' elseif data(row, col + 1) == follower % if yes, add 1 to counting vector track_trans = [track_trans 1]; end end
do the work. . . % loop over 'data' rows for row = 1: data_row % loop over 'data' columns for col = 1: data_col % look for instances of 'leader' if data(row, col) == leader % check if 'leader' terminates line if col == data_col % if yes, add 1 to counting vector track_terms = [track_terms 1]; % see if next element is 'follower' elseif data(row, col + 1) == follower % if yes, add 1 to counting vector track_trans = [track_trans 1]; end end
compute outputs. . . % count total number of instances of 'leader' total_leader = length(find(data == leader)); % count number of times 'follower' followed 'leader' count_trans = sum(track_trans); % count number of times 'leader' terminated line terminations = sum(track_terms); % calculate probability that 'follower' follows 'leader' prob = count_trans/total_leader; % calculate probability that 'leader' terminates line term_prob = terminations/total_leader;
compute outputs. . . % count total number of instances of 'leader' total_leader = length(find(data == leader)); % count number of times 'follower' followed 'leader' count_trans = sum(track_trans); % count number of times 'leader' terminated line terminations = sum(track_terms); % calculate probability that 'follower' follows 'leader' prob = count_trans/total_leader; % calculate probability that 'leader' terminates line term_prob = terminations/total_leader;
compute outputs. . . % count total number of instances of 'leader' total_leader = length(find(data == leader)); % count number of times 'follower' followed 'leader' count_trans = sum(track_trans); % count number of times 'leader' terminated line terminations = sum(track_terms); % calculate probability that 'follower' follows 'leader' prob = count_trans/total_leader; % calculate probability that 'leader' terminates line term_prob = terminations/total_leader;
Extra credit Generalize this function to deal with sequences of variable length Hint: more of a data representation problem than a coding problem can't have a matrix with rows of different lengths use 'Na. N' to fill space, >>help isnan still want to know if 'leader' is last event in sequence Only need a couple extra lines of code
Extra credit Could also use C style file handling functions fopen, fgetl, etc to read one line at a time instead of loading whole data file at once into matrix Then no problems with unmatched row lengths etc, but would need more changes to code
- Slides: 34