Quantcast
Channel: Undocumented Matlab
Viewing all 219 articles
Browse latest View live

Another Command Window text color hack

$
0
0

Matlab’s Command Window text is notorious for its boring black & white appearance when sending output via the built-in fprintf or disp commands. Back in 2009, I explained the undocumented ability to display red or hyperlinked text using fprintf, or colored and underlined text using my cprintf utility. I followed this up last year with the relatively new ability to display bold text formatting, using either fprintf or cprintf.

A short while ago, Carsten Allefeld (a regular on this blog) alerted me to the fact that recent Matlab releases have added yet another undocumented feature, this time the ability to specify orange formatting to the output text. This made sense: after all, recent releases have started to display warnings as orange text on STDOUT. While errors have for ages been rendered red by the simple act of directing their output to STDERR, warnings are output to STDOUT and so a bypass was naturally devised. This is similar to the <strong> bypass that I explained last year, for the bold formatting. By redirecting STDOUT, Carsten was able to see that by adding '[\b...]\b' to the output text, anything between the brackets was given an orange color. Of course, we can still use cprintf to display any color in the rainbow, orange included:

Orange color in Command Window text

Orange color in Command Window text


The \b hack relies on the fact that \b is actually the standard back-space control-character, which erases the preceding [ (bracket) character. Matlab's implementation of fprintf simply has a back-door that switches to orange color when it sees a couple of these [\b. By the way, it won't work if you use any other combination, or if there are not exactly two such in the displayed text. MathWorks made the hack very specific so that it would be close to impossible to come by it by mistake.

<editorial>
If you ask me, this is an example of bad design: instead of modifying fprintf to enable generic color and text formatting, the developer hard-coded a specific [\b hack for a specific color, and a different specific <strong> hack for bold formatting. If tomorrow a green color or underlined text will be needed, they'll need to modify the hard-coding and extend it with yet new hard-coding. Moreover, the [\b hack does not enable multiple segments of orange colors in the same text, a natural extension. In their shoes, I'd probably have extended the <strong> paradigm with something like <font color="orange"> or: <span style="color:#FF8000;"> (I wonder where I got this idea from? hmm...) Maybe I'm just being too harsh: it's obviously easier to bitch from the benches than to score at the field...
</editorial>

Anyway, if you only need black, red and orange colors in your text, you need look no further than fprintf. If, however, you require your outputs to be a bit more lively, then consider using cprintf:

cpintf demo

cpintf demo

Do you know of any additional undocumented Command Window hack? If so, please do leave a comment below.

 
Related posts:
  1. Bold color text in the Command Window Matlab Command Window text can be formatted *bold* since R2011b. ...
  2. cprintf – display formatted color text in the Command Window cprintf is a utility that utilized undocumented Matlab desktop functionalities to display color and underline-styled formatted text in the Command Window...
  3. Command Window text manipulation Special control characters can be used to format text output in Matlab's Command Window. ...
  4. Changing Matlab’s Command Window colors – part 2 The Matlab Command Window enables a limited degree of inline color customization - this post describes how to use it...
 

Listbox layout customization

$
0
0

I haven’t written on listboxes in a long while, and since I’ve recently posted on related controls (editbox, combo-box), I thought of following up with an article on customizing Matlab listbox layout. By the end of today’s article, you should be able to customize the layout of items within your listbox, such as the following:

Customized listbox layout   Customized listbox layout

Customized listbox layouts


For the following hacks, we need to gain access to the listbox control’s underlying Java component, which is a MathWorks class that extends the standard JList. We can get this component’s reference using the findjobj utility:

>> hListbox = uicontrol('Style','List', 'String',{'item #1','item #2'});
 
>> jScrollPane = java(findjobj(hListbox))
jScrollPane =
com.mathworks.hg.peer.utils.UIScrollPane[...]
 
>> jListbox = jScrollPane.getViewport.getView
jListbox =
com.mathworks.hg.peer.ListboxPeer$UicontrolList[...]

Like multi-line editboxes, listboxes are actually composed of a container (a com.mathworks.hg.peer.utils.UIScrollPane object) that includes three children, as expected from any JScrollPane: a javax.swing.JViewport that contains the ListboxPeer$UicontrolList component, and horizontal/vertical scrollbars. I explained how to customize the scrollbars in an article back in early 2010.

Today we are not interested in the scroll-pane or scollbars, but rather the jListbox component that takes up the view-port’s contents. This component includes many useful properties that we can access and modify, including several that control the layout of the list items:

LayoutOrientation sets the layout of listbox items within the viewport. Possible values include:

  • The default value (jListbox.VERTICAL=0) indicates the regular top-to-bottom arrangement
  • jListbox.VERTICAL_WRAP=1 sets a horizontal item layout, wrapping to a new row as necessary for the maximum number of rows determined by the VisibleRowCount property (default=8)
  • jListbox.HORIZONTAL_WRAP=2 sets a vertical item layout, wrapping to a new column at row number VisibleRowCount

For example:

jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP);
jListbox.setVisibleRowCount(3);
 
set(jListbox, 'LayoutOrientation',2, 'VisibleRowCount',3);  % equivalent alternative

LayoutOrientation = VERTICAL = 0
VisibleRowCount is irrelevant

LayoutOrientation = VERTICAL_WRAP = 1
VisibleRowCount = 3

LayoutOrientation = HORIZONTAL_WRAP = 2
VisibleRowCount = 3

FixedCellHeight and FixedCellWidth hold the listbox’s cells height (default=13 pixels) and width (default=-1). A value of -1 means that the actual size is determined by the default platform-dependent CellRenderer size:


FixedCellHeight = -1
FixedCellWidth = -1

FixedCellHeight = 10
FixedCellWidth = 30

FixedCellHeight = 16
FixedCellWidth = 50

We can use these properties to display a selection matrix of icons. For example, let’s display the icons in Matlab standard icons folder:

% Prepare the list of ImageIcon objects
iconsFolder = fullfile(matlabroot,'toolbox/matlab/icons');
imgs = dir(fullfile(iconsFolder,'*.gif'));
for iconIdx = 1 : length(imgs)
   iconFilename = fullfile(iconsFolder,imgs(iconIdx).name);
   iconFilename = strrep(iconFilename, '\', '/');
   htmlStr{iconIdx} = ['<html><img src="file:/' iconFilename '"/>'];  % no need for </html>
end
 
% Display in a standard one-column listbox
hListbox = uicontrol('style','list', 'string',htmlStr, 'position',[10,10,160,90]);
 
% Modify the listbox layout to display 18x18-pixel cells
jScrollPane = findjobj(hListbox);
jListbox = jScrollPane.getViewport.getView;
jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP)
jListbox.setVisibleRowCount(4)
jListbox.setFixedCellWidth(18)   % icon width=16  + 2px margin
jListbox.setFixedCellHeight(18)  % icon height=16 + 2px margin
jListbox.repaint  % refresh the display

Customized listbox layout

Customized listbox layout

Other interesting things that we can do with listboxes (among others):

  • Customize the scrollbars, as noted above
     
  • Display HTML-formatted list items:
    uicontrol('Style','list', 'Position',[10,10,70,70], 'String', ...
       {'<html><font color="red">Hello</font></html>', 'world', ...
        '<html><font style="font-family:impact;color:green"><i>What a', ...   % note: </i></font></html> are not needed
        '<html><font color="blue" face="Comic Sans MS">nice day!</font>'});   % note: </html> is not needed

    Listbox with HTML'ed items

    Listbox with HTML colored items

  • Setting dynamic tooltips and right-click context-menus:
    Listbox dynamic tooltip

    Listbox dynamic tooltip

       
    Listbox dynamic context (right-click) menu

    Listbox dynamic context (right-click) menu

Note that while the code above used the underlying Java component, absolutely no knowledge of Java is required to understand it or use it. In fact, the entire code above is pure Matlab, simply setting the component’s properties and calling its methods, and using its inherent support of HTML strings.

Much more advanced customizations are possible at the Java level, especially using a dedicated CellRenderer. Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here ($39, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book.

If you’d like me to personally add similar magic to your GUI, email me to see if I can help.

Advanced listbox CellRenderer customization

Advanced listbox CellRenderer customization

Now tell the truth – doesn’t Matlab’s standard listbox look kinda boring after all this? :-)

 
Related posts:
  1. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  2. GUIDE customization Matlab's GUI Design Editor (GUIDE) has several interesting undocumented features. This post describes how to customize GUIDE rulers....
  3. Button customization Matlab's button uicontrols (pushbutton and togglebutton) are basically wrappers for a Java Swing JButton object. This post describes how the buttons can be customized using this Java object in ways...
  4. Uitable customization report In last week’s report about uitable sorting, I offered a report that I have written which covers uitable customization in detail. Several people have asked for more details about the...
 

Performance: accessing handle properties

$
0
0

Graphic handle properties

There are several ways to access (read or update) Handle Graphics object properties. The simplest (and documented) way is to use the built-in get and set functions on the HG object’s handle. However, it is not the fastest: a significant speedup is possible (see below).

Accessing individual properties is so fast that this speedup may not seem important. Individual properties are accessed in tens or hundreds of microseconds, which is a very short time for most Matlab programs. Indeed, if our application seldom accesses properties, it is probably not worth the effort to optimize this particular aspect of the program:

% Individual property access is extremely fast:
hFig = figure;
tic, figName = get(hFig,'name'); toc  % Elapsed time is 0.000229 seconds. 
 
tic, set(hFig,'name','testing'); toc  % Elapsed time is 0.000270 seconds.

But if we have thousands of reads and/or updates, this could possibly become an important factor (drawnow calls are intentionally omitted to illustrate the effect):

% Using the standard set() function
tic, for idx=1:10000, set(hFig,'name','testing'); end, toc  % Elapsed time is 0.229772 seconds. 
 
% Using the HG handle() wrapper is about 25% faster (or 1.3x speedup):
tic
hFig = handle(hFig);
for idx=1:10000, set(hFig,'name','testing'); end
toc  % Elapsed time is 0.170205 seconds. 
 
% Using the HG handle() wrapper with dot notation is even faster (65% faster, or 2.7x speedup):
tic
hFig = handle(hFig);
for idx=1:10000, hFig.name='testing'; end
toc  % Elapsed time is 0.083762 seconds.

Similar results occur when trying to get() a property value:

% Using the standard set() function
tic, for idx=1:10000, s=get(hFig,'name'); end, toc   % Elapsed time is 0.140865 seconds.
 
% Using the HG handle() wrapper is about 25% faster (or 1.3x speedup):
tic, hFig=handle(hFig); for idx=1:10000, s=get(hFig,'name'); end, toc  % Elapsed time is 0.108543 seconds.
 
% Using the HG handle() wrapper with dot notation is even faster (62% faster, or 2.6x speedup):
tic, hFig=handle(hFig); for idx=1:10000, s=hFig.name; end, toc   % Elapsed time is 0.053423 seconds.

We learn from this that using the HG handle() wrapper function is useful for improving performance. This has the benefit of improving our code performance with minimal changes to our code, by simply updating our handle to be a handle() wrapper:

hFig = handle(hFig);

Using the handle’d handle enables further performance benefits if we use the dot notation (handle.propertyName), rather than use the familiar get/set functions.

Note that both the handle function and its beneficial effects on performance are undocumented.

Java reference properties

The same conclusions also hold true for Java objects, where it turns out that using handle() and the simple dot notation is 2-6 times as fast as using the Java set<PropName> and get<PropName> functions, due to Matlab-Java interface aspects:

jb = javax.swing.JButton;
 
% Using the standard set() function
tic, for idx=1:10000, set(jb,'Text','testing'); end, toc  % Elapsed time is 0.278516 seconds.
 
% Using the HG handle() wrapper is about 35% faster (or 1.6x speedup):
jhb = handle(jb);
tic, for idx=1:10000, set(jhb,'Text','testing'); end, toc   % Elapsed time is 0.175018 seconds.
 
% Using the HG handle() wrapper with dot notation is even faster (65% faster, or 2.8x speedup):
tic, for idx=1:10000, jhb.text='testing'; end, toc  % Elapsed time is 0.100239 seconds.
 
% Using the Java setText() function, is actually slower (faster with the handle() wrapper, but still slower than dot-notation):
tic, for idx=1:10000, jb.setText('testing'); end, toc  % Elapsed time is 0.587543 seconds.
tic, for idx=1:10000, jhb.setText('testing'); end, toc  % Elapsed time is 0.201635 seconds.

The same holds true also for retrieving property values via the get function.

User handle class properties

Exactly the same conclusions also apply to non-graphical user classes that derive from the base handle class regarding property access. In this case, we derive the hgsetget built-in class, which provides a handle class with the standard get/set functions. Note that this is documented – it is only the performance implications that are undocumented in this case.

We first create a simple class for testing:

% Define a simple handle class
classdef TestClass < hgsetget 
    properties
        name
    end
end

Now let’s test both sides of the property access (get/set) – first let’s set the property value:

obj = TestClass;
 
% Using the standard set() function
tic, for idx=1:10000, set(obj,'name','testing'); end, toc  % Elapsed time is 0.138276 seconds.
 
% Using class.propName notation - 72x faster!
tic, for idx=1:10000, obj.name='testing'; end, toc  % Elapsed time is 0.001906 seconds.

And similarly for retrieving a property value:

% Using the standard set() function
tic, for idx=1:10000, a=get(obj,'name'); end, toc  % Elapsed time is 0.105168 seconds.
 
% Using class.propName notation - 6.5x faster
tic, for idx=1:10000, a=obj.name; end, toc  % Elapsed time is 0.016179 seconds.

Conclusions

The general conclusion is that we should always strive to use the dot notation (handle.propertyName), rather than use the familiar get/set functions, in performance hotspots. Naturally, doing this in non-hotspot locations is futile, since accessing individual properties is relatively fast.

In the upcoming HG2, when all of Matlab's GUI and graphic objects will use Matlab classes, this conclusion will be more important than ever. Initial tests on the HG2 alpha (that anyone can access) show that they hold true for HG2 just as they do in the current HG1.

The handle() function wrapper produces a UDD (schema) object, so while I have not specifically tested non-HG schema objects, I would be very surprised if the conclusions do not hold true for all UDD objects in general.

I have also not [yet] tested other types of handles (ActiveX/COM, Dot-Net etc.) but again, I would be very surprised if the conclusions would be any different.

If this performance tip has piqued your interest, then you might be interested in the several hundred other tips in my upcoming book "MATLAB Performance Tuning" (CRC Press, 2014). I'll post a note on this blog letting everyone know when it's officially available. In the meantime, enjoy my other performance-related articles - there are already several dozen of them by now, and the list will continue to grow...

Editorial note: In the past month I've gone to quite a lot of effort to improve the performance of this website. Most users should now see pages loading about twice as fast as one month ago. The effect should be especially noticeable on mobile devices connected over mobile, which is much slower than wifi/cable. I still have a few additional tweak ideas, so I expect performance to slightly improve even further in the upcoming weeks. Enjoy reading!

 
Related posts:
  1. Displaying hidden handle properties I present two ways of checking undocumented hidden properties in Matlab Handle Graphics (HG) handles...
  2. Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....
  3. Performance: scatter vs. line In many circumstances, the line function can generate visually-identical plots as the scatter function, much faster...
  4. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
 

sprintfc – undocumented helper function

$
0
0

Every now and then I discover a useful built-in Matlab function, often by bumping into them within the m-code of standard functions. Such was the case, for example, of the ismembc function, that I described here back in 2009, and the dtstr2dtnummx function that I described in 2011. Today I describe another such function, sprintfc, based on a tip I received from Dirk Engel.

The requirement

The use-case of generating a cell-array of formatted strings is often encountered. Unfortunately, the standard sprintf function generates a single string, rather than a cell-array of strings. So, for example,

>> data = pi * (0:.5:2)
data =
         0    1.5708    3.1416    4.7124    6.2832
 
>> sprintf('%.3f  ',data)
ans =
0.000  1.571  3.142  4.712  6.283

This is nice, but not exactly what we need, which is a cell array that looks like this:

>> c  % c is a 1x5 cell array
c = 
    '0.000'    '1.571'    '3.142'    '4.712'    '6.283'

The standard solutions

There are several standard solution for getting the required cell array. A simple for-loop is one of the fastest of these, due to JIT optimizations in recent Matlab releases. Some of the other alternatives may seem very strange, but they perform faster than the simpler variants. Note that the following code should be run within a testing function, to remove extraneous influences on the timing (JIT compilation etc.):

% 1) Simple for-loop with sprintf
tic
for idx = 1 : 1000
    c = {};  %initialize
    % note: reallocations are not really a factor here, so don't bother preallocating
    for dataElement = data
        c{end+1} = sprintf('%.3f',dataElement);
    end
end
toc
% Elapsed time is 0.076002 seconds.
 
% 2) Using arrayfun + num2str
tic
for idx = 1 : 1000
    c = arrayfun(@(c) num2str(c,'%.3f'), data, 'uniform',false);
end
toc
% Elapsed time is 0.557993 seconds.
 
