Posts Tagged ‘matlab’

Fun, fun fun! (array, cell and struct)

3rd October, 2010 Leave a comment

The other day I was asked what the point of MATLAB’s cellfun function was. “Surely I can do what it does with a for loop?”, they said. The quick answer is, “yes you can use a for loop, but it’s still very useful”. This post tells you why.

The three functions arrayfun, cellfun and structfun are for solving split-apply-combine problems. That is, you split your data up into chunks, you apply some function to each chunk, then you combine the results together. The difference between them is the type of input variable that they accept: arrayfun takes arrays, and so forth. (It should be noted that having just three functions for this is very restrained. R has half a dozen functions in the apply family, plus aggregate and by, not to mention the plyr package.)

A simple example is to try and get the number of characters in each string of a cell array. We start by defining some data (in this case, the first four metasyntactic variables).

msv = {'foo' 'bar' 'baz' 'quux'};

Now compare using a for loop

n = zeros(size(msv));
for i = 1:numel(msv)
   n(i) = numel(msv{i});

with cellfun

n = cellfun(@numel, msv)      %The @ symbol denotes a handle to numel 

Aside from the obvious benefit that we’ve hugely cut down on the amount of typing, I think the second method expresses the intent of the code much more clearly. The use of cellfun means that you must have a split-apply-combine problem, whereas for loops are more general concepts, so you need to study the code more closely to understand what is happening.

There is one little niggle with cellfun that I hope The MathWorks will correct one day. If the result of applying the function to each chunk can have a different size, then the result needs to be stored in a cell array rather than a vector. In this case, you need to explicitly set 'UniformOutput' to false. Ideally, cellfun would be able to automatically know when the output doesn’t have uniform size and act appropriately. Keep your fingers crossed that this gets sorted eventually.

Tags: ,

Update to shortcut tools

1st October, 2010 Leave a comment

I’ve made a small update to the MATLAB shortcut tools collection in the File Exchange. (See the previous post A Shortcut to Success for advice on usage.) The main change is that I’ve been persuaded of the virtue of hiding code in private folders, after finding myself with an increasingly mangled search path. AddShortcutCategory has been replaced with AddShortcutCategories, since you’ll naturally want to add a few at a time, and I’ve added the IconDir function which simply returns the name of the directory of the icons that ship with MATLAB since R2009a. It should be available in the FEX shortly.

Tags: ,

MATLAB Conference 2010

1st October, 2010 Leave a comment

I went to the MATLAB conference at Wembley Stadium yesterday. There were two presentations and a lot of discussion about parallel computing (more on that later). One of the most interesting things to me was that The MathWorks have gotten command history files from a bunch of students learning MATLAB, which they are using to weed out some of the problems that users get when they first learn the language. I can proudly report that I’ve been bitten by several of the examples that were presented.

round 1.234

ans =
    49    46    50    51    52

Here, the input is converted to a character array, then returns the ascii values of each character.   (round is being altered to throw an error upon character input.)

Likewise the unhelpful error message that occurs when you mess up a multiplication is being revamped.

eye(3) * magic(4)
??? Error using ==> mtimes
Inner matrix dimensions must agree.

mtimes is the underlying function that * calls. The error message should now display *, as expected.

I’m really glad to see that The MathWorks are taking in interest in cleaning up these niggles. Little improvements can save users hours of frustration. It reminds me of Canonical’s 100 paper cuts project for Ubuntu.

The parallel computing discussions focussed on two areas: gpu computing and scaling from a single core to multiple cores on a single machine, through to clusters of machines. The gpu and mulicore cases are dealt with via the parallel computing toolbox; scaling to multiple machines requires the rather-more-expensive distributed computing toolbox.

Both products seem to be in a teenage-state: mature enough to get some useful things done with them, but missing a few features.   For example, it’s really easy to parallelise a for loop: you simply replace for with parfor, but arrayfun only works in parallel with gpus, not cpus.   (John Walley, an application engineer with The MathWorks, is discussing rectifying this.) In fairness to The Mathworks, parallel computing from your desktop is in its infancy everywhere.

If I successfully bat my eyelids at the people in charge of the software budget, I’m hoping to be able to play with the parallel computing toolbox in the near future;  I’ll give you some code examples once that happens.


A shortcut to success

23rd August, 2010 2 comments

The MATLAB user interface is laid out in a way so you spend a fair amount of time with one hand on your mouse.  When that happens, toolbar shortcuts are a great way to run chunks of code that you use regularly.  The trouble is, in order to set them up, you need to do lots of clicking to interact with the MATLAB UI.  This has two big problems.  Every time you install a new copy of MATLAB, you need to set up your shortcuts again.  Click, click, click.  Sigh.  It also means that shortcuts are difficult to share with your colleagues/friends/that hot chick you want to impress with your scientific coding skillz.

The solution to this is to generate the shortcuts programmatically.  Write your shortcut script once, and you can reuse the code  to your heart’s content.  The trouble is, MATLAB doesn’t ship with any tools to manipulate shortcuts.  All the details of your shortcuts (that’s the toolbar shortcuts your help browser favourites, and any other shortcuts you care to define) are stored in the file shortcuts.xml in your preferences directory (as returned by prefdir).

