A5 Functions
A5 Functions
Our first function is one of the simplest I have ever written.
To write a function, we open Matlab, go to the Matlab Editor window, and under ‘new’ we select ‘function’. The new function template will initially look like this:
The first function we will write is useful for removing unwanted rows of data, which can be useful if, for example, we have a data matrix and want to remove the rows that correspond to a particular condition (and then make computations on the remaining conditions). Again, we start by opening a new (blank) function in the Matlab editor. Then, we update the blank function to read:
% RFL.m
%
function [MATout]=RFL(MATin,list) %#ok<*STOUT,*INUSL,*AGROW>
MATout=MATin;
MATout(list,:)=[]; %set desired indices to be empty (thus removing them)
We can test it:
k2=magic(4)
RFL(k2,[1 3])
RFL(k2,[2 4])
Now, that works as far as it goes. But what if we want to pass the function a 3D matrix input:
k3=k2; k3(:,:,2)=k2*2 %3d matrix
RFL(k3,[1 3])
This does not produce an error message, but also doesn’t produce the correct result because the output is 2D rather than 3D with some rows removed. Instead, the third dimension is added onto the output as additional columns. To fix this, we could add an additional colon in the function, updating it to:
% RFL.m
%
function [MATout]=RFL(MATin,list) %#ok<*STOUT,*INUSL,*AGROW>
MATout=MATin;
MATout(list,:,:)=[]; %set desired indices to be empty (thus removing them)
The problem with this, is that while it can handle the k3 input, it fails for a k4 input:
k4=k3; k4(:,:,:,2)=k3 %4d matrix
RFL(k4,[1 3])
To handle any number of dimensions (2D, 3D, 4D, etc.) in the input matrix, we make use of the eval.m function. This function reads a string of text as a command. Thus, the following two lines produce the same output:
mean(k2) %3d matrix
strng=['mean(k2)']; eval(strng)
This is obviously extra work for computing a mean, but we can use eval to our advantage when we do not know how many dimensions our input matrix will have:
% RFL.m
%
function [MATout Mremoved]=RFL(MATin,list,keeporient) %#ok<*STOUT,*INUSL,*AGROW>
nd=ndims(MATin); MATout=MATin;
Mstr='MATout(list,:'; %initialize Mstr
for n=1:nd-2, %loop to ensure number of colons is at least nd-1
Mstr=[Mstr ',:'], end
eval([Mstr ')=[];']); %remove submatrix given by list
Save this function and run it with:
Mout=RFL(k2,[1 3]);
Mout
Mout=RFL(k4,[1 4]);
Mout
Notice that the function is giving an output while it runs, because we have a comma instead of a semi-colon on the line of the for-loop that we are using to construct a definition of Mstr that has the appropriate number of colons. Change the comma to a semi-colon to suppress this output once you understand how the desired Mstr string is being formed within that for-loop. Finally, when we run this function we may want to give a second output that gives us a matrix formed by the subset of rows that was removed from MATin. The complete version of the function is:
% RFL.m
%
% usage: [MATout]=RFL(MATin,list);
% [MATout Mremoved]=RFL(MATin,list) %return the shortened matrix (MATout)
% as well as submatrix of deleted rows (Mremoved)
% [MATout]=RFL(MATin,list,keeporient) %optional input
%
% remove from list: removes a subset of rows from a matrix
%
% INPUTS
% MATin: matrix or vector input
% list: matrix input
% keeporient: if unset, a row vector MATin will be converted to a column vector
%
% OUTPUT
% MATout: output matrix with subset of rows removed
% Mremoved: matrix made of removed rows
%
% EXAMPLES:
% k2=magic(4) %2d input matrix
% [Mout Mremoved]=RFL(k2,[1 3])
%
% k3=k2; k3(:,:,2)=k2*2 %3d input matrix
% RFL(k3,[1,3])
%
% teh wrote it [3.14.20]
function [MATout Mremoved]=RFL(MATin,list,keeporient) %#ok<*STOUT,*INUSL,*AGROW>
if nargin<3, keeporient=0; end
if and(~keeporient,size(MATin,1)==1), MATin=str8n(MATin); end
nd=ndims(MATin); MATout=MATin;
Mstr='MATout(list,:'; %initialize Mstr
for n=1:nd-2, %loop to ensure number of colons is at least nd-1
Mstr=[Mstr ',:']; end
if nargout==2, eval(['Mremoved=' Mstr ');']); end %save submatrix to Mremoved
eval([Mstr ')=[];']); %remove submatrix given by list