% 3) Using cellfun + num2str + num2cell
tic
for idx = 1 : 1000
    c = cellfun(@(c) num2str(c,'%.3f'), num2cell(data), 'uniform',false);
end
toc
% Elapsed time is 0.566924 seconds.
 
% 4) Using num2cell + num2str
tic
for idx = 1 : 1000
    c = num2cell(num2str(data','%.3f'),2)';
end
toc
% Elapsed time is 0.173026 seconds.
 
% 5) Using cellstr + num2str
tic
for idx = 1 : 1000
    c = reshape(cellstr(num2str(data(:),'%.3f')),size(data));
end
toc
% Elapsed time is 0.175769 seconds.
 
% 6) Using num2cell + num2str (after Urs Schwartz & Jiro Doke)
tic
for idx = 1 : 1000
    c = reshape(num2cell(num2str(data(:),'%.3f'),2),size(data));
end
toc
% Elapsed time is 0.170247 seconds.
 
% 7) Using strread + sprintf
tic
for idx = 1 : 1000
    c = reshape(strread(sprintf(['%.3f','$'], data),'%s', 'delimiter','$'),size(data));
end
toc
% Elapsed time is 0.059457 seconds.

There are also some File Exchange contributions that do a similar thing, including num2cellstr or mtx2charcell, which basically implement the last two variants.

sprintfc

It turns out that the standard num2str function uses an undocumented built-in function sprintfc that already does this for us in one fell swoop – this is both the simplest and the fastest solution:

% 8) fastest and simplest - sprintfc
tic
for idx = 1 : 1000
    c = sprintfc('%.3f',data);
end
toc
% Elapsed time is 0.015714 seconds.

This is a 35x speedup compared to arrayfun/cellfun, 5x speedup compared to the JIT-optimized for-loop, and 4x speedup compared to the fastest other variant. Useful indeed.

The syntax of the sprintfc function can be seen in the num2str.m function:

[cells, errorMsg, isLeft] = sprintfc(format, data, isImaginary);

where isImaginary is an optional flag (default=false) indicating that data should be formatted as imaginary values with the specified magnitude:

>> data = pi * (-1:.5:1)
data =
   -3.1416   -1.5708         0    1.5708    3.1416
 
>> sprintfc('%.3f', data, false)
ans = 
    '-3.142'    '-1.571'    '0.000'    '1.571'    '3.142'
 
>> sprintfc('%.3f', data, true)
ans = 
    '-3.142i'    '-1.571i'    '+0.000i'    '+1.571i'    '+3.142i'

The second returned argument is an errorMsg string that is returned when sprintfc fails, typically due to an invalid format:

>> [c,errMsg] = sprintfc('%r', data)
c = 
    {''}
errMsg =
Invalid format.

The third returned value, isLeft, is apparently used to indicate whether the output cell-string is left-justified; namely, if the ‘-’ flag is used within the format (thanks Yaroslav!). For example,

>> [cells, ~, isLeft] = sprintfc('%-8.5g', sqrt(2), false)
cells = 
    '1.4142  '
isLeft =
    1
 
>> [cells, ~, isLeft] = sprintfc('%8.5g', sqrt(2), false)
cells = 
    '  1.4142'
isLeft =
    0

sprintfc has apparently remained in its current stable state since it was first introduced in the last decade (sometime between Matlab release 7.1 [in 2005] and R2008a). I do not know why MathWorks chose to keep sprintfc as an internal undocumented and unsupported function, despite its obvious usefulness.

If anyone finds any other similar useful built-ins, please do let me know.

London training course – Feb/Mar 2014

I am planning a week of advanced Matlab training workshops/seminars in London in Feb/Mar 2014. I plan two separate courses:

This is a unique opportunity to enhance your Matlab skills in a few days, at an affordable cost, by an established expert. This training is not provided anywhere else. If you have a specific topic that you would like me to discuss, then I would be happy to do it. In other words, I can customize the training to your specific needs, within the provided framework. More details on my training can be found here.

If you are interested in the London courses or a private dedicated course, please Email me (altmany at gmail dot com) for details.

Happy Hanukkah/Thanksgiving everyone :-)

 
Related posts:
  1. ismembc – undocumented helper function Matlab has several undocumented internal helper functions that can be useful on their own in some cases. This post presents the ismembc function....
  2. Undocumented feature() function Matlab's undocumented feature function enables access to some internal experimental features...
  3. tic / toc – undocumented option Matlab's built-in tic/toc functions have an undocumented option enabling multiple nested clockings...
  4. uiundo – Matlab’s undocumented undo/redo manager The built-in uiundo function provides easy yet undocumented access to Matlab's powerful undo/redo functionality. This article explains its usage....
 

Plotly graphs

$
0
0

I would like to welcome Chris Parmer of plot.ly, who will describe the integration of Plotly graphs and charts in Matlab. Unlike the open-source JFreeChart and Waterloo plotting libraries that were described here in the past, Plotly is a commercial (not open-source) service. Contact Plotly for the exact license terms and costs. However, as you can see below, there’s a demo account that you can freely use. While I do not directly endorse Plotly as a commercial operation, I love its beautiful visualizations and interactivity. I think MathWorks would be wise to copy ideas from Plotly to Matlab’s graphics library, esp. new chart types and the interactivity features. In the future I hope that either Plotly concepts get included in Matlab’s HG, or that Plotly plots become embeddable in Matlab GUI (or both).

Plotly is a new web-based graphing application. You can interactively make, style, analyze and share beautiful graphs. Here is an example (move your mouse over the graph to see the interactive effects): 


Full size: https://plot.ly/~chris/1638/

Additional examples: https://plot.ly/~bchartoff/603/, https://plot.ly/~jackp/1000/ and Washington Post.

Creating Plotly graphs in Matlab

Plotly has a Matlab interface. From Matlab, you send data to plotly where it will be stored and made into a graph that you view in your browser. Let’s get started.

  1. download the Plotly-Matlab API package.
     
  2. Add folder and subfolders to your Matlab path:
    path_to_downloaded_folder = '/User/chris/Downloads/plotly'; % fill in with your path
    addpath(genpath(path_to_downloaded_folder))
  3. Sign up through the API, or sign-in with a demo account:
    % To sign up, run:
    r = signup('my_desired_plotly_username', 'my_desired_plotly_username@my_email.com') % plotly generates a temp password and api_key for you
    signin(r.un, r.api_key); % then, sign in with your newly created account
     
    % OR to use the demo account, do:
    plotly_username = 'MATLAB_example' % a demo username you can use
    plotly_key = 'h5n38rzyjo' % a demo api key you can use
    signin(plotly_username, plotly_key)  % sign in to plotly
  4. Create a new chart using the API’s plotly function:
    % Here's a simple line chart example:
    >> x = linspace(0, 6*pi, 100);
    >> y1 = exp(-0.2*x).*sin(x);
    >> y2 = exp(-0.3*x).*sin(x);
    >> r = plotly(x,y1,x,y2) % call plotly instead of plot
    High five! You successfully sent some data to your account on plotly. 
    View your plot in your browser at https://plot.ly/~MATLAB_example/3 or inside your plot.ly account where it is named 'plot from API (3)'
    ans = 
       url: 'https://plot.ly/~MATLAB_example/3'
       message: [1x205 char]
       warning: [1x0 char]
       filename: 'plot from API (3)'
       error: [1x0 char]

And here’s the graph that you just generated: https://plot.ly/~MATLAB_example/3

Note that the graph won’t actually appear in a Matlab figure, nor can it be viewed in Matlab’s limited built-in browser (web). Instead, you view all of your plots in your “real” web browser, at the URL that plotly has returned. You can also have Matlab automatically open up the browser by running dos(['open ' r.url]) on a Mac, or dos(['start ' r.url]) on Windows. Within a webpage, you can embed it using an iframe tag (as I have done in this article), as follows:

<iframe width="800" height="400" seamless="seamless" scrolling="no" src="https://plot.ly/~MATLAB_example/3"></iframe>

Here is a side-by-side comparison with the corresponding Matlab plot:

Corresponding Matlab and Plotly plots (click for details)

Corresponding Matlab and Plotly plots (click for details)

Customizing Plotly graphs

Every aspect of the plotly graph can be customized online. This means no more 500-line styling scripts! To open up the plot into the GUI, click the “Save a copy” button. You can also download the graphs to EPS, SVG, PNG, and PDF:

Web-based Plotly chart customization (click for details)

Web-based Plotly chart customization (click for details)

Plotly can make line charts, scatter plots, histograms, 2D histograms, box plots, heatmaps, and error bars. They also support log axes, date axes, multiple axes and subplots.

Plotly’s graphing syntax is a little unconventional. Plots are described with cell arrays of structs. Each struct describes a single “trace” of the plot with data, chart-type, and optional styling information. There are no setters or getters (Why? Well, because behind the scenes, the data gets converted to a JSON object and the closest analogue of a JSON array of key-value pair objects in Matlab is a cell array of structs). For example:

samples = randn(500,1); % 500 normally distributed samples
trace1 = struct('y', samples, ...
                'type', 'histogramy', ... % make a histogram type plot
                'histnorm', 'probability density'); % normalized by probability density distribution
trace2 = struct('x', linspace(-3,3,100), ...
                'y', 1./sqrt(2*pi)*exp(-linspace(-3,3,100).^2/2.), ...
                'fill', 'tozeroy') % "fill" the curve to the "zero-y" line i.e. make an area plot
response = plotly({trace1, trace2});  % => https://plot.ly/~MATLAB_example/5

Now let’s make some graphs not generally seen in Matlab :)

First, triple y-axis:

x = linspace(0,6*pi,100);
trace1 = struct('x',x, 'y',sin(x).*exp(-0.3*x));
trace2 = struct('x',x, 'y',10*sin(x-2*pi/3).*exp(-0.3*x), 'yaxis','y2'); % this trace will correspond to 2nd y-axis, 'y2'
trace3 = struct('x',x, 'y',100*sin(x-4*pi/3).*exp(-0.3*x), 'yaxis','y3'); % this trace will correspond to 3rd y-axis, 'y3'
layout = struct('xaxis', struct('domain',[0,0.9]), ... % set x-axis to span 90% of plot width, like Matlab's 'Position' property
                'yaxis2', struct('anchor','x', 'side','right', 'overlaying','y'), ... % places another y-axis on the right side of the plot
                'yaxis3', struct('anchor','side', 'right','free', 'position',1.0, 'overlaying','y')) % places 3rd y-axis at 100% plot width
r = plotly({trace1, trace2, trace3}, struct('layout', layout));  % => https://plot.ly/~MATLAB_example/13
dos(['open ', r.url])

Try clicking and dragging on the y-axis (along the number lines). Notice how each axes is totally independent of the other trace. Panning is done by dragging the x-axis. Also, try zooming (click-and-drag).

Here’s another neat example of how subplots’ axes can be linked to each other or can be independent:

x1 = [1, 2, 3];  y1 = [2,3,4];
x2 = [20,30,40]; y2 = [3,4,5];
x3 = [2, 3, 4];  y3 = [600,700,800];
x4 = [4000,5000,6000]; y4 = [7000,8000,9000];
 
% build structs describing the plot traces and assigning data to axes
trace1 = struct('x',x1, 'y',y1);
trace2 = struct('x',x2, 'y',y2, 'xaxis','x2', 'yaxis','y');  % new x-axis but same y-axis as trace1; 'x2' is shorthand for 'xaxis2' below
trace3 = struct('x',x3, 'y',y3, 'xaxis','x',  'yaxis','y3'); % same x-axis as trace 1 but a new y-axis
trace4 = struct('x',x4, 'y',y4, 'xaxis','x4', 'yaxis','y4'); % new x-axis and new y-axis
 
% build a layout struct describing the layout of the different axes
xaxis =  struct('domain', [0, 0.45]); % let the first x-axis span the first 45% of the plot width
yaxis =  struct('domain', [0, 0.45]); % and let the first y-axis span the first 45% of the plot height
xaxis2 = struct('domain', [0.55, 1]); % and let the second axis span the latter 45% of the plot width
yaxis3 = struct('domain', [0.55,1]);
xaxis4 = struct('domain', [0.55, 1], 'anchor','y4'); % anchor axis vertical position to start of yaxis4
yaxis4 = struct('domain', [0.55, 1], 'anchor','x4'); % anchor axis horizontal position to start of xaxis4
layout = struct('xaxis',xaxis, 'yaxis',yaxis, 'xaxis2',xaxis2, 'yaxis3',yaxis3, 'xaxis4',xaxis4, 'yaxis4',yaxis4);
r = plotly({trace1,trace2,trace3,trace4}, struct('=> layout', layout))  % => https://plot.ly/~MATLAB_example/15
dos(['open ', r.url])

The bottom two plots share the same y-axis, the two stacked plots on the left share the same y-axis, the two stacked plots on the left share the same x-axis and the plot in the top right has its own x and y axes. Try zooming (click-and-drag), auto-scaling (double-click), or axis panning (click-and-drag on the axes number lines) around in the different plots and see how the axes respond.

In case you don’t have the Matlab Stats toolbox, you can use plotly to make your box plots:

y1 = randn(50,1); y2 = rand(50,1);
r = plotly({struct('y',y1, 'type','box'), struct('y',y2, 'type','box')}) % => https://plot.ly/~MATLAB_example/17
dos(['open ', r.url])

In case you don’t have the Matlab Bioinformatics toolbox or Yair’s DataMatrix utility, you can use plotly to make your heatmaps:

r = plotly({struct('z',randn(50,50), 'type','heatmap')}) % => https://plot.ly/~matlab_example/18
dos(['open ', r.url])

Or, a different type of heat-map (click here for details):

This was an introduction to the plotly-Matlab interface. Plotly is bridging desktop-based technical computing with the modern web. Inside the tool itself, you can share graphs and data with others (similarly to Google Docs), view revisions of your graph and data (similarly to GitHub), and even make graphs without coding by uploading a CSV, Excel, or even a .mat file. Since it’s entirely web-based, you can share your graphs and data with a link to anyone, even if they don’t have Matlab. There are also similar interfaces in Python, R, Perl, Julia, and Arduino, so if you or if you and your colleagues like to work in different languages, you can keep all of your data and graphs in the same place, online.

Last but not least, it’s much easier to make beautiful, publication-quality graphs. Here are some of our favorite examples:

Graphs: plot.ly/~carmeloosh/66/, plot.ly/~flann321/9/, plot.ly/~carmeloosh/81/, plot.ly/~carmeloosh/83/, plot.ly/~demos/444, plot.ly/~demos/390

Scripts: plot.ly/MATLAB/script-demos/fractal-barnsley-fern-graph-example/, plot.ly/MATLAB/script-demos/math-scores-boxplot-line-chart-example/

Additional resources

 
Related posts:
  1. JFreeChart graphs and gauges JFreeChart is an open-source charting library that can easily be integrated in Matlab...
  2. Pinning annotations to graphs Annotation object can be programmatically set at, and pinned-to, plot axes data points. ...
  3. Specialized Matlab plots The new MathWorks Plot Gallery provides access to some plotting examples on the File Exchange. Numerous others are available, extending the customizability of Matlab graphics. ...
  4. Waterloo graphics Waterloo is an open-source library that can significantly improve Matlab GUI. ...
 

Class object creation performance

$
0
0

Matlab’s Class Object System (MCOS) is a powerful way to develop maintainable, modular, reusable code using a modern Object Oriented Programming (OOP) paradigm. Unfortunately, using OOP in Matlab carries some performance penalties that need to be considered when deciding whether to code in the new paradigm or keep using the older, simpler procedural paradigm. A major resource in this regard is a detailed post from 2012 by Dave Foti, who heads MCOS development at MathWorks.

As Dave pointed out, the importance of MCOS’s overheads only comes into play when our program uses many class objects and calls many short-duration methods. In the majority of cases, this is actually not the case: Our performance bottlenecks are normally I/O, GUI, memory and processing algorithm – not object manipulation and function-call overheads. Unfortunately, Dave’s article left out many ideas for improving MCOS performance in those cases where it does matter.

Today’s article will expand on the sub-topic of MCOS object creation. While it does not directly rely on any undocumented aspect, I have also not seen it directly explained in the official docs. So consider this to be the missing doc page…

Constructor chaining

In his article, Dave’s main suggestion for improving object creation performance was to reduce the number of super-classes. When creating class objects, each creation needs to chain the default values and constructors of its ancestor super-classes. The more superclasses we have, the more modular our code can become, but this makes object creation slightly slower. The effect is typically on the order of a few millisecs or less, so unless we have a very long super-class chain or are bulk-creating numerous objects, this has little impact on the overall program performance.

Object pooling

Objects are typically created at the beginning of a program and used throughout it. In such cases, we only pay the small performance penalty once. In cases where objects are constantly being destroyed and created throughout the program’s duration, consider using object pooling to reuse existing objects. The basic idea is to create a set of ready-to-use objects at the beginning of the program. A static (singleton) dispatcher (factory) object would create this pool of objects in its constructor, possibly with a few new objects ready for use. The factory’s only public interface would be public pull/recycle methods to retrieve and return objects from/to the pool. The program would have no access to the objects pool (except via these public methods), since the pool is stored in the factory object’s private data.