There are two ways to write methods to add and remove shortcuts.  You can use some XML tools, of which my favourite is the xml_io_tools package by Jaroslaw Tuszynski.  The other alternative is to delve into the mostly undocumented MATLAB UI functions.  These are mostly built out of Java Swing widgets, and while the documentation is sketchy to non existent, it is possible to utilise their features.  I don’t want to dwell on the technicalities of these widgets; if you want to know more then Yair Altman’s Undocumented Matlab blog is the best place to look.

My shortcut tools package uses this second method. It contains methods for adding, moving and removing toolbar shortcuts and browser favourites, and a few other utility functions.  I going to discuss two possible use cases for the toolbox, one really simple and another that’s slightly more advanced.

First of all, we need some code to be called by the shortcut.  This is a very simple function to tidy up your workspace:

function tidy()
%TIDY Clear workspace and command window; close plots.
close all hidden;
clear all;

MATLAB secretly ships with a set of icons; I’m using a cross, which is available from R2009a onwards. Feel free to use any icon you like, or leave the icon argument blank to use the standard icon. Adding a shortcut is as easy as calling AddShortcut.

iconPath = fullfile( ...
matlabroot, ...
   'toolbox', ...
   'shared', ...
   'dastudio', ...
   'resources', ...
AddShortcut('Tidy', 'tidy();', iconPath);

You should see the shortcut appear in your toolbar. If you decide you don’t want this shortcut, you can remove it with

RemoveShortcuts([], 'Tidy');

(The first parameter requests the category of shortcut, which by default is 'Toolbar Shortcuts'. We don’t want to change this, so we can just leave it empty.)

An idea that was suggested to me by Iram Weinstein was to have different shortcuts available when you work on different projects. This requires a little more setting up, but when you can script it, it’s easy enough to do.  Let’s imagine that you like to work on both cellular automatons and 3D graphics.  Some shortcuts you use will be needed by both projects, but others will be specific to each research area.

First we need to create some categories to contain the shortcuts; one for each project and one to contain the shortcuts common to all your projects.

project1 = 'Cellular Automaton Project';
project2 = '3D Graphics Project';
common = 'Common';

Then we add shortcuts to each category, using AddShortcut, like before. You’ll probably want several shortcuts per project, but for now let’s stick to one shortcut for each.

AddShortcut('Life', 'life();', [], project1);
AddShortcut('Teapot', 'teapotdemo();', [], project2);
AddShortcut('Tidy', 'tidy();', iconPath, common);
AddShortcut('Cellular', 'SetupCelluarProject();', [], common);
AddShortcut('Graphics', 'SetupGraphicsProject();', [], common);

In the common section, at the very least you need a shortcut to initialize each project. All that is left is to write the callback functions for those shortcuts.

function SetupCellularProject()
%SETUPCELLULARPROJECT Sets up the Cellular Automaton Project.

% Get rid of work from other projects.

% Clear the existing toolbar

% Copy the shortcuts from the common category and the project category
% to the toolbar. (The toolbar is the default target location.)
CopyShortcuts('Cellular Automaton Project');

% Other setup code goes here. You'll probably want a call to cd here to
% move to the project directory, and perhaps addpath or load as well.

SetupGraphicsProject will contain similar contents. By encapsulating this setup code into a function, it means that you can call it from the command line to get going with your project as well. As a lazy typist I tend to use shorter function names for these, or at least have a short alias.

That’s it. You can now update your shortcuts at the click of a button.


20th August, 2010 Leave a comment

Anyone who knows anything about presenting data will tell you that pie charts are rubbish.  Even their idiot cousins will tell you that 3D pie charts are even worse.  That got me thinking, “how bad can it get?”.  Sure you can choose garish colour schemes and glossy reflective coatings and transparency, but that has been done before.  By almost every two-bit data-viz charlatan in existence, judging by a Google Image search.  To break new ground in awfulness, we need to enter (cue atmospheric intro)… a new dimension!  In fact, we’re going to make the pie chart travel through time (woo!) with an animation.

The MathWorks, to their eternal shame, include a 3D pie chart function, pie3.  By combining it with their rotate function, we can enter into new levels of crappiness.

First, we draw the pie chart.  This code is tweaked from the example on the pie3 help page.

x = [1 0.25 3 2.5 2 1];
explode = [0 1 0 0 0 1];
h = pie3(x, explode, repmat({''}, size(x)));

3D pie chart

Now we animate it.

n = 180;
mov(n) = getframe;
for i = 1:n
   rotate(h, [20 20], 360 / n);
   mov(i) = getframe;

MATLAB ships with the functions movie, to play back your animation, and movie2avi to export it to video.  For more web-friendlyness, we’re going to create an animated gif using movie2gif on the FEX.

movie2gif(mov, 'pie4.gif', 'DelayTime', 0.5 / n);

And there we have it.  (Click to see it in all its animated glory.)

4D Pie Chart joy

Now, having set the bar suitably low, I promise all future mosts will be more useful than this.