PART 2. Introduction to Programming in MATLAB

advertisement
Introduction to MATLAB
Programming Techniques
Course notes for the course organized by KEDIMA UCY in October 2012
Copyright 2010-2012 Timos Papadopoulos
Contents







Introductory Notes
PART 1. MATLAB bacics
PART 2. Introduction to Programming in MATLAB
PART 3. Programming for Efficiency and Speed
PART 4. Interfacing with external data containers - Using the Appropriate
Data Type
PART 5. Data Visualisation - Advanced plotting
Wrap Up Notes
Introductory Notes










The course addresses students with different levels of experience in
MATLAB and programming.
The priority is to not leave anybody behind, the pace is suited to the least
experienced among those attending.
Not all parts of the course are for everybody attending. Easier parts for
beginners and optional parts for advanced.
MATLAB offers a very kind learning curve but certainly not a flat one; it is
not a fool's ticket to a Nobel Prize!
Its main strength is the very high level programming language environment
it offers.
We aim to cover the programming essentials quite thoroughly and only
give pointers to some more advanced topics.
My main concern is user-friendliness, not rigour; in some points we are
cutting corners.
These notes are not a textbook; they are not 100% sequential and they work
best with explanations during the lecture.
The main objective of the course is to get our hands dirty.
Feel free to interrupt at any point!
PART 1. MATLAB bacics
In this part we will briefly go over the basics of MATLAB's working environment
including the MATLAB desktop, variables, the workspace, .mat files and the basic
MATLAB data types.
Section 1.1 - Variables, Vectors and Matrices, Computations in the Command
Window
Let's start by spending a bit of time to familiarize ourselves with the MATLAB
environment and to make sure we are confident with:





