Friday, March 30, 2012

A tip to speed up your MATALB script

A few days ago, my friend sent me a MATLAB script asking for help.
The script had a bug, but he said if the bug is fixed it would take a few hours to run.
I fixed the bug and made some changes, then it took less than 20 seconds to run.
How could this be?

Here's a small tip that can make a huge change in calculation time.

Let's say we are calculating something and updating an array. For example, you start with an array with size (10,1). During the for-loop or while-loop you're adding one more value to it.
So the array size becomes (11,1). This is what happens behind the scene.

Click on the picture to enlarge.

When you ask for one more space that's not ready to use yet, MATLAB has to get that extra space from Windows. (follow the orange arrows). Windows wants to keep elements of an array together, physically. So it goes to the memory to see if there's a room or one more element.

If there is, it gives ok sign to MATLAB (still following the orange arrows), and MATLAB can use it.
If there isn't, Windows has to find a space somewhere else on the memory (not we're following the red arrows). Once that relocation is done, it gives ok sign to MATLAB.

This can be avoided by declaring an empty array before you use it. Like, A=zeros(11,1). Now the space is available and initialized with zeros. When your MATLAB script wants to use that 11th space, it can just go there and use it (blue arrows).

The yellow and red arrows shown above takes much longer time compared to the blue route, and becomes really noticeable when you deal with large array size.

If your array is expanding from (10,1) to (11,1), you won't notice a difference, but if you're expanding from (100000,1) to (100001,1) then (100002,1) and so on, you may end up spending hours instead of minutes.

So guesstimate the array size you'll need and initialize it.
MATLAB is very forgiving in many aspects, but that can slow down your code.




Sunday, March 25, 2012

GUI in MATLAB 8

Wow, it's been 2 weeks since I wrote something for this blog.

I think this will be the last part of GUI in MATLAB series unless I remember something I missed.
I hope the stuff I covered so far have helped whoever out there in some way.
If not, oh well.

Last time I showed you how to save data to the on-screen objects, like a monitor screen, a window you just opened, axes, or plots. (Ok, I just showed how to save things on a monitor screen, but the idea is the same for others as well)

Today, I'll demonstrate how to save data in a storage and retrieve it later.
As usual, the source code is at the bottom of this posting.

Let's start with opening a figure and placing things on it.
Then assign what the buttons should do when pressed.
 As you see here, the last three buttons are not doing anything. I just made them because I didn't like to have too much empty space on a corner.

Now, let's write a local function for the first button. This button is supposed to open a data file and import the data, but since I don't have any sample data, I made series or random numbers. Then save it in storage spaces called, x, y1, y2, y3, and y4.

It's time to write instructions for the rest of buttons. When the plot buttons are pressed, it gets data from the storage and plot them on the axes. Here you see I did not specify which axes to put the plots on because there's only one axes. Someday, if you work with more than one axes, be sure to specify it along with plot.

The end result looks like this. Start with "Get Data" button and play with the rest of plotting buttons.

Now you see there isn't much too GUI in MATLAB. It's just a bunch of somewhat unfamiliar keywords, and the concept is fairly straight forward.

Well, of course there is much more to the GUI in MATLAB but I think this is a good place to start with it.

One more thing. Compared to the text-only MATLAB codes, you see that the GUI takes more work time and effort to write a code. One time I heard someone saying, "To make a program easy to use, the programmer should put more time and effort to write it." He was talking about GUI.
But the upside of this is that once you write it, you won't have to tell others how to use it much. How convenient!!

I'll add more to the GUI in MATLAB if any of you reading this have a question aspired by a burning curiosity. But until then, this is it.
Have fun with it.




Source code:
% I'm calling this STORAGE because it's about a hidden storage.
function STORAGE

F1 = figure('Position',[100 200 700 500],'toolbar','none','menubar','none');
A1 = axes('Parent',F1,'unit','pixel','position',[50 50 500 440]);
B1 = uicontrol('Parent',F1,'style','pushbutton','position',[560 460 130 30]);
B2 = uicontrol('Parent',F1,'style','pushbutton','position',[560 420 130 30]);
B3 = uicontrol('Parent',F1,'style','pushbutton','position',[560 380 130 30]);
B4 = uicontrol('Parent',F1,'style','pushbutton','position',[560 340 130 30]);
B5 = uicontrol('Parent',F1,'style','pushbutton','position',[560 300 130 30]);
B6 = uicontrol('Parent',F1,'style','pushbutton','position',[560 260 130 30]);
B7 = uicontrol('Parent',F1,'style','pushbutton','position',[560 220 130 30]);
B8 = uicontrol('Parent',F1,'style','pushbutton','position',[560 180 130 30]);

set(B1,'string','Get Data','callback',{@LOCALGetData F1})
set(B2,'string','Plot 1st Data','callback',{@LOCALPlot F1 1})
set(B3,'string','Plot 2nd Data','callback',{@LOCALPlot F1 2})
set(B4,'string','Plot 3rd Data','callback',{@LOCALPlot F1 3})
set(B5,'string','Plot 4th Data','callback',{@LOCALPlot F1 4})
set(B6,'string','This doesn''t do anything')
set(B7,'string','This doesn''t do anything')
set(B8,'string','This doesn''t do anything')

function LOCALGetData(varargin)
% Since I don't have data file, I'll just generate something random.
F_Handle = varargin{3};
x = 1:10;
y1=rand(1,10);
y2=rand(1,10);
y3=rand(1,10);
y4=rand(1,10);

setappdata(F_Handle,'x',x)
setappdata(F_Handle,'y1',y1)
setappdata(F_Handle,'y2',y2)
setappdata(F_Handle,'y3',y3)
setappdata(F_Handle,'y4',y4)

