Table of Contents

1 Matlab as a first language

1.0.1 Setup for this tutorial

https://gitlab.com/opensourcedave/matlabcourse
Download zip
Unzip (on windows click and drag contents to a new directory)
In matlab cd to unzipped directory
(On windows you can click on an empty space of the address bar to get the address. Highlight it, then copy it. Then in matlab paste it after the cd command)

1.1 Editor

More than just a couple of lines, use the editor
You can use any editor you like as well.
Comments start with % - won't be ran
_ Depending on your OS…
_ You can comment a whole line with <C-/>
_ Uncomment a line with <C-T>
Break up your code into sections with %%
_ You can run your code section wise if you do this <C-return>
_ <C-down> lets you jump to next section
_ To run everything F5

  • You can also see how long it takes to run your code with "Run & Time"
  • If these are not your hotkeys see Editor->Run

Plenty of buttons for everything, but just learn the hotkeys

  • Under Editor->Edit, hover over buttons to see some common hotkeys
  • See all your hotkeys under Home->Preferences->Keyboard->Shortcuts

Most of the buttons in the UI have a command line equivalent, which is usually quicker to user
(I'll be using my own editor for speed)

1.2 Writing Scripts

%Runs just like inputting a bunch of commands in the commandline
%All variables will end up in your workspace
%Writing a script is the best way to begin writing a function

%Lets write a script that solves a quadratic equation
x(1) = -b + sqrt(b^2-4*a*c)/(2*a);
x(2) = -b - sqrt(b^2-4*a*c)/(2*a);

%save as "quadratic"
%assign some variables
a=1;
b=0:
c=0;
quadratic

a=1
b=-1
c=-2
quadratic

1.3 Writing Functions

% Difference between a function and a script
%  - Other than input and output, functions create variables in different workspaces
% Good practice for writing a function - start out in a script then make it a function

%Lets turn our script into a function
function [ansP, ansN] = quadratic(a,b,c)

% *Name of function needs to be the same as the filename*
% Comment section - what it does, what inputs and outputs mean
% Remember: matlab will not warn you if there are multiple functions of the same name
%  - If you have multiple functions of the same name, matlab will choose for you without warning
%  - Use 'which' function
% Also comment the body of your function for later reference

1.4 Conditional statements

% Conditional statements allow for certain code to be ran if a certain condition is met.
% In a single if-statement, you can have as many conditions as you like. The first must always be 'if'.
% 'elsif' and 'else are optional
a=3;
b=3;
if a==b %if this condition is met
  disp('These are the same') %run this nested indented code
  c=3;
elseif a==(b*-1) %This condition in only checked if the previous statement was false
  disp('These have the same magnitude');
elseif a==0      %This condition in only checked if the previous statements were false
  disp('A is zero');
else %no semicolon requred
  disp('these are not the same');
end
%Multiple conditions may in fact be true, but the entire block (starting with 'if' ending with 'end') will terminate after the indeted code associated with the first match is met.
%Therefore, it may be necessary to further condition your code, or use multiple if statements.
%Semicolons do nothing on lines containing 'if', 'elseif', 'else', or 'end'

%Indentation is good form, but not required
% If you are running the matlab editor, this is usually done automatically

function [b,ind] = isalpha(in)
%determine whether string is contains only letters
  ind=find(~ismember(in,alphaV));
  if isempty(ind)
      b=1;
  else
      b=0;
  end
end %This end is required if multiple functions are in the same file

% Put the below function in the same file as 'isalpha'!
function A = alphaV()
  A=['abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'];
  A=A(:);
end
%By including a secondary funciton in the same file, we have limited the scope of this additional function.
%That is, it can only be called on by code within the file.

1.5 Switch case

%switch-case is like if-statments but more convenient for simple conditions especially if you have a lot of them.
function [txt] = num2literal(num)
switch abs(num)
  case 1
    txt='one';
  case 2
    txt='two';
  case 3
    txt='three';
  case 4
    txt='four';
  case 5
    txt='five';
  case 6
    txt='six';
  case 7
    txt='seven';
  case 8
    txt='eight';
  case 9
    txt='nine';
  case 0
    txt='zero';
  case{Inf,NaN} %Having a case like this is saying Inf | NaN
    txt='infinity';
  otherwise
    if isalpha(num)
      disp('String contains non-number') %We will change this later
    end
end %Note only one end
if num<0
   txt=['negative-' txt];
end

 are

1.6 For Loops

% Loops allow you to repeat code as many times as you want.
% For loops let you repeat that code, but each time it repeats, you can have a variable (commonly i) take on a specific number
% Assigning a temporary variable from a row vector on each iteration
% Visualizing a sampling procedure as a movie:
A=[]
for i = 1:100  %We are repeating the indented code 100 times. Systematically i will take on values 1:100 with each iteration
    A=[A; randn(10,1)]
    histogram(A)
    drawnow
    pause(.1)
end
%You don't have to have i = 1:100. You can replace 1:100 with any row vector!

% Preallocation - assining placeholder values in matrix/cell before its populated with desired values
% - Makes sure that you have enough memory before you run
% - Breaks on first line rather than later
% - Helps you write out statments in loop and check your work
% Step by step watch the evolution of some matrices
B=zeros(size(A,1),size(A,2),2)
for i = 1:size(A,1)
    B(i,:,1)=A(i,:)
    B(i,:,2)=A(i,:)+3./2
    imagesc(B(:,:,1))
    drawnow
    kk=waitforbuttonpress;
end

function SEM=SEMboot(data,nBootS,bPlot)
% Bootstrapping to get Standard error of the mean
% be used for confidence intervals for the sample mean
M=zeros(length(data),1);
for i=1:nBootS
   y=datasample(data,'Replacement',true);
   M(i)=mean(y);
end
SEM=std(M);
if bPlot==1
    histogram(M);
    title('SEM: ' num2str(SEM));
end

1.7 While loops

% While loops are a loop that continues until some condition is met
% Ask for input that re-prompts as long as there is an invalid responses:
while true
   r=input('Please input your name: ','s');
   if isalpha(r)
      break
   else
      disp('Invalid name. Try again')
   end
end

OR

while true
   r=input('Please input your name: ','s');
   if ~isalpha(r)
      disp('Invalid name. Try again')
      continue % Ends current iteration and begins just under while loop
   end
   break
end

% Continue and break also work in for-loops
% If using continue on a for-loop, will start on the next iteration value
for i = 1:5
    if mod(i,2)
       disp([i ' is even'])
       continue
    end
    dis([i ' is odd'])
end

function tlines = txt2lines(fname)
% Opens a text file, returns each line of the file as an element in a cell
fid=fopen(fname);  %opens file
tline = fgetl(fid);%reads file into variable
tlines = cell(0,1);
while ischar(tline)
    tlines{end+1,1} = tline;
    tline = fgetl(fid);
end
fclose(fid); %closes file

1.8 Error handling

%You can have code that doesn't error-out if something goes wrong
try
%Run Something that may break
catch ME; %ME is struct that contains the error message
%do something, like save data
  rethrow(ME); %rethrows error
end

%Warning %Disp with 'Warning:' attached to the beginning & can trigger debugging tools (next section)
%Error - create your own errors!
%assert -> throw error if condition is not met - like an if statement and 'error' combined

1.9 Advanced example

%Lets build a simple experiment
%First lets build a function to act as a template that can run different types of experiments
function R = questionaire(Q,validRange)
%A questionaire that accepts responses in numbers
% Q          - Questions to ask
% validRange - range of numbers that are acceptable
% R          - Responses
assert(iscell(Q),'Questions are not in cell format.')
R=zeros(size(Q));
for i = 1:length(Q)
    clc %clear screen with every new question
    while true

        try
            %PROMPT FOR INPUT
            rsp=input([Q{i} ': '],'s');
            R(i)=str2double(rsp);

            %CHECK IF RESPONSE IS WITHIN RANGE
            fail=~ismember(R(i),validRange);
        catch
            fail=1;
        end

        if fail
            clc
            disp('Invalid response. Try again.')
        else
            break
        end

    end
end
clc
disp('Questionaire Complete. Thank you!')

%Now lets build a function to run a specific experiment using the general function
function [] = ADDquestionaire(subj);
if ~exist('subj','var') || isempty(subj)
    error('Requires subject initials.');
end
Q=txt2lines('addquestions.txt');
validRange=1:9;
clc
input(['Welcome.' ...
   newline 'Please rate your response with the following questions with numbers ' num2str(validRange(1)) ' to ' num2str(validRange(end)) '.' ...
   newline 'Press return to start questionaire: '],'s');
R=questionaire(Q,validRange);
dname='ADDquestionaireResponses';
mkdir(dname);
fname=[ dname filesep subj '_addQs'];
save(fname,'R','subj')

%You can run this on your own, but you can generate similar data by running 'makeData'
%Lets build some scripts to analyze this data
%ANALYSIS SCRIPT
try
    dname='ADDquestionaireResponses';
    cd(dname);
    files=dir; %dir returns all contents of a directory
    files={files.name}; %the following process removes any files that don't end with .mat
    ind=contains(files,'mat');
    files=files(ind);
    scores=zeros(length(files),1);
    Subjs=cell(length(files),1);

    %PROCESS BY SUBJECT
    All=[]; %ALL IS A GOOD
    for i = 1:length(files)
        load(files{i});
        Subjs{i}=subj;
        S.(subj).R=R;
        scores(i)=sum(num2str(R));
        S.(subj).score=scores;
        S.(subj).num=i;
        All=[All; R];
    end

    %Z-SCORES
    zscores=zscore(scores);
    for i = 1:length(Subjs)
        S.(Subjs{i}).zscore=zscores(i);
    end

    figure(1)
    plot(zscores)
    title('ADD questionare Z-scores')
    xlabel('Subject number')
    ylabel('Z-Score')

    %Correlation
    n=randn(length(Subjs),1);
    rho=corr(scores,n);

    figure(2)
    plot(scores,n,'k.')
    title(['rho = ' num2str(rho)])

catch ME
    cd ..
    rethrow(ME)
end
cd ..

%Try using the variable 'All' in your bootstrap function

1.10 Debugging Basics

When traceback is not clear

  • Commenting out code
  • Printing and non semi-colon
  • More advanced in next lecture

Most common errors

  • Closing a bracket or parenthesis
  • Indexing/subscripting -> trying to fit wrong dimension

1.11 Breakpoints

% After you save a function or script, you will notice dashes next to the line numbers
% If you click on this, it will turn into a red circle called a 'breakpoint'
% When you run your code, it will run into it reaches this line.
% You will be entered into debug mode
% You can hit 'continue' to move to next breakpoint or 'step' to move line by line
% If there is an error, it will stop won't error out if 'stop on errors' is on
% This is good if you have code that takes a long time to run before a new section
% If you hit an error, you can can fix the code and use command line
% Your active workspace is the function's workspace
% Useful commands:
dbstop if error %turns on 'stop on errors'
dbstep %debug step
dbcont %debug continue
dbclear all %removes all breakpoints

%Try debugging out on a function that you know works and break it systematically

1.12 Input output handling

% You can create defaults if no inputs are created
if ~exist('validRange','var') && isempty(validRange)
   validRange=0:1
end

%Sometimes its nice to have variables available outside a function without it being assigned an output
%This is good for me where I have a function that spontaneously crashes before data is saved
%I can send data from function workspace to 'base'/default workspace before I reach that line
%I can then cleanup the data and save it manually
%assignin -> send variable from one workspace to another
assignin('base','A_base',A_fcn)

%Remember how 'plot' has options that can be assigned by a field?
%You can do this same thing with input parsing
functionA(varargin)                      %Varargin is an input variable that allows for an ambiguous number of inputs
p = inputParser('variableA',variableA);  %Essentially just reads through all inputs and organizes them
p.addParameter('variableA','D',@ischar); %Checks to make sure that variable is is of char type, assigns default 'D' if not present
variableA          =p.Results.variableA; %Optional, but easier to use 'variableA' in this format

1.13 Statistics

%Creating a probability distribution
m=linspace(-5,10,50);
Mu=2
Sigma=1.5
p=normpdf(m,Mu,Sigma)
plot(p)

%Creating a cumulative probability distribution
P=normcdf(m,Mu,Sigma)
plot(P)

%Random values from multivariate normal distribution
Mu=[0 0]
Sigma=[1  0; ...
       0  1];
[p]=mvnrand(Mu,Sigma)
p=mvnrnd(Mu,Sigma,10000);
plot(p(:,1),p(:,2),'+')

%multivariate normal pdf
m=linspace(-5,5,50);
nM=length(m);
[M1,M2]=meshgrid(m);
p=mvnpdf([M1(:) M2(:)],Mu,Sigma);
p=reshape(p,nM,nM);

figure(938)
subplot(1,2,1)
imagesc(p)
axis square

subplot(1,2,2)
surf(p)
colormap summer

1.14 Array and cell functions

%There are a group of functions that can replace loops and will run faster
%They are often less intuitive
%If I needed to get subscripts of each pixel of a patch 7x7 patch in a 1920x1080 image and all I have is patch centers
N=randi(1080,100,1); %example subscripts
M=randi(1920,100,1); %example subscripts
fun=@(x) x-3:x+3;
Nall=cell2mat(arrayfun(fun,N,'UniformOutput',false))
Mall=cell2mat(arrayfun(fun,M,'UniformOutput',false))
%you could see how this can replace a loop
Nall=zeros(length(N),7)
for i = 1:length(N)
    Nall(i,:)=N(i)-3:N(i)+3;
    Mall(i,:)=M(i)-3:M(i)+3;
end
%By default these functions assume that your outputs are matrices. This option assigns to cells instead, allowing for inconsistent dimensions.
%The 'UniformOutput' is usually necessary if output is not same size as input

%An equivalent for cells also exists:
data{1}='This is a string';
data{2}='This is also a string';
data{3}='A third string';
fun=@(x) strsplit(x);
cellfun(fun,data,'UniformOutput',false);

1.15 Misc

1.15.1 Parallelization

parfor is a for loop, but will run each iteration on its own processor core
rules:
Only 1 parfor at a time
parfor; parfor; end; end
independent (variables must not depend on previous interation)
parfor t=1:10; x=(t-1); end
increasing, positive, & integer, iterator
no breaks

1.15.2 Rng

%Manage random number generator with rng
rand(10)
rng('shuffle')
rand(10)

%You can also set a seed
rng(10)
rand(10)
rng(10)
rand(10)

1.15.3 'System'

%You can tell matlab to run a system command line function
program='matlab'
command=['ps aux | grep ' program] %You can pass matlab variables to it;
[status,out]=system(command)
%On linux/mac, status will return
%  1 if error
%  0 if successful

1.15.4 Short Circuiting

%If using logical indexing, always use & and |
%When using if statements, && and || are prefferable
% && and || do what is called 'short-circuiting'
if exist('variableA','var') && exist(variableA)
%if statement 1 fails, it will short-circuit, meaning that it won't test statement2
if exist('variableA','var') & exist(variableA)
%if statement 1 fails, it will test statement2 in this case, and error-out

1.15.5 Advanced figure properties

%Making advanced changes to properties of figure
f=figure(1)
%whether you assign to a variable, your figure is an object with properties
%you can change these through f, or if you havn't assigned a variable, you can use gcf
fig=gcf %get current figure

%To make some advanced changes to your axes, you need to adjust the properties of your axes object
axes=gca %get current axes

%Not all properties are listed.  See "Figure Properties" in online documentation

1.15.6 Manage path from command line

path %list path
g=genpath('/home') %returns all directiories within /home
addpath(g)         %add all directiroies within home to path

1.15.7 Startup

There is a file called startup.m located in (Your matlab install directory)/toolbox/local/
This file will run everytime you start matlab

1.16 Intro to object oriented programming

+BEGINSRC octave
Object-oriented programming is a newer way of programming that has potential to make things more organized and
objects - variables created from a class
classes - a template for objects -> call on classes to make objects
properties - variables nested within a class (like fields in structs)
modules - subroutines/functions of a class, usually meant to do something to the object its being called from
Matlab has objects, but is only partially object oriented
for example:
varA="this is a string"
python:
varA='some string'; %Variables are already treated like objects…
out=varA.split() %with modules
out=["this", "is", "a, "string"]
matlab;
out=strsplit(varA)
out=["this", "is", "a, "string"]
%further modules are not attached to modules. If the module split existed in matlab you would call it like this.
split(out) %The function 'split' does exist in matlab that has the same functionality, but it isn't a module
%This makes object orientend programming in matlab more pain that it may be worth
Matlab is function oriented

General form for
lassdef exampleClassName
properties
var1=1
var2=1
end
methods
function out1 = method1(obj)
obj.var1=3 %Changing a property of an object
end
function obj = method2(val) %Contructors are methods that create objects
obj.var1=3
obj.var2=val
end
end

%To create an object from this class
object1=exampleClassName

%To call one of its methods
method1(object1)

%To create an object using the constructor
object2=method2(1)
%This allows creation of an object and assigning a value in one step
#+endsrc

1.17 Conclusion

In this tutorial we have covered about 99% of what is commonly used in matlab
There are many options that we didn't cover in the functions that we went over, so check the documentation
If you want to maintain what we've learned here, you should make your next project in matlab/octave

1.18 Extra

1.18.1 Capture input that can be assigned to different commands

keys.space=32; %Space
keys.L=28; %LEFT
keys.R=29; %RIGHT
keys.U=30; %UP
keys.D=31; %DOWN
keys.r=114; %DOWN
keys.esc=27;
keys.zero=48;
for
  draw now
  k = double(get(gcf,'CurrentCharacter')); % NOTE uncomment to see keycodes on keypress
end

1.18.2 Symbolic solver

%solve system of linear equations
syms x y z
syms x y z
eqn1 = 2*x + y + z == 2;
eqn2 = -x + y - z == 3;
eqn3 = x + 2*y + 3*z == -10;
sol = solve([eqn1, eqn2, eqn3], [x, y, z]);

1.18.3 Absolute vs relative directories

relative and absolute directories
aboslute begin with a slash in unix
absolute begin with drive then backslash
difference between windows and mac/linux/unix
/Users/dambam %mac
/home/dambam %unix
C:\ %windows
relative directories are relative to where you are, they don't start with a slash
cd('C:\') %absolute
cd('Documents1') %relative

Author: Dave White

Created: 2019-01-31 Thu 17:56

Validate