The MATLAB desktop layout
The Command Window
The Workspace
The Folder Browser
The Command History
Make sure you are familiar with docking and undocking the different windows of the
MATLAB Desktop. This can be quite confusing for MATLAB beginners and
instances have been reported of hair pulling desperation in front of windows that
simply do not go where they are told to. If you find yourselves in such a situation
keep in mind that you can always go back to the factory default by Desktop ->
Desktop Layout -> Default.
The simplest thing to start with if you are first using MATLAB would be to use it as a
calculator. Try the following in the Command Window:
1 + 1
ans =
2
2 * 2
ans =
4
3^3
ans =
27
sqrt(2)
ans =
1.4142
What is the difference between the examples above and the ones below?
a = 3 + 5
a =
8
b = 2 * 4;
c = a + b
c =
16
d = sqrt(c);
d == c
ans =
0
e = d ~= a
e =
1
10^(d==b)
ans =
1
We have assigned values to the variables a, b, c and d. These now appear in the
Workspace and are available for further computations.
Can you figure out what the 'ans' workspace variable corresponds to?
Observe the difference in the Class of these variables. Observe also their dimensions.
They are scalars. In the very core of MATLAB's design is the notion of the Numeric
Array or Matrix (MATLAB was coined as short for MATrix LABoratory).
clear
a = [1 2 3]
a =
1
b = [3:5].'
b =
3
4
5
2
3
c = a*b
c =
26
d = b*a
d =
3
4
5
6
8
10
9
12
15
randn(3)
ans =
-1.4132
-1.1923
0.5190
0.8488
-0.4851
-1.6008
1.5191
-2.3766
0.9954
0.4553
-0.2978
0.7505
0.1634
0.3359
-0.5959
randn(3)
ans =
0.7829
-1.4753
-0.0175
a = magic(6)
a =
35
3
31
8
30
4
1
32
9
28
5
36
6
7
2
33
34
29
26
21
22
17
12
13
19
23
27
10
14
18
24
25
20
15
16
11
111
111
111
111
111
sum(a,1)
ans =
111
sum(a,2)
ans =
111
111
111
111
111
111
From the superclass of 'numerics' we will only be concerned with the class of
'doubles'. These are double-precision 64bit floating point representations of the real
numbers and they are the default number representation in MATLAB. Note that the
number precision displayed in the prompt is not the actual precision of MATLAB's
internal number representation.
sqrt(3)
ans =
1.7321
format long
sqrt(3)
ans =
1.732050807568877
format
sqrt(3)
ans =
1.7321
We will also go over the most important of the other classes, i.e. 'chars', 'cells',
'logicals' and 'structs'
A few moments ago we used the command 'clear' to empty the workspace from all the
variables it contained. The same happens when we exit MATLAB, all variables in the
workspace (and hence all the data they contain) are cleared. What if we want to keep
some of those variables for future use?
Right-click on a selection of variables from the Workspace and choose 'Save as...' to
save them in a .mat file (you can use any valid filename and the default is
'matlab.mat'). The same can be done from the prompt using the command 'save'.
save('my_variables','a','b','c','d')
Use the 'help' command to check its syntax and use. Execute help save in the
Command Window or look it up in the help browser (menu 'Help -> Product Help' in
version R2011b or similar in other versions).
Usually a Google search of the notion in question preceded by the word 'matlab' will
directly land upon the relevant MathWorks website documentation page. In this case
Googling 'matlab save' should return this as the first hit.
Now after exiting and reopening MATLAB one can start working on the data
contained in the saved variables. Make sure you can do this by using the 'File -> Open
... ' menu or the 'load' command (again, use the various options for getting help on
how to use these commands).
PART 2. Introduction to Programming in MATLAB
We now move on to the MATLAB's main intended mode of use, i.e. the use of Scripts
and Functions .
Section 2.1 - A slightly more interesting problem
Consider, as an example, the (still quite rudimentary) technical computation
corresponding to numerically solving the equation
in the interval
[-10 10] for
and
two given parameters.
Before solving the equation, it may be worth giving a simple depiction of how the
function
behaves for different values of the parameter . We create the plot
using the function ExpFuncPlot (we will go over functions and graphics later on in the
course).
ExpFuncPlot
Clearly, for given values of the parameters and , the equation can have 0, 1, or 2
roots. We can use the fzero function to check that. You can type help fzero in the
prompt to check how fzero is used.
For instance, in the case
the quantity
a unique solution
for every
A = 0;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,0)
ans =
0.1000
A = 0;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,-5)
becomes linear and the equation has
ans =
0.1000
A = 0;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,10)
ans =
0.1000
Whereas for positive values of
the equation can have 0, 1, or 2 roots. You can
play around choosing values of the parameters
and check for yourselves. A few
examples are:
A = 2;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,0)
ans =
0.1296
A = 2;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,1)
ans =
1.2713
A = 2;
B = 1;
fzero(@(x)x*exp(-A*x)-B,0)
Exiting fzero: aborting search for an interval containing a sign
change
because NaN or Inf function value encountered during search.
(Function value at -463.41 is -Inf.)
Check function or try again with a different starting value.
ans =
NaN
A = 2;
B = -10;
fzero(@(x)x*exp(-A*x)-B,0)
ans =
-1.1025
A = 2;
B = 0.1;
fzero(@(x)x*exp(-A*x)-B,-20)
Exiting fzero: aborting search for an interval containing a sign
change
because NaN or Inf function value encountered during search.
(Function value at -429.6 is -Inf.)
Check function or try again with a different starting value.
ans =
NaN
Section 2.2 - MATLAB Scripts
What we have just done is a typical example of a first look into a (very simplistic)
problem. We devised a rough solution and we started checking it out by playing
around with different values of the parameters involved in order to get a feeling of
whether the solution is satisfactory. With any luck some of the cases we have checked
are of interest and we would like to put them together as a first answer to the problem
at hand. For instance, we migh want to present those selected cases to a colleague or
our supervisor as a solution to the problem. How would we do that? Would we need
to keep retyping the same commands every time? That wouldn't be very practical
really...
This is where scripts come into play. A MATLAB script is a essentially a text file but
one that rather than having a .txt extension has by a .m extension. Lines in that file are
MATLAB commands as we would type them in MATLAB's command window (and
it can also have comment lines). We can create a new script file by File -> New (this
can vary slightly across different versions of MATLAB but is always self evident).
Let's try and create such a file that will contain the equation solution cases we
checked just above. (If you run into difficulties open IntroScript.m in the CourseData
material. That file does exactly that. To open a file use File -> Open (again this can
vary slightly across different versions of MATLAB).
To execute a script we just type the name of the script (i.e. the filename withouth the
.m extension) on the prompt of the Command Window and press Enter. Important
Note: The script has to reside either in the Current Folder or in the Matlab Path
otherwise it will not run.
Experiment a bit on creating, opening, editing, saving and executing scripts as
described above. Make sure you are confident in managing the cases described above.
Section 2.3 - For Loop
We saw above that the solution returned by our algorithm depends not only on the
parameter values but also on the value of ot the initial point we choose. So say
that our job is to compute the root computed for a list of
parameter pairs and
for given initial values and keep the computed values as indicated in the table below
A B x0 = 0 x0 = 1 x0 = 10 x0 = 20
0 -0.2
0 +0.1
0 +0.2
1 -0.2
1 +0.1
1 +0.2
2
2
2
5
5
5
-0.2
+0.1
+0.2
-0.2
+0.1
+0.2
How would we do that? One (rather stupid) way would be to go over each one of the
15 rows of this table separately, execute the corresponding command in the Command
Window and populate the corresponding table entry. Another (only slightly) more
convenient way would be to edit a script like the one we saw above with the required
computation lines and then execute the script. The appropriate way would be to use
the workhorse of technical computation, namely a 'for loop'. (Type help for in the
Command Window for a brief explanation).
Depending on your level of experience in programming and in MATLAB this task
can range from 'A walk in the park' to 'Climbing Mount Everest'. We will go over this
until all of us have somehow managed to make it work (or are adequately close to
that...).
For your reference, a fairly optimised solution is given the ForLoopScript.m in the
CourseData material. Reverse engineering that solution with the 'help' options of
MATLAB should do the trick if you are stuck in any point. When you get it right your
code should return this result...
clear
ForLoopScript
0
-0.2000
0
0.1000
0
0.2000
1.0000
-0.2000
1.0000
0.1000
1.0000
0.2000
2.0000
-0.2000
2.0000
0.1000
2.0000
0.2000
5.0000
-0.2000
5.0000
0.1000
5.0000
0.2000
-0.2000
0.1000
0.2000
-0.1689
0.1118
0.2592
-0.1486
0.1296
NaN
-0.1134
NaN
NaN
-0.2000
0.1000
0.2000
-0.1689
0.1118
0.2592
-0.1486
1.2713
NaN
-0.1134
NaN
NaN
-0.2000
0.1000
0.2000
-0.1689
3.5772
2.5426
-0.1486
1.2713
NaN
-0.1134
NaN
NaN
-0.2000
0.1000
0.2000
-0.1689
3.5772
2.5426
-0.1486
NaN
NaN
-0.1134
NaN
NaN
... which as you can see is the table defined above populated with the equation
solutions (not all of which are correct)
In order to run the ForLoopscript.m file you have to make sure it is either in the
current directory or in a directory of the MATLAB path (you can check that in File ->
Set Path...). This can be verified by running which ForLoopScript at the prompt.
This is also a good point to spend a bit of time to familiarize yourselves with
MATLAB's Function Precedence Order
Section 2.4 - Basic Programming - MATLAB Functions
To conclude this part of the course we go over the fundamental notion of the
'function'.
Simply speaking, a MATLAB function is quite similar to a MATLAB script with the
very important difference that it accepts input and output arguments and it has its own
Workspace.
To create a function we go about in pretty much the same way as above with scripts
but we include a first line that starts with the reserved word function followed by the
list of output arguments, the function name and the list of input arguments. For
instance, to convert the ForLoopScript.m to a function we include the first line
function eq_sol_results = ForLoopFunction(As,Bs,x0) in the .m file and save
it (preferably) as ForLoopFunction.m. Spend a bit of time to:
1. Work out any other changes needed to create the function corresponding to the
previous script
2. Run the function in the prompt and make sure you become familiar with the
fact that is has its own workspace
3. Check the basic functionality of MATLAB's debugger
4. Check the provided ForLoopFunction.m file in the CourseNotes folders
5. See what the help preamble amounts to
6. See what the validateattributes functionality amounts to
PART 3. Programming for Efficiency and Speed
The programming language offered by the MATLAB environment is what we call an
'Interpreted Language' unlike the more typical 'Compiled Languages' such as C/C++,
JAVA etc. In conjunction with other features and characteristics of MATLAB, this
has as a consequence that MATLAB code is much easier to start writing and faster to
develop in a prototyping application stage, but slower in running/executing, especially
when it comes to computations involving for-loops. As this speed disadvantage can
prove very problematic in computationally demanding cases, we list below possible
ways to mitigate it and we present the details for the easier ones (those that you
should be following pretty much always).
Section 3.1 - Vectorization
In the MATLAB world (practically) everything revolves around the notion of
matrices. All elementary operations (in fact nearly every operation, elementary or not)
can be written in what is called a 'vectorized form', i.e. as a sequence of linear
algebraic operations involving whole matrices and vectors rather than loops over their
individual elements. Such vectorized form computations can be very much faster than
the corresponding ones using loops.
See for example the four ways to do the same thing (assign a sinusoid sequence to a
vector in the variable name x) that are listed in the script CheckSpeed1.m
CheckSpeed1
Non-vectorized (for loop) assignment:
Vectorized assignment:
0.49348[s]
0.039664[s]
Non-vectorized (for loop) preallocated assignment: 0.16933[s]
(Repeated) non-vectorized (for loop) assignment:
0.48736[s]
Evidently the vectorized assignment (second case) is about 25 time faster than the
non-vectorized equivalent. Notice how the preallocation of an appropriately sized
vector to the variable x also has a dramatic effect in the efficiency of the assingment
(comparison of third and fourth cases). We will return to the technique of
preallocation in a bit.
The efficiency associated with vectorization becomes even more striking when an
actual computation is used an an example, i.e. the inner product of two vectors
Examine the three ways to implement that inner product computation listed in the
script CheckSpeed2.m
CheckSpeed2
Non-vectorized (2 for loops) inner product:
Non-vectorized (for loop) inner product:
Vectorized inner product:
0.47596[s]
0.021636[s]
0.0026821[s]
Notice how the computation of unnecessary quantities (first case) can make the
computation tens of times slower than a non-vectorized implementation (second case)
and hundreds of time slower than the proper vectorized computation (these ratios can
change in implementations in different computers).
You have probably noticed the orange underlinings in the CheckSpeed1.m and
CheckSpeed2.m files and you wonder what they are. This is a feature of MATLAB's
Code Analyzer. Hover over the underlined variables to read the issue identified by the
analyzer. In the next example we discuss the technique of 'preallocation' and that
should help you understand what's going on and how you can address this issue.
Section 3.2 - Preallocation
When using MATLAB extensively vectorization becomes second nature and it turns
out it is possible to vectorize most computations (even more so with the use of tools
such as arrayfun, cellfun, structfun etc. which are not covered in this course) .
Nevertheless, there are cases where the use of one or more loops is dictated either by
necessity or convenience. In newer versions of MATLAB this turns out to not be
completely detrimental as long as the arrays are properly preallocated, i.e. they are not
allowed to change dimensionality inside the loop. Such an example was very briefly
given in the CheckSpeed1.m example and it is further elaborated in CheckSpeed3.m
which computes the external product of two vectors.
CheckSpeed3
Non-vectorized (for loop) non-preallocated outer product: 1.7519[s]
Non-vectorized (for loop) preallocated outer product:
0.032799[s]
Vectorized outer product:
0.010563[s]
Evidently, when preallocation is used the many tens of times speed ratio between the
vectorized computation and the for loop (third v. first cases) reduces to a just a few
times speed ratio (again these ratios can change in implementations in different
computers).
Section 3.3 - Use of the Profiler to identify Bottlenecks
MATLAB offers a powerful tool to check the execution time used by the code we
write in the form of the Command Window function profile and it Graphical User
Interface counterpart Profiler. To give an example of this tool we go to Desktop ->
Profiler, we type CheckSpeed3 in the Run this code: box and we hit Start
Profiling. We should then get something like this. Spend a bit of time in exploring
that report you just generated and making sense of the information it provides.
Section 3.4 - Simple parallelization using parfor
Another option offered by recent versions of MATLAB (so long as the installation
includes the Parallel Computing Toolbox) is that of parallizing the code over multiple
CPU cores on a single computer. This is done by converting the for in for-loops to
parfor and it can achieve a maximum execution speed up ratio equal to the number
of cores present in the CPU. Note that parfor loops come with certain restrictions and
that not every for loop can be directly converted to a parfor loop (far from it actually).
An example of a parfor implementation compared to a standard for that does the same
thing sequentially is given in the ParForExample.m file. Note that these timing are
specific to the 4core CPU where the notes where created and will vary considerably in
other computers.
[time_seq, time_par] = ParForExample
Starting matlabpool using the 'local' configuration ... connected to
2 labs.
Sending a stop signal to all the labs ... stopped.
time_seq =
3.0867
time_par =
2.2337
Moving slightly off topic, we note that the last example silently introduced two new
concepts namely those of:


Multidimensional Arrays.
Varying number of outputs, a point that leads to the varargin and varargout
constructs which in turn make use of the cell data type (discussed in more
detail in the next section).
We conclude this part of the course by just mentioning the MATLAB offers many
more (more complicated) options for parallelizing the execution of code including
accessing dedicated MATLAB clusters, deploying in UNIX clusters and targeting
GPUs. Further to that, probably the most efficient way to speed up a piece of mature
code after the prototyping stage has concluded in MATLAB is to rewrite it as a C (or
Fortran) source file and interface to it using MATLAB's mex functionality
PART 4. Interfacing with external data containers Using the Appropriate Data Type
It is often the case that in order to do a computation one has to first obtain data that
may exist in a different format. A typical example would be the case where the data
are in an Excel datasheet. Furthermore, in such a case the data we encounter are very
often heterogenous, e.g. there are numerical data together with text. In order to
successfully work with such type of data we will need to extend our command on
Data Types offered by MATLAB's to more than the numeric arrays seen so far.
In this part of the course we go over such a typical (albeit grossly oversimplified)
work scenario whereby we import data from an .xlsx file, do a bit of processing and
then create a plot reporting on some property of the data that we have identified. In
particular, in this part of the course we will go over:




Cell arrays
Interfacing with Excel Spreadsheets
Structure arrays
Multidimensional arrays
Section 4.1 - Cell Arrays
MATLAB allows the use of string variables:
my_name = 'Timos';
my_surname = 'Papadopoulos';
What type of variables are my_name and my_surname?
What are their dimensions?
Can you manipulate the letters in the strings?
What if we want to keep both variables in single matrix?
Why do you get an error if you type my_full_name = [my_name;my_surname]; ?
You could overcome that by:
my_full_name = strvcat(my_name,my_surname);
Again what type of variable is my_full_name?
What are its dimensions?
Can you manipulate the letters in it?
What is the main disadvantage of using this method to keep string in an array?
Another way would be to use a cell array, as will be shown in the following. Cell
arrays are similar to standard matrices in the sense that they have dimensions in the
same way as arrays, but they are more versatile containers as they can contain
anything as elements: numbers, matrices strings, others cells, cells of other cells,
structures, etc.
How to create an empty 2x2 cell:
simple_cell = cell(2,2);
Now let's assign values to the each of the four elements. Remember, these can be
anything. Notice that we are using curly brackets {}. This is how we index into cell
contents and we will get to that in a few minutes.
simple_cell{1,1}
simple_cell{1,2}
simple_cell{2,1}
simple_cell{2,2}
=
=
=
=
5;
'Matlab';
[1 2 4];
{7;8;9};
Check whether the contents of the cell array that we have created are as expected.
simple_cell
simple_cell =
[
5]
[1x3 double]
'Matlab'
{3x1 cell}
Because a cell array can contain different types of data stored in various array sizes,
cell array indexing is a little more complex than indexing into a numeric or character
array.
There are two methods of accessing data in a cell: cell indexing and content indexing.
The first returns a cell with the contents of the indexed range as elements. It is chosen
with the parentheses operator (). The second returns the contents themselves (rather
than the contents in a cell). It is chosen with the curly brackets operator {}.
In the previous example of the simple_cell cell array:
What do you get with the following expression?
simple_cell(1,1)
ans =
[5]
What do you get with the folloing expression?
simple_cell{1,1}
ans =
5
Can you explain the difference?
Furthermore, how can we obtain:


The letter 't' from the {1,2} element of the cell_array?
The numerical matrix contained in the {2,1} element of the cell_array?
Finally, how can we concatenate



The contents of the {1,1} and {1,2} elements in a 2x1 cell array?
The contents of the {1,1} and {2,1} elements in a 1x4 numerical array?
The contents of the {2,1} and {2,2} elements in a 2x3 numerical array?
Returning to the name/surname examples above, we can now see that the cell
containing the name and surname strings will be created by:
my_full_name = {my_name;my_surname}
my_full_name =
'Timos'
'Papadopoulos'
Section 4.2 - Interfacing with Excel Spreadsheets
To give a practical example of the use of cells, we can import the list of attendants of
last year's course from the course_list.xlsx MS Excel file.
We can do that using the xlsread command. Try:
[num1] = xlsread('course_list.xlsx','A5:I58');
[num2 txt2] = xlsread('course_list.xlsx','A5:I58');
[num3 txt3 course_cell_raw] = xlsread('course_list.xlsx','A5:I58');
All three of the above lines use xlsread. What is the difference between them?
You can verify that the first output argument of xlsread returns only the numeric
values in a numeric array, the (optional) second argument returnds only the string
values in a cell array and the (optional) third argument returns all values in a cell
array.
We will work with the course_cell_raw output, so you can clear the others from the
workspace.
clear num* txt*
Notice that xlsread also returns the contents of hidden excel cells and replaces them
with NaN elements in the cell array output. Other formatted cells are also interpreted
as NaN elements. Verify that this is indeed the case by comparing the cell array
elements with the corresponding cells in the excel file.
We would like to discard the rows of the cell array that have a NaN entry or a string
element in their first column. But we would like to keep the first row of header strings
as the first row of our cell.
course_cell(1,:) = course_cell_raw(1,:);
k = 2;
for n = 2:size(course_cell_raw,1)
if isnumeric (course_cell_raw{n,1})
if ~isnan(course_cell_raw{n,1})
course_cell(k,:) = course_cell_raw(n,:);
k = k+1;
end
end
end
Alternatively you can use the short-circuit properties of the logical operator && to
write
course_cell2(1,:) = course_cell_raw(1,:);
k = 2;
for n = 2:size(course_cell_raw,1)
if isnumeric (course_cell_raw{n,1}) &&
~isnan(course_cell_raw{n,1})
course_cell2(k,:) = course_cell_raw(n,:);
k = k+1;
end
end
Now that we have successfully imported the data in an appropriate data container we
can exemplify the plot of results.
For instance, we can identify the groups of different entries in the 7th column of the
cell array (corresponding to different Study Levels) and draw a pie-chart.
[unique_strings, scrap1, scrap2] = unique(course_cell(2:end,7));
for n = 1:length(unique_strings)
pie_data(n) =
sum(strcmp(unique_strings{n},course_cell(2:end,7)));
end
% h = figure;
pie(pie_data,unique_strings);
Similarly for the 4th column of the cell array (corresponding to different
departments).
clear pie_data
[unique_strings, scrap1, scrap2] = unique(course_cell(2:end,4));
for n = 1:length(unique_strings)
pie_data(n) =
sum(strcmp(unique_strings{n},course_cell(2:end,4)));
end
% h2 = figure;
pie(pie_data,unique_strings);
And a difficult one!!! (Vectorisation using cellfun). Try to create a bar plot of the
YearOfStudy of those attendants for which such information is available and applies
(i.e. not NaN and not string)
temp_cell = course_cell(:,5);
check_numerics = cellfun(@isnumeric,temp_cell);
temp_index = find(check_numerics);
temp_cell = temp_cell(temp_index);
check_finites = cellfun(@isfinite,temp_cell);
temp_index = find(check_finites);
temp_cell = temp_cell(temp_index);
bar([temp_cell{1:end}])
Section 4.3 - Stucture Arrays
The course_cell example is a good point to introduce the structure array data type
(and to practice in indexing and data arrangement in structure arrays)
What is the main shortcoming in having the course list data in a cell array?
ANSWER: We have limited ability of labelling and structuring the data (put simply,
we would have to check the header cells everytime to verify which column of the cell
holds which type of data).
We can address this with the structure array data construct.
Structures are MATLAB data constructs with named "data containers" called fields.
The fields of a structure can contain any kind of data (much the same as was the case
with cells).
As with cells, structure arrays also have a specific syntax for indexing and organising
data. The syntax for accessing an element is of the form struct(n,m,...).fieldname
where the subscripts n, m, etc. determine the element of the array and fieldname the
field. In the specific example considered here, the array is of dimensionality 45x1 so
only one index is needed.
In our case, the natural choice would be to have a structure with 9 fields having the
(self-explanatory) fieldnames:



ID
Name
Surname






Department
YearOfStudy
Email
StudiesLevel
Phone
Answer
The structure should have a dimensionality of 45x1 to include all 45 persons in the
list.
We can do that in a number of ways:
1st Method - Using loops
for n = 2:size(course_cell,1)
CourseStruct(n-1).ID = course_cell{n,1};
CourseStruct(n-1).Name = course_cell{n,2};
CourseStruct(n-1).Surname = course_cell{n,3};
CourseStruct(n-1).Department = course_cell{n,4};
CourseStruct(n-1).YearOfStudy = course_cell{n,5};
CourseStruct(n-1).Email = course_cell{n,6};
CourseStruct(n-1).StudiesLevel = course_cell{n,7};
CourseStruct(n-1).Phone = course_cell{n,8};
CourseStruct(n-1).Answer = course_cell{n,9};
end
2nd Method - Using cell2struct
CourseStruct2 =
cell2struct(course_cell(2:end,:),course_cell(1,:),2)';
Again, picking subjects of the dataset and concatenating to appropriate simpler
containers is possible.
clear pie_data
temp_cell = {CourseStruct(1:end).Department};
[unique_strings, scrap1, scrap2] = unique(temp_cell);
for n = 1:length(unique_strings)
pie_data(n) = sum(strcmp(unique_strings{n},course_cell(:,4)));
end
pie(pie_data,unique_strings);
Section 4.4 - Multidimensional Arrays
All the concepts described above for numerical arrays, cell arrays and structure arrays
can be expanded to arrays of dimension higher than 2D. In such cases we use a
number of indices equal to the dimensionality: That is, we would have
num_array_3D(n,m,k), array_4D(n,m,k,l), etc. Similarly we would have
cell_array(n,m,k) or cell_array{n,m,k} and struct_array(n,m,k).fieldnames.
For example we could have a 2x2 array
fashion.
A(1,1,:)
A(1,2,:)
A(2,1,:)
A(2,2,:)
=
=
=
=
sin(linspace(0,10*pi,1000));
cos(linspace(0,10*pi,1000));
2*sin(linspace(0,8*pi,1000));
0.1*sin(linspace(0,4*pi,1000));
and a second 2x2 array
B(1,1,:)
B(1,2,:)
B(2,1,:)
B(2,2,:)
=
=
=
=
which varies with time in a harmonic
which varies with time as a decaying exponential.
exp(-.05*[0:999]);
zeros(1,1000);
ones(1,1000);
2*exp(-.5*[0:999]);
Many operations that work for 2D arrays work in the same manner for higherdimensional arrays. Such a case is the element-by-element dot-product C(t) =
A(t).*B(t)
C1 = A.*B;
However, if we need to compute the algebraic matrix product
cannot write C2 = A*B; (try it for yourselves).
we
Instead, we would have to either compute C2 in a slow for-loop
for n = 1:size(A,3)
C2(:,:,n) = squeeze(A(:,:,n))*squeeze(B(:,:,n));
end
or we could try and vectorize for speed improvement
C2(1,1,:) = squeeze(A(1,1,:)).*squeeze(B(1,1,:))+...
squeeze(A(1,2,:)).*squeeze(B(2,1,:));
C2(1,2,:) = squeeze(A(1,1,:)).*squeeze(B(1,2,:))+...
squeeze(A(1,2,:)).*squeeze(B(2,2,:));
C2(2,1,:) = squeeze(A(2,1,:)).*squeeze(B(1,1,:))+...
squeeze(A(2,2,:)).*squeeze(B(2,1,:));
C2(2,2,:) = squeeze(A(2,1,:)).*squeeze(B(1,2,:))+...
squeeze(A(2,2,:)).*squeeze(B(2,2,:));
(notice the need of reducing the dimensionality with squeeze)
Having concluded the presentation of this material we can now go back to what was
mentioned at the end of PART 3 about a variable number of input and output
arguments in a function. Check the VarIOExample.m function file and see if you can
make out what it does and how it does it.
PART 5. Data Visualisation - Advanced plotting
In this part of the course we start from the most basic form of a plotting a 2D graph
and build on the concept of Graphic Object Handles to show (or rather just hint to)
Data Visualisation capabilities of MATLAB.
In the restricted time we have we try to introduce and explain as simply as possible:




The hierarchy of graphics object
The concept of "handles" to graphics objects
The get and set methods
The uicontrol interaction capabilities
Section 5.1 - Graphic objects handles
We have already come across 2D plots of a function using plot. In those cases we
have overlaid more plots on the same figure, we added labels, legends, etc. Let's
briefly go over these functionalities:
x = [-2:0.1:2];
plot(x,x.^2)
hold on;
plot(x,x.^3,'r')
xlabel('x')
ylabel('f(x)')
legend({'f1(x) = x^2','f2(x) = x^3'})
grid on
What if want to create another plot on a separate figure?
figure;
x = linspace(-pi,pi,1000);
plot(x,sin(x))
Now, if we want to change the color of the lines, or the position of the legend, or take
the grid off etc, in the first figure? Since using commands like the ones above will
affect the newly created figure, the only way to make changes on the first figure
would be to that graphically. This can indeed be easy and convenient (make sure you
have played a bit with the available options).
But does this option cover all possible scenarios or does it come with limitations?
What if I create a figure like that, edit it graphically to my liking by following a
sequence of actions and then I want apply the same 'cosmetics' to another figure. I
would have to repeat the same sequence again. Quite often there are cases where we
need to process tens of figures in which case such an approac could be severely
problematic, or even cases where a figure was created some time ago and now it has
to be recreated, modified etc.
A way to address these problems is to modify the figures programmatically in code.
In such cases the code can be reexecuted, modified, copied etc. very conveniently in a
scalable way. To achieve that we need a way to refer to specif figures and graphical
obejcts in figures. This is achieved by using handles.
Let's close the figures created previously (xan you spot the danger in this command?)
close all
... and recreate the figures assigning handles
x = (-2:0.1:2);
hfig1 = figure;
haxes1 = axes;
hline1 = plot(x,x.^2);
hold on;
hline2 = plot(x,x.^3,'r');
xlabel('x')
ylabel('f(x)')
hleg1 = legend({'f_1(x) = x^2','f_2(x) = x^3'});
grid on
hfig2 = figure;
haxes2 = axes;
x = linspace(-pi,pi,1000);
hline3 = plot(x,sin(x));
get
and set are commands that allow us to, respectively, inspect and change the
Properties of a certain objects.
The syntax is of the type
set(obj_handle,'prop_name1',prop_value1,,'prop_name2',prop_value2,...
)
and get(obj_handle,'prop_name') or get(obj_handle) for all properties of the
specified object.
Now to change the line color of the x.^2 plot in the first figure we need:
set(hline1,'color','y')
Observe that the legend changed accordingly
Or we can do the same by:
set(hline1,'color',[0 0 0])
To move the location of the legend we can do:
set(hleg1,'location','North')
To remove the grid from figure1 we can do:
set(haxes1,'xgrid','on','ygrid','off')
And to add x-axis grid and y-axis minor grid to figure2
set(haxes2,'xgrid','on','yminorgrid','on')
Referring to the issue spotted above with clear all, we can now close each figure
we choose separately
close(hfig1)
... thus keeping the most recent 2nd figure before we close it at some later stage
close(hfig2)
If you have finished ahead the rest of the class and feel adventurous, lookup the help
files and experiment with gca (get current axes) and gcf (get current figure). Check
the Graphics Windows — the Figure section in MATLAB's documentation and see if
you can familiarize yourself with the result you get from quering the 'children'
property of the graphics objects you have created so far.
Section 5.2 - Adding interaction to the figure
In this section we add to the same figure as above a push button that changes the color
of the lines in the figure.
First we create the figure:
x = [-2:0.1:2];
hfig1 = figure;
haxes1 = axes;
hline1 = plot(x,x.^2);
hold on;
hline2 = plot(x,x.^3,'r');
xlabel('x')
ylabel('f(x)')
hleg1 = legend({'f_1(x) = x^2','f_2(x) = x^3'});
Then we add the push button using the uicontrol command. The syntax of this
command is similar to the set/get philosophy described above. That is, it takes as
arguments pairs of properties and values.
Observe that the interaction is effected by use of the 'callback' property which assigns
the action taken when the button is pressed to the function change_color_button
defined in the change_color_button.m file.
As always, we want to keep a handle to the button in the hbutton output.
hbutton = uicontrol('Style','pushbutton','Units','Normalized',...
'Position',[0.6 0.2 0.2 0.1],'string','change color',...
'callback','change_color_button');
Check for yourselves what this does before closing it
close(hfig1)
What we did in this section is the basic building block of a Graphical User Interface
(GUI). By building upon that one can quite easily and efficiently create such
MATLAB GUIs for all kinds of experimental
... or demonstration purposes.
Wrap Up Notes









MATLAB is a working environment that presents a very gentle learning
curve compared to other programming tools
Its real power as a working environment lies in its very high level
programming language
To use it effectively it is very important to understand how functions work
(workspace, path, scope precedence, debugger)
It is very well documented, both in the help material maintained by
MathWorks and in resources from the research community
Vectorized code is a plus and preallocation in loops a must to avoid very
slow execution (and other options exist sto speed it up)
MATLAB comes with all kinds of possibilities for interfacing with other
tools and programming platforms
It offers easy and hustle-free access to data types capable to describe pretty
much everything you would need (with a premium on resources
requirements)
One of its most strong point is the Interactive Data Visualisation options it
offers which keeps expanding in every new release
At least until the latest release (R2012b) it does not offer the option of
completing your PhD Thesis on its own! (but it can help quite a bit...)
Published with MATLAB® 7.13
Download