function LOCALPlot(varargin)
F_Handle = varargin{3};
PlotNum = varargin{4};

x = getappdata(F_Handle,'x');
y1= getappdata(F_Handle,'y1');
y2= getappdata(F_Handle,'y2');
y3= getappdata(F_Handle,'y3');
y4= getappdata(F_Handle,'y4');

if PlotNum == 1
    plot(x,y1)
elseif PlotNum == 2
    plot(x,y2)
elseif PlotNum == 3
    plot(x,y3)
elseif PlotNum == 4
    plot(x,y4)
end
xlim([1 10])
ylim([0 1])

Saturday, March 10, 2012

GUI in MATLAB 7

I've been super busy with things, and haven't posted anything new for some time.
I'm back now.

Today's portion is about saving data (whatever type it is) in a hidden storage of a figure.
Why do we need this? Well, let's think about a hypothetical situation where you're dealing with a data of some kind.

You make a uicontrol button that opens up and load data from an excel file. This is done by a local function.
Then, you need to send it to the main function, so the main function can play with the data some place else.
The main function can send it to another local function when you press another function, and this local function will plot it on an axes or filter it out using whatever tools it has.

Of course you can think of sending your data out and returning it back to main function from the local function. However, this can easily make your code horribly complicated (well, at least that's what I experienced).

So, what if we save all the common data in one place, and different local functions can go grab it whenever they need it? There's no need to pass data from one location to another in the function, because the "storage space" is there holding it.
Ah~.

That's what we're doing this time and next.
I tried to put it in one posting, but I figured it's better to split into two.

So, let's start.

Before using the storage, you need to know where it is.
The answer is: anything you see on the screen. This storage is hidden, so you won't see it unless you go dig it out.
Anything you see on the screen... well, almost anything.
That includes your monitor screen, the figure window you just opened, the axes you just placed on that figure, the plot you just drew. They all have their own storage spaces.

Then how do you get in there and put things in it?
The magic key word is "setappdata" and "getappdata".
As you guessed it, "setappdata" put things(matrix, array, strings, etc) in a specific place.

Let's try something simple now.
When it comes to MATLAB, object handle "0" is reserved for the entire monitor space.

Let's make a test matrix, x.

Now save it to the monitor screen's storage.

Go back to the storage and bring it out.

That's not bad.
I'll show you how to use this in the GUI programming next time.

Thursday, March 1, 2012

GUI in MATLAB 6

We tasted what uicontrol is like last time.
Let's see what else is available and what more we can do with it.

There are 10 different types of uicontrol - pushbutton, togglebutton, ...
I'll show you 6 types of uicontrol that I use most.

Let's start with the usual - making windows without a menubar or a toolbar, and 6 uicontrols with different styles.

Then, change the displayed strings using set(handle, 'string',...).
Also, add a local functions that will do something when the uicontrol is changed in some way

These two are the local functions for the uicontrols.

Run this, and this figure with things appear.

Now when you click the uicontrol or make changes on the uicontrol, a message will appear on the command window.
These are how to use them.

Pushbutton: click it
Checkbox: check or uncheck the box
Edit box: type something in and press enter
Text box: sorry. it's for display only. So, even though we have callback feature set up for it, it won't do anything.
Listbox: click different items
Popupmenu: use the drop down triangle on the right and click different entries.

There are a few things to note. The listbox and popupmenu have different local function set up than the rest of uicontrols. Do you wonder why? Change the callback to user 1st local function and see what happens when you play with listbox or popupmenu.


Next time I'll show you how to save information on the hidden storage of the figure.



This is the source code for this exercise.

function GUI2
% Start with the usual.
% Open a window, get rid of the menubar and toolbar.
F1 = figure('Position',[100 300 700 250],'menubar','none','toolbar','none');

% Add differnt kinds of uicontols. Handles are S#. S for style
S1 = uicontrol('unit','pixel','Position',[10 210 680 30],...
    'style','pushbutton');
S2 = uicontrol('unit','pixel','Position',[10 170 680 30],...
    'style','checkbox');
S3 = uicontrol('unit','pixel','Position',[10 130 680 30],...
    'style','edit');
S4 = uicontrol('unit','pixel','Position',[10 90  680 30],...
    'style','text');
S5 = uicontrol('unit','pixel','Position',[10 50  680 30],...
    'style','listbox');
S6 = uicontrol('unit','pixel','Position',[10 10  680 30],...
    'style','popupmenu');

% Set strings on the uicontrol
set(S1, 'string','This is pushbutton')
set(S2, 'string','This is checkbox')
set(S3, 'string','This is edit box')
set(S4, 'string','This is text box')
set(S5, 'string','This is listbox-line1 | line2 | line3 | line4')
set(S6, 'string','This is popupmenu-line1 | line2 | line3 | line4')

% Configure what's going to happen if you click, change, or something.
set(S1, 'callback',{@LOCALReaction})
set(S2, 'callback',{@LOCALReaction})
set(S3, 'callback',{@LOCALReaction})
set(S4, 'callback',{@LOCALReaction})
set(S5, 'callback',{@LOCALReaction2})
set(S6, 'callback',{@LOCALReaction2})

function LOCALReaction(varargin)
Handle = varargin{1};
disp(['You''re playing with ',get(Handle,'Style'),', and the contents are:'])
disp(get(Handle,'string'))
disp(' ')

function LOCALReaction2(varargin)
Handle = varargin{1};
disp(['You''re playing with ',get(Handle,'Style'),', and the value is:'])
disp(get(Handle,'value'))
disp(' ')