The pull method would create new objects only when asked to retrieve objects from an empty pool; otherwise it would simply return a reference to one of the unused pool objects (which need to be handle class objects to be reference-able). The recycle method will be used to return objects to the pool, once they have been used, to enable these objects to be reused later (via subsequent pulls).

Object pooling entails programming overheads that only make sense when a large number of short-lived objects are constantly being created and destroyed, or when object creation is especially expensive. It is often used in databases (connection pooling), since programs often connect to a database numerous times for short-lived SQL queries. Similar ideas can be found in GUI and I/O programming.

Here is a simple implementation of such a system. The singleton factory class is Widgets and it holds a pool of reusable Widget objects:

% Manage a persistent, global, singleton list of Widget objects
classdef Widgets < handle
    properties (Access=private)
        UnusedWidgets@Widget   % only accept elements of type Widget
    end
 
    methods (Access=private)
        % Guard the constructor against external invocation.
        % We only want to allow a single instance of this class
        % This is ensured by calling the constructor from the static (non-class) getInstance() function
        function obj = Widgets()
            % Initialize an initial set of Widget objects
            for idx = 1 : 5
                try
                    obj.UnusedWidgets(idx) = Widget;
                catch
                    obj.UnusedWidgets = Widget;  % case of idx==1
                end
            end
        end
    end
 
    methods (Static)  % Access=public
        % Get a reference to an unused or new widget
        function widget = pull()
            obj = getInstance();
            try
                % Try to return a widget from the list of UnusedWidgets
                widget = obj.UnusedWidgets(end);
                obj.UnusedWidgets(end) = [];  % remove from list
            catch
                widget = Widget;  % create a new Widget object
            end
        end
 
        % Return a widget to the unused pool, once we are done with it
        function recycle(widget)
            obj = getInstance();
            obj.UnusedWidgets(end+1) = widget;
        end
    end
end
 
% Concrete singleton implementation
% Note: this is deliberately placed *outside* the class, so that it is not accessible to the user
function obj = getInstance()
    persistent uniqueInstance
    if isempty(uniqueInstance)
        obj = Widgets();
        uniqueInstance = obj;
    else
        obj = uniqueInstance;
    end
end

We can access and use the Widgets object pool as follows:

% Retrieve a Widget object instance from the pool of objects, or create a new instance as needed
widget = Widgets.pull();
 
% Now use this widget object until we're done with it
 
% Return the object to the pool, for possible later reuse
Widgets.recycle(widget);

Handle vs. value class objects

Another consideration when designing classes is that while handle classes are slightly slower to create (due to multiple super-class overheads), they are typically much faster to use. The reason is that handle classes are passed to functions by reference, whereas value classes are passes by value. Whenever we modify a handle class property within a function, we directly manipulate the relevant property memory. On the other hand, when we manipulate a value class property, a copy of the class needs to be created and then the modified class needs to be copied back to the original object's memory (using Matlab's Copy-on-Write mechanism). Since we cannot normally anticipate all usage patterns of a class when we create it, I suggest to create any new user class as handle class, unless there is a specific good reason to make it a value class. All it takes is to add the handle (or hgsetget) inheritance to the class definition:

classdef MyClass < handle

Preallocation

When implicit expansion of class-object arrays takes place, an abbreviated version of object instance creation takes place, which bypasses the constructor calls and just copies the instance properties. For example, array(9)=Widget creates an array of 9 separate Widget objects, but the Widget constructor is only called for array(1) and array(9); array(1) is then expanded (copied-over) to the remaining objects array(2:8).

When preallocating, ensure that you are using the maximal expected array size. There is no point in preallocating an empty array or an array having a smaller size than the expected maximum, since dynamic memory reallocation will automatically kick-in within the processing-loop. For this reason, avoid using the empty() method of class objects to preallocate - use repmat instead (ref).

When using repmat to replicate class objects, always be careful to note whether you are replicating the object itself (this happens if your class does NOT derive from handle) or its reference handle (which happens if you derive the class from handle). If you are replicating objects, then you can safely edit any of their properties independently of each other; but if you replicate references, you are merely using multiple copies of the same reference, so that modifying referenced object #1 will also automatically affect all the other referenced objects. This may or may not be suitable for your particular program requirements, so be careful to check carefully. If you actually need to use independent object copies, you will need to call the class constructor multiple times, once for each new independent object (ref).

Preallocation of class objects (class instances) can be used not just as a means of avoiding dynamic allocation, but also as a means of controlling the time of object initialization. Object initialization, typically done in the class’s constructor method, could be lengthy (depending on your specific application). By preallocating the object, we can control the exact timing in which this initialization occurs, possibly at such a time that is less time-critical in the regular application time-flow. This relates to the concepts of lazy initialization, a special case of deferred (or demand-driven) evaluation.

For additional aspects of preallocation performance, refer to my article from last year, which discusses class objects only briefly, but expands on the other data types.

London training course - March 2014

If you are interested in improving your Matlab application's performance and your Matlab programming skills in general, join my upcoming Advanced Matlab Programming course in London, March 2014 – an intensive 2 day course on best practices, preparing professional reports and performance tuning. I guarantee that following this course your Matlab programming skills will be at a higher level.

 
Related posts:
  1. Performance: accessing handle properties Handle object property access (get/set) performance can be significantly improved using dot-notation. ...
  2. Creating a simple UDD class This article explains how to create and test custom UDD packages, classes and objects...
  3. Preallocation performance Preallocation is a standard Matlab speedup technique. Still, it has several undocumented aspects. ...
  4. Array resizing performance Several alternatives are explored for dynamic array growth performance in Matlab loops. ...
 

Accessing private object properties

$
0
0

Some time ago, I needed to modify a property value of a class object. The problem was that this property was declared as private and for some reason my client could not modify the originating classdef to make this property accessible.

Problem definition

We start with a very simple class definition:

Inaccessible private property (or is it?)

Inaccessible private property (or is it?)

classdef MyClass
    properties (SetAccess=private)  %GetAccess = public
        y
    end
    properties (Access=private)  %GetAccess = SetAccess = private
        x
    end
 
    methods
        function obj = MyClass(x,y)  % constructor
            if nargin>0, obj.x = x; end
            if nargin>1, obj.y = y; end
        end
 
        function result = isPropEqualTo(obj,propName,value)
            result = (obj.(propName)==value);
        end
    end
end

The problem is simple: we need to both get and set the value of inaccessible private properties x,y. But following object construction, MyClass enables direct read access only to property y, and write access to neither of its properties:

>> obj = MyClass(3,4)
obj = 
  MyClass with properties:
 
    y: 4
 
>> obj.x
You cannot get the 'x' property of MyClass. 
 
>> obj.x=5
You cannot set the 'x' property of MyClass. 
 
>> obj.y=5
You cannot set the read-only property 'y' of MyClass.

A dead end, would you say? – Well, it never stopped us before, has it? After all, is it not the raison-d’être of this blog?

Reading private properties

Getting the value of x is simple enough when we recall that calling Matlab’s struct function on a class object reveals all its hidden treasures. I wrote about this a couple of years ago, and I’m not sure how many people realize the power of this undocumented feature:

>> s = struct(obj)
Warning: Calling STRUCT on an object prevents the object from hiding its implementation details and should thus be avoided.
Use DISP or DISPLAY to see the visible public details of an object. See 'help struct' for more information.
(Type "warning off MATLAB:structOnObject" to suppress this warning.)
 
s = 
    y: 4
    x: 3

As the warning mentions, we should not do this often (bad, bad boy!). If we must (I promise I had a good reason, ma!), then we can simply turn off the nagging warning:

warning off MATLAB:structOnObject

We can now read all the private internal properties of the object. Yummy!

Setting private properties

The natural attempt would now be to update the struct’s fields with new values. Unfortunately, this does not affect the original class properties, since our struct is merely a copy of the original. Even if our original object is a handle class, the struct would still be a shallow copy and not a real reference to the object data.

Mex’s standard mxGetProperty cannot be used on the original object, because mxGetProperty returns a copy of the property (not the original reference – probably to prevent exactly what I’m describing here…), and in any case it can’t access private properties. mxSetProperty is a dead-end for similar reasons.

The core idea behind the solution is Matlab’s Copy-on-Write mechanism (COW). This basically means that when our struct is created, the field values actually hold references (pointers) to the original object properties. It is only when trying to modify the struct fields that COW kicks in and a real copy is made. This is done automatically and we do not have any control over it. However, we can use this information to our advantage by retrieving the field references (pointers) before COW has a chance to ruin them. Once we have the reference to the private data, we can modify the data in-place using a bit of Mex.

So the trick is to get the reference address (pointer) of s.x and s.y. How do we do that?

We can use another trick here, which is a corollary to the COW mechanism: when we pass s.x into a function, it is not a data copy that is being passed (by value), but rather its pointer (by reference). So we can simply get this pointer in our Mex function and use it to modify the original property value. Easy enough, right?

Not so fast. Don’t forget that s.x is merely a reference copy of the original property data. If we modify s.x‘s reference we’re just killing the so-called cross-link of the shared-array. What we need to do (more or less) is to traverse this cross-link back to its source, to get the real reference to the data.

Sounds complicated? Well, it is a bit. Luckily, Mex guru James (Jim) Tursa comes to the rescue with his mxGetPropertyPtr function on the File Exchange, which does all that for us. Once we have it compiled (the utility automatically Mex-compiles itself on first use), we can use it as follows (note the highlighted line using mxGetPropertyPtr):

/* Place in mxMySetProperty.c and mex-compile*/
#include "mex.h"
#include "mxGetPropertyPtr.c"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    mxArray *x;
    register double *xpr;
    int buflen;
    char *propName = "x";
    double newValue = -3.14159265358979;
 
    if ( nrhs > 1 ) {
        /* Get the specified property name (or "x" if not specified) */
        buflen = mxGetNumberOfElements(prhs[1]) + 1;
        propName = mxCalloc(buflen, sizeof(char));
        mxGetString(prhs[1], propName, buflen);
    }
 
    /* Get the pointer to the original property data */
    x = mxGetPropertyPtr(prhs[0],0,propName);    if ( !x ) {
        mexErrMsgTxt("Failed to get pointer to property.");
    }
 
    /* Display the existing property value */
    xpr = mxGetPr(x);
    mexPrintf("existing value of property %s = %f\n", propName, *xpr);
 
    /* Update the property with the new value */
    if ( nrhs > 2 ) {
        /* Get the specified new value (or -pi if not specified) */
        double *pr = mxGetPr(prhs[2]);
        newValue = *pr;
    }
    mexPrintf("setting value of property %s to %f\n", propName, newValue);
    *xpr = newValue;
}

Naturally, this simplistic Mex function should also be made to accept non-scalar values. This is left as an exercise to the reader.

The usage in Matlab of this mxMySetProperty function is super simple:

% Update obj.x from 3 => pi/2
>> mxMySetProperty(s,'x',pi/2);
existing value of property x = 3.000000
setting value of property x to 1.570796
 
% Update obj.y from 4 => -5
>> mxMySetProperty(s,'y',-5);  % here we can also use obj instead of s since obj.y is accessible
existing value of property y = 4.000000
setting value of property y to -5.000000
 
% Check that the struct copy has been updated correctly
>> s
s = 
    y: -5
    x: 1.5707963267949
 
% Check that the original object's private properties have been updated correctly
>> obj
obj = 
  MyClass with properties:
 
    y: -5
 
>> obj.isPropEqualTo('x',pi/2)
ans =
    1     % ==true

Jim Tursa has promised to supply a mxSetPropertyPtr variant of his mxGetPropertyPtr for the past two years (1,2,3,4). It will surely be more robust than my simplistic mxMySetProperty function, so I look forward to finally seeing it on FEX!

Conclusion

With some dirty tricks and undocumented hacks, we can both get and set private-access object properties. Please don’t do this unless you have a really good reason (such as a customer breathing down your neck, who doesn’t give a fig that his properties were declared private…).

The mechanism shown above can also be used to improve performance when updating public object properties, since it updates the data in-place rather than create a copy. This could be significant when the property size is very large (multi-MB), since it avoids unnecessary memory allocation and deallocation. You might think that with public properties we could use the standard mxGetProperty for this, but as I said above this function apparently returns a copy of the data, not a direct reference. Also note that last month I discussed additional performance aspects of accessing object properties.

This blog will now take a short break for the holidays. I hope you had a good ride this year, see you again on the other side of 2013.

Merry Christmas and happy New-Year everybody!

 
Related posts:
  1. Performance: accessing handle properties Handle object property access (get/set) performance can be significantly improved using dot-notation. ...
  2. getundoc – get undocumented object properties getundoc is a very simple utility that displays the hidden (undocumented) properties of a specified handle object....
  3. Class object creation performance Performance aspects of Matlab class object creation are discussed, with specific suggestions. ...
  4. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
 

2013 perspective & plans for 2014

$
0
0

With 2013 behind us and a fresh 2014 ahead, it is time again for a short look at this website’s achievements so far, and plans for the future.

I started this blog nearly five years ago, thinking it would be nice to post about a few dozen undocumented features. I had no idea whether this material would be of any use to Matlab users, and I expected the website to become just another a niche blog. In fact, I was not sure that at a rate of one article per week I would have enough content for more than a year or two.

250 posts, 2000 reader comments, and 500K unique visitors later, it is obvious that I underestimated the impact that this blog would make. My pipeline of future articles continues to grow along with all other measurable quantities of website traffic.

Stats for nerds (and potential advertisers…)

Interest in this website still grows steadily, continuing the trend from the past years. To date, 514,400 unique readers have read at least one article here (two on average), in almost a million different visits, reaching over 8000 unique visits (plus ~2000 RSS and email subscribers) per week. These figures are about 60% up from last year, so the upward trend continues although at a slightly lower pace than previously. In the following graph, the traffic dips are due to the annual December holidays and the site-overhaul in 2011. The growth trend is quite evident:

Steady readership growth (click for details)

Steady readership growth (click for details)


How significant are the absolute numbers? I believe that my 2012 analysis remains valid, so please refer there.

2013 in review

In 2013, I published 47 articles, including:

As can be seen, quite a few posts deal with performance, which is one of my favorite topics, and the topic of my upcoming second book, MATLAB Performance Tuning, which I hope to publish this autumn. I originally planned to publish it in early 2014 but research has steadily tripled the book size, from the envisioned 250 pages to nearly 800 (the CRC webpage still reflects the lower page-count). There’s a ton of new material in there, and it took me time to process and write. Anyway, I expect to post more articles on this topic in 2014.

Guest bloggers

2013 continued the trend in previous years of hosting articles by guest bloggers:

I am very pleased at the growing list of guest bloggers. If you have any Matlab topic with an undocumented twist, I will be happy to post your contents here as well. Don’t be shy – email me (altmany at gmail) and I’ll help with the details.

Public events

In 2013 I was graciously invited by MathWorks and its country representatives to speak at 4 public events, of which I attended three. All events focused on my recent work on Matlab applications for finance and trading. I presented a real-time trading demo in two physical and one virtual Matlab conferences. Interested readers can see a recorded webinar of the presentation. Note that my participation in the MathWorks events does not constitute any official endorsement by MathWorks for my work. I would like to think that it at least acknowledges that I provide some benefit to the community by showing how Matlab can be used for real-life trading applications.

Plans for 2014

I plan to continue posting about undocumented aspects of Matlab. Specific plans include the much-overdue article on checkClass (this is a promise from last year that I failed to deliver, sorry…). I also hope to cross out additional items in my TODO list. Two mini-series that I hope to get around to, are about Matlab-database connectivity and Matlab’s new toolstrip/ribbon (again undelivered promises…).

Concurrently with the posts, I will continue to provide professional Matlab consulting and contract work for clients. If you have an interesting project that could use professional Matlab programming, please let me know.

Training

Finally, I plan to continue Matlab training courses/seminars. The upcoming event is in London in March 10-14. I plan two separate courses:

This is a unique opportunity to enhance your Matlab skills in a few days, at an affordable cost, by an established expert. This training is not provided anywhere else. If you have a specific topic that you would like me to discuss, then I would be happy to do it. In other words, I can customize the training to your specific needs, within the provided framework. More details on my training can be found here.

If you are interested in the London courses or a private dedicated course, please Email me (altmany at gmail dot com) for details.

Happy 2014 everybody!

- Yair Altman

 
Related posts:
  1. 2012 perspective & plans for 2013 2012 has seen a continued steady growth in website content and readership. This post takes an overview of past achievements and future plans. ...
  2. 2011 perspective & plans for 2012 2011 has seen a continued steady growth in readership of this website. This post takes an overview of past achievements and future plans. ...
  3. 2010 perspective & plans for 2011 2009 and 2010 have seen steady growth in readership of this website. This post takes an overview of past achievements and future plans....
  4. New York City visit, 21-24 May 2013 I will be visiting New York 21-24 May 2013 to speak at the Matlab Computational Finance Conference. ...
 

