For more details, and talks in past semesters, consult the full schedule of talks.
Past topics can (and should) be repeated occasionally. In addition, here are some topics people might like to hear about:
To give a talk, please contact swig@math.arizona.edu.
MATLAB is a high level language and computing environment for scientific and mathematical problems. It was initially developed by Cleve Moler in the late 1970s to provide access to the Fortran linear algebra software packages EISPACK and LINPACK. The name, from Matrix Laboratory, reflects this origin in linear algebra. Since then MATLAB has developed into a great tool for trying out new ideas and fidgeting with algorithms. It has excellent graphics capabilities and an easily understood syntax. It also has some wonderful features that are less commonly used such built in ODE-solvers, dialog boxes, and commands for constructing graphical user interfaces. It is also possible to generate new commands written in C or Fortran that MATLAB can interpret. To understand these features it is however first necessary to have some familiarity with MATLAB's basic commands. If you are not familiar with these or if you are like me and constantly forget the syntax, then a good place to look is the SWIG page Matlab Introduction or the website by the company which owns MATLAB The MathWorks, Inc.. In the following, I assume that you have already had some exposure.
The files that I use for illustrating some of these not-so-well-known tools are provided in the link SWIG Talk Files. As usual, I make no claims that these codes are perfectly correct. In fact, I doubt it since most are cutout of larger codes. I should also point out that they were written using MATLAB version 6 installed with Linux. I have found that, in general, almost all of MATLAB's commands work perfectly in both Linux and Windows. However, there are always a few quirks when running MATLAB on different operating systems. There are also probably better ways to do much of this than as I have written it. I hope that they will provide simply a starting point for your own scripts.
The phrase that comes to my mind when I work with MATLAB is proof of concept. If I want to demonstrate to my adviser or myself that a concept is fundamentally correct, then I can code it and debug it quickly in MATLAB.
It is often the case however that the algorithms I am using have tunable parameters which need to be adjusted by the user. Since another person is usually not familiar with the variables in the script, I normally prefer that they do not open the file containing the algorithm. Input boxes and messages can be one way of avoiding this problem. They also be very useful in the classroom or a talk. Everyone likes something nice and flashy between the equations.
One way to avoid others editing your code is to provide
graphical input and output by means of dialog boxes and
requesters. MATLAB makes a slight distinction here between
dialog boxes which provide information and requesters which
accept information. For our purposes, we simply refer to both
as dialog boxes. One could develop on a very basic level
their own graphical user interface (GUI). This is the next
topic. However, I have found that MATLAB's own
built-in/ready-to-go dialog boxes are almost always
sufficient for my needs. These commands have names that
typically end in dlg, such as errordlg,
inputdlg, and questdlg. There are also simples
things like message boxes msgbox. MATLAB's helpdesk
can provide you with the details of the input to these
functions. Typically, one provides a title for the box, a
message to the user, default parameter values, and variables
names.
In the SWIG Talk Files ExpAdvectInputFunc.m and
ExpAdvectModule.m I demonstrate the use of three of
these commands, inputdlg, msgbox and
questdlg. The program is a simple advection equation
solver. It uses explicit Euler and the full matrix
exponential to propagate the system of ordinary differential
equations one obtains from a center-difference approximation
to the spatial derivative. The error reported in the code is
the absolute error of the propagator; that is, this is the
difference between the matrix exponential solution and the
explicit Euler solution.
Go ahead now and run the script. Open MATLAB and at the
prompt type ExpAdvectModule. At this point, a nice
little message should pop up. This will wait for you to close
it or push OK. The icon in the figure is easy to make. The
commands are simply
Idata = (-pi/4):0.1:(pi/4);
Idata = (cos(Idata)-cot(Idata));
uiwait(msgbox('Welcome to the Advection
Program','Hello','custom',Idata,pink(size(Idata,2))));
The inputs are self-explanatory and you can modify the icon
data to come up with more interesting figures. Important here
is the command uiwait. One of the major issues with
dialog boxes and GUIs in general is controlling the flow of
the code. uiwait tells the program to wait for the
user to either close the figure or push 'OK'. Without this,
the code will continue to the next line and the user might
not see your groovy icon.
Now push 'OK'. Next should come up the inputdlg box
that asks for the simulation parameters. This box is not as
simple as the previous and thus I wrote a second function
ExpAdvectInputFunc.m specifically for it. The function
itself is called with the single line
[NTSteps,DeltasRatio,XLength,DeltaX,ICFunction] =
ExpAdvectInputFunc;The five variables I have allowed to be global variables so that they are visible to both functions. In general, one is discouraged from using global variables in MATLAB but this is one case where I have found them particularly useful. Keeping them global and writing the separate input function also helps me to determine what the simulation parameters are.
In the input function, the input dialog box is created with the line
inputdata =
inputdlg(prompt,dlgTitle,lineNo,defaultvalues,AddOpts);
The inputs are again fairly simple to understand. The file also contains comments to describe them. More important is the format of the output from the dialog box. It is simply a list of strings, not numbers. Thus, one must first assign variable names to the strings. This is done with the command
inputdata = cell2struct(inputdata,fields);.
After this, one needs to convert the strings to numerical values using a command like
XLength = str2num(inputdata.XLength).
After you have selected your parameters and initial condition and hit 'OK', the code will then ask you if you wish to plot your results. Plotting is usually a very expensive process and thus there are many times when I do not want to plot the simulations as they evolve. This box is easily constructed with the command
Reply =
questdlg('Plotting','Plot?','Yes','No','Yes');
The string output from the dialog box is then used to define a switch variable.
if(strcmp(Reply,'Yes')==1)
PlotSwitch = 1; %On
else
PlotSwitch = 0; %Off
end
If you choose to plot, the code will generate two figures.
The first uses subplot to show together the solutions
from explicit Euler and the matrix exponential. The second is
of the absolute error. One should see the Gaussian initial
condition scroll around the domain.
The dialog boxes that MATLAB provides ready-to-go are great. As I said, I usually can do just about anything I want with only these commands. There are however more sophisticated graphical objects available. Constructing a GUI from scratch is not easy, thus MATLAB has a built-in GUI editor for creating GUIs called GUIDE. More about GUIDE can be found on the main MATLAB website. I have found this program useful for constructing very simple GUIs but it can also be overkill. In the following I will show you I have used both MATLAB's dialog boxes and basic GUI commands together. First however, here are a few really good examples of MATLAB GUIs:
The MATLAB files for this example begin their names with
Swiggui. Go ahead in MATLAB and type at the prompt:
clear all. This will remove the variable from the
previous example. Now type: Swiggui_Main. Up should
pop a new figure with five buttons. You may need to resize
the figure to see all the buttons. This example is taken from
a larger interface where there are further images to the
right of the buttons which arise when the buttons are
clicked. To make the code readable, I have reduced it to
simply take input from the user for a simulation and write it
to a data file.
At this point, open the file Swiggui_Main.m. You will
see that I have again used global variables. The different
buttons in the GUI allow the user to access different
collections of these variables and each button has its own
function telling it what to do. Reading down the file, one
finds that I have also added the function
Swiggui_Default_Values. I find that it helps to keep
things organized to put the default values for the parameters
in their own file.
Continuing to read down the function, we come across our first new object.
Hc_frame_1 = uicontrol(gcf, ...
'Style', 'frame',...
'Units', 'pixels',...
'Position', [25 250 200 230]);
The statement
uicontrol is a generic command for graphical user
input. The first line tells MATLAB to get the current figure,
that is the GUI. The second tells MATLAB that this particular
uicontrol object is a frame; it is simply a background
box. For the units, I have chosen pixels and the position I
have set manually. Setting the positions by-hand without
GUIDE can be a pain but also very liberating. The three dots
after each line are not necessary. In general, these three
dots tell MATLAB to continue the command on the next line.
Without them MATLAB will think that the command is
incomplete.
A more interesting animal is the next object in the code, a text box.
Hc_text_Title = uicontrol(gcf,...
'Style', 'text',...
'Units', 'pixels',...
'Position', [25 500 200 12],...
'String', ['Graphical User Interface'],...
'FontSize', [10.0]);
The inputs are again very similar as to the frame. Note however that the "Style" option is now "text". This simple box I have used merely to give the name of our GUI.
Finally, we get to the push buttons.
Hc_button_Write_Parameter_File = uicontrol(gcf,...
'Style', 'pushbutton',...
'Units', 'pixels',...
'Position', [25 450 200 15],...
'String', 'Write',...
'Callback', 'Swiggui_Button_Write');
Most important
here is the "Callback" option. It is this option which tells
MATLAB what to do when the button is pushed. In particular, the
Callback option sends the string given to MATLAB's eval
command. In this case, I have told it to execute the function
to write the data to a file.
That is pretty much it for the basic GUI commands for this example. There are many more styles to choose from such as
Again, one of the major difficulties with GUIs is
controlling the flow of the script. Thus, I try to use MATLAB's
built in functions as much as possible. Go ahead now and push
the "physical parameters" button. Up should come a standard
input dialog box, coded as we did in the previous section. A
more interesting object is the list dialog box listdlg
that one gets when they hit the "computation parameters
button". If you play around with the GUI, you will find that by
separating the GUI functions thematically one is able easily
to incorporate dialog boxes of different types. Finally, if you
hit "write" you will see that the GUI terminates and writes the
file RunParameters.dat containing the input parameters.
The last topic to discuss are MEX files or MATLAB Executable files. To quote MathWorks, MEX-files are dynamically linked subroutines produced from C or Fortran source code that, when compiled, can be run from within MATLAB in the same way as MATLAB M-files or built-in functions. When considering that MATLAB originated as a way to easily access Fortran libraries, it is perhaps not too surprising that MATLAB can utilize code written in lower level languages. The details of how to this however are not trivial and I can only give some insight here from my own attempts. Also, since I am more familiar with C, my examples are written in this programming language. The relevant files are: xdotyMex.c, RealTridiagSolverMex.c, LagClenshawAlgorithm.m, LagClenshawMEX.c, and LagClenshawTest.m. Again, a good reference to start from is the SWIG page SWIG MEX. Another is the MathWorks site MathWorks MEX Website .
Just looking at the LAPACK command for inverting a tridiagonal matrix
zgtsv_(&NXNodes,&NRHS,DLArray,DArray,DUArray,Gvector,&LDB,&INFO);
it is clear why MATLAB has become so successful. While this
commands is not horrid to implement, it is also certainly not
as efficient as simply typing in MATLAB A\b. There is
however an advantage of directly coding in C or Fortran and
that is speed. MATLAB often runs much more slowly than a
comparable program in C or Fortran, especially when computing
for loops. This is not really surprising however since
MATLAB was designed originally for linear algebra packages
and not for the large scale simulation of differential
equations. The point then is that there are situations where
one has either a need for faster computations or code in C or
Fortran and would simply like to implement it within MATLAB.
Every C MEX file has the follow 5 things:
mxArray
#include mex.h
mexFunction gateway
mxArray One of the really nice features of MATLAB is
that one does not need to predefine variable types. Thus,
when translating information between MATLAB and a C code, one
needs an intermediate variable. The mxArray is the
central structure that one uses for all data types, including
matrices, vectors, and scalars. It contains all the necessary
information such as the variable formats (characters or
complex double precision number), the variable dimensions,
and of course the data.
mex.h and API functions The header file
mex.h has the prototypes for the functions that C
uses. There are two basic types of functions mx* and
mex* which together constitute the API (Application
Program Interface) functions. mx* functions are used
to manipulate data within an mxArray. These are primarily
memory management tools and should be used in place of the
common commands in C. The mex* functions do everything
else that you might need.
mexFunction The object which allows one to go between
MATLAB and C is the gateway function
void mexFunction( int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[] )All C MEX files must have this command just as every standard C code must have a "main" function. The inputs are important to understand, the following table is taken from the MathWorks MEX website:
| MexFunction | Name of the gateway routine (same for every MEX-file) |
| nlhs | Number of expected mxArrays (Left Hand Side) |
| plhs | Array of pointers to expected outputs |
| nrhs | Number of inputs (Right Hand Side) |
| prhs |
Array of pointers to input data. The input data is
read-only and should not be altered by your mexFunction .
|
C Function to Compute In addition, one must of course
have a function in the C code which performs the desired
operation. The name of this function is also the name of the
command for MATLAB. Thus for example, if the C function is
called kanowins and has input onecow, then in
MATLAB one would type at the prompt kanowins(onecow)
With these basic concepts, we can write simple programs. At
this points, lets open the file xdotyMex.c. This
function computes the dot product of two vectors. The
corresponding commands from MATLAB are sum(u.*v). At
the top of the file containing the C code, I have placed the
example:
>> mex -g xdotyMex.c
>> VecOne = [1 2 3 4]
VecOne =
1 2 3 4
>> VecTwo = [4 5 6 7]
VecTwo =
4 5 6 7
>> xdotyMex(VecOne,VecTwo)
ans =
60
The first to note is that the MEX file must be compiled like
any other C code. This done within MATLAB using the command
mex. In Linux, the output is a file with the extension
mexglx. MATLAB's helpdesk can assist you if it is
necessary. Go ahead and try now this example for your self.
The code for the dot product example is very easy to understand.
#include "mex.h"
void xdotyMex(double *x,double *y,double *z,int ColLen)
{
int j;
z[0] = 0;
for(j=0;j<j++){z[0] = z[0] + x[j]*y[j];}
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
double *x,*y, *z;
int ColLen;
if(nrhs!=2) {
mexErrMsgTxt("Two inputs required.");
} else if(nlhs>1) {
mexErrMsgTxt("Too many output arguments");
}
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
x = mxGetPr(prhs[0]);
y = mxGetPr(prhs[1]);
z = mxGetPr(plhs[0]);
ColLen = mxGetN(prhs[0]); /*M-Rows N-Columns*/
xdotyMex(x,y,z,ColLen);
}
The function xdotyMex is the dot product operation.
The mexFunction has the two vector inputs. Thus,
nrhs=2 should be true if you have entered the correct
number of vectors in your call to the function within MATLAB.
These vectors are stored in the pointer for the double
precision variables x and y. To get input data
mapped to x and y I use the mx* function
mxGetPr. The output is pointed to by z, which
because it is generated in C must be created with the command
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);. Finally,
I use mxGetN to get the length of the vectors.
The previous example is a standard. One which I have written
and is perhaps more interesting is found in the file
RealTridiagSolverMex.c. This uses the Thomas algorithm
to invert a tridiagonal matrix. This script is particular
interesting because it demonstrates the need for caution when
translating from MATLAB to C. In the following example, one
sees that the super and sub-diagonals must be shifted when
going from MATLAB which indexes starting at 1 to C which
begins with 0.
>> mex -g RealTridiagSolverMex.c
>> sub = [6 7 0]';
>> sup = [0 4 5]';
>> diag = [1 2 3]';
>> A = spdiags([sub diag sup],-1:1,3,3);
>> full(A)
ans =
1 4 0
6 2 5
0 7 3
>> Bvector = [8 9 10]';
>> A\Bvector
ans =
1.3861
1.6535
-0.5248
>> subc = [0 6 7]';
>> supc = [4 5 0]';
>> diagc= [1 2 3]';
>> RealTridiagSolverMex(Bvector,subc,diagc,supc)
Number of Rows = 3 Columns = 1
ans =
1.3861
1.6535
-0.5248
The last example of a MEX function that I can share is provided in LagClenshawMEX.c. The corresponding MATLAB implementation of the program is given in LagClenshawAlgorith.m. A test case comparing the speed of the codes is given in LagClenshawTest.m This example is particularly interesting because it deals with complex variables. Originally C did not include an inherent complex variable. Fortunately with the updates in C99 a complex data type has been included but I have found that MATLAB's choice of C compiler does not adhere to the C99 conventions and thus does not include complex variables. It is possible to specify the compiler that MATLAB uses for the MEX file however this a topic which I have not been successful with. Instead, I have chosen to simply hard code the real and imaginary procedures in the C MEX code.
This LagClenshawAlgorithm.m and corresponding C codes compute the sum
f(t) = e(σ-b)tΣ an Ln(2bt)
In our case the coefficients an are complex vectors which are formed from the product of a matrix and a vector. The direction computation of the Laguerre polynomials Ln(2bt) and subsequent summation is a highly unstable process. The Clenshaw algorithm is a numerically stable procedure for the summation. It is described in detail in the website Mathworld Clenshaw.
Go ahead now and run the C and MATLAB codes by typing at the prompt LagClenshawTest.m. The coefficients in test run are random values. However, by selecting the seed for the rand number generator with the command rand('seed',0); I generate the same "random" numbers with run of the test file. A typical run generates data like this
Setting things up...
Matrix and Vector Set up time
elapsed_time =
0.0039
Coefficient Matrix Set up Time
elapsed_time =
9.2600e-04
Matlab Script
elapsed_time =
0.0148
C MEX Code
elapsed_time =
0.0152
Maximum Absolute Element Difference
ans =
1.2313e-13
Maximum Relative Element Difference
ans =
1.1370e-14
Surprisingly, I have found that the C code and the MATLAB semi-vectorized script perform at nearly the same speed. Also, there are some variations from
run to run in the computation times of the algorithms.
[Note: this seems to be true only for small size matrices/vectors. For large matrices/vectors the C code outperforms the Matlab script by about a factor of 5.]
MATLAB has a incredible diversity of rather obscure but potentially useful features. In this webpage, I have only attempted to illustrate, primarily through examples, how to use GUIs, dialog boxes, and MEX files. I only hope that these will be of use to you in your own endeavors with MATLAB.
Patrick Kano / 15 February 2004