MathWorks blogs facelift

$
0
0

For those of you who have not noticed, MathWorks has made a very nice facelift to its official blogs section on Matlab Central (there are also some unofficial internal blogs, but they are unfortunately not publicly accessible).

If you have not done so already, I encourage you to browse the available blogs and subscribe – some very interesting content has accumulated there, and continues to be added a few times each month. I follow these blogs closely, and have learned quite a bit from them over the years.

No official announcement has been released yet AFAIK. However, I expect (at the very least) a post about this in the next few days in the “Matlab Spoken Here” blog (formerly the Desktop or Community blog). If and when it is posted, I encourage you to post a comment there, letting MathWorks know what you think of the new look-&-feel. Until then, this remains an undocumented feature [ he he :-) ] and you can leave your comments below…

Don’t let this stop you from subscribing to this blog – simply click the RSS button or subscription link at the top of this webpage to get the latest undocumented article delivered to you via email or reader, once a week. And guess what? it’s completely free… In the meantime, enjoy the following earth-shattering archaeological find that I found in some online archive:

Prehistorical Matlab blog from Draa River

Prehistorical Matlab blog from Draa River
note the incomplete formula (left) and the simplistic plot figure (right)

 
Related posts:
  1. Docs of old Matlab releases MathWorks recently posted archived documentation for many previous Matlab releases...
  2. Removing user preferences from deployed apps An unsupported MathWorks Technical Solution explains how to remove private information from deployed (compiled) matlab applications. ...
  3. Spicing up Matlab uicontrol tooltips Matlab uicontrol tooltips can be spiced-up using HTML and CSS, including fonts, colors, tables and images...
  4. BlinkDagger – the end? In his latest post on BlinkDagger, Quan Quach announced that the BlinkDagger blog will be frozen following co-author Daniel Sutoyo’s hiring by The MathWorks and the continuous strain of maintaining...
 

Serializing/deserializing Matlab data

$
0
0

Last year I wrote an article on improving the performance of the save function. The article discussed various ways by which we can store Matlab data on disk. However, in many cases we are interested in a byte-stream serialization, in order to transmit information to external processes.

The request to get a serialized byte-stream of Matlab data has been around for many years (example), but MathWorks has never released a documented way of serializing and unserializing data, except by storing onto a disk file and later loading it from file. Naturally, using a disk file significantly degrades performance. We could always use a RAM-disk or flash memory for improved performance, but in any case this seems like a major overkill to such a simple requirement.

In last year’s article, I presented a File Exchange utility for such generic serialization/deserialization. However, that utility is limited in the types of data that it supports, and while it is relatively fast, there is a much better, more generic and faster solution.

The solution appears to use the undocumented built-in functions getByteStreamFromArray and getArrayFromByteStream, which are apparently used internally by the save and load functions. The usage is very simple:

byteStream = getByteStreamFromArray(anyData);  % 1xN uint8 array
anyData = getArrayFromByteStream(byteStream);

Many Matlab functions, documented and undocumented alike, are defined in XML files within the %matlabroot%/bin/registry/ folder; our specific functions can be found in %matlabroot%/bin/registry/hgbuiltins.xml. While other functions include information about their location and number of input/output args, these functions do not. Their only XML attribute is type = ":all:", which seems to indicate that they accept all data types as input. Despite the fact that the functions are defined in hgbuiltins.xml, they are not limited to HG objects – we can serialize basically any Matlab data: structs, class objects, numeric/cell arrays, sparse data, Java handles, timers, etc. For example:

% Simple Matlab data
>> byteStream = getByteStreamFromArray(pi)  % 1x72 uint8 array
byteStream =
  Columns 1 through 19
    0    1   73   77    0    0    0    0   14    0    0    0   56    0    0    0    6    0    0
  Columns 20 through 38
    0    8    0    0    0    6    0    0    0    0    0    0    0    5    0    0    0    8    0
  Columns 39 through 57
    0    0    1    0    0    0    1    0    0    0    1    0    0    0    0    0    0    0    9
  Columns 58 through 72
    0    0    0    8    0    0    0   24   45   68   84  251   33    9   64
 
>> getArrayFromByteStream(byteStream)
ans =
          3.14159265358979
 
% A cell array of several data types
>> byteStream = getByteStreamFromArray({pi, 'abc', struct('a',5)});  % 1x312 uint8 array
>> getArrayFromByteStream(byteStream)
ans = 
    [3.14159265358979]    'abc'    [1x1 struct]
 
% A Java object
>> byteStream = getByteStreamFromArray(java.awt.Color.red);  % 1x408 uint8 array
>> getArrayFromByteStream(byteStream)
ans =
java.awt.Color[r=255,g=0,b=0]
 
% A Matlab timer
>> byteStream = getByteStreamFromArray(timer);  % 1x2160 uint8 array
>> getArrayFromByteStream(byteStream)
 
   Timer Object: timer-2
 
   Timer Settings
      ExecutionMode: singleShot
             Period: 1
           BusyMode: drop
            Running: off
 
   Callbacks
           TimerFcn: ''
           ErrorFcn: ''
           StartFcn: ''
            StopFcn: ''
 
% A Matlab class object
>> byteStream = getByteStreamFromArray(matlab.System);  % 1x1760 uint8 array
>> getArrayFromByteStream(byteStream)
ans = 
  System: matlab.System

Serializing HG objects

Of course, we can also serialize/deserialize also HG controls, plots/axes and even entire figures. When doing so, it is important to serialize the handle of the object, rather than its numeric handle, since we are interested in serializing the graphic object, not the scalar numeric value of the handle:

% Serializing a simple figure with toolbar and menubar takes almost 0.5 MB !
>> hFig = handle(figure);  % a new default Matlab figure
>> length(getByteStreamFromArray(hFig))
ans =
      479128
 
% Removing the menubar and toolbar removes much of this amount:
>> set(hFig, 'menuBar','none', 'toolbar','none')
>> length(getByteStreamFromArray(hFig))
ans =
       11848   %!!!
 
% Plot lines are not nearly as "expensive" as the toolbar/menubar
>> x=0:.01:5; hp=plot(x,sin(x));
>> byteStream = getByteStreamFromArray(hFig);
>> length(byteStream)
ans =
       33088
 
>> delete(hFig);
>> hFig2 = getArrayFromByteStream(byteStream)
hFig2 =
	figure

The interesting thing here is that when we deserialize a byte-stream of an HG object, it is automatically rendered onscreen. This could be very useful for persistence mechanisms of GUI applications. For example, we can save the figure handles in file so that if the application crashes and relaunches, it simply loads the file and we get exactly the same GUI state, complete with graphs and what-not, just as before the crash. Although the figure was deleted in the last example, deserializing the data caused the figure to reappear.

We do not need to serialize the entire figure. Instead, we could choose to serialize only a specific plot line or axes. For example:

>> x=0:0.01:5; hp=plot(x,sin(x));
>> byteStream = getByteStreamFromArray(handle(hp));  % 1x13080 uint8 array
>> hLine = getArrayFromByteStream(byteStream)
ans =
	graph2d.lineseries

This could also be used to easily clone (copy) any figure or other HG object, by simply calling getArrayFromByteStream (note the corresponding copyobj function, which I bet uses the same underlying mechanism).

Also note that unlike HG objects, deserialized timers are NOT automatically restarted; perhaps the Running property is labeled transient or dependent. Properties defined with these attributes are apparently not serialized.

Performance aspects

Using the builtin getByteStreamFromArray and getArrayFromByteStream functions can provide significant performance speedups when caching Matlab data. In fact, it could be used to store otherwise unsupported objects using the save -v6 or savefast alternatives, which I discussed in my save performance article. Robin Ince has shown how this can be used to reduce the combined caching/uncaching run-time from 115 secs with plain-vanilla save, to just 11 secs using savefast. Robin hasn’t tested this in his post, but since the serialized data is a simple uint8 array, it is intrinsically supported by the save -v6 option, which is the fastest alternative of all:

>> byteStream = getByteStreamFromArray(hFig);
>> tic, save('test.mat','-v6','byteStream'); toc
Elapsed time is 0.001924 seconds.
 
>> load('test.mat')
>> data = load('test.mat')
data = 
    byteStream: [1x33256 uint8]
>> getArrayFromByteStream(data.byteStream)
ans =
	figure

Finally, note that as built-in functions, these functions could change without prior notice on any future Matlab release.

MEX interface – mxSerialize/mxDeserialize

To complete the picture, MEX includes a couple of undocumented functions mxSerialize and mxDeserialize, which correspond to the above functions. I assume that getByteStreamFromArray and getArrayFromByteStream call them internally. Back in 2007, Brad Phelan wrote a MEX wrapper that could be used directly in Matlab (mxSerialize.c, mxDeserialize.c). The C interface was very simple, and so was the usage:

#include "mex.h"
 
EXTERN_C mxArray* mxSerialize(mxArray const *);
EXTERN_C mxArray* mxDeserialize(const void *, size_t);
 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if (nlhs && nrhs) {
          plhs[0] = (mxArray *) mxSerialize(prhs[0]);
        //plhs[0] = (mxArray *) mxDeserialize(mxGetData(prhs[0]), mxGetNumberOfElements(prhs[0]));
    }
}

Unfortunately, MathWorks has removed the C interface for these functions from libmx in R2014a, keeping only their C++ interfaces (If you have ever used these C++ interfaces, please leave a comment below):

mxArray* matrix::detail::noninlined::mx_array_api::mxSerialize(mxArray const *anyData)
mxArray* matrix::detail::noninlined::mx_array_api::mxDeserialize(void const *byteStream, unsigned __int64 numberOfBytes)
mxArray* matrix::detail::noninlined::mx_array_api::mxDeserializeWithTag(void const *byteStream, unsigned __int64 numberOfBytes, char const* *tagName)

The roundabout alternative is of course to use mexCallMATLAB to invoke getByteStreamFromArray and getArrayFromByteStream. This is actually rather silly, but it works…

These are not the only MEX functions that were removed from libmx in R2014a. Hundreds of other C functions were also removed with them, some of them quite important. A few hundred new C++ functions were added in their place, but I fear that these are not readily accessible to MEX users. libmx has always changed between Matlab releases, but not so drastically for many years. If you rely on any undocumented MEX functions in your code, now would be a good time to recheck it, before R2014a is officially released.

p.s. – Happy 30th anniversary, MathWorks!

 
Related posts:
  1. Controlling plot data-tips Data-tips are an extremely useful plotting tool that can easily be controlled programmatically....
  2. Draggable plot data-tips Matlab's standard plot data-tips can be customized to enable dragging, without being limitted to be adjacent to their data-point. ...
  3. Accessing plot brushed data Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
  4. Undocumented Matlab MEX API Matlab's MEX API contains numerous undocumented functions, that can be extremely useful. ...
 

Assessing Java object size in Matlab

$
0
0

Have you noticed that all Java object references are displayed as using 0 bytes in the Matlab Workspace browser and the whos function? This is not a bug, but in fact a deliberate design decision, in order to avoid the need to calculate the deep-memory usage of Java references (i.e., objects that include references to other objects etc.).

Well, sometimes it so happens that we really need to know the size of the Java object, or the size difference between two objects (to help resolve memory leaks, for example). There are several resources online that explain how to do this in Matlab (examples 1, 2, 3). Today I will show two alternatives that I found useful within the context of Matlab:

ObjectProfiler

A full decade ago, Vladimir Roubtsov posted a very detailed article in the JavaWorld magazine explaining how to profile and report Java object sizes. The article contained a downloadable Java archive that we can easily use in Matlab. After downloading the zip file, extract the contained objectprofiler.jar file, add it to the Java classpath and start using it, as follows:

>> javaaddpath 'C:\path\to\where\you\placed\your\copy\of\objectprofiler.jar'
 
>> com.vladium.utils.ObjectProfiler.sizeof(java.awt.Color.red)
ans =
    28

Note that the reported sizes may be different on different Matlab releases (=JVM versions) and platforms. Also note that the reported size (28 bytes for the Java Color object) is much smaller than the size required to serialize the object into a byte stream (408 bytes in this case), as I’ve shown in last week’s article.

Running the sizeof method on deeply referenced objects could quickly exhaust Matlab’s memory:

>> jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;

% on R2012a: takes a long time and finally reports
>> com.vladium.utils.ObjectProfiler.sizeof(jDesktop)
ans =
    72011200

% on R2014a: takes a long time and finally croaks
% (which is not surprising, considering the Desktop's new toolstrip)
>> com.vladium.utils.ObjectProfiler.sizeof(jDesktop)
Java exception occurred:
java.lang.OutOfMemoryError: Java heap space
	at java.util.IdentityHashMap.resize(Unknown Source)
	at java.util.IdentityHashMap.put(Unknown Source)
	at com.vladium.utils.ObjectProfiler.computeSizeof(ObjectProfiler.java:329)
	at com.vladium.utils.ObjectProfiler.sizeof(ObjectProfiler.java:85)

ObjectProfiler has a very handy feature of enabling a visual display of the object’s reference tree. For example:

>> jObject = java.util.Hashtable
jObject =
{}
>> com.vladium.utils.ObjectProfiler.sizeof(jObject)
ans =
   105
>> com.vladium.utils.ObjectProfiler.profile(jObject).dump
ans =
  105 -> <INPUT> : Hashtable
    60 (57.1%) -> Hashtable#table : Hashtable$Entry[]
      60 (57.1%) -> <shell: Hashtable$Entry[], length=11>
    45 (42.9%) -> <shell: 6 prim/4 ref fields>

>> jObject.put('key1',1.23);
>> com.vladium.utils.ObjectProfiler.sizeof(jObject)
ans =
   189
>> com.vladium.utils.ObjectProfiler.profile(jObject).dump
ans =
  189 -> <INPUT> : Hashtable
    144 (76.2%) -> Hashtable#table : Hashtable$Entry[]
      84 (44.4%) -> Hashtable#table[4] : Hashtable$Entry
        44 (23.3%) -> Hashtable$Entry#key : String
          24 (12.7%) -> String#value : char[]
            24 (12.7%) -> <shell: char[], length=4>
          20 (10.6%) -> <shell: 2 prim/1 ref fields>
        24 (12.7%) -> <shell: 1 prim/3 ref fields>
        16 (8.5%) -> Hashtable$Entry#value : Double
          16 (8.5%) -> <shell: 1 prim/0 ref fields>
      60 (31.7%) -> <shell: Hashtable$Entry[], length=11>
    45 (23.8%) -> <shell: 6 prim/4 ref fields>

As we can see, adding the 'key1' key to the hashtable object actually added 2 new references: a 44-byte String and a 16-byte Double, plus 24 additional overhead bytes, for a total addition of 84 bytes.

ObjectProfiler has a convenience method sizedelta(jObject1,jObject2) which returns the size delta in bytes between the two specified objects. There are a few additional methods for ObjectProfiler and the ObjectProfiler.profile() object – interested readers are referred to the original article and to the source code (which is included within the zip file that we downloaded).

Classmexer

The Classmexer utility works a bit differently but is also very easy to use once the initial setup is done. First we need to download the zip file, then extract the classmexer.jar and place it in your Matlab’s startup folder. In that same folder, edit (create if necessary) a java.opts file with the following line:

-javaagent:classmexer.jar

After restarting Matlab, we can use Classmexer as follows:

>> com.javamex.classmexer.MemoryUtil.deepMemoryUsageOf(java.awt.Color.red)
ans =
    32
 
>> jObject = java.util.Hashtable;
>> com.javamex.classmexer.MemoryUtil.deepMemoryUsageOf(jObject)
ans =
   120
>> jObject.put('key1',1.23); jObject
jObject =
{key1=1.23}
>> com.javamex.classmexer.MemoryUtil.deepMemoryUsageOf(jObject)
ans =
   264

Note how the values reported by Classmexer differ from those of ObjectProfiler. To tell the truth, I’m not sure which of them to believe: ObjectProfiler seems more detailed, but Classmexer uses Java’s preferred mechanism of using an instrumentation agent.

We can also use java.lang.Runtime.getRuntime‘s methods (maxMemory(), freeMemory() and totalMemory()) to monitor overall Java memory (note a MathWorks blog article on this). Note that this reports the total memory values, and fluctuates (sometimes dramatically) from second to second, as Matlab’s desktop and other Java-heavy tools create Java objects, which the JVM garbage-collects.

Jeff Gullet has suggested to monitor these values and programmatically activate a synchronous Java garbage-collection when the memory appears too “crowded” (I fixed Jeff’s posted idea in the snippet below):

r = java.lang.Runtime.getRuntime;
if (r.freeMemory/r.totalMemory) < 0.1
    r.gc();
end

A MathWorks technical article provided some assistance on using the JConsole utility to profile Java memory in Matlab. We can also use the JMap and JHat utilities. All these utilities are part of the free Java Development Kit (JDK) that can be downloaded online, just ensure you’re using the same Java version as reported by Matlab:

>> version -java
ans =
Java 1.7.0_11-b21   % i.e., Java 7 update 11

In addition to the JDK tools, I find the open-source JVisualVM utility informative and easy to use. We can also use JMP (R2007a and earlier), TIJMP (R2007b and later), or other 3rd-party tools. A list of Java-centric resources is available in the Java SE Troubleshooting guide.

To complete the picture, a couple of years ago I posted an article on profiling Matlab's memory usage, which included a section on Java memory. You may also find useful another article I wrote, on finding and fixing a Java memory leak in Matlab.

 
Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  2. Matlab-Java memory leaks, performance Internal fields of Java objects may leak memory - this article explains how to avoid this without sacrificing performance. ...
  3. Using Java Collections in Matlab Java includes a wide selection of data structures that can easily be used in Matlab programs - this article explains how. ...
  4. Matlab-Java book Undocumented Secrets of Matlab-Java Programming (ISBN 9781439869031) is a book dedicated to the integration of Matlab and Java. ...
 

Undocumented button highlighting

$
0
0

One of my consulting clients approached me yesterday with a mystery: In his GUIDE-generated GUI, one of the buttons had a bluish tint, and no obvious property seemed to control this or to differentiate it from its sibling controls. Here’s a parred-down version of his GUI:

Highlighted GUI button

Highlighted GUI button

So while it was very nice to have a highlighted button in this manner, the fact that he did not know why it happened and how to control it was a bit unsettling. Which is where I came in, and it turns out that the solution to the mystery is simple and very easy to use. My client now happily switches button highlights on and off, just for the fun of it…

Before I describe the solution (spoiler alert: scroll down), I think it is instructional to understand the unsuccessful attempts, so here goes:

Various alternatives

Our first attempts to understand the situation were to modify the button control’s obvious suspect properties:

  • String – the button had an HTML label. One might presume that this caused the highlighting tint, perhaps an HTML image painted the background? HTML labels for uicontrols are really cool so it would be a pity to have to stop using them. Fortunately, replacing the HTML label with a simple string had no effect, so we can keep using HTML labels safely and freely. But we’re still left with our mystery, so moving on…
  • Border – yet another suspect: the control’s border and fly-over appearance feature affects its appearance. This also proved a dead-end: all the buttons had simple default borders, nothing special about the highlighted one.
  • Background – another dead end: while we could indeed set a non-standard button color, this property does not enable the tinting effect (lighter half at top, darker at bottom). Needless to say, in our case this property had the default (gray) value.
  • Selected – this property does not really highlight the control, but rather draws a thick dashed border around it (see below).
  • focus – by calling uicontrol(hButton) we can have Matlab set the focus on the button. The Operating System then automatically kicks in to add some shading effect. This finally looked close, but again, it was just not quite right.

Highlight (left); focus (center); Selected (right)

Highlight (left); focus (center); Selected (right)

Solution of the highlighting mystery

So maybe GUIDE attached some funky property value to the control? Let’s investigate. Remembering that the GUIDE-generated *.fig file is simply a standard MAT file with a different extension, we can load it into the Matlab workspace and dissect it. Drilling down the GUI hierarchy we find:

>> data = load('myGUI.fig', '-mat')
data = 
    hgS_070000: [1x1 struct]
 
>> d.hgS_070000.children(9).properties
ans = 
              Units: 'pixels'
           Callback: [function_handle]
           Position: [20 20 60 20]
             String: 'Yes'
              Value: 1    ApplicationData: [1x1 struct]
>> d.hgS_070000.children(10).properties
ans = 
              Units: 'pixels'
           Callback: [function_handle]
           Position: [100 20 60 20]
             String: 'No'
    ApplicationData: [1x1 struct]

When we compare the information that GUIDE stored for the two buttons we see that it stored an extra Value property for the ‘Yes’ button, and used the default HG value for the ‘No’ button. Let’s compare the property values in run-time (I’m using my objDiff utility for this):

>> hButton1 = findall(gcf, 'String', 'Yes');
>> hButton2 = findall(gcf, 'String', 'No');
>> props1 = get(hButton1);
>> props2 = get(hButton2);
>> objdiff(props1, props2)
ans = 
      Extent: {[0 0 24 19]  [0 0 17 19]}
    Position: {[20 20 60 20]  [100 20 60 20]}
      String: {'Yes'  'No'}
       Value: {[1]  [0]}

This pretty much nails it: pushbutton highlighting is controlled via the Value property. According to the official documentation, the Value property has no meaning for push-buttons, only for other uicontrol styles. This is obviously not so:

set(hButton, 'Value', 1);   % Turn button highlighting on
set(hButton, 'Value', 0);   % Turn button highlighting off (can use any value ~=1)

Under the hood

Under the hood, updating the Value property sets the pushbutton’s underlying Java control‘s Selected property to true. Note that the Java Selected property is entirely unrelated to Matlab’s Selected property (which has no underlying Java counterpart). I do not understand the design decision that let to this, but since it has been like this for many years I see little chance that it will be changed in the near future.

In any case, the Java Selected property indeed has a visual effect, but the actual effect depends on the current operating system and Look-&-Feel (LnF). You can play around with the LnF to achieve various other alternative highlighting effects, or customize one of your own.

Advanced Matlab GUI course – London 12-14 March, 2014

If this topic has piqued your interest, consider joining my Advanced Matlab GUI course in London on 12-14 March, 2014. In this course/seminar I will explore numerous other ways by which we can customize Matlab’s GUI and graphics in ways that you never knew were even possible! This is a unique opportunity to take your Matlab skills to a higher level within just a few days. This training is not offered anywhere else.

 
Related posts:
  1. Borderless button used for plot properties A borderless button can be used to add unobtrusive functionality to plot axes...
  2. Button customization Matlab's button uicontrols (pushbutton and togglebutton) are basically wrappers for a Java Swing JButton object. This post describes how the buttons can be customized using this Java object in ways...
  3. uiundo – Matlab’s undocumented undo/redo manager The built-in uiundo function provides easy yet undocumented access to Matlab's powerful undo/redo functionality. This article explains its usage....
  4. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
 

Improving Simulink performance

$
0
0

A few days ago I happened to speak with a colleague about Simulink run-time performance, and we discussed various ideas for simulation speed-up. This topic is very important to MathWorks, as evidenced by a dedicated documentation section, newsletter articles (1, 2), webinars (1, 2, 3, 4) and multiple blog posts on improving simulation performance using the Simulink product.

This blog covers mainly the Matlab core product and closely-related toolboxes. However, since the various suggestions for improving performance are spread across so many resources, I thought that it would be worthwhile to create a post listing all the suggestions in a single place. When faced with a slow simulation, it’s nice to know that there are so many available speed-up options, so I hope readers will find it useful. Note that these suggestions are in the large part fully documented and supported. The ideas are listed based on semantic relationship, and not by order of importance:

  • Select Accelerator or Rapid Accelerator simulation mode (also see here)
  • Enable the options for Compiler optimization, automatic Block Reduction and others in the Optimization pane of the Configuration Parameters window.
  • Switch the Compiler optimization from faster build to faster run.
  • Disable the options for debugging/animation support, overflow detection and echoing expressions without semicolons in the Simulation Target pane of the Configuration Parameters window. Note that overflow detection is important for fixed-point data so if your model includes FP data, keep this option enabled.
  • Disable similar configuration options in Stateflow’s Configuration Parameters window (which is similar but separate from the Simulink window).
  • Keep Stateflow charts and Simulink blocks/models closed during simulation to prevent run-time updates (this relates to the animation feature, if enabled)
  • Keep output scopes closed during simulation run-time; open the scopes only after the simulation ends. If a scope must remain open in run-time, reduce the number of data points (via decimation, reduced time range and reduced number of plotted signals), increase the plotting refresh period, disable scope scrolling, remove data markers and legends, limit the history size, and use reduced fidelity in the viewer parameters. A similar recommendation applies to regular Matlab plots, by the way.
  • Vectorize processing by combining multiple signals into a vector and applying the processing on the vector rather than on the separate signals.
  • Sample data in batches (rather than one-by-one) using frame-based processing (R2011b and newer). This can speed up simulations by 10x or more, at the expense of just a little extra memory.
  • Aggregate small blocks into larger ones.
  • Load the model in memory using load_system instead of open_system and simulate it using the sim command, then post process/display the outputs.
  • Avoid blocks that do not support code generation, since they would have to be run in slower interpreted mode.
  • If your simulation does not use linear algebra (matrix arithmetic), disable BLAS library support in the Simulation Target pane. But if it does use it, then ensure that BLAS is enabled for optimal performance.
  • Avoid algebraic loops where possible.
  • Avoid Matlab S-Function and Interpreted Matlab Function blocks. Instead, use Matlab Function, System and C-MEX blocks.
     

    Note: IMHO, the naming of these blocks is quite confusing: Matlab Function refers to a subset of the Matlab language previously called Embedded Matlab that can be directly converted into C-code without requiring the Matlab run-time (MCR); this is basically the language subset used by the Matlab Coder Toolbox. Interpreted Matlab Function refers to the full Matlab functionality and requires the Matlab run-time (MCR) – it was previously called Matlab Function.
  • Reduce, simplify or eliminate initialization and termination phases.
  • Use the Mask Editor to reduce block images resolution and size.
  • Store configurations in loadable MAT files rather than programmatically.
  • Consolidate multiple set_param calls into a single call having several name / value pairs.
  • Use a stronger platform (esp. increase the amount of memory).
  • Limit or disable log output, and disk I/O in general.
  • Use the sldiagnostics and slprofreport functions and the Simulink Profiler, to identify and eliminate simulation bottlenecks.
  • Use the performanceadvisor function and the Simulink Model Performance Advisor to automatically adjust model configurations for best performance (R2012b and newer; also see this webinar).
  • Manually adjust model solver parameters for optimal performance, based on a-priori knowledge about the model behavior.
  • Use a faster solver that can still process the model. Different models may require different solvers to run optimally (also see here).
  • Tune solver parameters (decrease solver order, increase step size and error tolerance) to improve solution convergence speed at the expense of some accuracy. One user reported a 20x speedup by simply increasing the step-size.
  • Prevent excessive zero-crossing or disable zero-crossing detection (also see here and here).
  • Use simpler models or models with reduced fidelity.
  • Store the simulation state at specific points, then load these states for repeated later simulations, thus saving the simulation time of the loaded portion.
  • Run simulations in parallel using Parallel Computing Toolbox (also see here, here and here). An easy way to do this is to run the sim command within a parfor loop.
  • Move some calculations onto FPGA or GPU.
  • Use a real-time system and set simulation speed to real-time (high priority).

Some additional ideas can be found in the blog posts and webinars mentioned in the hyperlinks at the top of this post. One of the newsletter articles concludes with an example of how applying some of these techniques to a specific model resulted in reduced simulation time, from 453 down to 5 seconds.

I would like to take this opportunity to congratulate MathWorks on a job well done with Simulink’s Performance Advisor. I expect a variant of this tool to be available for regular Matlab m-code in some future Matlab release; it would blend in nicely with the existing mlint (Code Analyzer) tool.

Advanced Matlab Programming course – London 10-11 March, 2014

If this topic has piqued your interest, consider joining my Advanced Matlab Programming course in London on 10-11 March, 2014. In this course/seminar I will explore numerous other ways by which we can improve Matlab’s performance and create professional code. This is a unique opportunity to take your Matlab skills to a higher level within a couple of days.

 
Related posts:
  1. Improving save performance There are many different ways of improving Matlab's standard save function performance. ...
  2. Improving fwrite performance Standard file writing performance can be improved in Matlab in surprising ways. ...
  3. Plot performance Undocumented inner plot mechanisms can be used to significantly improved plotting performance...
  4. Performance: scatter vs. line In many circumstances, the line function can generate visually-identical plots as the scatter function, much faster...
 

Explicit multi-threading in Matlab – part 1

$
0
0

One of the limitations of Matlab already recognized by the community, is that it does not provide the users direct access to threads without the PCT (Parallel Computing Toolbox). For example, letting some expensive computations or I/O to be run in the background without freezing the main application. Instead, in Matlab there is either implicit multiprocessing which relies on built-in threading support in some MATLAB functions, or explicit multiprocessing using PCT (note: PCT workers use heavyweight processes, not lightweight threads). So the only way to achieve truly multi-threading in Matlab is via MEX, Java or .Net, or by spawning external standalone processes.

Note that we do not save any CPU cycles by running tasks in parallel. In the overall balance, we actually increase the amount of CPU processing, due to the multi-threading overhead. However, in the vast majority of cases we are more interested in the responsivity of Matlab’s main processing thread (known as the Main Thread, Matlab Thread, or simply MT) than in reducing the computer’s total energy consumption. In such cases, offloading work to asynchronous C++, Java or .Net threads could remove bottlenecks from Matlab’s main thread, achieving significant speedup.

Today’s article is a derivative of a much larger section on explicit multi-threading in Matlab, that will be included in my upcoming book MATLAB Performance Tuning, which will be published later this year.

Sample problem

In the following example, we compute some data, save it to file on a relatively slow USB/network disk, and then proceed with another calculation. We start with a simple synchronous implementation in plain Matlab:

tic
data = rand(5e6,1);  % pre-processing, 5M elements, ~40MB
fid = fopen('F:\test.data','w');
fwrite(fid,data,'double');
fclose(fid);
data = fft(data);  % post-processing
toc
 
Elapsed time is 9.922366 seconds.

~10 seconds happens to be too slow for our specific needs. We could perhaps improve it a bit with some fancy tricks for save or fwrite. But let’s take a different approach today, using multi-threading:

Using Java threads

Matlab uses Java for numerous tasks, including networking, data-processing algorithms and graphical user-interface (GUI). In fact, under the hood, even Matlab timers employ Java threads for their internal triggering mechanism. In order to use Java, Matlab launches its own dedicated JVM (Java Virtual Machine) when it starts (unless it’s started with the -nojvm startup option). Once started, Java can be directly used within Matlab as a natural extension of the Matlab language. Today I will only discuss Java multithreading and its potential benefits for Matlab users: Readers are assumed to know how to program Java code and how to compile Java classes.

To use Java threads in Matlab, first create a class that implements the Runnable interface or extends java.lang.Thread. In either case we need to implement at least the run() method, which runs the thread’s processing core.

Now let us replace the serial I/O with a very simple dedicated Java thread. Our second calculation (fft) will not need to wait for the I/O to complete, enabling much faster responsiveness on Matlab’s MT. In this case, we get a 58x (!) speedup:

tic
data = rand(5e6,1);  % pre-processing (5M elements, ~40MB)
javaaddpath 'C:\Yair\Code\'  % path to MyJavaThread.class
start(MyJavaThread('F:\test.data',data));  % start running in parallel
data = fft(data);  % post-processing (Java I/O runs in parallel)
toc
 
Elapsed time is 0.170722 seconds.   % 58x speedup !!!

Note that the call to javaaddpath only needs to be done once in the entire Matlab session, not repeatedly. The definition of our Java thread class is very simple (real-life classes would not be as simplistic, but the purpose here is to show the basic concept, not to teach Java threading):

import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class MyJavaThread extends Thread
{
    String filename;
    double[] doubleData;
    public MyJavaThread(String filename, double[] data)
    {
        this.filename = filename;
        this.doubleData = data;
    }
    @Override
    public void run()
    {
        try
        {
            DataOutputStream out = new DataOutputStream(
                                     new FileOutputStream(filename));
            for (int i=0; i < doubleData.length; i++)
            {
                out.writeDouble(doubleData[i]);
            }
            out.close();
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
    }
}

Note: when compiling a Java class that should be used within Matlab, as above, ensure that you are compiling for a JVM version that is equal to, or lower than Matlab’s JVM, as reported by Matlab’s version function:

% Matlab R2013b uses JVM 1.7, so we can use JVMs up to 7, but not 8
>> version –java
ans =
Java 1.7.0_11-b21 ...

Matlab synchronization

Java (and C++/.Net) threads are very effective when they can run entirely independently from Matlab’s main thread. But what if we need to synchronize the other thread with Matlab's MT? For example, what if the Java code needs to run some Matlab function, or access some Matlab data? In MEX this could be done using the dedicated and documented MEX functions; in Java this can be done using the undocumented/unsupported JMI (Java-Matlab Interface) package. Note that using standard Java Threads without Matlab synchronization is fully supported; it is only the JMI package that is undocumented and unsupported.

Here is the relevant code snippet for evaluating Matlab code within a Java thread:

import com.mathworks.jmi.Matlab;  //in %matlabroot%/java/jar/jmi.jar
...
Matlab matlabEngine = new Matlab();
...
Matlab.whenMatlabReady(runnableClass);

Where runnableClass is a class whose run() method includes calls to com.mathworks.jmi.Matlab methods such as:

matlabEngine.mtEval("plot(data)");
Double value = matlabEngine.mtFeval("min",{a,b},1); //2 inputs 1 output

Unfortunately, we cannot directly call matlabEngine's methods in our Java thread, since this is blocked: in order to ensure synchronization Matlab only enables calling these methods from the MT, which is the reason for the runnableClass. Indeed, synchronizing Java code with MATLAB could be quite tricky, and can easily deadlock MATLAB. To alleviate some of the risk, I advise not to use the JMI class directly: use Joshua Kaplan's MatlabControl class, a user-friendly JMI wrapper.

Note that Java's native invokeAndWait() method cannot be used to synchronize with Matlab. M-code executes as a single uninterrupted thread (MT). Events are simply queued by Matlab's interpreter and processed when we relinquish control by requesting drawnow, pause, wait, waitfor etc. Matlab synchronization is robust and predictable, yet forces us to use the whenMatlabReady(runnableClass) mechanism to add to the event queue. The next time drawnow etc. is called in M-code, the event queue is purged and our submitted code will be processed by Matlab's interpreter.

Java threading can be quite tricky even without the Matlab synchronization complexity. Deadlock, starvation and race conditions are frequent problems with Java threads. Basic Java synchronization is relatively easy, using the synchronized keyword. But getting the synchronization to work correctly is much more difficult and requires Java programming expertise that is beyond most Java programmers. In fact, many Java programmers who use threads are not even aware that their threads synchronization is buggy and that their code is not thread-safe.

My general advise is to use Java threads just for simple independent tasks that require minimal interactions with other threads, Matlab engine, and/or shared resources.

Additional alternatives

In addition to Java threads, we can use other technologies for multi-threading in Matlab: Next week's article will explore Dot-Net (C#) threads and timers, and that will be followed by a variety of options for C++ threads and spawned-processes IPC. So don't let anyone complain any longer about not having multi-threading in Matlab. It's not trivial, but it's also not rocket science, and there are plenty of alternatives out there.

Still, admittedly MT's current single-threaded implementation is a pain-in-the-so-and-so, relic of a decades-old design. A likely future improvement to the Matlab M-code interpreter would be to make it thread-safe. This would enable automatic conversion of for loops into multiple threads running on multiple local CPUs/cores, significantly improving Matlab's standard performance and essentially eliminating the need for a separate parfor in PCT (imagine me drooling here). Then again, this might reduce PCT sales...

Advanced Matlab Programming course – London 10-11 March, 2014

If Matlab performance interests you, consider joining my Advanced Matlab Programming course in London on 10-11 March, 2014. In this course/seminar I will explore numerous other ways by which we can improve Matlab's performance and create professional code. This is a unique opportunity to take your Matlab skills to a higher level within a couple of days. Registration closes this Friday, so don't wait too long.

 
Related posts:
  1. Multi-line tooltips Multi-line tooltips are very easy to set up, once you know your way around a few undocumented hiccups....
  2. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
  3. Multi-column (grid) legend This article explains how to use undocumented axes listeners for implementing multi-column plot legends...
  4. JMI wrapper – local MatlabControl part 2 An example using matlabcontrol for calling Matlab from within a Java class is explained and discussed...
 

Explicit multi-threading in Matlab – part 2

$
0
0

Last week, I explained how we can start asynchronous Java threads to run in parallel to the main Matlab processing. Today I continue the series by examining .Net threads. Next week I will discuss C++ threads, followed by a final article on timers and process-spawning.

I continue using last week’s example, where we compute some data, save it to file on a relatively slow USB/network disk, and then proceed with another calculation. The purpose of multi-threading would be to offload the I/O onto a separate thread, so that the Matlab computation can continue in parallel without needing to wait for the slow I/O.

Dot-Net (.Net), like Java and C++, also enables multithreading. .Net libraries (assemblies) are commonly distributed as DLL files, which can be loaded into Matlab using the NET.addAssembly function, similarly to the javaaddpath function for Java classes. Using these assemblies in Matlab is then as straight-forward as in Java:

NET.addAssembly('C:\Yair\Code\NetThread.dll');
data = rand(5e6,1);  % pre-processing (5M elements, ~40MB)
start(My.NetThread('F:\test.data',data));  % start running in parallel
data = fft(data);  % post-processing (.Net I/O runs in parallel)

As with Java, the assembly only needs to be loaded once per Matlab session, not repeatedly. The definition of the .Net class closely follows that of the Java class. Unfortunately, .Net’s System.Threading.Thread class is sealed (non-inheritable), so we cannot extend it as we did in Java. However, we can instantiate an internal Thread object within our class and use it. Here is the corresponding C# source code (thanks to Ronnie Shmuel who assisted):

using System;
using System.IO;
using System.Threading;
namespace My
{
    public class NetThread
    {
        string filename;
        double[] doubleData;
        Thread thread;
        public NetThread(string filename, double[] data)
        {
            this.filename = filename;
            this.doubleData = data;
            thread = new Thread(this.run);
        }
        public void start()
        {
            thread.Start();  // note the capital S in Start()
        }
        private void run()
        {
            try
            {
                BinaryWriter out = new BinaryWriter(
                                   File.Open(filename,FileMode.Create))
                for (int i = 0; i < doubleData.Length; i++)
                {
                    out.Write(doubleData[i]);
                }
                out.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

Note that C# Thread uses the Start() method (uppercase S), unlike java.lang.Thread that uses start() (lowercase s). Also, while java.lang.Thread.start() always invokes a run() method (the “run” name is predefined), C# Thread.Start() can invoke any delegate method. In this example I chose to name it run() for consistency with the Java example, but in fact I could have named it anything else.

In this example I’ve used C# source code, but in fact I could also use C++, F# or VB code, since the System.Threading.Thread class behaves very similarly in all of them. Once we compile it in our favorite compiler [hmmm, Microsoft Visual Studio anyway...], the resulting .Net assembly aught to work exactly the same in Matlab.

Compatibility and synchronization

Unlike Java and C++, .Net is not platform-independent: it only works on Windows, so if we need a cross-platform solution then we need to use Java or one of the other alternatives.

Also note that the .Net solution will only work on platforms that installed .Net of a supporting .Net version (Framework). .Net is commonly installed on Win7+, but not for example on XP. On Windows platforms where .Net is not installed, we need to download and install it before we can use any .Net features (duh!). To ensure .NET is supported on our current platform, use the NET.isNETSupported function:

>> NET.isNETSupported  % returns true/false
ans =
     1

As with Java, when compiling a .Net class that should be used within Matlab, we must ensure that we are compiling for a .Net Framework that is equal to or lower than what Matlab will actually use in the target platform, as reported by System.Environment.Version:

% My system uses .Net 4.0, so we should compile for .Net 4.0, not 4.5
>> char(System.Environment.Version.ToString)
ans =
4.0.30319.18034

As with Java threads, .Net threads are most effective when they can run independently of Matlab and of each other. I do not know of any mechanism for data synchronization between .NET threads and Matlab. However, we can use one of the standard IPC mechanisms, as I shall discuss in a future article. For example, it is possible to open a COM connection to the invoking Matlab (serving as an automation server) and then use it in the .Net code.

 
Related posts:
  1. Explicit multi-threading in Matlab – part 1 Explicit multi-threading can be achieved in Matlab by a variety of simple means. ...
  2. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
  3. Multi-column (grid) legend This article explains how to use undocumented axes listeners for implementing multi-column plot legends...
  4. Solving a Matlab hang problem A very common Matlab hang is apparently due to an internal timing problem that can easily be solved. ...
 

Explicit multi-threading in Matlab – part 3

$
0
0

In the past weeks, I explained how we can start asynchronous Java threads to run in parallel to the main Matlab processing using Java and Dot-Net threads. Today I continue by examining C/C++ threads. This series will conclude next week, by discussing timer objects and process-spawning.

The alternatives that can be used to enable Matlab multithreading with C/C++ include standard POSIX threads, native OS threads, OpenMP, MPI (Message Passing Interface), TBB (Thread Building Blocks), Cilk, OpenACC, OpenCL or Boost. We can also use libraries targeting specific platforms/architectures: Intel MKL, C++ AMP, Bolt etc. Note that the Boost library is included in every relatively-modern Matlab release, so we can either use the built-in library (easier to deploy, consistency with Matlab), or download and install the latest version and use it separately. On Windows, we can also use .Net’s Thread class, as explained in last week’s article. This is a very wide range of alternatives, and it’s already been covered extensively elsewhere from the C/C++ side.

Today I will only discuss the POSIX alternative. The benefit of POSIX is that is is more-or-less cross-platform, enabling the same code to work on all MATLAB platforms, as well as any other POSIX-supported platform.

POSIX threads (Pthreads) is a standard API for multi-threaded programming implemented natively on many Unix-like systems, and also supported on Windows. Pthreads includes functionality for creating and managing threads, and provides a set of synchronization primitives such as mutexes, conditional variables, semaphores, read/write locks, and barriers. POSIX has extensive offline and online documentation.

Note that POSIX is natively supported on Macs & Linux, but requires a separate installation on Windows. Two of the leading alternatives are Pthreads_Win32 (also works on Win64, despite its name…), and winpthreads (part of the extensive MinGW open-source project).

When creating a C/C++ -based function, we can either compile/link it into a dynamic/shared library (loadable into Matlab using the loadlibrary & calllib functions), or into a MEX file that can be called directly from M-code. The code looks the same, except that a MEX file has a gateway function named mexFunction that has a predefined interface. Today I’ll show the MEX variant using C; the adaptation to C++ is easy. To create multi-threaded MEX, all it takes is to connect the thread-enabled C/C++ code into our mexFunction(), provide the relevant threading library to the mex linker and we’re done.

The example code below continues the I/O example used throughout this series, of asynchronously saving a vector of data to disk file. Place the following in a file called myPosixThread.c:

#include "mex.h"
#include "pthread.h"
#include "stdio.h"
 
char *filename;
double *data;
size_t numElementsExpected;
size_t numElementsWritten;
 
/* thread compute function */ 
void *thread_run(void *p)
{
    /* Open the file for binary output */
    FILE *fp = fopen(filename, "wb");
    if (fp == NULL)
        mexErrMsgIdAndTxt("YMA:MexIO:errorOpeningFile", "Could not open file %s", filename);
 
    /* Write the data to file */
    numElementsWritten = (size_t) fwrite(data, sizeof(double), numElementsExpected, fp);
    fclose(fp);
 
    /* Ensure that the data was correctly written */
    if (numElementsWritten != numElementsExpected)
        mexErrMsgIdAndTxt("YMA:MexIO:errorWritingFile",
                "Error writing data to %s: wrote %d, expected %d\n", 
                filename, numElementsWritten, numElementsExpected);
 
    /* Cleanup */
    pthread_exit(NULL);
}
 
/* The MEX gateway function */
void mexFunction(int nlhs,       mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    pthread_t thread;
 
    /* Check for proper number of input and output arguments */
    if (nrhs != 2)
        mexErrMsgIdAndTxt("YMA:MexIO:invalidNumInputs", "2 input args required: filename, data");
    if (nlhs > 0)
        mexErrMsgIdAndTxt("YMA:MexIO:maxlhs", "Too many output arguments");
    if (!mxIsChar(prhs[0]))
        mexErrMsgIdAndTxt("YMA:MexIO:invalidInput", "Input filename must be of type string");
    if (!mxIsDouble(prhs[1]))
        mexErrMsgIdAndTxt("YMA:MexIO:invalidInput", "Input data must be of type double");
 
    /* Get the inputs: filename & data */
    filename = mxArrayToString(prhs[0]);
    data = mxGetPr(prhs[1]);  
    numElementsExpected = mxGetNumberOfElements(prhs[1]);
 
    /* Launch a new I/O thread using default attributes */
    if (pthread_create(&thread, NULL, thread_run, NULL))
        mexErrMsgIdAndTxt("YMA:MexIO:threadFailed", "Thread creation failed");
}

This source file can be compiled as follows on Macs/Linux:

mex myPosixThread.c –lpthread

Or on Windows, assuming we installed Pthreads-Win32, we need to set-up the environment:

% prepare the environment (we could also use the -I, -L flags)
pthreadsInstallFolder = 'C:\Program Files\Pthreads_Win32\';  % change this as needed
setenv('PATH',   [getenv('PATH')    ';' pthreadsInstallFolder 'dll\x64']);
setenv('LIB',    [getenv('LIB')     ';' pthreadsInstallFolder 'lib\x64']);
setenv('INCLUDE',[getenv('INCLUDE') ';' pthreadsInstallFolder 'include']);
 
% create a 64-bit MEX that uses the pthreads DLL
mex myPosixThread.c -lpthreadVC2
 
% copy the pthreadVC2.dll file to be accessible to the MEX file, otherwise it will not run
copyfile([pthreadsInstallFolder 'dll\x64\pthreadVC2.dll'], '.')

To run the MEX file from MATLAB, we use the following code snippet (note the similarity with our Java/.Net examples earlier in this series):

addpath('C:\Yair\Code\');  % location of our myPosixThread MEX file
data = rand(5e6,1);  % pre-processing (5M elements, ~40MB)
myPosixThread('F:\test.data',data);  % start running in parallel
data2 = fft(data);  % post-processing (pthread I/O runs in parallel)

Note that we cannot directly modify the data (data=fft(data)) while it is being accessed by the I/O thread. This would cause the data to be reallocated elsewhere in memory, causing the I/O thread to access invalid (stale) memory – this would cause a segmentation violation causing Matlab to crash. Read-only access (data2=fft(data)) is ok, just ensure not to update the data. This was not a problem with our earlier Java/.Net threads, since they received their data by value, but mexFunction() receives its data by reference (which is quicker and saves memory, but also has its limitations). Alternatively, we can memcpy() the Matlab data to a newly-allocated memory block within our thread and only use the memcpy‘ed data from then on. This will ensure that if any updates to the original data occur, the parallel thread will not be affected and no SEGV will occur.

Also note that we call a few MEX functions from within the parallel portion of our code (the thread’s run() function). This works without problems on recent Matlab releases since some MEX API functions have been made thread-safe, however it might not work in earlier (or future) Matlab versions. Therefore, to make our code portable, it is recommended to not interact with Matlab at all during parallel blocks, or to protect MEX API calls by critical sections. Alternatively, only use MEX API calls in the main thread (which is actually MT), defined as those parts of code that run in the same thread as mexFunction(). Synchronization with other threads can be done using POSIX mechanisms such as pthread_join().

To complete the picture, it is also possible to use native threads (rather than POSIX) on Windows: The MEX file should #include <process.h> and call _beginthread(). In fact, since Microsoft for some reason decided to reinvent the wheel with its own native threads and not to support POSIX, all the POSIX implementations on Windows are basically a wrapper for the native Window threads. Using these native threads directly often proves to be the fastest alternative. Unfortunately, code using native threads is not portable to Macs/Linux, unlike POSIX-based code.

Yuval Tassa’s excellent mmx utility (which deserves a detailed review by its own right!) employs both Pthreads (Mac/Linux) and Windows threads in its MEX file. Readers are encouraged to review mmx’s code to see the specifics.

Another related utility on the Matlab File Exchange is Thomas Weibel’s MexThread, which uses C++11‘s std::threads.

 
Related posts:
  1. Explicit multi-threading in Matlab – part 2 Matlab performance can be improved by employing .Net (C#, VB, F# or C++) threads. ...
  2. Explicit multi-threading in Matlab – part 1 Explicit multi-threading can be achieved in Matlab by a variety of simple means. ...
  3. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
  4. Matlab mex in-place editing Editing Matlab arrays in-place can be an important technique for optimizing calculations. This article shows how to do it using Mex. ...
 

Explicit multi-threading in Matlab – part 4

$
0
0

In the past weeks, I explained how we can start asynchronous Java threads to run in parallel to the main Matlab processing using Java, Dot-Net and C++ POSIX threads. Today I conclude the mini-series by examining two other alternatives, timer objects and process-spawning. As we shall see below, these are not “real” multi-threading alternatives, but they can indeed be important in certain use-cases.

Matlab timers

Multithreading helps application performance in two related but distinct ways:

  • By allowing code to run in parallel, on different CPUs or cores
  • By allowing code to run asynchronously, rather than in serial manner

C++, Java and .Net threads can improve performance by both of these manners. Matlab timers, on the other hand, only enable the second option, of running code asynchronously. The reason for this is that all M-code, including timer callback code, is executed by Matlab’s interpreter on a single processing thread (MT).

So, while a timer callback executes, no other M-code can run. This may seem on the face of it to be unhelpful. But in fact, the ability to schedule a Matlab processing task for later (non-serial) invocation, could be very handy, if we can time it so that the timer callback is triggered when the application is idle, for example, waiting for user input, following complex GUI update, or during late hours of the night.

I continue using last weeks’ example, where we compute some data, save it to file on a relatively slow USB/network disk, and then proceed with another calculation. The purpose of multi-threading would be to offload the I/O onto a separate thread, so that the Matlab computation can continue in parallel without needing to wait for the slow I/O. Here is an implementation of our asynchronous I/O example, this time using Matlab timers. First we define the timer’s callback function, using pure M-code (this is the Matlab equivalent of the run() method in the previous examples):

function timerCallback(hTimer,eventData,filename,data)
    try
        fid = fopen('F:\test.data','w');
        fwrite(fid,data,'double');
        fclose(fid);
    catch
        err = lasterror;
        fprintf(2,'Error saving to file:\n%s\n',err.message);
    end
end

We can now use this timer in Matlab, similarly to our previous examples:

data = rand(5e6,1);  % pre-processing (5M elements, ~40MB)
timerFcn = {@timerCallback,'F:\test.data',data};
start(Timer('StartDelay',2, 'TimerFcn',timerFcn)); % start after 2sec
data = fft(data);  % post-processing (timer I/O will run later!)

The difference vs. our earlier examples is that the timer code is not run in parallel to the fft post-processing, but rather 2 seconds later, when MT is hopefully idle.

I often employ Matlab timers in GUIs: the initial GUI is presented to the user immediately, and then a timer is used to load data from I/O, something which could take long seconds. During this time the user can peruse the GUI, getting a feeling of improved responsiveness compared to a situation of having to wait all those long seconds for the GUI to initially load. This relates to the interesting topics of perceived performance and lazy/delayed evaluation. Matlab timers are certainly under-appreciated for their performance usefulness.

As a related usage, GUI callbacks should be designed to be as short as possible. The quicker the callback, the more responsive the GUI. Users may lose patience with long callback execution. Unfortunately, callbacks sometimes need to perform a lengthy computation or update (for example, updating an Excel file). In such a case, consider delegating the lengthy update task to a timer object that will execute asynchronously, and enable the synchronous callback to complete its work much quicker. This will ensure better GUI responsiveness without affecting the actual program logic. Here is a simple example (we may wish to specify some more timer properties – the snippet below is only meant for illustration):

% A utility function that performs a lengthy calculation/update
function utilityFcn()
    % some lengthy calculation/update done here
end
 
% Regular callback function – takes a long time to complete
function myCallbackFcn(varagin)
    % Call the utility function directly (synchronously)
    utilityFcn();
end
 
% A better callback – completes much faster, using asynchronous timer
function myCallbackFcn(varagin)
    % Start an asynchronous timer to perform the lengthy update
    start(timer('StartDelay',0.5, 'TimerFcn',@utilityFcn));
end

Similarly, when plotting real-time data, we can employ a timer to periodically update the graph in near-real-time, enabling the main processing to work in near-parallel.

Matlab timers have an advantage over Java/C++/.Net multithreading in their synchronization with Matlab, since the M-code interpreter is single-threaded. We just need to handle cases where a timer callback might interrupt other M-code.

Matlab timers run pure M-code, so there is no need to know Java/C#/C++ or to use external compilers, and they are easy to set up and use. They can be very effective when tasks can be postponed asynchronously to when the MT is idle.

Spawning external processes

In some cases, it is impractical to create additional processing threads. For example, we might only have the processing element in executable binary format, or we might wish to use a separate memory space for the processing, to sandbox (isolate) it from the main application. In such cases, we can spawn heavyweight processes (as opposed to lightweight threads), either directly from within Matlab, or externally.

The simplest way to spawn an external process in Matlab is using the system function. This function accepts a string that will be evaluated in the OS prompt (shell), at Matlab’s current folder. By appending a ‘&’ character to the end of the string, we let Matlab return immediately, and the spawned process will run asynchronously (in parallel to Matlab); otherwise, Matlab will block until the spawned process ends (i.e., synchronous invocation of the process).

system('program arg1 arg2');    % blocking, synchronous
system('program arg1 arg2 &');  % non-blocking, asynchronous

Matlab normally uses only a single core on a single CPU, except when using the Parallel Computing Toolbox or when doing some implicit parallelization of vectorized code. Therefore, on a quad-core dual-CPU machine, we would normally see Matlab’s CPU usage at only 1/(2*4)=12%. The simplest way to utilize the unused CPU cores without PCT is to spawn additional Matlab processes. This can be done using the system function, as above. The spawned Matlab sessions can be made to run specific commands or functions. For example:

system('matlab –r "for idx=1:100, doSomething(idx); end" &');
system(['matlab –r "processFile(' filename ');" &']);

At this point, we may possibly wish to use processor affinity to ensure that each process runs on a separate CPU. Different OSes have different ways of doing this. For example, on Windows it can easily be done using Process Explorer’s context menu.

When Matlab spawns an external process, it passes to it the set of environment variables used in Matlab. This may be different than the set that is normally used when running the same process from the OS’s command prompt. This could lead to unexpected results, so care should be taken to update such environment variables in Matlab before spawning the process, if they could affect its outcome.

Once an asynchronous (non-blocking) process is started, Matlab does not provide a way to synchronize with it. We could of course employ external signals or the state or contents of some disk file, to let the Matlab process know that one or more of the spawned processes has ended. When multiple processes are spawned, we might wish to employ some sort of load balancing for optimal throughput.

We can use OS commands to check if a spawned processId is still running. This ID is not provided by system so we need to determine it right after spawning the process. On Unix systems (Linux and Mac), both of these can be done using a system call to the OS’s ps command; on Windows we can use the tasklist or wmic commands.

An alternative is to use Java’s built-in process synchronization mechanism, which enables more control over a spawned process. The idea is to spawn an external asynchronous process via Java, continue the Matlab processing, and later (if and when needed) wait for the external process to complete:

runtime = java.lang.Runtime.getRuntime();
process = runtime.exec('program arg1 arg2');  % non-blocking
% Continue Matlab processing in parallel to spawned process

When we need to collect scalar results, we could use the process’ result code:

rc = process.waitFor();    % block Matlab until external program ends
rc = process.exitValue();  % fetch an ended process' return code

Or, if we need to abandon the work, we could stop the spawned process:

process.destroy();         % force-kill the process (rc will be 1)

While this mechanism enables synchronization of the Matlab and external process at the basic execution level, it does not enable synchronization of the data. Doing this between processes (that have independent memory spaces) is much harder (and slower) than it is between threads (that share their memory) or MEX. For inter-process data synchronization (known as IPC, or Inter-Process Communication), we can use shared memory, named pipes or data files. There are various mechanisms and libraries that enable this using C++ and Java that could be used in Matlab. Examples of memory sharing are Joshua Dillon’s sharedmatrix and Kevin Stone’s SharedMemory utilities, which use POSIX shared-memory and the Boost IPC library (SharedMemory is an improved version of sharedmatrix). Rice University’s TreadMarks library is another example of a shared-memory approach that has been used with Matlab, in the MATmarks package (whose current availability is unclear).

Named pipes can be used on Unix systems (Linux and Mac). In this case, the source process sends information to the pipe and the destination process reads from it. After setting up the pipe in the OS, it can be opened, updated and closed just like any other data file. Unfortunately, this mechanism is not generally used on Windows.

Matlab includes a dedicated doc-page showing how to synchronize inter-process data using disk files. An approach that combines memory sharing and files is use of memory-mapped files on R2008a or newer (memmapfile was buggy before then, so I suggest not using it on earlier releases).

Finally, we can use Matlab’s documented ability to serve as a COM/DCOM (automation) server to communicate with it from the external process via the COM interface. Data can be exchanged and Matlab functionality can be invoked by the process.

Followup – MEX functions in R2014a

A few weeks ago I reported that hundreds of internal MEX functions that were previously available and which were enormously useful for a variety of use-cases, have been removed in the R2014a pre-release. Now that the official R2014a has been released, I am happy to report that most of the more-important MEX functions have been restored in the official release (see details in the article addendum), perhaps in some part due to lobbying by yours truly and by others.

MathWorks should be commended for their meaningful dialog with users and for making the fixes in such a short turn-around before the official release, despite the fact that they belong to the undocumented netherworld. MathWorks may appear superficially to be like any other corporate monolith, but when you scratch the surface you discover that there are people there who really care about users, not just the corporate bottom line. I really like this aspect of their corporate culture. I wish all software developers were as receptive to user input as MathWorks is.

 
Related posts:
  1. Explicit multi-threading in Matlab – part 3 Matlab performance can be improved by employing POSIX threads in C/C++ code. ...
  2. Explicit multi-threading in Matlab – part 2 Matlab performance can be improved by employing .Net (C#, VB, F# or C++) threads. ...
  3. Explicit multi-threading in Matlab – part 1 Explicit multi-threading can be achieved in Matlab by a variety of simple means. ...
  4. Multi-line tooltips Multi-line tooltips are very easy to set up, once you know your way around a few undocumented hiccups....
 

Undocumented feature list

$
0
0

Three years ago I posted an article on Matlab’s undocumented feature function. feature is a Matlab function that enables access to undocumented internal Matlab functionality. Most of this functionality is not very useful, but in some cases it could indeed be very interesting. As sometimes happens, this innocent-enough article generated a lot of interest, both online and offline. Perhaps the reason was that in this article I listed the known list of supported features with a short explanation and references were available. At the time, this was the only comprehensive such listing, which I manually collected from numerous sources. For this reason I was delighted to receive Yves Piguet’s tip about the availability of a programmatic interface for a full listing of features:

>> list = feature('list')   % 260 features in R2013b
list = 
1x260 struct array with fields:
    name
    value
    has_callback
    has_builtin
    call_count

Which can be listed as follows:

for i = 1 : length(list)
   fprintf('%35s has_cb=%d has_bi=%d calls=%d val=%g\n', ...
      list(i).name, list(i).has_callback, list(i).has_builtin, list(i).call_count, list(i).value);
end
 
                    100 has_cb=0 has_bi=1 calls=0 val=1
                    102 has_cb=0 has_bi=1 calls=0 val=1
                     12 has_cb=0 has_bi=1 calls=0 val=1
                     14 has_cb=0 has_bi=1 calls=0 val=1
                     25 has_cb=0 has_bi=1 calls=0 val=1
                    300 has_cb=0 has_bi=0 calls=0 val=1
                    301 has_cb=0 has_bi=0 calls=0 val=1
                     44 has_cb=0 has_bi=1 calls=0 val=1
                     45 has_cb=0 has_bi=1 calls=0 val=1
                      7 has_cb=0 has_bi=0 calls=0 val=1
                      8 has_cb=0 has_bi=1 calls=0 val=1
                      9 has_cb=0 has_bi=0 calls=0 val=1
                  accel has_cb=0 has_bi=1 calls=0 val=0
         AccelBlockSize has_cb=0 has_bi=1 calls=0 val=0
          AccelMaxTemps has_cb=0 has_bi=1 calls=0 val=0
    AccelThreadBlockMin has_cb=0 has_bi=1 calls=0 val=0
              allCycles has_cb=0 has_bi=1 calls=0 val=0
 AllWarningsCanBeErrors has_cb=1 has_bi=0 calls=0 val=0
           ArrayEditing has_cb=0 has_bi=0 calls=0 val=1
       AutomationServer has_cb=0 has_bi=1 calls=0 val=0
              CachePath has_cb=0 has_bi=0 calls=0 val=1
     CaptureScreenCount has_cb=0 has_bi=0 calls=0 val=0
       CheckMallocClear has_cb=0 has_bi=0 calls=0 val=1
                    ... (etc. etc.)

Unfortunately, in the latest Matlab R2014a, which was released last week, this nice feature has been removed:

>> list = feature('list')
Error using feature
Feature list not found

Luckily, the list can still be retrieved programmatically, using an undocumented MEX library function. Place the following in a file called feature_list.cpp:

#include "mex.h"
void svListFeatures(int, mxArray_tag** const, int, mxArray_tag** const);
 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    svListFeatures(1,plhs,0,NULL);
}

Now compile this MEX file:

if isunix
   mex('feature_list.cpp',['-L',matlabroot,'/bin/',computer('arch')],'-lmwservices');
else
   mex('feature_list.cpp','-llibmwservices');
end

As you can see, all this MEX function does is just call the svListFeatures() function from the libmwservices dynamic/shared library.

We can now run this MEX function directly in Matlab:

>> list = feature_list
list = 
1x273 struct array with fields:
    name
    value
    has_callback
    has_builtin
    call_count

Running both the new feature_list and the previous feature(‘list’) on previous Matlab releases produces exactly the same result, showing that under the hood, feature(‘list’) was basically just calling libmwservices‘s svListFeatures() function.

There are 273 undocumented features in R2014a: 20 were added and 7 were removed compared to R2013b. For those interested, the modified features in the past two releases are:

  • R2013b:
    1. ConvertAllDoublesToHandles (added)
    2. DrawnowNowaitFeature (added)
    3. getsimd (added)
    4. CoreDump (removed)
  • R2014a:
    1. GPUAllowPartialSharedDataCopies (added)
    2. GPUAllowSharedDataCopies (added)
    3. GetOpenGLData (added)
    4. GetOpenGLInfo (added)
    5. HGUpdateErrorChecking (added)
    6. JVMShutdown (added)
    7. LoadHG1FigFileWithHG1Defaults (added)
    8. OpenGLBitmapZbufferBug (added)
    9. OpenGLClippedImageBug (added)
    10. OpenGLDockingBug (added)
    11. OpenGLEraseModeBug (added)
    12. OpenGLLineSmoothingBug (added)
    13. OpenGLPolygonOffsetBiasBug (added)
    14. OpenGLVerbose (added)
    15. OpenGLWobbleTesselatorBug (added)
    16. SaveFigFileWithHG1Defaults (added)
    17. ShutdownReportLevel (added)
    18. UseGenericOpenGL (added)
    19. crash_mode (added)
    20. isLightweightEval (added)
    21. EnableBangErrors (removed)
    22. EnableJavaAsGObject (removed)
    23. List (removed) – this is actually the reason for today’s article!
    24. hwtic (removed)
    25. hwtoc (removed)
    26. oldtictoc (removed)
    27. timing (removed)

Happy digging!

 
Related posts:
  1. Undocumented feature() function Matlab's undocumented feature function enables access to some internal experimental features...
  2. Legend ‘-DynamicLegend’ semi-documented feature The built-in Matlab legend function has a very useful semi-documented feature for automatic dynamic update, which is explained here....
  3. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  4. Undocumented Matlab MEX API Matlab's MEX API contains numerous undocumented functions, that can be extremely useful. ...
 

JSON-Matlab integration

$
0
0

I would like to once again welcome guest blogger Mark Mikofski. Mark has written here last year about JGIT-Matlab integration (p.s., in the recently-released R2014a, MathWorks added GIT support to Simulink projects, although for some reason not to Matlab projects). Today, Mark discusses how to integrate JSON with Matlab.

What is JSON

It’s often necessary to save objects and arrays to a file, for lots of reasons. In Matlab, you would just save the desired objects in a mat-file, but that’s a binary format that in general only Matlab can read. One reason you might want to cache objects is to pass to a non-Matlab API. True there are libraries to import mat-files (for example: JMatIO), but there are already accepted standards for passing objects such as XML and JSON (JavaScript Object Notation, http://json.org) that most APIs readily understand. Both of these methods attempt to serialize data into a text based format that limits the types of objects they can contain. Because sometimes the API is a human being who needs to read and edit the file, one of the JSON’s goals is to be “easy for humans to read and write”.

Here’s a sample of a JSON object:

{
    "students": ["Dick", "Jane"],
    "assignments": ["essay", "term paper"]
    "scores": {
        "essay": {"Dick": 86, "Jane": 88},
        "term paper":  {"Dick": 89, "Jane": 87}
    },
    "cool": {"Dick": true, "Jane": true},
    "misc": null
}

Many web services, such as Twitter, use JSON in their APIs, because another JSON goal is to be “easy for machines to parse and generate”. JSON is based on the JavaScript ECMA standard in which it is native, and is extremely well documented.

JSON Primer

The documentation on json.org’s main page includes several train-track style graphics that best explain JSON usage, but here is a short primer:

  • There are two main types of JSON objects, a JSONObject and a JSONArray.
  • A JSONObject is enclosed in braces and consists of a collection of unordered key-value pairs separated by a commas. Each key-value pair is separated by a colon, with the key given before the value. In the example above, “students” is a key and its value is the JSONArray ["Dick", "Jane"]. Keys must be strings, as explained below.
  • A JSONArray is enclosed in brackets and is ordered array of valid JSON types.
  • Items in a JSONObject or JSONArray may be one of 7 types: string, number, JSONObject, JSONArray, true, false, or null.
  • Strings are always enclosed in double-quotes and may contain backslashed escapes such as newline (\n), tab (\t), double-quotes (\”), backslash (\\) etc.
  • Numbers can be integers, floats, and scientific notation.
  • JSON interprets true and false as booleans (or logicals), and null as nothing.

There are several options to use JSON in Matlab, depending on what JSON parsing interface you wish to use. Matlab can use external libraries such as Java, .NET and C that allow us to use different implementations of the standard, including the original Java-based implementation by Douglas Crockford himself, the primary author of JavaScript of which JSON is a subset. A full list of JSON implementations is given on the main website along with its documentation. Here is a short list of some libraries:

JSONlab

The most popular and mature Matlab implementation is JSONlab, which was started in 2011 by a Qianqian Fang, a medical researcher at Massachusetts General Hospital. It is available on the Matlab File Exchange, on SourceForge and via a Subversion repository. The latest version is 1.0beta that includes BSON, a variant of JSON used in MongoDB, which compresses JSON data into a binary format. JSONlab is based in part on earlier JSON-Matlab implementations that are now deprecated: JSON Parser (2009) by Joel Feenstra, another JSON Parser (2011) by François Glineur, and Highly portable JSON-input parser (2009) by Nedialko.

JSONlab converts both strings and files given by filename directly into Matlab structures and vice-versa. For example:

>> loadjson('{"this": "that", "foo": [1,2,3], "bar": ["a", "b", "c"]}')
ans = 
    this: 'that'
    foo: [1 2 3]
    bar: {'a'  'b'  'c'}
 
>> s = struct('this', {'a', 'b'}, 'that', {1,2})
s = 
1x2 struct array with fields:
    this
    that
 
>> j = savejson(s)
j =
{
    "s": [
        {
            "this": "a",
            "that": 1
        },
        {
            "this": "b",
            "that": 2
        }
    ]
}

JSONlab will nest structures as necessary and translates the JSON types into the appropriate Matlab types and vice-versa. JSONlab is well documented, easy and fast. It is reliable because it is well-maintained, has been around for several years and has many users. It is open source and issues and contributions are welcomed.

org.json (aka JSON-Java)

This is the Java implementation of JSON by the creator JSON and JavaScript, Douglas Crockford. This version is very well documented and under active development, but since there are no releases and only one branch, it could be considered the development branch. There are several other popular Java implementations listed on the JSON.org website.

The JSON library itself is called json.jar or org.json.jar. The easiest way to use it in Matlab is to add it to your java class path and then use it as if you were calling Java code. I put together a gist of examples and links for your reference. In particular take a look at orgJSONdemo.m which has several examples of creating JSON objects and then using them. I addition, take a look at this CSSM newsgroup thread.

How to add the jar file to your java class path depends on your version of Matlab: starting in R2012b, Matlab switched from using classpath.txt in your Matlab workspace to using javaclasspath.txt, which is much easier (however, see here). Make a file in your Matlab workspace, usually /home/MATLAB or /home/documents/matlab (e.g. on windows 7: c:\users\you\documents\matlab), called “javaclasspath.txt” and put the full path to your jar file. For example if you put the jar file in a MATLAB/JSON/ folder, then put the following line (on windows 7) in javaclasspath.txt:

the path specified in the javaclasspath.txt file should be the path to the actual jar file, so assuming your jar is called json.jar then you would put this path in your file:

C:\Users\your-user-name\Documents\MATLAB\JSON\json.jar

You must restart Matlab before this change takes effect. An alternate method is to load the jar file dynamically to Matlab’s Java classpath, using javaaddpath(‘path\to\json.jar’).

All this is pretty straight-forward in Matlab R2013b and newer, which use Java 7. json.org was implemented in Java 7 as javax.json, and so can be used with Matlab R2013b and newer. Matlab versions R2013a and earlier use Java 6, so another Java implementation must be used. You can either download a pre-compiled JAR file from my dropbox, or compile the source files on your system as follows:

  1. Confirm the version of Java used in Matlab by typing
    >> version -java
    Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode
  2. Download and install the corresponding Java JDK from Oracle or OpenJDK
  3. Obtain the source by cloning the repository or downloading a tar/zip-ball
  4. If necessary, extract the source then browse to the “src” folder
  5. Compile the source into a class files from the command line:
    C:\> C:\Program Files\Java\jdk1.7.0_45\bin\javac -verbose -sourcepath org\json\ -source 1.6 -target 1.6 -d ..\bin\ org\json\*.java org\json\zip\*.java
  6. Browse the created “bin” folder
  7. Archive the class files into a jar file:
    C:\> C:\Program Files\Java\jdk1.7.0_45\bin\jar -cvf JSON.jar org\
  8. Add the new jar file to the Matlab static Java classpath, which will depend on what version of Matlab you have:
    1. Matlab <= 2012a:
      • Find the system classpath.txt file by typing:
        >> [matlabroot '\toolbox\local\classpath.txt']
        C:\Program Files\MATLAB\R2012a\toolbox\local\classpath.txt
      • Copy the classpath to your working folder and append the path the jar file to the end. Use hash marks to comment lines.
         
    2. Matlab >= 2012b: create a new file called “javaclasspath.txt” in your working folder with the path of the new jar file in it. Use hash marks for comments.
       
  9. Restart Matlab to enable the jar file within Matlab.

Using the Java library is the same as using any Java library in Matlab. One nice feature is that tabbing after typing “object.” gives a pop-up list of available properties and methods, including inherited ones. Here are some simple usage examples:

>> j1 = org.json.JSONObject('{"this": "that", "foo": [1,2,3], "bar": ["a", "b", "c"]}')
>> j2 = j1.put('hello', 'world')
j2 =
{"hello":"world", "foo":[1,2,3], "bar":["a","b","c"], "this":"that"}
 
>> w = j1.getString('hello')
ans =
world

Watch out: the output is actually a java.lang.String object; use char() to convert it into a Matlab string:

>> char(w)
ans =
world

There is no easy way to convert a JSONArray to an array, so you can either loop over it, or convert it to a string and parse it. Note that JSONArray indexes start from 0, as in Java (contrary to Matlab indexes, which start at 1)

>> f = j1.get('foo')
f =
[1,2,3]
 
>> for n = 1:f.length,  fa(n)=f.get(n-1);  end
>> fa
fa =
     1     2     3

Json.NET and fastJSON

These libraries require you to add add the path of the .NET dll to Matlab using NET.addAssembly. For fastJSON, since binaries are not available, you will also need to compile the .NET dll. I’ll leave it to the reader to investigate further, independently.

 
Related posts:
  1. JGit-Matlab integration JGit source-control integration package can easily be integrated in Matlab. ...
  2. Matlab installation woes Matlab has some issues when installing a new version. This post discusses some of them and how to overcome them....
  3. Using spinners in Matlab GUI Spinner controls can easily be added to Matlab GUI. This article explains how. ...
  4. Using Groovy in Matlab Groovy code can seamlessly be run from within Matlab. ...
 

uicontextmenu performance

$
0
0

I would like to introduce guest blogger Robert Cumming, an independent contractor based in the UK who has recently worked on certification of the newest advanced civil aircraft. Today Robert will discuss the performance of uicontextmenus in interactive GUIs, which were used extensively in flight test analysis.

Have you ever noticed that a GUI slows down over time? I was responsible for designing a highly complex interactive GUI, which plotted flight test data for engineers and designers to analyze data for comparison with pre-flight predictions. This involved extensive plotting of data (pressure, forces/moments, anemometry, actuator settings etc….), where individual data points were required to have specific/customizable uicontextmenus.

Matlab’s documentation on uicontextmenus discusses adding them to plots, but makes no mention of the cleaning up afterwards.

Let’s start with some GUI basics. First we create a figure with a simple axes and a line:

x = [-10:0.2:10];
y = x.^2;
h = figure;
ax = axes ( 'parent',h );
hplot = plot ( ax, x, y );

Adding a uicontextmenu to the plot creates extra objects:

uic = uicontextmenu;
uimenu ( uic, 'Label','Menu A.1' );
set ( hplot, 'uicontextmenu',uic );
fprintf ( 'Figure (h) has %i objects\n', length ( findobj ( h ) ) );

In this instance there are 5 objects, the individual menu and uicontextmenu have created an additional 2 objects. All of this is quite basic as you would expect.

Basic plot with a custom context menu

Basic plot with a custom context menu


We now clear the plot using cla and draw a new line with its own new uicontextmenu. Note that we don’t save the plot handle this time:

cla ( ax );
uic = uicontextmenu;
uimenu ( uic, 'Label','Menu B.1' );
plot ( ax, x, -y , 'uicontextmenu',uic );
fprintf ( 'Figure (h) has %i objects\n', length ( findobj ( h ) ) );

Another basic plot with a new context menu

Another basic plot with a new context menu

This time the fprintf line tells us that the figure has 7 objects. This may not have been expected, as the first plot was cleared and the original context menu is no longer accessible (cla removed the plot and the line object hplot).

Let’s check these object handles:

>> ishandle ( findobj( h ) )'
ans =
     1     1     1     1     1     1     1     1     1     1     1     1     1

We see that all the objects are valid handles. At first this may perhaps appear confusing: after all, the plot with “Menu A.1″ was deleted. Let’s check this:

>> ishandle ( hplot )
ans =
     0
 
>> get(hplot)
Error using handle.handle/get
Invalid or deleted object.

So it appears that although the plot line was indeed deleted, its associated context menu was not. The reason for this is that the context menu is created as a child of the figure window, not the plot. We are simply using the plot line’s UIContextMenu property to allow the user to obtain access to it and its associated menus.

Once we understand this we can do two things:

  1. Use the same uicontextmenu for each plot
  2. Built individual uicontextmenus for each plot, but remember to clean up afterwards

Is this really such a big issue?

You may be wondering how big a problem is this creation of extra objects. The answer is that for simple cases like this it is really not a big issue. But let’s consider a more realistic case where we also assign callbacks to the menus. First we will create a figure with an axes, for plotting on and a uicontrol edit for displaying a message:

function uicontextExample
   h.main = figure;
   h.ax = axes ( 'parent',h.main, 'NextPlot','add', 'position',[0.1 0.2 0.8 0.7] );
   h.msg = uicontrol ( 'style','edit', 'units','normalized', 'position',[0.08 0.01 0.65 0.1], 'backgroundcolor','white' );
   uicontrol ( 'style','pushbutton', 'units','normalized', 'position',[0.75 0.01 0.2 0.1], 'Callback',{@RedrawX20 h}, 'string','re-draw x20' );
   redraw ( [], [], h )  % see below
end

The callback redraw (shown below) draws a simple curve and assigns individual uicontextmenus to each individual item in the plot. Each uicontextmenu has 12 menu items:

function redraw ( obj, event, h, varargin )
   cla(h.ax);
   start = tic;
   x = -50:50;
   y = x.^2;
   for ii = 1 : length(x)
      uim = uicontextmenu ( 'parent',h.main );
      for jj = 1 : 10
         menuLabel = sprintf ( 'Menu %i.%i', ii, jj );
         uimenu ( 'parent',uim, 'Label',menuLabel, 'Callback',{@redraw h} )
      end
      xStr = sprintf ( 'X = %f', x(ii) );
      yStr = sprintf ( 'Y = %f', y(ii) );
      uimenu ( 'parent',uim, 'Label',xStr, 'Callback',{@redraw h} )
      uimenu ( 'parent',uim, 'Label',yStr, 'Callback',{@redraw h} )
      plot ( h.ax, x(ii), y(ii), 'rs', 'uicontextmenu',uim );
   end
   objs = findobj ( h.main );
   s = sprintf ( 'figure contains %i objects - drawn in %3.2f seconds', length(objs), toc(start) );
   set ( h.msg, 'string',s );
   fprintf('%s\n',s)
end

To help demonstrate the slow-down in speed, the pushbutton uicontrol will redraw the plot 20 times, and show the results from the profiler:

function RedrawX20 ( obj, event, h )
   profile on
   set ( obj, 'enable','off' )
   for ii = 1 : 20
      redraw ( [], [], h );
      drawnow();
   end
   set ( obj, 'enable','on' )
   profile viewer
end

The first time we run this, on a reasonable laptop it takes 0.24 seconds to draw the figure with all the menus:

Multiple context menus assigned to individual data points

Multiple context menus assigned to individual data points

When we press the <re-draw x20> button we get:

figure contains 2731 objects - drawn in 0.28 seconds
figure contains 4044 objects - drawn in 0.28 seconds
figure contains 5357 objects - drawn in 0.28 seconds
figure contains 6670 objects - drawn in 0.30 seconds
figure contains 7983 objects - drawn in 0.32 seconds
figure contains 9296 objects - drawn in 0.30 seconds
figure contains 10609 objects - drawn in 0.31 seconds
figure contains 11922 objects - drawn in 0.30 seconds
figure contains 13235 objects - drawn in 0.32 seconds
figure contains 14548 objects - drawn in 0.30 seconds
figure contains 15861 objects - drawn in 0.31 seconds
figure contains 17174 objects - drawn in 0.31 seconds
figure contains 18487 objects - drawn in 0.32 seconds
figure contains 19800 objects - drawn in 0.33 seconds
figure contains 21113 objects - drawn in 0.32 seconds
figure contains 22426 objects - drawn in 0.33 seconds
figure contains 23739 objects - drawn in 0.35 seconds
figure contains 25052 objects - drawn in 0.34 seconds
figure contains 26365 objects - drawn in 0.35 seconds
figure contains 27678 objects - drawn in 0.35 seconds

The run time shows significant degradation, and we have many left-over objects. The profiler output confirms where the time is being spent:

Profiling results - context menu creation is an evident hotspot

Profiling results - context menu creation is an evident hotspot

As expected the menus creation takes most of the time. Note that the timing that you will get on your own computer for this example may vary and the slowdown may be less noticeable.

Let’s extend the example to include extra input arguments in the callback (in this example they are not used – but in the industrial example extra input arguments are very possible, and were required by the customer):

for ii=1:length(x)
   uim = uicontextmenu ( 'parent',h.main );
   for jj = 1 : 10
      menuLabel = sprintf ( 'Menu %i.%i', ii, jj );
      uimenu ( 'parent',uim, 'Label',menuLabel, 'Callback',{@redraw h 1 0 1} )
   end
   xStr = sprintf ( 'X = %f', x(ii) );
   yStr = sprintf ( 'Y = %f', y(ii) );
   uimenu ( 'parent',uim, 'Label',xStr, 'Callback',{@redraw h 1 0 1} )
   uimenu ( 'parent',uim, 'Label',yStr, 'Callback',{@redraw h 1 0 1} )
   plot ( h.ax, x(ii), y(ii), 'rs', 'uicontextmenu',uim );
end

Re-running the code and pressing <re-draw x20> we get:

figure contains 1418 objects - drawn in 0.29 seconds
figure contains 2731 objects - drawn in 0.37 seconds
figure contains 4044 objects - drawn in 0.48 seconds
figure contains 5357 objects - drawn in 0.65 seconds
...
figure contains 23739 objects - drawn in 4.99 seconds
figure contains 25052 objects - drawn in 5.34 seconds
figure contains 26365 objects - drawn in 5.88 seconds
figure contains 27678 objects - drawn in 6.22 seconds

Note that the 6.22 seconds is just the time that it took the last individual redraw, not the total time to draw 20 times (which was just over a minute). The profiler is again used to confirm that the vast majority of the time (57 seconds) was spent in the uimenu calls, mostly on line #23. In comparison, all other lines together took just 4 seconds to run.

The simple act of adding extra inputs to the callback has completely transformed the speed of our code.

How real is this example?
In code written for a customer, the context menu had a variety of sub menus (dependent on the parameter being plotted – from 5 to ~20), and they each had multiple parameters passed into the callbacks. Over a relatively short period of time the user would cycle through a lot of data and the number of uicontextmenus being created was surprisingly large. For example, users would easily look at 100 individual sensors recorded at 10Hz for 2 minutes (100*10*60*2). If all sensors and points are plotted individually that would be 120,000 uicontextmenus!

So how do we resolve this?

The problem is addressed by simply deleting the context menu handles once they are no longer needed. This can be done by adding a delete command after cla at the top of the redraw function, in order to remove the redundant uicontextmenus:

function redraw ( obj, event, h, varargin )
   cla(h.ax);
   delete ( findobj ( h.main, 'type','uicontextmenu' ) )   set ( h.msg, 'string','redrawing' );
   start = tic;
   ...

If we now click <redraw x20> we see that the number of objects and the time to create them remain its essentially the same as the first call: 1418 objects and 0.28 seconds:

figure contains 1418 objects - drawn in 0.28 seconds
figure contains 1418 objects - drawn in 0.30 seconds
figure contains 1418 objects - drawn in 0.33 seconds
figure contains 1418 objects - drawn in 0.29 seconds
figure contains 1418 objects - drawn in 0.29 seconds
...

Advanced users could use handle listeners to attached a callback such that when a plot element is deleted, so too are its associated context menus.

Conclusions

Things to consider with uicontextmenus:

  1. Always delete uicontextmenus that you have finished with.
  2. If you have multiple uicontextmenus you will want to only delete the ones associated with the axes being cleared – otherwise you will delete more than you want to.
  3. Try to reduce the number of input arguments to your callbacks, group into a structure or cell array.
  4. Re-use uicontextmenus where possible.

Have you had similar experiences? Or other issues where GUI slow down over time? If so, please leave a comment below.

 
Related posts:
  1. Performance: accessing handle properties Handle object property access (get/set) performance can be significantly improved using dot-notation. ...
  2. Plot performance Undocumented inner plot mechanisms can be used to significantly improved plotting performance...
  3. Performance: scatter vs. line In many circumstances, the line function can generate visually-identical plots as the scatter function, much faster...
  4. Preallocation performance Preallocation is a standard Matlab speedup technique. Still, it has several undocumented aspects. ...
 
Viewing all 219 articles
Browse latest View live