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

Matlab-Latex interface

$
0
0

I would like to welcome guest blogger Yaroslav Don, known to vim users as the author of the Matlab color-scheme. Today Yaroslav discusses some little-known aspects of Matlab’s support for Latex.

One of the most appealing aspects of Matlab is the cross-talk with other programs via a friendly user-interface. An excellent example is the Latex interpreter inside the Handle-graphics axes and texts, which comes to a good use to many inside the scientific community. In recent years I’ve noticed a slow but steady tendency of degrading the Latex capabilities inside Matlab. The most apparent example is the decreasing fonts; I’ll show its downward progression below:

Matlab R2010a

When I started using Latex in Matlab, I wrote a small script (latexfonts.m) to check the available Latex options in Matlab. In the figure below several attributes are depicted: font-families (roman, sans-serif and typewriter), font-shapes (upright, slanted, italics and small-caps) and font-series (medium and bold). It also shows other tweaks such as kerning, ligatures, underline, etc.

Latex support in R2010a

Latex support in R2010a

It is clearly seen that most of the Latex options above are available. Analyzing further, the list of fonts inside Matlab is quite vast, as seen below:

>> dir(fullfile(matlabroot,'sys','fonts','ttf','cm'))
.             cmbxsl10.ttf  cmmi12.ttf    cmr7.ttf      cmssi12.ttf   cmti10.ttf    eufb5.ttf     eurb9.ttf     eusm7.ttf     
..            cmbxti10.ttf  cmmi5.ttf     cmr8.ttf      cmssi17.ttf   cmti12.ttf    eufb6.ttf     eurm10.ttf    eusm8.ttf     
README        cmcsc10.ttf   cmmi6.ttf     cmr9.ttf      cmssi8.ttf    cmti7.ttf     eufb7.ttf     eurm5.ttf     eusm9.ttf     
cmb10.ttf     cmcsc8.ttf    cmmi7.ttf     cmsl10.ttf    cmssi9.ttf    cmti8.ttf     eufb8.ttf     eurm6.ttf     msam10.ttf    
cmbsy10.ttf   cmcsc9.ttf    cmmi8.ttf     cmsl12.ttf    cmssq8.ttf    cmti9.ttf     eufb9.ttf     eurm7.ttf     msam5.ttf     
cmbsy6.ttf    cmdunh10.ttf  cmmi9.ttf     cmsl8.ttf     cmssqi8.ttf   cmtt10.ttf    eufm10.ttf    eurm8.ttf     msam6.ttf     
cmbsy7.ttf    cmex10.ttf    cmmib10.ttf   cmsl9.ttf     cmsy10.ttf    cmtt12.ttf    eufm5.ttf     eurm9.ttf     msam7.ttf     
cmbsy8.ttf    cmex7.ttf     cmmib6.ttf    cmsltt10.ttf  cmsy5.ttf     cmtt8.ttf     eufm6.ttf     eusb10.ttf    msam8.ttf     
cmbsy9.ttf    cmex8.ttf     cmmib7.ttf    cmss10.ttf    cmsy6.ttf     cmtt9.ttf     eufm7.ttf     eusb5.ttf     msam9.ttf     
cmbx10.ttf    cmex9.ttf     cmmib8.ttf    cmss12.ttf    cmsy7.ttf     cmu10.ttf     eufm8.ttf     eusb6.ttf     msbm10.ttf    
cmbx12.ttf    cmff10.ttf    cmmib9.ttf    cmss17.ttf    cmsy8.ttf     cmvtt10.ttf   eufm9.ttf     eusb7.ttf     msbm5.ttf     
cmbx5.ttf     cmfi10.ttf    cmr10.ttf     cmss8.ttf     cmsy9.ttf     euex10.ttf    eurb10.ttf    eusb8.ttf     msbm6.ttf     
cmbx6.ttf     cmfib8.ttf    cmr12.ttf     cmss9.ttf     cmtcsc10.ttf  euex7.ttf     eurb5.ttf     eusb9.ttf     msbm7.ttf     
cmbx7.ttf     cminch.ttf    cmr17.ttf     cmssbx10.ttf  cmtex10.ttf   euex8.ttf     eurb6.ttf     eusm10.ttf    msbm8.ttf     
cmbx8.ttf     cmitt10.ttf   cmr5.ttf      cmssdc10.ttf  cmtex8.ttf    euex9.ttf     eurb7.ttf     eusm5.ttf     msbm9.ttf     
cmbx9.ttf     cmmi10.ttf    cmr6.ttf      cmssi10.ttf   cmtex9.ttf    eufb10.ttf    eurb8.ttf     eusm6.ttf     
 
>> dir(fullfile(matlabroot,'sys','fonts','type1','cm'))
.             cmbxsl10.pfm  cmmi12.pfm    cmr6.pfm      cmss17.pfm    cmssqi8.pfm   cmti10.pfm    lasy10.pfm    lcmssi8.pfm   
..            cmbxti10.pfb  cmmi5.pfb     cmr7.pfb      cmss8.pfb     cmsy10.pfb    cmti12.pfb    lasy5.pfb     line10.pfb    
README        cmbxti10.pfm  cmmi5.pfm     cmr7.pfm      cmss8.pfm     cmsy10.pfm    cmti12.pfm    lasy5.pfm     line10.pfm    
cmb10.pfb     cmcsc10.pfb   cmmi6.pfb     cmr8.pfb      cmss9.pfb     cmsy5.pfb     cmti7.pfb     lasy6.pfb     linew10.pfb   
cmb10.pfm     cmcsc10.pfm   cmmi6.pfm     cmr8.pfm      cmss9.pfm     cmsy5.pfm     cmti7.pfm     lasy6.pfm     linew10.pfm   
cmbsy10.pfb   cmdunh10.pfb  cmmi7.pfb     cmr9.pfb      cmssbx10.pfb  cmsy6.pfb     cmti8.pfb     lasy7.pfb     logo10.pfb    
cmbsy10.pfm   cmdunh10.pfm  cmmi7.pfm     cmr9.pfm      cmssbx10.pfm  cmsy6.pfm     cmti8.pfm     lasy7.pfm     logo10.pfm    
cmbx10.pfb    cmex10.pfb    cmmi8.pfb     cmsl10.pfb    cmssdc10.pfb  cmsy7.pfb     cmti9.pfb     lasy8.pfb     logo8.pfb     
cmbx10.pfm    cmex10.pfm    cmmi8.pfm     cmsl10.pfm    cmssdc10.pfm  cmsy7.pfm     cmti9.pfm     lasy8.pfm     logo8.pfm     
cmbx12.pfb    cmff10.pfb    cmmi9.pfb     cmsl12.pfb    cmssi10.pfb   cmsy8.pfb     cmtt10.pfb    lasy9.pfb     logo9.pfb     
cmbx12.pfm    cmff10.pfm    cmmi9.pfm     cmsl12.pfm    cmssi10.pfm   cmsy8.pfm     cmtt10.pfm    lasy9.pfm     logo9.pfm     
cmbx5.pfb     cmfi10.pfb    cmmib10.pfb   cmsl8.pfb     cmssi12.pfb   cmsy9.pfb     cmtt12.pfb    lasyb10.pfb   logobf10.pfb  
cmbx5.pfm     cmfi10.pfm    cmmib10.pfm   cmsl8.pfm     cmssi12.pfm   cmsy9.pfm     cmtt12.pfm    lasyb10.pfm   logobf10.pfm  
cmbx6.pfb     cmfib8.pfb    cmr10.pfb     cmsl9.pfb     cmssi17.pfb   cmtcsc10.pfb  cmtt8.pfb     lcircle1.pfb  logosl10.pfb  
cmbx6.pfm     cmfib8.pfm    cmr10.pfm     cmsl9.pfm     cmssi17.pfm   cmtcsc10.pfm  cmtt8.pfm     lcircle1.pfm  logosl10.pfm  
cmbx7.pfb     cminch.pfb    cmr12.pfb     cmsltt10.pfb  cmssi8.pfb    cmtex10.pfb   cmtt9.pfb     lcirclew.pfb  
cmbx7.pfm     cminch.pfm    cmr12.pfm     cmsltt10.pfm  cmssi8.pfm    cmtex10.pfm   cmtt9.pfm     lcirclew.pfm  
cmbx8.pfb     cmitt10.pfb   cmr17.pfb     cmss10.pfb    cmssi9.pfb    cmtex8.pfb    cmu10.pfb     lcmss8.pfb    
cmbx8.pfm     cmitt10.pfm   cmr17.pfm     cmss10.pfm    cmssi9.pfm    cmtex8.pfm    cmu10.pfm     lcmss8.pfm    
cmbx9.pfb     cmmi10.pfb    cmr5.pfb      cmss12.pfb    cmssq8.pfb    cmtex9.pfb    cmvtt10.pfb   lcmssb8.pfb   
cmbx9.pfm     cmmi10.pfm    cmr5.pfm      cmss12.pfm    cmssq8.pfm    cmtex9.pfm    cmvtt10.pfm   lcmssb8.pfm   
cmbxsl10.pfb  cmmi12.pfb    cmr6.pfb      cmss17.pfb    cmssqi8.pfb   cmti10.pfb    lasy10.pfb    lcmssi8.pfb   
 
>> dir(fullfile(matlabroot,'sys','tex','tfm'))
.               cmbxsl10.tfm    cmmi12.tfm      cmr6.tfm        cmssdc10.tfm    cmtex8.tfm      icmmi8.tfm      lcmss8.tfm      
..              cmbxti10.tfm    cmmi5.tfm       cmr7.tfm        cmssi10.tfm     cmtex9.tfm      icmsy8.tfm      lcmssb8.tfm     
cmb10.tfm       cmcsc10.tfm     cmmi6.tfm       cmr8.tfm        cmssi12.tfm     cmti10.tfm      icmtt8.tfm      lcmssi8.tfm     
cmbsy10.tfm     cmcsc8.tfm      cmmi7.tfm       cmr9.tfm        cmssi17.tfm     cmti12.tfm      ilasy8.tfm      line10.tfm      
cmbsy5.tfm      cmcsc9.tfm      cmmi8.tfm       cmsa10.tfm      cmssi8.tfm      cmti7.tfm       ilcmss8.tfm     linew10.tfm     
cmbsy6.tfm      cmdunh10.tfm    cmmi9.tfm       cmsl10.tfm      cmssi9.tfm      cmti8.tfm       ilcmssb8.tfm    manfnt.tfm      
cmbsy7.tfm      cmex10.tfm      cmmib10.tfm     cmsl12.tfm      cmssq8.tfm      cmti9.tfm       ilcmssi8.tfm    old_manfnt.tfm  
cmbsy8.tfm      cmex7.tfm       cmmib5.tfm      cmsl8.tfm       cmssqi8.tfm     cmtt10.tfm      lasy10.tfm      trip.tfm        
cmbsy9.tfm      cmex8.tfm       cmmib6.tfm      cmsl9.tfm       cmsy10.tfm      cmtt12.tfm      lasy5.tfm       
cmbx10.tfm      cmex9.tfm       cmmib7.tfm      cmsltt10.tfm    cmsy5.tfm       cmtt8.tfm       lasy6.tfm       
cmbx12.tfm      cmff10.tfm      cmmib8.tfm      cmss10.tfm      cmsy6.tfm       cmtt9.tfm       lasy7.tfm       
cmbx5.tfm       cmfi10.tfm      cmmib9.tfm      cmss12.tfm      cmsy7.tfm       cmu10.tfm       lasy8.tfm       
cmbx6.tfm       cmfib8.tfm      cmr10.tfm       cmss17.tfm      cmsy8.tfm       cmvtt10.tfm     lasy9.tfm       
cmbx7.tfm       cminch.tfm      cmr12.tfm       cmss8.tfm       cmsy9.tfm       dummy.tfm       lasyb10.tfm     
cmbx8.tfm       cmitt10.tfm     cmr17.tfm       cmss9.tfm       cmtcsc10.tfm    icmcsc10.tfm    lcircle10.tfm   
cmbx9.tfm       cmmi10.tfm      cmr5.tfm        cmssbx10.tfm    cmtex10.tfm     icmex10.tfm     lcirclew10.tfm

Matlab R2011b

Each time a new Matlab version is introduced, the joy of getting many fresh or upgraded features is mixed with the worry of getting some good-old ones removed. Unfortunately, such a regression was exactly the case in the R2011b version (and to this day in R2013a), as seen below:

Latex support in R2011b

Latex support in R2011b

Suddenly, many of the former features are missing and a cascade of warnings is thrown:

Warning: Font cmss10 is not supported. 
Warning: Font cmss10 is not supported. 
Warning: Font cmss10 is not supported. 
Warning: Font cmss10 is not supported. 
Warning: Font cmssi10 is not supported. 
Warning: Font cmssi10 is not supported. 
Warning: Font cmssi10 is not supported. 
Warning: Font cmssi10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Font cmcsc10 is not supported. 
Warning: Unable to interpret LaTeX string "\ttfamily\scshape\mdseries WALT bla fi f{}i ff" 
Warning: Font cmssbx10 is not supported. 
...

Note: you can turn these warnings off using:

>> warning off MATLAB:gui:latexsup:UnableToInterpretLaTeXString
>> warning off MATLAB:gui:latexsup:UnsupportedFont

Having the fonts inspected, the cause becomes crystal-clear: most of the fonts used by Latex have been removed from Matlab’s installation. Apparently, I am not the only one to have noticed this problem.

>> dir(fullfile(matlabroot,'sys','fonts','ttf','cm'))
.                 mwa_cmbsy10.ttf   mwa_cmitt10.ttf   mwa_cmsltt10.ttf  mwb_cmbsy10.ttf   mwb_cmitt10.ttf   mwb_cmsltt10.ttf  
..                mwa_cmbx10.ttf    mwa_cmmi10.ttf    mwa_cmsy10.ttf    mwb_cmbx10.ttf    mwb_cmmi10.ttf    mwb_cmsy10.ttf    
LICENCE           mwa_cmbxsl10.ttf  mwa_cmmib10.ttf   mwa_cmti10.ttf    mwb_cmbxsl10.ttf  mwb_cmmib10.ttf   mwb_cmti10.ttf    
README            mwa_cmbxti10.ttf  mwa_cmr10.ttf     mwa_cmtt10.ttf    mwb_cmbxti10.ttf  mwb_cmr10.ttf     mwb_cmtt10.ttf    
mwa_cmb10.ttf     mwa_cmex10.ttf    mwa_cmsl10.ttf    mwb_cmb10.ttf     mwb_cmex10.ttf    mwb_cmsl10.ttf    
 
>> dir(fullfile(matlabroot,'sys','fonts','type1','cm'))
.                 mwa_cmbx10.pfb    mwa_cmmi10.pfb    mwa_cmsy10.pfb    mwb_cmbx10.pfb    mwb_cmmi10.pfb    mwb_cmsy10.pfb    
..                mwa_cmbxsl10.pfb  mwa_cmmib10.pfb   mwa_cmti10.pfb    mwb_cmbxsl10.pfb  mwb_cmmib10.pfb   mwb_cmti10.pfb    
README            mwa_cmbxti10.pfb  mwa_cmr10.pfb     mwa_cmtt10.pfb    mwb_cmbxti10.pfb  mwb_cmr10.pfb     mwb_cmtt10.pfb    
mwa_cmb10.pfb     mwa_cmex10.pfb    mwa_cmsl10.pfb    mwb_cmb10.pfb     mwb_cmex10.pfb    mwb_cmsl10.pfb    
mwa_cmbsy10.pfb   mwa_cmitt10.pfb   mwa_cmsltt10.pfb  mwb_cmbsy10.pfb   mwb_cmitt10.pfb   mwb_cmsltt10.pfb  
 
>> dir(fullfile(matlabroot,'sys','tex','tfm'))
.               cmbxti10.tfm    cmmib10.tfm     cmssi10.tfm     cmu10.tfm       lcirclew10.tfm  
..              cmcsc10.tfm     cmr10.tfm       cmssq8.tfm      icmcsc10.tfm    line10.tfm      
cmb10.tfm       cmdunh10.tfm    cmsl10.tfm      cmssqi8.tfm     icmex10.tfm     linew10.tfm     
cmbsy10.tfm     cmex10.tfm      cmsltt10.tfm    cmsy10.tfm      lasy10.tfm      manfnt.tfm      
cmbx10.tfm      cmitt10.tfm     cmss10.tfm      cmti10.tfm      lasyb10.tfm     trip.tfm        
cmbxsl10.tfm    cmmi10.tfm      cmssbx10.tfm    cmtt10.tfm      lcircle10.tfm

It seems that Mathworks have changed their approach to Latex; less fonts with different names imply a different future direction — perhaps to diminish Latex’s capacity in Matlab.

Summary

Being neither Tex nor Matlab expert, this is the farthest I could achieve. I’ve tried unsuccessfully to install the missing fonts in the new Matlab (as suggested by bug reports 249537 and 398506); I even tried to modify some tex-files — all in vain. Perhaps someone could find a workaround or a full solution to this issue. If so, please post a comment.

Note that I do not wish to incorporate Matlab figures in a Latex document (this can be done using the LaPrint utility or its variants), but rather the reverse – including Latex formatting within Matlab figures.

 
Related posts:
  1. JMI – Java-to-Matlab Interface JMI enables calling Matlab functions from within Java. This article explains JMI's core functionality....
  2. Matclipse – Eclipse-Matlab interface Matclipse is an open-source plugin for the popular Eclipse IDE that connects it with Matlab. ...
  3. Matlab-Java interface using a static control The switchyard function design pattern can be very useful when setting Matlab callbacks to Java GUI controls. This article explains why and how....
  4. HG’s undocumented parameters interface Some HG functions also accept inputs parameters in a struct fields rather than the normal P-V pairs format. ...
 

A couple of internal Matlab bugs and workarounds

$
0
0

Like any other major software package, Matlab too has its share of bugs. If you ask me, the number of known bugs in Matlab is actually very small compared to the industry standard. Posting bugs online saves the support staff work on duplicates and provides immediate relief for users if the bug happens to have a posted workaround. It also increases transparency, which helps customer loyalty and confidence in the product. Serious engineering work that relies on Matlab for anything from designing cars and planes to trading on stock exchanges needs to be aware of all the current bugs, in order to avoid them in the production code.

Unfortunately, for some reason MathWorks does not publicize all the bugs that it knows about. I know this since there are multiple bugs that I have reported and were confirmed by the competent technical support staff, which do not appear on the online list. I do not know whether this is a deliberate MathWorks policy based on some criteria, but I would hope not and I hope it will be fixed. IMHO, Matlab in general is a very stable system that has absolutely nothing to be ashamed of in terms of the low number, and relatively low-impact, of its open bugs.

Today I write about two internal Matlab bugs that I have recently discovered and reported, along with their workarounds. None of them is really critical, but since neither appears in the official bug parade (as of today), I figured it would do some public good to post them here.

The clf function does not clear javacomponents (1-MNELS1)

The clf function clears the specified figure window (or the current figure [gcf] if no figure handle was specified as input) of any axes and GUI controls. At least, that what it is supposed to do and what it did pretty well until R2012a (Matlab 7.14). Apparently, in R2012b (Matlab 8.0) something broke and controls that are added to the figure window using the javacomponent function are no longer cleared by clf – all the regular Matlab axes and uicontrols are deleted, but not the Java controls.

figure;
[jButton, hContainer] = javacomponent(javax.swing.JButton('Click'), [], gcf); 
drawnow;
clf  % bug - clf does not delete the jButton/hContainer component from the figure

There are several possible workarounds:

  1. Keep the handles of all the relevant Java components, and then delete them directly:
    delete(hContainer)
  2. Use findobj to delete all components, rather than the clf function (we use setdiff to prevent deletion of the figure window itself):
    delete(setdiff(findobj(gcf),gcf))

Note that this bug does not occur when using HG2. However, for users who use the still-standard HG1, this bug is still unfixed as of Matlab R2013b Pre-release (which is now available for download for subscribed users).

GUIDE is unusable with dbstop if error (1-MH5KVI)

In R2013a (Matlab 8.1) I encounter a recurring error when attempting to inspect properties of objects in GUIDE, when “dbstop if error” is turned on.

The error happens when I have “dbstop if error” enabled. This is an enormously helpful debugging tool, so I normally have it turned on in my startup.m file. But in R2013a, if I try to inspect an object’s properties in GUIDE, I see a problem. Matlab hits the breakpoint in %matlabroot%/toolbox/matlab/codetools/+internal/+matlab/+inspector/SceneViewerListener.m line 99 due to the fact that isvalid() is not defined for the object, and the inspector window remains blank.

How to reproduce:

  • run “dbstop if error” in the Matlab command window
  • open a *.fig file in the Matlab command window (e.g., “guide myApplication.fig“)
  • right-click and inspect the properties for an axes (for example)
  • wait for the breakpoint to occur – “K>>” in the command window; the Editor stops (green arrow) in SceneViewerListener.m line 99
  • an empty inspector window is displayed

Analysis:
Because SceneViewerListener is called from Java, not Matlab, the error is thrown as an exception that is trapped by the Java code and therefore does not appear to the user unless “dbstop if error” is on. Here is the full stack trace at the point of error (see this post regarding how to generate the Java stack dump):

K>> dbstack
> In SceneViewerListener>SceneViewerListener.isBeingDeleted at 99
 
K>> st = java.lang.Thread.currentThread.getStackTrace; for idx = 2 : length(st), disp(st(idx)); end
com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Native Method)
com.mathworks.jmi.NativeMatlab.sendMatlabMessage(NativeMatlab.java:219)
com.mathworks.jmi.MatlabLooper.sendMatlabMessage(MatlabLooper.java:120)
com.mathworks.jmi.Matlab.mtFeval(Matlab.java:1540)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.isBeingDeleted(JidePropertyViewTable.java:154)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.filterOutInvalidObjects(JidePropertyViewTable.java:170)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.setObjects_MatlabThread(JidePropertyViewTable.java:187)
com.mathworks.mlwidgets.inspector.PropertyView.setObject_MatlabThread(PropertyView.java:655)
com.mathworks.mlwidgets.inspector.PropertyView.setObject_AnyThread(PropertyView.java:591)
com.mathworks.mlwidgets.inspector.PropertyView.access$1300(PropertyView.java:37)
com.mathworks.mlwidgets.inspector.PropertyView$RegistryHandler.itemStateChanged(PropertyView.java:698)
java.awt.AWTEventMulticaster.itemStateChanged(Unknown Source)
com.mathworks.services.ObjectRegistry.fireItemEvent(ObjectRegistry.java:763)
com.mathworks.services.ObjectRegistry.setSelected(ObjectRegistry.java:700)
com.mathworks.services.ObjectRegistry.setSelected(ObjectRegistry.java:617)
com.mathworks.mde.inspector.Inspector.setSelected(Inspector.java:584)
com.mathworks.mde.inspector.Inspector.inspectObjectArray(Inspector.java:569)
com.mathworks.mde.inspector.Inspector.inspectObjectArray(Inspector.java:520)
com.mathworks.mde.inspector.Inspector$11.run(Inspector.java:478)
com.mathworks.jmi.NativeMatlab.dispatchMTRequests(NativeMatlab.java:347)

Workaround:
replace the existing code of SceneViewerListener.m:

>> edit internal.matlab.inspector.SceneViewerListener
 
...
if ~isvalid(selectedObject)
    beingDeleted = true;
elseif isprop(selectedObject,'BeingDeleted') && strcmp('on',selectedObject.BeingDeleted)
    beingDeleted = true;
elseif ~isempty(ancestor(selectedObject,'figure')) && strcmp('on',get(ancestor(selectedObject,'figure'),'BeingDeleted'))
    beingDeleted = true;
else
    beingDeleted = false;
end

with the following (changed lines are highlighted):

if any(~isobject(selectedObject))    beingDeleted = false;elseif ~isValid    beingDeleted = true;
elseif isprop(selectedObject,'BeingDeleted') && strcmp('on',selectedObject.BeingDeleted)
    beingDeleted = true;
elseif ~isempty(ancestor(selectedObject,'figure')) && strcmp('on',get(ancestor(selectedObject,'figure'),'BeingDeleted'))
    beingDeleted = true;
else
    beingDeleted = false;
end

It looks like this bug was apparently fixed in the R2013b Pre-release without needing to modify SceneViewerListener. But if you still encounter this problem you now know what to do.

I have reported another GUIDE-related bug, but I do not have a workaround for this one: If you run the GUI from within GUIDE, and some uncaught error (exception) occurs, then from that moment onward you cannot save any modifications to the figure file in that session.

Do you know of any other undocumented bugs, preferably with workarounds? If so, please post them in a comment here.

 
Related posts:
  1. Internal Matlab memory optimizations Copy-on-write and in-place data manipulations are very useful Matlab performance improvement techniques. ...
  2. Matlab’s internal memory representation Matlab's internal memory structure is explored and discussed. ...
  3. Solving a Matlab hang problem A very common Matlab hang is apparently due to an internal timing problem that can easily be solved. ...
  4. Spicing up Matlab uicontrol tooltips Matlab uicontrol tooltips can be spiced-up using HTML and CSS, including fonts, colors, tables and images...
 

Using Java 7 in Matlab R2013a and earlier

$
0
0

Today I would like to introduce guest blogger Roderick, who wishes to remain anonymous. Roderick discusses his experience with setting up Matlab to use the latest stable release of Java, namely JVM 1.7, a.k.a. Java 7.

Background and executive summary

I work in the team where I do a lot of research and prototyping with Matlab. The final production code is however coded by a separate development team in Java 7. When running back-tests on our models I have to either ensure my Matlab prototype exactly matches the Java behavior, or to call the Java production code directly. However, although Java 7 has been available since July 2011, the latest official Matlab version (R2013a at this point) still uses the JVM 1.6 (Java 6), which does not allow calling Java 7 code directly. Today’s article contains my experience in trying to let Matlab use JVM 1.7 code.

I urge readers to consider the following before trying the hacks I’ve found:

  • The hacks described below were found to work for Matlab R2012b and R2013a on Windows 64bit. Simulink or any Matlab toolboxes were not tested, nor any other operating systems (although I’ve found most solutions to work on Linux as well).
  • The set of hacks is not complete; some issues remain in the setup of Matlab to use Java 7.
  • As with all other undocumented Matlab features, they may break in future Matlab versions.
  • A future Matlab version (possibly as close as the upcoming R2013b) might be updated use Java 7 natively – the hacks should only be used on versions that have JVM 1.6.

It is worth considering a number of alternatives before trying to setup Matlab with the JVM 1.7:

  • Compiling the Java project using JDK 1.6 instead of JDK 1.7. If you have the source code for a project and no specific Java 7 features are being used in the code, you could simply recompile it using JDK 1.6 or even 1.5. This would be a more advisable approach than switching Matlab to use Java 7, and enable full backward compatibility on Matlab releases as old as R2007b (for 1.6) or R14 SP2 (for 1.5).
  • Use Java Remote Method Invocation (Java RMI). This enables using Java 6 Java code that calls the Java 7 code. It requires some more work starting off, but has the benefit of not needing to switch Matlab to use Java 7. Due to using a different Java virtual machine, it also prevents duplicate dependencies between Matlab and Java code, when a Java project depends on Java libraries on which Matlab also depends. If Java code relies on a different version than Matlab for such a library, this may give problems with the Java classloader that could result in Matlab being unable to add Jar-file(s) to the java classpath – this issue is solved by separating the Java 7 code to use an independent JVM. The Java RMI approach appears to be a longer-term solution than hacking Matlab to use JVM 1.7.

If after considering the alternatives you have a valid use-case for Matlab to call Java 7 code, follow these steps:

  1. Download the latest Matlab release if you can; earlier releases have more issues with JVM 1.7
  2. Setup Matlab to use JVM 1.7
  3. Create a startup function to detect if JVM 1.7 is used; if so, update the default figure’s CreateFcn to force visibility and then use drawnow
  4. Enable the UseOldFileDialogs feature
  5. Copy and patch listdlg.m to remove the hardcoded figure CreateFcn callback override
  6. Copy and patch gui_mainfcn.m to force visibility of GUI objects by using uistack and by recursively flipping the order of all Children property, or by using the supplied code below

The text below details these steps.

Switching Matlab to use the JVM 1.7

To run Java 7 code from Matlab, Matlab needs to use JVM 1.7. To do this, see this MathWorks page, or follow these steps:

  1. Ensure that you are using Java 6 or earlier – no need to do anything if your Matlab already has Java 7
    >> version -java
    ans =
    Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode
  2. Download and install JRE 1.7 or JDK 1.7 from the Oracle website
  3. Create a new System Environment Variable called MATLAB_JAVA with the installation folder as its value. For example: “C:\Program Files\Java\jdk1.7.0_21\jre”
  4. Restart Matlab and verify that it picked up the new Java version:
    >> version('-java')
    ans =
    Java 1.7.0_21-b11 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode

Problems and workarounds with Matlab using JVM 1.7

Certain Matlab functionality was found to give issues when using the JVM 1.7. Most problems are related to visibility and display, although most Matlab code ran as-is without issue.

A) Matlab hangs after “Save As” or “Import Data”

Matlab hangs after clicking the <Import Data> button, or when trying to use the <Save As> functionality. This problem seems to be related to opening a certain type of window after which focus is not returned to Matlab. The user is forced to close Matlab via the Windows Task Manager. This problem was found in R2012b and earlier, however it seems fixed in R2013a. I have not found a solution for this problem; perhaps it is related to this issue. Consider importing data via the command line, and first creating a new m-file then open it in the Matlab Editor. Alternatively, if you really get annoyed by this, you could use findobj functionality to disable the Matlab buttons.

B) Java exceptions from java.awt

Exceptions are occasionally thrown when multiple monitors are used, e.g. when moving figures from one screen to the other, or when docking figures. These exceptions can be a bit annoying, but they do not seem critical.

C) Matlab R2012b hangs using uigetfile

Matlab freezes when using uigetfile. It seems R2013a does not have this problem; for R2012b a solution was found by setting the undocumented UseOldFileDialogs feature:

feature('UseOldFileDialogs', 1)
D) Defective Matlab dialog windows

Certain Matlab dialogs, such as questdlg, listdlg and inputdlg are missing some components. For example:

ButtonName = questdlg('What is your favorite color?', 'Color Question', 'Red', 'Green', 'Blue', 'Green');

Defective dialog window with Java 7

Defective dialog window with Java 7

The problem seems to be related to visibility of the objects, whereby the command buttons or input text objects are part of the figure, but they are just not displayed. The same problem was found for Matlab GUIs that are created by Matlab users and in guide.

Solution: force the figure visibility in its CreateFcn callback, by setting the Visible property to ‘on’ and using drawnow.

set(0, 'DefaultFigureCreateFcn', @DefaultFigureCreationFcnForJVM7);
 
function DefaultFigureCreationFcnForJVM7(aObject, aEventdata)
    % PURPOSE: This function acts as the default figure create function to enforce focus for UI dialog objects % when using JVM 7.
    % IN:       - aObject (1x1 float): the handle to figure object
    %           - aEventdata (1x1 struct): the event data
    myDbStack = dbstack();
    if length(myDbStack) > 1 && any(strcmp(myDbStack(2).file, 'hgloadStructDbl.m'))
        % don't force visibility when GUIs are opened
    else
        set(aObject, 'Visible', 'on');
        drawnow();
    end

The UI dialogs flash a bit more when created, due to the fact that they resize and move around the screen for optimal placement. But at least they look ok now:

Fixed dialog window with Java 7

Fixed dialog window with Java 7

This solution works for all dialogs except listdlg, which is hardcoded to disable the figure’s CreateFcn. For listdlg, follow these steps:

  1. Find listdlg.m
    >> which listdlg
    C:\Program Files\MATLAB\R2013a\toolbox\matlab\uitools\listdlg.m
  2. Copy listdlg.m to a personal folder and comment out the figure’s CreateFcn override in the copied file:
    fig_props = { ...
        'name'                   	figname ...
        'color'                  	get(0,'DefaultUicontrolBackgroundColor') ...
        'resize'                 	'off' ...
        'numbertitle'            	'off' ...
        'menubar'                	'none' ...
        'windowstyle'            	'modal' ...
        'visible'                	'off' ...
        ... % comment out the createfcn to empty such that we don't override the specific createfcn for JVM 1.7!    ... %'createfcn'  	''    ...    'position'               	fp   ...
        'closerequestfcn'        'delete(gcbf)' };
  3. Similarly, copy the private functions getnicedialoglocation.m and setdefaultbutton.m and place their entire contents at the end of your copied listdlg.m.
  4. Ensure that your personal folder is higher on the Matlab path than toolbox\matlab\uitools\
E) Custom GUI visibility problems

If you developed custom Matlab GUIs, you might notice visibility problems when opening the GUIs. For example, assume we have developed the following simple GUI:

Sample custom GUI

Sample custom GUI

If we try to open this GUI we see missing objects again:

Defective custom GUI

Defective custom GUI

This problem seems related to the one with the Matlab dialogs, however it does not seem to be resolved by forcing visibility upon figure creation. After much trial and error, it seems we can fix this by playing around with the order of the figure’s Children:

myFigureHandle = TestGUI;
myChildHandles = get(myFigureHandle, 'Children')
set(myFigureHandle, 'Children', flipud(myChildHandles))

Defective custom GUI take #2

Defective custom GUI take #2

Notice that flipping the order of Children in the main figure did not resolve the visibility of objects in the panels. The procedure needs to be done recursively for all the figure’s containers. One more step gives:

set(myChildHandles(1), 'Children', flipud(get(myChildHandles(1), 'Children')))

Defective custom GUI take #3

Defective custom GUI take #3

Solution: for a single solution that applies to all GUIs, you can do the following:

  1. Locate gui_mainfcn.m
    >> which gui_mainfcn
    C:\Program Files\MATLAB\R2013a\toolbox\matlab\guide\gui_mainfcn.m
  2. Copy gui_mainfcn.m to a personal folder and add a new call to a specific function for handling JVM7 issues for GUIs. The location of this function is important, put it just after the following feval command:
    ...
    feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});
    % Patched logic to ensure visibility of all objectsHandleJvm7SupportForGUIs(gui_hFigure, guidata(gui_hFigure));...
  3. Place the following code at the end of your copied gui_mainfcn.m file:
    function HandleJvm7SupportForGUIs(aGUIObject, aGUIHandles)
        % PURPOSE: This function hacks around with the focus of objects on a GUI. It was found that GUIs do not
        % work as intended with the jvm 7 setup, and that objects on panels lose focus/visibility.
        % The approach which at is taken now is by flipping the order of childrens in uipanels.
        % Before the order is swapped, the panel is set to be the visible top-layer panel. 
        % IN:       - aGUIObject (1x1 float): the handle the GUI figure
        %           - aGUIHandles (1x1 struct): the GUI handles
        if ~IsJvm7Used()
            return
        end
        myListOfHandleArrayFields = 'tabPanels';
        try
            set(aGUIObject, 'Visible', 'on');
            drawnow();
     
            if isprop(aGUIObject, 'Children')
                myChildren = get(aGUIObject, 'Children');
                myIsMenuItem = false(length(myChildren), 1);
                for i = 1:length(myChildren)
                    if isprop(myChildren(i), 'Type') && strcmp(get(myChildren(i), 'Type'), 'uimenu')
                        myIsMenuItem(i) = true();
                    end
                end
                myChildren(~myIsMenuItem) = flipud(myChildren(~myIsMenuItem));
                set(aGUIObject, 'Children', myChildren);
                drawnow();
            end
     
            myFields = fieldnames(aGUIHandles);
            myIsValid = true(size(myFields));
            for i = 1:length(myListOfHandleArrayFields)
                myIsValid = myIsValid & cellfun('isempty', strfind(myFields, myListOfHandleArrayFields{i}));
            end
            myFields = myFields(myIsValid);
            myPanelFields = {};
            for i = 1:length(myFields)
                if isprop(aGUIHandles.(myFields{i}), 'Type') && strcmp(get(aGUIHandles.(myFields{i}), 'Type'), 'uipanel')
                    myPanelFields =  [myPanelFields; myFields(i)]; %#ok
                end
            end
            for i = 1:length(myPanelFields)
                % allow three layers of panels maximum!
                if isprop(aGUIHandles.(myPanelFields{i}), 'Parent')
                    myParent = get(aGUIHandles.(myPanelFields{i}), 'Parent');
                    if strcmp(get(myParent, 'Type'), 'uipanel')
                        if isprop(myParent, 'Parent')
                            mySecondParent = get(myParent, 'Parent');
                            if strcmp(get(mySecondParent, 'Type'), 'uipanel')
                                uistack(mySecondParent, 'top');
                                drawnow();
                            end
                        end
                        uistack(myParent, 'top');
                        drawnow();
                    end
                end
                uistack(aGUIHandles.(myPanelFields{i}), 'top'); 
                drawnow();
                set(aGUIHandles.(myPanelFields{i}), 'Children', flipud(get(aGUIHandles.(myPanelFields{i}), 'Children'))); 
                drawnow();
            end
        catch myException
            disp(['WARN: could not initialize the GUI correctly with JVM 1.7 override logic, in ', mfilename()]);
            myException.getReport()
        end
     
    function theIsJvm7Used = IsJvm7Used()
        % PURPOSE: To indicate if Matlab is setup to use jvm 7
        % OUT:      - theIsJvm7Used (1x1 logical): whether or not JVM 7 is used
        myJavaVersion = version('-java');
        theIsJvm7Used = strcmpi(myJavaVersion(1:8), 'java 1.7');
  4. Ensure that your personal folder is higher on the Matlab path than toolbox\matlab\uitools\

Fixed custom GUI

Fixed custom GUI

Notice that the panel names are still missing. So far no solution for this has been found. Perhaps this can be overcome using the fact that uipanel titles are simply hidden children of the panel object.

 
Related posts:
  1. Matlab-Java interface using a static control The switchyard function design pattern can be very useful when setting Matlab callbacks to Java GUI controls. This article explains why and how....
  2. 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....
  3. JMI – Java-to-Matlab Interface JMI enables calling Matlab functions from within Java. This article explains JMI's core functionality....
  4. Matlab callbacks for Java events Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
 

Waterloo graphics beta

$
0
0

Once again I’d like to welcome guest blogger Malcolm Lidierth of King’s College London. Malcolm has written several articles here, including a couple of articles on his Waterloo graphing library. Today, Malcolm discusses new features in this library, as it matures into an official beta phase.

Waterloo contour plot of Matlab's penny image

Waterloo contour plot of Matlab's penny image

Last year, Yair kindly allowed me space for a couple of guest blogs on the Waterloo graphics open-source project. Waterloo has recently transitioned to a ‘beta’ release status, with several new features – many of them in response to suggestions from readers of this blog. Many thanks to all who made those.

One of the motivations in writing Waterloo was to get better, less pixellated graphs in Matlab. By using Java 2D, the core library is not tied to Matlab. Waterloo graphics can be used wherever there is access to a Java Virtual Machine: R, ScilLab etc. MathWorks obviously feel the need for better graphics too: Yair recently blogged about the next generation Matlab graphics (HG2). The Waterloo beta release provides support for mixing both Waterloo graphs and Matlab HG2 graphs in a single figure (as well as current HG1 graphics of course).

The new features in the Waterloo beta can be summarized as:

  1. Introducing new plot types: contours, bars, polar and area charts
  2. Mouse-selectable regions of interest
  3. Support for fast-plot updates without redrawing the entire graph
  4. Support for web-deployment of the graphs using SVG or Processing and ProcessingJS

Today I will concentrate on [1] and [2], illustrated with some Matlab examples; I will discuss [3] and [4] next week.

Installation of Waterloo in Matlab

For those readers who have not yet installed Waterloo in Matlab, the process is very simple: download the latest zip file and extract it. All the sub-folders in the waterloo folder are needed but only the Waterloo_MATLAB_Library subfolder (not its subfolders) should be added to the Matlab path. Once installed, just type waterloo at the Matlab prompt in each Matlab session.

A Matlab script file that will do it all is available here (Waterloo_installer.m). The script is harmless to run if you already have Waterloo installed, but if not then it will automatically find the latest zip file on SourceForge, download and install it, and then configure the Matlab path appropriately.

Contour plots

I ended my last guest article with an example of work-in-progress: filled contours. The beta release now fully supports these.

Recall from the previous articles that GXFigure creates a Waterloo-compatible Matlab figure window. gxgca() returns a reference to the container for the graph as a Matlab GXGraph object, much as Matlab’s built-in gca returns an axes reference.

Here is Matlab’s Lincoln penny demo in Waterloo:

% Get some pre-defined colors
colors = [kcl.waterloo.defaults.Colors.getColor(0)];
for k = 1 : 17
    colors = horzcat(colors,kcl.waterloo.defaults.Colors.getColor(k));
end
 
f = GXFigure();
set(gcf, 'Name','Filled Contour', 'Units','normalized', 'Position',[0.3 0.3 0.4 0.4])
 
load penny;
ax = subplot(f,1,1,1);
ax.getObject().setAspectRatio(1);
p2 = contourf(ax, flipud(P), 18, 'LineStyle','-', 'LineWidth',0.4);
p2.getObject().setFillClipping(false);
p2.getObject().setFill(colors);
drawnow();

(resulting in the contour plot above)

To transform Abe Lincoln to a logarithmic world, just double-click the graph and select the log transform. The result is shown on the right here:

Transformed Matlab penny image

Transformed Matlab penny image

All plots in Waterloo share a common data model, including contour plots. For a scatter plot, x, y pairs in a set represent the offsets to display a marker e.g. a circle or square that is generally of fixed size. For a contour plot, the marker is the contour line and the values for that incorporate the offsets. The xdata and ydata are added during plotting; while these will normally be zero, this makes it trivial to construct montages of contour plots simply by using non-zero values.

Plainly, this needs some extra work to support the common model: circles for a scatter plot are still painted as fixed diameter circles when the plot is rescaled or transformed but the pixel values for a contour line, bar plot etc will need to be recalculated. To achieve this:

  • the data model incorporates an extra object to do the work
  • such plots implement a new interface – GJTransformUpdateInterface – that specifies a transformUpdate() method that refreshes the pixel-coordinates. End-users will not normally need to concern themselves with this, as transformUpdate method will be called by the listeners as required.

Categorical data

Waterloo always uses numeric data to position markers, bars etc in a plot. However, categorical data can be used to supplement those data. Here is an example using the new bar plot:

Categorized Waterloo bar plot Categorized Waterloo bar plot

Categorized Waterloo bar plots

f = GXFigure();
set(gcf, 'Name','TestBar4', 'Units','normalized', 'Position',[0.1 0.1 0.8 0.8]);
m = {'Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'};
gr1 = subplot(f, 2, 2, 1);
a = bar(gr1, 1:12, 1:12);
for k = 1 : 12
   a.getObject().getDataModel().getXData().setCategory(k, m{k});
end
gr1.getObject().setTitleText('Label using the XData categories');
gr1.getObject().getView().autoScale();

Support for categorical labels on the axes is supported for all plots via the common data model. For bar charts, the extra object associated with the plot also supports adding labels to the bars themselves:

f = GXFigure();
set(gcf, 'Name','Categorized Bars', 'Units','normalized', 'Position',[0.3 0.3 0.4 0.4]);
m = {'Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'};
gr = subplot(f, 1, 1, 1);
c = barh(gr, 1:10, 1:10,'stacked');
c.getObject().setFill([java.awt.Color.yellow, java.awt.Color.blue]);
c.getObject().getDataModel().getExtraObject().setFontForeground([java.awt.Color.BLACK, java.awt.Color.WHITE]);
for k = 1 : 12
   c.getObject().getDataModel().getExtraObject().getLabels().add(k-1, m{k});
end
gr.getObject().getView().autoScale();

Note that the standard method setFill, is used to set the bar colors and as two colors are supplied the data are assumed to contain a pair of multiplexed series. This is common to all plots.

To customize the labels, we need to set a property in the extra object which is retrieved with a call to c.getObject().getDataModel().getExtraObject().

The same principles apply to pie charts:

Labelled Waterloo pie chart

Labelled Waterloo pie chart

f = GXFigure();
set(gcf, 'Name','TestPie1', 'Units','normalized', 'Position',[0.1 0.1 0.8 0.8]);
colors = [kcl.waterloo.defaults.Colors.getColor(0)];
y = ones(1,18)*100/18;
gr = subplot(f, 1, 1, 1);
colors = [kcl.waterloo.defaults.Colors.getColor(1),...
    kcl.waterloo.defaults.Colors.getColor(17),...
    kcl.waterloo.defaults.Colors.getColor(2),...
    kcl.waterloo.defaults.Colors.getColor(16),...
    kcl.waterloo.defaults.Colors.getColor(3),...
    kcl.waterloo.defaults.Colors.getColor(15),...
    kcl.waterloo.defaults.Colors.getColor(4),...
    kcl.waterloo.defaults.Colors.getColor(14)];
c = pie(gr, [10 20 45 42 22 26 42 20], logical([0 0 1]), 'FaceColor',colors);

Polar charts

Polar bar and compass charts are also now supported:

Waterloo polar bar chart (click for details)Waterloo compass chart (click for details)

Waterloo polar bar and compass charts (click for details)

f = GXFigure();
set(gcf, 'Name','TestPie1', 'Units','normalized', 'Position',[0.1 0.1 0.8 0.8]);
load sunspot.dat  % Contains a 2-column vector named sunspot
colors = [kcl.waterloo.defaults.Colors.getColor(0)];
for k = 1 : 17
    colors = horzcat(colors,kcl.waterloo.defaults.Colors.getColor(k));
end
gr1 = subplot(f, 1,2, 1);
a = polarbar(gr1, sunspot(1:48,2), 'FaceColor',colors, 'EdgeWidth',0.5);
 
[a,b] = hist(sunspot(:,2),12);
gr2 = subplot(f, 1,2, 2);
b = polarbar(gr2, a, 'FaceColor',colors);
 
Z = eig(randn(20,20));
a = compass(gr1, real(Z), imag(Z), 'LineColor','r');

Area plots

Area plots are supported through a new plot class and also by having all plots implement a new Java interface. To illustrate, create two line plots:

Waterloo area-fill chart

Waterloo area-fill chart

f = GXFigure();
set(gcf, 'Name','TestAreaFill', 'Units','normalized', 'Position',[0.4 0.1 0.5 0.4]);
x = 0.5 : 0.5 : 10;
y = sin(x);
gr1 = gxgca();
a1 = line(gr1, x, y, 'LineSpec','-ob');
b1 = line(gr1, x, y*2, 'LineSpec','-sg');
gr1.getObject().getView().autoScale();
 
% Filling the area between the two plots requires one extra line and a refresh call to paint the result:
a1.getObject().setAreaFill(b1.getObject());
refresh();

All the work is done in the Java code because plots now implement the GJFillable interface. All that is required is to call the setAreaFill() method on a class implementing GJFillable, specifying another GJFillable as input.

A new java class, GJFill, also implements GJFillable and can be used to fill an area relative to a scalar constant or an arbitrary shape. I have also written a Matlab wrapper class for this (GXFill, see below) but I shall use a Java-based example here.

Whether the fill is made horizontally (from the plot) or vertically (from the axes) can be selected by setting the orientation property of the GJFill instance. This can also be set to arbitrary, in which case we can create a custom fillable area sythesized from java.geom shapes:

Waterloo full area fill chart Waterloo custom area fill chart

Waterloo full (above) & custom (below) area fill charts

f = GXFigure();
set(gcf, 'Name','Constant Fill', 'Units','normalized', 'Position',[0.3 0.3 0.4 0.4]);
x = 0.5 : 0.5 : 10;
y = sin(x);
gr1 = subplot(f, 1, 1, 1);
a1 = line(gxgca, x+1, y+3, 'LineSpec','-sg');
 
% Now create a GJFill instance, using a constant as the reference (1.5 in this case), and use this as this area's fill
v = kcl.waterloo.graphics.plots2D.GJFill(a1.getObject(), 1.5);
a1.getObject().setAreaFill(v);
 
%% Start complex
   % Alternately, we can use an arbitrary fill shape:
   v.setOrientation(javaMethod('valueOf', 'kcl.waterloo.graphics.plots2D.GJFill$ORIENTATION', 'ARBITRARY'));
   a1.getObject().setAreaFill(v);
 
   % Create a shape (which can be complex)
   area = java.awt.geom.Area(javaObject('java.awt.geom.Rectangle2D$Double',1,1,5,5));
   area.add(java.awt.geom.Area(javaObject('java.awt.geom.Rectangle2D$Double',8,1,2,5)));
 
   % Add the shape to the GJFill instance
   v.setArbitraryArea(java.awt.geom.Area(area));
%% End complex
 
% Customize the fill color
v.setAreaPaint(java.awt.Color(0,1,0,0.5));
 
% Manually rescale and refresh the plot
gr1.getObject().getView().setAxesBounds(0,0,12,5);
refresh();

To make this simpler from Matlab, a new Matlab class GXFill is provided. This constructs and adds a fill in a single step:

fill = GXFill(plot_reference, value, orientation);

where value is a scalar or a Java Shape object, and orientation is a string e.g. ‘horizontal’. Note that the coordinates are specified in axes units and they will rescale and be transformed as needed when the axes are changed.

Specifying/selecting ROIs

Finally, regions of interest (ROIs) can be selected both programmatically and with the mouse. One of these can be set as the “current” ROI and that is the one that is mouse selectable: set the current ROI using shift-left mouse drag, set the region and rescale to display only that region using shift-right mouse drag.

To create an ROI that can be dragged and resized, add a GJRoi instance to the graph, e.g. with an existing current ROI selected:

gr = gxgca;
gr = gr.getObject().getView();
gr.add(kcl.waterloo.graphics.GJRoi.createInstance(gr, gr.getCurrentROI()));

Waterloo and Matlab’s Java support

Note: It appears that HG2, like HG1, creates an offscreen bitmap that is then blitted onto a Java Canvas within a Matlab figure. Matlab warns that the JavaFrame property will (no longer may) be discontinued in some future release, but it is my guess that this will not be the case when HG2 is released. A new set of uicontrols may indeed be included using a C-based library like wxWidgets or Qt. However, it seems unlikely that Java support will be dropped completely – too much of Matlab’s GUI uses Java (for example, the new desktop introduced in R2012b is entirely Java-based). So the Waterloo Matlab library should work, even if a switch is needed to using JFrames instead of Matlab figures for output.

For the adventurous, Waterloo graphs can also be deployed using JavaFX via the SwingNode class – but that requires installation of the latest Java 8 (currently in early release status). Noting that Matlab is still (as of R2013a) using Java 6, this may indeed be a big jump (note last week’s article on upgrading Matlab to use Java 7).

Naturally, Waterloo’s graphs and classes can also be used in stand-alone Java applications, entirely outside Matlab, even on a $30 ARM6 Raspberry Pi.

Next week, I will look at methods for animating plots (e.g. using Matlab timers) and deploying vector graphics to web pages using the in-built GUIs.

 
Related posts:
  1. Waterloo graphics Waterloo is an open-source library that can significantly improve Matlab GUI. ...
  2. Waterloo graphics examples Some Matlab usage examples for the open-source Waterloo graphics package. ...
  3. Waterloo graphics animation and web deployment Waterloo graphics can be updated very quickly in Matlab, enabling plot animation; web deployment of the graphics is also possible. ...
  4. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
 

Waterloo graphics animation and web deployment

$
0
0

Once again I’d like to welcome guest blogger Malcolm Lidierth of King’s College London. Last week Malcolm wrote about integrating the Waterloo graphing library in Matlab figures. Today, Malcolm discusses advanced features in this library.

Readers who are interested in high-quality plotting in Matlab may also be interested in the JFreeChart and MTEX open-source packages. JFreeChart provides chart types that are unavailable in Matlab, while MTEX builds upon existing Matlab plots using sophisticated data analysis and visualization. Unlike JFreeChart, I haven’t mentioned MTEX here before. MTEX is definitely worth a good mention, perhaps I’ll write about it someday. If you are using any other good charting packages for Matlab, please add a comment below.

A feature request received from several of Yair’s readers for the Waterloo graphics project was for fast updating and animation of plots. This week, I’ll describe features supporting this. As those need to be illustrated here on a web page, I’ll also describe Waterloo’s new deploy-to-web feature.

Waterloo animated plot

Waterloo animated plot


Updating Waterloo plots

Recall that Waterloo provides a Matlab OOP class called GXPlot, which wraps the underlying Waterloo plot type and can be retrieved using the getObject() method. For a GXPlot named p, the data can easily be updated from Matlab by passing it a new data array of values:

p.getObject().getXData().setDataBufferData(XData);
p.getObject().getYData().setDataBufferData(YData);

This will be fast enough for most purposes, although the exchange of arrays between Matlab and Java is done by copying the data rather than by reference (a limitation imposed by the Java Native Interface rather than Matlab).

If only a few data points are to be changed at any one time, an alternative approach is available of setting individual data points (referenced by their index, 0 being the first):

p.getObject().getXData().setEntry(index, value);
p.getObject().getYData().setEntry(index, value);

These methods will update the plot p, as well as all other plots that share its underlying data buffer.

All that is then needed is to update the display. This means:

  1. Optionally, checking and rescaling the axes as needed
  2. Calling repaint on the graph or its container

The best way will often be to make the container a listener on the relevant data object (the container houses the axes, so these will then be repainted if the scale changes). For example, for the YData:

% get a reference to the plot's graph container
container = p.getObject().getParentGraph().getGraphContainer();
 
% attach the graph as a listener to the ydata buffer 
dataObject = p.getObject().getYData();
dataObject.addPropertyChangeListener(p.getObject().getParentGraph());

Now any change to the YData object will fire a property change event causing the display to update.

A simple example

Waterloo animated bar plot

Waterloo animated bar plot

f = GXFigure();
set(gcf, 'Units','normalized', 'Position',[0.3 0.3 0.4 0.4], 'Name','TestUpdate1');
 
% Create some data and plot a bar chart
Y = hist(randn(1,100), 50);
 
container = gxgca();
p = bar(container, -1:0.0408:1, Y, 'BarWidth',0.0408, 'Fill','LIGHTCORAL');
container.getView().setAxesBounds(-1,0,2,225);
container.getView().setBackground(kcl.waterloo.defaults.Colors.getColor('WHEAT'));
container.getView().setBackgroundPainted(true);
refresh();
 
% Attach the graph as a listener to the ydata buffer 
p.getObject().getYData().addPropertyChangeListener(p.getObject().getParentGraph());
 
% Now update the ydata in a loop - pausing for 0.1s on each iteration.
% The listener attached above will cause a repaint
for k = 1 : 50
    Y = hist(randn(1,100),50);
    Y = Y + p.getObject().getYData().getRawDataValues().';
    p.getObject().getYData().setDataBufferData(Y);
    pause(0.1);
end

Note that the repaints will be done on the Event Dispatch Thread (EDT). The call to the Matlab pause above causes EDT to be flushed so a full repaint is done for each iteration of the loop. Using a timer, as in the example below, can avoid this and allows the Swing repaint mechanisms to collapse multiple repaint calls into a single rendering operation. This will almost always be faster: use drawnow and pause sparingly with Waterloo code.

Improving speed

Refreshing the display as above requires that

  1. the graph container is repainted together with the axes – using internal axes that are rendered as part of step [2] will speed this up
  2. the graph is repainted including grids and internal axes – speed this up by turning off, or reducing the number of, grid lines. Switch off background painting – the container’s background will suffice (this is the default).
  3. the plot displays are updated – to speed this up:
    • Use objects that are easily translated into a square pixel-grid on screen. e.g. use squares instead of circles in a scatter plot
    • Use solid lines, not dashed or dotted ones
    • Turn off anti-aliasing of the plot

As painting is done on the EDT it will not block the Matlab thread. The time taken to update a plot will be variable, but it typically takes 5-20 msecs.

Fast plot updates

In the beta release, new methods have been added to the plots: plotRedraw() and plotUpdate() both redraw a plot without refreshing the background, grids or axes.

In the default implementation, plotUpdate simply calls plotRedraw: there actions are identical. plotUpdate is intended to be overridden in custom user subclasses to paint only points that have been added to end of a plot since the last update and the logic to do that needs to be added to the plot methods in those subclasses.

This logic can also be synthesized on-the-fly (e.g. in Matlab, as in the example below) by adding NaNs in the data objects – Waterloo ignores these values. In the example below, a timer is used to update the plot.

function update2(thisDelay)
 
    if nargin == 0
        DELAY = 0.01;
    else
        DELAY = thisDelay;
    end
 
    % Set up and create some data
    f = GXFigure();
    set(gcf, 'Units','normalized', 'Position',[0.3 0.3 0.4 0.4], 'Name','TestAnimation');
    x = linspace(-pi*4, pi*4, 50);
    y = cos(x);
 
    % Now  the plot
    gr1 = subplot(f, 1,1, 1);
    p1 = line(gxgca, [], [], 'LineSpec', '-og');
    gr1.getObject().getView().setAxesBounds(-pi*4,-2.5,pi*8,5);
 
    % We'll draw 2 points only in each timer call below (2 points needed for interconnecting line)
    % This plot will therefore show only these points when the normal paint mechanism is
    % used unless all the data are added at the end: which the timer callback below does
    p1.getObject().setXData(x(1:2));
    p1.getObject().setYData(y(1:2)*2);
 
    p1.getObject().getParentGraph().setLeftAxisPainted(false);
    p1.getObject().getParentGraph().setRightAxisPainted(false);
    p1.getObject().getParentGraph().setTopAxisPainted(false);
    p1.getObject().getParentGraph().setBottomAxisPainted(false);
    p1.getObject().getParentGraph().setInnerAxisPainted(true);
    p1.getObject().getParentGraph().setInnerAxisLabelled(true);
 
    p1.getObject().getParentGraph().getGraphContainer().repaint();
    drawnow();
 
    t = timer('ExecutionMode','fixedSpacing', 'Period',DELAY, 'TimerFcn', {@localTimer, p1.getObject(), x, y});
    start(t);
 
    function localTimer(t, EventData, p1, x, y)
        k = get(t,'TasksExecuted');
        if k > numel(x)
            % Finished
            stop(t);
            p1.setXData(x);
            p1.setYData(y*2);
            p1.plotRedraw();
        elseif k > 1
            % Add 2 new data points to the plot
            p1.setXData(x(k-1:k));
            p1.setYData(y(k-1:k)*2);
            p1.plotRedraw();
        end
    end  % localTimer
 
end  % update2

Calls to plotRedraw and plotUpdate are extremely fast, typically 1-2 msecs. Each call to plotRedraw() adds two new data points to the existing plot. The result is the animated plot shown at the very top of this article.

Notes:

  • this example used the same timer callback to update both data and display; it will often be best to do this is separate callbacks – the refresh rates for data update and display animation can then be set independently.
  • readers who need plot animation may find interest in the related Matlab functions comet and comet3, or this week’s POTW multicomet.
  • plot animation in standard Matlab typically relies on the EraseMode property. In the upcoming HG2, this mechanism will no longer work, at least as seen in the HG2 prequel that is available today. So if your code uses any plot animation, you should expect it to break when HG2 is released (2014?), and you will need to convert your code to use HG2′s new animation functionality. Waterloo graphs and animation, being independent Java-based, are not expected to be affected, and will run the same way in both HG1 and HG2.

Deploying graphics to the web

Waterloo enables export of static graphics to a variety of vector and bit-mapped formats (PNG, PDF, SVG etc.) that can be included in web pages. In the beta version, deployment to web is also supported directly, with automatic generation of the graphics files together with accompanying HTML files and optional CSS styling sheets and supporting Javascript. These are available from the Graph Editor, which is activated by double-clicking a graph and selecting the world (Waterloo world icon) button.

Two formats are presently supported:

  • Scalable Vector Graphics (SVG). By default, the generated files provide conversion of the SVG to HTML5 canvas commands when loaded into a browser via the canvg.js JavaScript by Gabe Lerner. Use of canvg provides better cross-browser consistency in the rendering of the graphics, particularly for text. Note that only static graphics are presently supported with SVG.
  • Through the Processing script language for visual arts and processing.js JavaScript.

Processing script output supports animations using a new class developed for Waterloo (PDEGraphics2D), which also supports an AWT/Swing container. The generated script files can be loaded and customized using the Process.app file available at the web site above.

In addition, experimental (and presently quirky) support for generating animated GIFs is included. The animations for this blog were generated using this. Animated GIFs are to be preferred when vector graphics are not required because GIFs

  • are universally and consistently supported in browsers
  • are smaller and less computationally intensive. They therefore consume less power and are environmentally friendlier. Visitors to a website, especially those using battery-powered devices, are likely to stay longer on the site.

For the present, only static graphics are supported through the GUIs, so animations need to be created programmatically. A “record” button will be added to the GUIs in future Waterloo releases.

Users can edit the default settings for deployment using the preferences editor, now available from the Graph Editor using the key (Waterloo key icon) button. For SVG, the options are shown below: allowing a choice of whether SVG is to be embedded in the generated HTML file; whether canvg.js should be used and selection of a styling sheet. Customize the file addresses relative to the target folder for the HTML file or use a URL. The “httpd.py” file here is a Python 2.7 script that will set up a local server and display the HTML file in your system browser – it is needed only if the security rules for your browser prevent the files being loaded directly from the local file system.

Waterloo preferences window

Waterloo preferences window

By default, the deploy tool uses a template index.html file that is embedded in the distribution. You can specify your own instead, although I have not yet added that to the Preferences GUI.

 
Related posts:
  1. Waterloo graphics examples Some Matlab usage examples for the open-source Waterloo graphics package. ...
  2. Waterloo graphics beta The Waterloo graphics library extends Matlab graphics with numerous customizable plots that can be embedded in Matlab figures. ...
  3. Waterloo graphics Waterloo is an open-source library that can significantly improve Matlab GUI. ...
  4. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
 

JGit-Matlab integration

$
0
0

I would like to introduce guest blogger Mark Mikofski, of SunPower Corp. Mark has developed the JGit4MATLAB utility, which can be used to integrate Matlab with the popular JGit open-source version-control system.

Introduction

JGit logo

JGit logo

JGit is an open-source Java implementation of Git, a popular distributed version control system. Since Matlab is essentially a Java interpreter, JGit is an obvious candidate for integrating Git into Matlab. Luckily, JGit also comes with a porcelain class that has the most popular commands conveniently packaged. This is the starting point for JGit4MATLAB – a thin Matlab wrapper utility on the Matlab File Exchange.

The first step is to download and install JGit4MATLAB in your Matlab path. The first time that the JGit Matlab class is called, it downloads the latest version of org.eclipse.jgit.jar, adds it to Matlab’s static Java classpath and makes a backup of the existing javaclasspath.txt file as javaclasspath.JGitSaved. Matlab must then be restarted for the changes to the static Java class path to take effect. From now on, you can use the commands in the JGit Matlab class or the jgit.m wrapper function. These use basic JGit commands, which shall be described below:

Most of the important JGit methods are encapsulated in the Matlab JGit wrapper class and jgit.m function, but you can also use them directly if you wish. The Matlab wrapper currently supports ADD, BRANCH, CHECKOUT, CLONE, COMMIT, DIFF, INIT, LOG, MERGE & STATUS, but there are many more in org.eclipse.jgit.api.Git that you can use directly. In fact you don’t really need to use the wrapper at all if you don’t want to – all you really need is the JAR file, which the wrapper downloads and installs for you. You can also download the JAR file independently from here (latest only, which is what JGit4MATLAB does), or here (latest and previous releases). If you’re using JGit4MATLAB, you can update the JAR file to the latest version at will, by issuing JGit.downloadJGitJar('@JGit\org.eclipse.jgit.jar').

The most basic Git commands are clone, init, add and commit. Let us explore how to use JGit’s “Git-Porcelain API” class in Matlab to perform these tasks.

Clone and Init

Clone and Init are both class methods of the Git-Porcelain API class and return a Command API class object, which is what nearly all of the Git-Porcelain methods do:

import org.eclipse.jgit.api.Git   % import the package
cloneCMD = Git.cloneRepository;   % return a CloneCommand object
URI = 'git://github.com/mikofski/JGit4Matlab.git';   % a Git repository
cloneCMD.setURI(URI)   % set the repository to clone
g = cloneCMD.call;   % clone the repository

or more compactly:

g = org.eclipse.jgit.api.Git.cloneRepository.setURI(URI).call;

The call method executes the command with the options and arguments set by the other methods. Calling the clone method also returns a Git instance. The full API for the CloneCommand class lists all the possible options and arguments for cloning. One option lets you set an optional progress monitor; there are some already included in JGit, but unfortunately, they use the carriage return (or ‘\r’) escape sequence which in Windows is the same as a newline (read here). So, I implemented a customized ProgressMonitor class for Matlab that uses backspace (or ‘\b’) instead.

Init is very similar to clone:

g = org.eclipse.jgit.api.Git.init.call;

Configuring author information

Before moving on, it is important to set the “author” and “email” fields in the Git config. JGit will use your computer’s info if you provide nothing. You probably want to set these values globally, so the place to put them is in your $HOME folder in the “.gitconfig” file.

file = java.io.File(fullfile(getenv('home'),'.gitconfig'));
gitconfig = org.eclipse.jgit.storage.file.FileBasedConfig(file, org.eclipse.jgit.util.FS.DETECTED);
gitconfig.setString('user',[], 'name','John Doe');       % place your name in here
gitconfig.setString('user',[], 'email','john@doe.com');  % place your email in here
gitconfig.save;

Hopefully your commits will all have the right name and email address in them from now on.

Typical JGit Workflow

Now that you have a Git repository, you will want to start working with it. The typical workflow is to create a feature branch in which to work. But first JGit needs a Git instance. If you saved it from cloning or initializing a new repo then good for you! But if you need to recreate it, just pass the constructor a File object that points to the .git folder inside your Git repo:

JGit workflow

JGit workflow

file = java.io.File(fullfile('path', 'to', 'repo', '.git'));
g = org.eclipse.jgit.api.Git.open(file);
g.checkout.setCreateBranch(true).setName('newbranch').call;

Now you are no longer on the “master” branch, which is usually reserved for buildable/deployable code. Start working. But before you do too much, commit your work to your branch:

g.add.addFilepattern('file1.m').addFilepattern('file2.m').call;
g.commit.setMessage('initial dump').call;

JGit commit log

JGit commit log


All commits should have a message, so you know what work was completed in that commit. Branch and commit frequently. You can always clean them up later. There are lots of options for adding and committing files, so look at the API’s AddCommand and CommitCommand classes.

Everything else is pretty much the same as above: Get a Git instance; create a command; set the options; and finally call the command:

file = java.io.File(fullfile('path', 'to', 'repo', '.git'));
g = org.eclipse.jgit.api.Git.open(file);
r = g.getRepository;  % a Repository instance can be very useful
g.status.call;
g.log.call;
g.checkout.setName('master').call;
g.merge.include(r.resolve('newbranch')).call;
g.push.call;
g.pull.call;

Note: Repository.resolve() is one of the most powerful methods.

The JGit log window on the left can be gotten using glog – the standalone JGit command line log GUI (slightly similar to gitk) that can be downloaded as a binary for systems with /bin/sh from the eclipse site (same place as the jar download).

Some tricks can be gleaned by what little work I’ve done so far on the JGit4MATLAB wrapper on the Matlab File Exchange. I’ll be happy to answer whatever questions I can there, or comments here. I’m also happy to accept pull requests on Github, of course using JGit4MATLAB!

Authentication

You can only use an SSH paired keys to authenticate remote repositories, the keys must **not** have a pass-phrase, they must be in the openSSH format and they must be in $HOME/.ssh. PuTTYgen let’s you do all of this, so it’s really not an issue. Of course you can still use remotes that do not require authentication with no problems.

All commands that deal with remotes and that require authentication, e.g. CLONE, FETCH, PULL, PUSH, will only work

  • with SSH
  • with *no* passphrase
  • with keys in the openSSH format
  • with keys and known hosts in $HOME\.ssh

Obviously remotes that do not require authentication will work fine. e.g. public, read-only and local repositories.

SSH is very easy to set up:

  1. Download puttygen (Intel x86). Disregard the “Intel x86″ business, it doesn’t matter what processor you have or whether your os is 64-bit or 32-bit. Puttygen is a very mature well establish application that is used by many other applications, for example all of the TortoiseXXX scm clients use Putty, Plink and Pageant. Here is the actual download here (click to download then click to install): http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe
  2. Create a folder called .ssh in your %USERPROFILE%. On Windows 7 this is C:\Users\ and on XP it is C:\Documents and Settings\. You can do this in Matlab: mkdir(fullfile(getenv('userprofile'), '.ssh')).
  3. Create a key using puttygen, this is fairly self explanatory, and kind of fun, but do *not* set a pass-phrase; leave those fields blank!
  4. Using puttygen, find the conversion menu tab and export the key in the openSSH format to the .ssh folder that you created earlier.
  5. Now copy and paste your public key to your remote repositories (Github, Bitbucket, etc.) as needed. Jsch, which is the ssh client that JGit uses, should now work out of the box.

Unfortunately using SSL (HTTPS) isn’t possible with JGit4MATLAB. Sorry. but hopefully you’ll love the excitement of using ssh key pairs!

Further development

Possible future work on the Matlab-JGit integration includes assigning standard keyboard-shortcuts to common source-control tasks, integration as toolbar/toolstrip icons for easier access, and in the Matlab Editor in general. Only a few days ago, a reader on this blog has shown interest in this.

In the far future, integration with Matlab’s existing source-control system. Anyone wish to pick up the glove?

JGit is covered by the BSD 3-clause license which is very permissive, and should allow MathWorks or anyone for that matter to develop an integrated JGit application for Matlab. There are more packages in JGit than just the porcelain API, including Swing utilities and other utilities that can be used to create rich user interfaces and experiences, but the development would have to be in Java. Developers should look at the developer’s section of the JGit website and use either the Maven or Github repository to set up their forks.

Conclusion

JGit and Matlab are a natural combination. JGit is a mature and thorough open-source project. Most porcelain commands are available without any additional work. There are some arcanae, but the API documentation is sufficient to figure out most things using short high-level code. If you find yourself diving too deep, then scan the docs some more, and you will probably find a shortcut.

 
Related posts:
  1. Using Groovy in Matlab Groovy code can seamlessly be run from within Matlab. ...
  2. JBoost – Integrating an external Java library in Matlab This article shows how an external Java library can be integrated in Matlab...
  3. Accessing the Matlab Editor The Matlab Editor can be accessed programmatically, for a wide variety of possible uses - this article shows how....
  4. Setting the Matlab desktop layout programmatically The Matlab desktop enables saving and switching layouts using the main menu. This post shows how to do so programmatically....
 

Math libraries version info & upgrade

$
0
0

version is a well-known Matlab function, which displays and returns information about the installed release:

>> [v,d] = version
v =
8.1.0.604 (R2013a)
d =
February 15, 2013
 
>> version('-java')
ans =
Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode

This is pretty boring stuff. But it starts to get interesting when we learn the undocumented fact that version can also report version information of the installed math libraries, starting in R2009b (Matlab 7.9):

FFTW logo
LAPACK logo

% R2013a (Matlab 8.1) on Win7 64b
>> version('-fftw')
ans =
FFTW-3.3.1-sse2-avx
 
>> version('-blas')
ans =
Intel(R) Math Kernel Library Version 10.3.11 Product Build 20120606 for Intel(R) 64 architecture applications
 
>> version('-lapack')
ans =
Intel(R) Math Kernel Library Version 10.3.11 Product Build 20120606 for Intel(R) 64 architecture applications
Linear Algebra PACKage Version 3.4.1

This information is sometimes useful, and is sometimes asked by users. Specific versions of BLAS, LAPACK and FFTW, which Matlab uses under its hood for all linear algebra and FFW computations, may exhibit idiosyncrasies that may be important in certain cases.

In versions up to R2013a, this information could also be retrieved using the internal.matlab.language.versionPlugins.* mex functions (e.g., internal.matlab.language.versionPlugins.blas, which runs the mex function %matlabroot%\toolbox\matlab\matfun\+internal\+matlab\+language\+versionPlugins\blas.mexw64). I’ll have a separate post (or series of posts) on Matlab’s internal.* functions, but at least with regards to version information they should NOT be relied upon. These interfaces (and their mex files) have changed their name and availability in some Matlab releases. Luckily, the version format that I showed above seems pretty stable and can be used as-is across multiple Matlab releases.

Here is a summary of the math libraries version in recent Matlab releases (Windows only):

Matlab release FFTW MKL (BLAS) LAPACK
R2009b SP1 (7.9.1) 3.2.0-sse2 10.2.2 (2009-08-14) 3.1.1
R2010a (7.10) 3.2.2-sse2 10.2.2 (2009-08-14) 3.2.1
R2010b (7.11) 3.2.2-sse2 10.2.3 (2009-11-30) 3.2.1
R2011a (7.12) 3.2.2-sse2 10.2.6 (2010-07-28) 3.2.2
R2011b (7.13) 3.2.2-sse2 10.3.2 (2011-01-17) 3.2.2
R2012a (7.14) 3.2.2-sse2 10.3.5 (2011-07-20) 3.3.1
R2012b (8.0) 3.3.1-sse2 10.3.9 (2012-01-31) 3.3.1
R2013a (8.1) 3.3.1-sse2-avx 10.3.11 (2012-06-06) 3.4.1

Note that the LAPACK version is not always updated together with BLAS, although they are both part of Intel’s MKL (more on MKL below).

Do you know of any other hidden version info anywhere in Matlab? If so, please post a comment below.

Upgrading library versions

It may well be possible for users to upgrade the internal libraries that Matlab uses to the latest version, assuming that backward compatibility is preserved in these libraries (which I suppose is the case). Naturally, you can only upgrade if you have a license for the upgraded library. For those interested, the libraries are located in %matlabroot%/bin/%arch%. For example: C:\Program Files\Matlab\R2013b\bin\win64\mkl.dll is Intel’s MKL (Math Kernel Library), which contains BLAS and LAPACK. Using this example, the latest official version of MKL is 11.0, which promises several important improvements over R2013a’s bundled version (10.3.11):

  • A fix for a bug in the svd routines
  • Improved performance
  • Improved support for Intel’s AVX2 instruction set (see related comment by Eric Sampson recently)
  • Improved functionality of MKL’s FFT implementation — Matlab’s *fft functions use FFTW, but in some cases MKL’s FFT implementation outperforms FFTW’s. You may wish to use MKL’s FFTW wrapper in such cases rather than calling MKL’s FFT routines directly.

Similarly, FFTW’s latest stable release is 3.3.3, offers advantages compared to R2013a’s bundled 3.3.1 version. Unfortunately, unlike MKL, FFTW is not bundled as a replaceable library file. I believe that FFTW is directly integrated in Matlab’s code. However, nothing prevents us from downloading the latest library and using it directly.

Warning! Needless to say, upgrading specific DLLs in Matlab can be extremely dangerous, and is entirely unsupported by MathWorks. Don’t come crying if Matlab starts to crash, or even worse – to return incorrect numerical results. If you design a car with upgraded libs, just let me know please, so that I’d know not to buy that model… I don’t often place such warnings on this blog. After all, this is a blog about undocumented / unsupported stuff. So when I do explicitly warn like this, you should take extra note. Upgrading Matlab’s math libs is purely an exercise for adventurous engineers who like to blow things up (oh, the sheer pleasure of charting undocumented waters!).

IPP library

If you have the Image Processing Toolbox (IPT), then you will also find Intel’s IPP (Integrated Performance Primitives) library (ippl.dll) in the same folder as mkl.dll. IPP is used by IPT for running some highly-optimized image-processing functions.

Intel logo Unfortunately, I could not find a parameter of version that returns the IPP version used by Matlab. However, we can get IPP’s version info using the ippl function, which is a semi-documented function in IPT (i.e., it has detailed help, but for some reason not an official doc page):

% R2013a (Matlab 8.1) on Win7 64b
>> [isIpplEnabled, ipplVersion] = ippl
isIpplEnabled =
     1                     % == true
ipplVersion = 
    'ippie9_t.lib 7.0 build 205.58 7.0.205.1054 e9   Apr 18 2011'

A few IPP-related aspects that you might find interesting in this regard:

  • Matlab currently (R2013a) uses IPPL 7.0 dated April 2011 – the latest version is 8.0 dated June 26, 2013 (only 3 weeks ago) includes significant performance boosts. Note that between 7.0 and 8.0 there was a 7.1 release that also had significant improvements, especially for modern CPUs. The 8.0 release changed some function names, so for compatibility with Matlab you might discover that you need to settle for the 7.1 DLL. This could still bring significant benefits.
  • Matlab currently limits IPP usage to uints, floats and (since R2012b) doubles, although (AFAIK) IPP also supports signed ints. For signed ints Matlab reverts to much slower functional processing, which seems a pity. I’m not 100% certain that these are indeed supported by IPP for the specific cases in which Matlab currently blocks them, but I think it’s worth a check – the performance boost could be worth the effort.
  • Matlab currently uses IPP only for some of the image-processing functions. It would make sense to use IPP much more widely, e.g. math, stats, convolution, FFT/FIR (I’m not sure it’s faster than FFTW, but it may be worth a check) and many others – IPP is much more versatile than an image processing toolkit (read here).

Even if we don’t upgrade the ippl.dll or mkl.dll version, we may still benefit by accessing them directly in Matlab and/or MEX code. They can be used in Matlab just like any other DLL. There are plenty of online resources that can help us program using the IPP/MKL functionalities, even on the Matlab CSSM newsgroup. It seems that quite a few Matlab users try to work directly with these libraries, sometimes perhaps not realizing that they are already pre-bundled within Matlab.

If you have successfully used one of these libraries directly in Matlab, and/or successfully upgraded the libs for some use, please share your experience by posting a comment below.

 
Related posts:
  1. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
  2. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  3. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  4. Matlab DDE support Windows DDE is an unsupported and undocumented feature of Matlab, that can be used to improve the work-flow in the Windows environment...
 

Undocumented Matlab MEX API

$
0
0

I would like to welcome guest blogger Pavel Holoborodko of Advanpix, maker of the Multiprecision Computing Toolbox. Today, Pavel discusses undocumented MEX functions that he encountered in his work to improve the toolbox performance.

Advanpix logo

Advanpix logo

It is not a secret that Matlab has many undocumented (or deliberately hidden) features and commands. After all, Yair’s website & book are devoted specifically to this topic.

However most of the findings are related to Matlab language itself and investigations on undocumented MEX API seems to be scarce.

During development of our toolbox we have found lots of hidden functions which can be helpful for creating speed-efficient extensions for Matlab using native languages.

Here we want to explain some of them in detail and provide complete list of undocumented MEX API functions.

Please note that there is a risk in using the functions – MathWorks can change / remove some of them in next versions. It is an additional burden for developers to stay tuned and update their toolboxes on time.

Reduced OOP capabilities of Matlab

Starting with R2008b Matlab allows user to introduce custom-type classes by the classdef keyword. Matlab was late on adding object oriented features – I can only image how hard it was for developers at MathWorks to add OOP constructs to a purely procedural language, which follows entirely different philosophy. (Yes, objects could be created using structs and special folder structure in earlier version of Matlab – but that was just ugly design, MathWorks will not support it in the future).

They still don’t have full support for OOP features though. The most important missing features are:

  • It is prohibited to have a destructor for custom non-handle classes
  • It is not possible to overload assignment-without-subscripts operator (e.g. A = B)

I don’t know the reasons why these fundamental OOP paradigms are not implemented in Matlab – but they surely prevent creating powerful virtual machine-type of toolboxes.

In that case Matlab objects would have only one property field – ‘id’, identifier of variable stored in MEX module – virtual machine (e.g. pointer to C++/C object). MEX module would only need to know ‘id’ of objects and what operation to conduct with them (+, -, *, etc.) – all processing would be done in MEX. Heavy data exchange between Matlab and MEX libraries would be completely unnecessary. Matlab would act as just an interpreter in such scenario. Moreover MEX API could be simplified to several functions only.

Access to object properties from MEX

Unfortunately we are restricted to current architecture – where all the data are allocated / stored on Matlab side and we have to transfer it from Matlab to MEX library in order to work with it. The official MEX API provides two functions to access object properties from within MEX library: mxGetProperty and mxSetProperty.

Both functions share the same problem – they create a deep copy of the data!

Imagine the situation when your object is a huge matrix with high-precision elements and it occupies 800MB of RAM. If we want to access it in MEX library (e.g. transpose) we would call mxGetProperty which will do ENTIRE COPY of your object’s property – wasting another 800MB!

Obviously this cannot be accepted, not speaking of totally reduced performance (copying could take a while for such amount too).

In search for remedy we found a similar (but) undocumented functions we can use to get shared access to objects properties (32-bit):

extern mxArray* mxGetPropertyShared(const mxArray* pa, 
                                    unsigned int index, 
                                    const char * propname);
 
extern void mxSetPropertyShared(mxArray* pa, 
                                unsigned int index, 
                                const char * propname, 
                                const mxArray* value);

These functions can be used as one-to-one replacement of the official functions: mxGetPropertyShared just returns pointer to existing property without any copying; mxDestroyArray can still be called on returned pointer (thanks to James Tursa for the correction).

Full list of MEX API functions

We have extracted the full list of usable MEX functions from libmx.dll and libmex.dll (Matlab R2012b Windows 32-bit) – the two main MEX API dynamic libraries. It includes functions from the official API as well as undocumented ones (which are in fact the majority):

  • libmx (856 exported functions)
  • libmex (44 exported functions)

The distinctive feature of the list – it provides de-mangled C++ names of functions, with type of arguments and return value. This makes usage of undocumented functions much easier. You can also easily see this list using tools such as DLL Export Viewer or the well-known Dependency Walker. This list was not previously published to the knowledge of this author; a much shorter unannotated list was posted by Yair in 2011.

Take a look at the function list – there are a lot of interesting ones, like mxEye, mxIsInf, mxFastZeros, mxGetReferenceCount and many others.

Moreover it is possible to see high level C++ classes MathWorks developers use for work. Peter Li has posted an article about mxArray_tag‘s evolution and internal structure in 2012. Now it is clear that the fundamental data type mxArray_tag is not a plain-old-struct anymore, it has member-functions and behaves more like a class. It even has custom new/delete heap management functions and overloaded assignment operator=. Reverse-engineering of these functions might reveal the exact & complete data structure of mxArray_tag, but perhaps this is not allowed by the Matlab license agreement.

Anyway, with some effort, the internal mxArray_tag class from MathWorks might be used in third-party MEX files. How much more easier this would be instead of clumsy mx**** functions!

Please feel free to leave your requests or comments below.

Note: This article was originally posted on the Advanpix blog; reposted here with kind permission and a few changes.

 
Related posts:
  1. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  2. Reasons for undocumented Matlab aspects There are many reasons for the numerous undocumented aspects in Matlab - this article explains them....
  3. Undocumented Profiler options part 3 An undocumented feature of the Matlab Profiler can report call history timeline - part 3 of series. ...
  4. Undocumented Profiler options part 4 Several undocumented features of the Matlab Profiler can make it much more useful - part 4 of series. ...
 

Sparse data math info

$
0
0

Two weeks ago, I posted about Matlab’s math libraries and their various versions across Matlab releases. Matlab relies on the proprietary Intel MKL and AMD ACML libraries for most of its core math, matrix manipulation and linear algebra functions, for Intel/AMD CPUs (respectively). MKL and ACML are adaptations of, and wrappers for, the ubiquitous BLAS and LAPACK packages (LAPACK uses BLAS for its low-level functionality).

Introducing SuiteSparse

CSparse book Unfortunately, BLAS can be used only with full (non-sparse) matrix data on a CPU. So, for GPU support Matlab uses MAGMA (libmwmagma.dll). Similarly, for sparse data Matlab uses the SuiteSparse library by University of Florida’s Tim Davis, whose work on sparse matrix software has very recently earned him SIAM fellowship. SuiteSparse is used by Google Earth and Street-View to create their amazing real-time 3D renditions.

SuiteSparse relies on sparse-data algorithms that have been developed over many years (since the 70′s elsewhere, since 1991 at UFL), and continuously evolve to this day. A presentation about the algorithms in 2006 is available: video, slides (FEX #12295). A detailed presentation of some of the algorithms can be found in Tim’s book “Direct Methods for Sparse Linear Systems” (SIAM, 2006), which should not be confused with Tim’s other book, the widely-popular “Matlab Primer“. A more recent technical description of the sparse algorithms is provided in an ACM paper.

SuiteSparse in Matlab

SuiteSparse has been incorporated into Matlab’s core functionality over the span of several years, between 2000 and 2009 (details). The functions were apparently incorporated into libmwmathlinalg.dll, libmwmathcore.dll, libcolamd.dll, libmwspmatrix.dll, libmwumfpack.dll, libmwumfpack_api.dll, libmwcholmod.dll, libmwamd.dll, libmwspqr.dll, libmwma57.dll, libmwcsparse.dll, libmwspqr.dll (and possibly a couple of other DLLs I missed). On *nix systems, the libraries have the same name, with an *.so extension (e.g., libmwcsparse.so). All these dynamic libraries are located in the /bin/%arch%/ folder of the Matlab installation, alongside the rest of Matlab’s libs. The lib names are pretty self-explanatory, for example libmwspqr.dll contains the SuiteSparse QR library; libmwcsparse.dll contains the CSparse library (which is described in the above-mentioned SIAM book).

Back in 2007, SuiteSparse could be used in Matlab as a separate package on the File Exchange (#12233), which was discussed on Loren’s blog. Since Matlab has incorporated SuiteSparse into its core functions, FEX #12233 is no longer available. We can still download the sources directly from the SuiteSparse page on UFL.

Sparse libs version info in Matlab

Unlike BLAS, LAPACK, FFTW and MKL, there is no known way to directly extract the sparse-libs version info in Matlab. But there is an indirect way to do so, and in the process, we discover lots of interesting information about the internal mechanisms of the sparse algos.

We begin by setting the debugging information to maximum using the spparms function. This not only provides version info, but also all kinds of diagnostics about the sparse matrices and the selected algorithm path. For example (note the highlighted version info text):

>> spparms('spumoni',2)
>> load west0479
>> b = rand(size(west0479,1));
>> x = west0479 \ b;
sp\: bandwidth = 388+1+337.
sp\: is A diagonal? no.
sp\: is band density (0.01) > bandden (0.50) to try banded solver? no.
sp\: is A triangular? no.
sp\: is A morally triangular? no.
sp\: is A a candidate for Cholesky (symmetric, real positive diagonal)? no.
sp\: use Unsymmetric MultiFrontal PACKage with automatic reordering.
UMFPACK V5.4.0 (May 20, 2009), Control:    Matrix entry defined as: double
    Int (generic integer) defined as: UF_long
    BLAS library used: Fortran BLAS.  size of BLAS integer: 8
    MATLAB:                           yes.
    CPU timer:                        ANSI clock ( ) routine.
    number of rows in matrix A:       479
    number of columns in matrix A:    479
    entries in matrix A:              1887
    memory usage reported in:         16-byte Units
    size of int:                      4 bytes
    size of UF_long:                  8 bytes
    size of pointer:                  8 bytes
    size of numerical entry:          8 bytes
 
    strategy used:                    unsymmetric
    ordering used:                    colamd on A
    modify Q during factorization:    yes
    prefer diagonal pivoting:         no
    pivots with zero Markowitz cost:               133
    ...  % lots of other interesting internal information

A Matlab script to extract the sparse libs’ version info is provided here. The script runs a few sparse math operations that more-or-less cover the sparse libs, and then reports the version data when it’s done. In order to parse the debugging info, the script uses either an external OS grep command (which is available on Linux & Macs), or a Matlab equivalent. Here are the results on my R2013a system:

>> sparse_lib_versions
 
...  % numerous debugging info...
 
=> sparse matrix library versions (from C:\Users\Yair\AppData\Local\Temp\sparse_info.txt):
============================================================
AMD version 2.2.0, May 31, 2007: approximate minimum degree ordering
AMD version 2.2.0, May 31, 2007, results:
colamd version 2.5, May 5, 2006: OK.  
CHOLMOD version 1.7.0, Sept 20, 2008:  : status: OK
CHOLMOD version 1.7.0, Sept 20, 2008: : status: OK
SuiteSparseQR, version 1.1.0 (Sept 20, 2008)
UMFPACK V5.4.0 (May 20, 2009), Control:
UMFPACK V5.4.0 (May 20, 2009), Info:

It looks like MathWorks haven’t updated Matlab’s sparse libs in quite a few years. These libraries continue to be improved continuously, but most of the tweaks are quite minor and no important bugs were found for many years, so I guess that we can’t really complain.

Austria & Switzerland visit

I will be visiting clients in Austria and Switzerland in August. If you live in the area, I will be happy to meet you to discuss how I could bring value to your needs, as consultant, contractor or trainer. Please email me if you think that this could be relevant for you. The relevant dates are:

  • Vienna – Aug 18, 25-26
  • Salzburg – Aug 19-23
  • Zurich – Aug 26-29

Bis bald!

 
Related posts:
  1. Math libraries version info & upgrade Matlab exposes undocumented info about its internal math libraries; these libraries can be upgraded manually. ...
  2. Controlling plot data-tips Data-tips are an extremely useful plotting tool that can easily be controlled programmatically....
  3. Accessing plot brushed data Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
  4. Spy Easter egg The built-in Matlab function spy has an undocumented feature (Easter egg) when it is called with no input arguments....
 

treeTable

$
0
0

Since Matlab 7.0 (R14), Matlab has included a built-in GUI table control (uitable), at first as a semi-documented function and in release 7.6 (R2008a) as a fully-documented function. Useful as this control is, it lacks many features that are expected in modern GUIs, including sorting, filtering, cell-specific appearance and behavior, gridline customization etc. In past articles I have explained how uitable can be customized to achieve a more professional-looking table. I expanded on this in my book and my detailed uitable customization report.

Today I explain how a grouping hierarchy can be achieved in a table control that can be used in Matlab GUI. Such a control, which is a combination of a uitree and uitable, is typically called a tree-table. We can find numerous examples of it in everyday usage. I have encapsulated the functionality in a utility called treeTable on the Matlab File Exchange (#42946). The utility is provided with full source code and open-source license, and readers are welcome to use and modify it. A detailed explanation of the technicalities follows below, but if you’re just interested in having a sortable, rearrangeable, customizable, groupable table control, then all you need to do is download and use the utility.

treeTable utility

treeTable utility

headers = {'ID','Label','Logical1','Logical2','Selector','Numeric'};
data = {1,'M11',true, false,'One', 1011;  ...
        1,'M12',true, true, 'Two', 12;   ...
        1,'M13',false,false,'Many',13.4; ...
        2,'M21',true, false,'One', 21;  ...
        2,'M22',true, true, 'Two', 22;   ...
        3,'M31',true, true, 'Many',31;   ...
        3,'M32',false,true, 'One', -32;  ...
        3,'M33',false,false,'Two', 33; ...
        3,'M34',true, true, 'Many',34;  ...
};
selector = {'One','Two','Many'};
colTypes = {'label','label','char','logical',selector,'double'};
colEditable = {true, true, true, true, true}
icons = {fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/file_open.png'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/foldericon.gif'), ...
}
 
% Create the table in the current figure
jtable = treeTable('Container',gcf, 'Headers',headers, 'Data',data, ...
                   'ColumnTypes',colTypes, 'ColumnEditable',colEditable, 'IconFilenames',icons);
 
% Collapse Row #6, sort descending column #5 (both are 0-based)
jtable.expandRow(5,false);  % 5=row #6; false=collapse
jtable.sortColumn(4,true,false);  % 4=column #5; true=primary; false=descending

The basic implementation concept

Unfortunately, uitable as-is cannot be customized to have groupable rows. It derives from JIDE’s SortableTable, rather than one of its groupable derived classes. On the other hand, uitree (don’t you agree that after a decade of this so-useful function being semi-documented it ought to be made official?) uses a different class hierarchy outside com.jidesoft.grid, and so it cannot be easily customized to display rows (as opposed to simple labels).

These limitations mean that we cannot use uitable or uitree and need to use a custom component. Luckily, such a component is available in all Matlab installations, on all platforms. It is part of the grid components package, on which Matlab GUI has relied for many years, by JIDE Software. JIDE Grids is a collection of components that extend the standard Java Swing JTable component, and is included in each Matlab installation (/java/jarext/jide/jide-grids.jar under the Matlab root). I discussed multiple JIDE controls in this blog over the years. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

In fact, there are no less than three different components that we could use in our case: TreeTable, GroupTable and HierarchicalTable:

JIDE Grids class hierarchy (we normally use only one of the marked classes)

JIDE Grids class hierarchy (we normally use only one of the marked classes)

Note that we cannot use PropertyTable since that component is limited to only two columns. This is perfect for presenting property names and values, which is the reason it is used by Matlab’s inspect function and my generic propertiesGUI utility or Levente Hunyadi’s Property Grid utility. But in this case we wish to display a general multi-column table, so PropertyTable is a no-go.

TreeTable and GroupTable enable data rows that have similar type (class), whereas HierarchicalTable enables more flexibility, by allowing display of any component type (including full tables) in child rows. This flexibility comes with a price that customizing a HierarchicalTable is more difficult than TreeTable or GroupTable. These latter two components are quite similar; we use GroupTable, which extends TreeTable with the ability to automatically group rows that have the same value in a certain column.

Data model

The above-mentioned table classes all derive from SortableTable (which also underlies uitable). Unfortunately, something in the Matlab-Java interface breaks the ability of the JIDE table classes (or rather, their data model) to understand numeric values for what they are. As a result, sorting columns is done lexically, i.e. “123″ < “34″ < “9″. To fix this, I’ve included a custom Java table model (MultiClassTableModel) with the treeTable utility, which automatically infers the column type (class) based on the value in the top row (by overriding the getColumnClass() method).

Using this new class is pretty easy:

% Create the basic data-type-aware model using our data and headers
javaaddpath(fileparts(mfilename('fullpath')));  % add the Java class file to the dynamic java class-path
model = MultiClassTableModel(data, headers);  % data=2D cell or numeric array; headers=cell array of strings
 
% Wrap the standard model in a JIDE GroupTableModel
com.mathworks.mwswing.MJUtilities.initJIDE;  % initialize JIDE
model = com.jidesoft.grid.DefaultGroupTableModel(model);
model.addGroupColumn(0);  % make the first column the grouping column
model.groupAndRefresh;  % update the model data
 
% Use the generated model as the data-model of a JIDE GroupTable
jtable = eval('com.jidesoft.grid.GroupTable(model);');  % prevent JIDE alert by run-time (not load-time) evaluation
jtable = handle(javaObjectEDT(jtable), 'CallbackProperties');  % ensure that we're using EDT
 
% Enable multi-column sorting
jtable.setSortable(true);
 
% Present the tree-table within a scrollable viewport on-screen
scroll = javaObjectEDT(JScrollPane(jtable));
[jhscroll,hContainer] = javacomponent(scroll, tablePosition, hParent);
set(hContainer,'units', 'normalized','pos',[0,0,1,1]);  % this will resize the table whenever its container is resized

Here, com.mathworks.mwswing.MJUtilities.initJIDE is called to initialize JIDE’s usage within Matlab. Without this call, we may see a JIDE warning message in some Matlab releases. We only need to initJIDE once per Matlab session, although there is no harm in repeated calls.

javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. I discussed it here.

Callbacks

There are two main callbacks that can be used with treeTable:

  • table data update – this can be set by uncommenting line #237 of treeTable.m:
    set(handle(jtable.getOriginalModel,'CallbackProperties'), 'TableChangedCallback', {@tableChangedCallback, jtable});

    which then activated the sample tableChangedCallback() function (lines #684-694). Naturally, you can also set your own custom callback function.

    % Sample table-editing callback
    function tableChangedCallback(hModel,hEvent,jtable)
        % Get the modification data
        modifiedRow = get(hEvent,'FirstRow');
        modifiedCol = get(hEvent,'Column');
        label   = hModel.getValueAt(modifiedRow,1);
        newData = hModel.getValueAt(modifiedRow,modifiedCol);
     
        % Now do something useful with this info
        fprintf('Modified cell %d,%d (%s) to: %s\n', modifiedRow+1, modifiedCol+1, char(label), num2str(newData));
    end  % tableChangedCallback
  • row selection update – this is currently enabled in line #238 of treeTable.m:
    set(handle(jtable.getSelectionModel,'CallbackProperties'), 'ValueChangedCallback', {@selectionCallback, jtable});

    which then activated the sample selectionCallback() function (lines #696-705). Naturally, you can also set your own custom callback function.

    % Sample table-selection callback
    function selectionCallback(hSelectionModel,hEvent,jtable)
        % Get the selection data
        MinSelectionIndex  = get(hSelectionModel,'MinSelectionIndex');
        MaxSelectionIndex  = get(hSelectionModel,'MaxSelectionIndex');
        LeadSelectionIndex = get(hSelectionModel,'LeadSelectionIndex');
     
        % Now do something useful with this info
        fprintf('Selected rows #%d-%d\n', MinSelectionIndex+1, MaxSelectionIndex+1);
    end  % selectionCallback

Some useful features of treeTable

  • Sortable columns (including numeric columns)
  • Rearrangeable columns (drag headers left/right)
  • Auto-fit the table columns into the specified container width
  • Manually resize columns by dragging the column divider gridlines (not just the header dividers as in uitable)
  • Flat or groupable table, based on the specified Groupable parameter (default=true)
  • Selector cells only show the drop-down arrow of the currently-selected cell (unlike uitable which shows it for all the column cells)
  • Selector cells enable editing, unlike uitable that only enables selecting among pre-defined values
  • Ability to attach user-defined icons for the leaf rows and the grouping rows (expanded/collapsed)
  • Easily attach custom cell editors or renderers to any table column (see my book and my detailed uitable customization report for details)

All of these features can be turned on/off using the control’s properties. Again, see my book or report for details (or ask me to do it for you…).

 
Related posts:
  1. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  2. 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...
  3. Uitable cell colors A few Java-based customizations can transform a plain-looking data table into a lively colored one. ...
  4. JIDE Property Grids The JIDE components pre-bundled in Matlab enable creating user-customized property grid tables...
 

Allocation performance take 2

$
0
0

Last week, Mike Croucher posted a very interesting article on the fact that cumprod can be used to generate a vector of powers much more quickly than the built-in .^ operator. Trying to improve on Mike’s results, I used my finding that zeros(n,m)+scalar is often faster than ones(n,m)*scalar (see my article on pre-allocation performance). Applying this to Mike’s powers-vector example, zeros(n,m)+scalar only gave me a 25% performance boost (i.e., 1-1/1.25 or 20% faster), rather than the x5 speedup that I received in my original article.

Naturally, the difference could be due to different conditions: a different running platform, OS, Matlab release, and allocation size. But the difference felt intriguing enough to warrant a small investigation. I came up with some interesting new findings, that I cannot fully explain:

The performance of allocating zeros, ones

The performance of allocating zeros, ones (x100)

function t=perfTest
    % Run tests multiple time, for multiple allocation sizes
    n=100; tidx = 1; iters = 100;
    while n < 1e8
        t(tidx,1) = n;
        clear y; tic, for idx=1:iters, clear y; y=ones(n,1);  end, t(tidx,2)=toc;  % clear; ones()
        clear y; tic, for idx=1:iters, clear y; y=zeros(n,1); end, t(tidx,3)=toc;  % clear; zeros()
        clear y; tic, for idx=1:iters,          y=ones(n,1);  end, t(tidx,4)=toc;  % only ones()
        clear y; tic, for idx=1:iters,          y=zeros(n,1); end, t(tidx,5)=toc;  % only zeros()
        n = n * 2;
        tidx = tidx + 1;
    end
 
    % Normalize result on a per-element basis
    t2 = bsxfun(@rdivide, t(:,2:end), t(:,1));
 
    % Display the results
    h  = loglog(t(:,1), t(:,2:end));  % overall durations
    %h = loglog(t(:,1), t2);  % normalized durations
    set(h, 'LineSmoothing','on');  % see http://undocumentedmatlab.com/blog/plot-linesmoothing-property/
    set(h(2), 'LineStyle','--', 'Marker','+', 'MarkerSize',5, 'Color',[0,.5,0]);
    set(h(3), 'LineStyle',':',  'Marker','o', 'MarkerSize',5);
    set(h(4), 'LineStyle','-.', 'Marker','*', 'MarkerSize',5);
    legend(h, 'clear; ones', 'clear; zeros', 'ones', 'zeros', 'Location','NorthWest');
    xlabel('# allocated elements');
    ylabel('duration [secs]');
    box off
end

The full results were (R2013a, Win 7 64b, 8MB):

The same data normalized per-element

The same data normalized per-element (x100)

       n  clear,ones  clear,zeros    only ones   only zeros
========  ==========  ===========    =========   ==========
     100    0.000442     0.000384     0.000129     0.000124
     200    0.000390     0.000378     0.000150     0.000121
     400    0.000404     0.000424     0.000161     0.000151
     800    0.000422     0.000438     0.000165     0.000176
    1600    0.000583     0.000516     0.000211     0.000206
    3200    0.000656     0.000606     0.000325     0.000296
    6400    0.000863     0.000724     0.000587     0.000396
   12800    0.001289     0.000976     0.000975     0.000659
   25600    0.002184     0.001574     0.001874     0.001360
   51200    0.004189     0.002776     0.003649     0.002320
  102400    0.010900     0.005870     0.010778     0.005487
  204800    0.051658     0.000966     0.049570     0.000466
  409600    0.095736     0.000901     0.095183     0.000463
  819200    0.213949     0.000984     0.219887     0.000817
 1638400    0.421103     0.001023     0.429692     0.000610
 3276800    0.886328     0.000936     0.877006     0.000609
 6553600    1.749774     0.000972     1.740359     0.000526
13107200    3.499982     0.001108     3.550072     0.000649
26214400    7.094449     0.001144     7.006229     0.000712
52428800   14.039551     0.001853    14.396687     0.000822

(Note: all numbers should be divided by the number of loop iterations iters=100)

As can be seen from the data and resulting plots (log-log scale), the more elements we allocate, the longer this takes. It is not surprising that in all cases the allocation duration is roughly linear, since when twice as many elements need to be allocated, this roughly takes twice as long. It is also not surprising to see that the allocation has some small overhead, which is apparent when allocating a small number of elements.

A potentially surprising result, namely that allocating 200-400 elements is in some cases a bit faster than allocating only 100 elements, can actually be attributed to measurement inaccuracies and JIT warm-up time.

Another potentially surprising result, that zeros is consistently faster than ones can perhaps be explained by zeros being able to use more efficient low-level functions (bzero) for clearing memory, than ones which needs to memset a value.

A somewhat more surprising effect is that of the clear command: As can be seen in the code, calling clear within the timed loops has no functional use, because in all cases the variable y is being overridden with new values. However, we clearly see that the overhead of calling clear is an extra 3µS or so per call. Calling clear is important in cases where we deal with very large memory constructs: clearing them from memory enables additional memory allocations (of the same or different variables) without requiring virtual memory paging, which would be disastrous for performance. But if we have a very large loop which calls clear numerous times and does not serve such a purpose, then it is better to remove this call: although the overhead is small, it accumulates and might be an important factor in very large loops.

Another aspect that is surprising is the fact that zeros (with or without clear) is much faster when allocating 200K+ elements, compared to 100K elements. This is indicative of an internal switch to a more optimized allocation algorithm, which apparently has constant speed rather than linear with allocation size. At the very same point, there is a corresponding performance degradation in the allocation of ones. I suspect that 100K is the point at which Matlab's internal parallelization (multi-threading) kicks in. This occurs at varying points for different functions, but it is normally some multiple of 20K elements (20K, 40K, 100K or 200K - a detailed list was posted by Mike Croucher again). Apparently, it kicks-in at 100K for zeros, but for some reason not for ones.

The performance degradation at 100K elements has been around in Matlab for ages - I see it as far back as R12 (Matlab 6.0), for both zeros and ones. The reason for it is unknown to me, if anyone could illuminate me, I'd be happy to hear. The new thing is the implementation of a faster internal mechanism (presumably multi-threading) in R2008b (Matlab 7.7) for zeros, at the very same point (100K elements), although for some unknown reason this was not done for ones as well.

Another aspect that is strange here is that the speedup for zeros at 200K elements is ~12 - much higher than the expected optimal speedup of 4 on my quad-core system. The higher speedup may perhaps be explained by hyper-threading or SIMD at the CPU level.

In any case, going back to the original reason I started this investigation, the reason for getting such wide disparity in speedups between using zeros and ones for 10K elements (as in Mike Croucher's post), and for 3M elements (as in my pre-allocation performance article) now becomes clear: In the case of 10K elements, multi-threading is not active, and zeros is indeed only 20-30% faster than ones; In the case of 3M elements, the superior multi-threading of zeros over ones enables much larger speedups, increasing with allocated size.

Some take-away lessons:

  • Using zeros is always preferable to ones, especially for more than 100K elements on Matlab 7.7 (R2008b) and newer.
  • zeros(n,m)+scalar is consistently faster than ones(n,m)*scalar, especially for more than 100K elements, and for the same reason.
  • In some cases, it may be worth to use a built-in function with more elements than actually necessary, just to benefit from its internal multi-threading.
  • Never take performance assumptions for granted. Always test on your specific system using a representative data-set.

p.s. - readers who are interested in the historical evolution of the zeros function are referred to Loren Shure's latest post, only a few days ago (a fortunate coincidence indeed). Unfortunately, Loren's post does not illuminate the mysteries above.

 
Related posts:
  1. Preallocation performance Preallocation is a standard Matlab speedup technique. Still, it has several undocumented aspects. ...
  2. Array resizing performance Several alternatives are explored for dynamic array growth performance in Matlab loops. ...
  3. Matrix processing performance Matrix operations performance is affected by internal subscriptions in a counter-intuitive way....
  4. Plot performance Undocumented inner plot mechanisms can be used to significantly improved plotting performance...
 

Function definition meta-info

$
0
0

Last week, Loren Shure posted an article explaining some documented ways to retrieve information about the type of Matlab functions. Loren basically showed how we can use a combination of the built-in nargin and exist functions to check whether a specified function-name is a regular m-file, a script filename, a class name or something else.

Today I will discuss several additional alternatives for retrieving information about a specified function:

The mtree() alternative

Reader Mark Brown has commented about an alternative, using the semi-documented built-in function mtree:

>> t = mtree('mtree.m','-file'); t.select(1).kind  % m-class file
ans =
CLASSDEF
 
>> t = mtree('profile.m','-file'); t.select(1).kind  % regular m-file function
ans =
FUNCTION
 
>> t = mtree('test.m','-file'); t.select(1).kind  % script file
ans =
EXPR

mtree contains numerous other goodies in its reported parse-tree, including information about who-calls-what-where, set/used info about variables and other information used in the lexical parsing of the m-file. mtree is a very sophisticated m-file function (or rather, a class), but is very heavily documented internally, and so it can definitely be read and followed. Unfortunately, much of the internal processing is carried out by opaque internal c-functions (mtreemex), but there is still plenty of processing left for the 3K+ lines of m-code. I plan to write an extensive article about this function one day.

Unlike many other internal m-files, which are much simpler, less well written and sparsely documented (if at all), but for which personal credit is included in a comment, mtree includes no personal credit although it appears to be very well written and documented. I have to congratulate the unknown author(s) for both their proficiency and humility. Addendum: This unknown author is now confirmed to have been Steve Johnson, author of the mlint set of tools and functionality.

For people worried about future compatibility, note that mtree has existed on the Matlab path (%matlabroot%\toolbox\matlab\codetools\@mtree\mtree.m) since 2006 (I think R2006a, but I’m not certain; it already had version 1.3 by R2007b; the latest version [R2013b] is 2.5). Considering the large investment in its code thus far, and the significant effort that it would take to create a replacement, I don’t see this function going away in the near future. Then again, there is no certainty about this, and it might well disappear without notice in some future Matlab release.

The getcallinfo() alternative

getcallinfo is another semi-documented internal function, which uses mtree to construct an m-file’s call-tree and reports the results in either a tabulated manner (if no output arg is request), or a struct array (as output arg):

>> getcallinfo('profile.m');
Name           Type             Starts Ends Length Full Name           
----           ----             ------ ---- ------ ---------           
profile        function             1   242    242 profile             
ParseInputs    subfunction        247   354     82 profile>ParseInputs 
ParseOption    nested-function    262   287     26 profile>ParseInputs/ParseOption
notifyUI       subfunction        356   370     15 profile>notifyUI    
 
>> s = getcallinfo('profile.m')
s = 
1x4 struct array with fields:
    type
    name
    fullname
    functionPrefix
    calls
    firstline
    lastline
    linemask
 
>> s(4).calls
ans = 
      fcnCalls: [1x1 struct]
    innerCalls: [1x1 struct]
      dotCalls: [1x1 struct]
       atCalls: [1x1 struct]
 
>> s(4).calls.fcnCalls
ans = 
    names: {'usejava'}
    lines: 359
 
>> s(4).calls.innerCalls
ans = 
    names: {1x0 cell}
    lines: [1x0 double]
 
>> s(4).calls.dotCalls
ans = 
    names: {'com.mathworks.mde.profiler.Profiler.start'  [1x40 char]  [1x41 char]}
    lines: [363 365 367]

Note: In order to use getcallinfo, we first need to fix a small internal bug in %matlabroot%/toolbox/matlab/codetools/getcallinfo.m, specifically within the displayStructure() sub-function. Modifying this file may require administrator privileges, and can be done in any text editor. The bug is that the keyword length is used as a variable in this function (line #136 in R2013b), and so cannot be used to reference the built-in function length(). We can either rename the variable (lines 136, 139, 145) or the function. It’s easiest to rename length() to numel() in line #147 (highlighted below):

130:   function displayStructure(strc)
           ...
136:       length = getString(message('MATLAB:codetools:reports:RptLength'));137:       fullName = getString(message('MATLAB:codetools:reports:RptFullName'));
138:       
139:       fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n',name,type,starts,ends,length,fullName);
140:       fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n', ...
               ...
145:           getDashesForString(length), ...
146:           getDashesForString(fullName));
147:       for n = 1:numel(strc)   % original code: n = 1:length(strc)               ...
152:       end
153:   end

The mlint() alternative

A few months ago, I wrote about mlint‘s undocumented interface and ability to report much internal information about the analyzed file. It is no surprise that one of the undocumented mlint options is -calls, which lists the calling-tree of an m-file. For example:

>> mlint profile.m -calls
M0 1 14 profile
E0 242 3 profile
U1 122 15 callstats
U1 131 11 ParseInputs
U1 133 10 MException
U1 134 5 throw
U1 161 8 lower
U1 164 9 notifyUI
U1 165 23 true
U1 169 23 false
U1 180 9 profreport
U1 183 13 usejava
U1 184 13 error
U1 184 19 message
U1 188 21 profile
U1 189 16 isempty
U1 192 17 profview
U1 236 9 warning
S0 248 7 ParseInputs
E0 354 3 ParseInputs
U1 260 1 error
U1 260 7 nargchk
U1 260 17 Inf
U1 260 21 nargin
N1 262 23 ParseOption
E1 287 7 ParseOption
U2 263 12 strcmp
...

In this report, the first character represents the function type:

  • M = main (top-level) function
  • S = sub-function
  • N = nested function
  • U = out-of-scope (external/built-in) function
  • A = anonymous function
  • E = end-of-function indication

The following numbers indicate the nesting level, line #, column # and function identifier (name). In essence, it’s the same information presented by getcallinfo, with two distinctions: getcallinfo‘s report is much more nicely formatted, and on the other hand getcallinfo does not include internal function-calls (maybe there’s an undocumented switch that I haven’t found for this).

In this regard, I wish to once again praise Urs Schwartz’s excellent farg and fdep utilities, which use this undocumented mlint syntax. They seem to out-perform and out-class the built-in depends function by a wide margin…

The which() alternative

The built-in which function can be used to report the file-path of m-file functions, or an indicate that the function is built-in (i.e., coded as a C/C++ function in one of the Matlab libraries):

>> str = which('perfTest')
str =
C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m
 
>> str = which('matlab.io.MatFile')
str =
C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\+matlab\+io\MatFile.m
 
>> str = which('sin')
str =
built-in (C:\Program Files\Matlab\R2013b\toolbox\matlab\elfun\@double\sin)
 
>> str = which('noSuchFunction')
str =
     ''

Note: a little-known option enables specifying sub-functions (although this does not work for nested functions for some unknown reason [bug? oversight?]):

>> str = which('nestedFuncName','in','MFileName');

The functions() alternative

Similar functionality can be achieved via the built-in functions, using function handles rather than function names:

>> functions(@perfTest)
ans = 
    function: 'perfTest'
        type: 'simple'
        file: 'C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m'
 
>> functions(@matfile)
ans = 
    function: 'matfile'
        type: 'simple'
        file: 'C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\matfile.m'
 
>> fType = functions(@(a)a+1)
fType = 
     function: '@(a)a+1'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}
 
>> functions(@transpose)
ans = 
    function: 'transpose'
        type: 'simple'
        file: ''

Unlike which, functions can also be used for both sub- and nested-functions:

% The following was called within the confines of a specific m-file function:
K>> fType = functions(@MFileName)
fType = 
    function: 'MFileName'
        type: 'simple'
        file: 'C:\Yair\MFileName.m'
 
K>> fType = functions(@subFunc)
fType = 
     function: 'subFunc'
         type: 'scopedfunction'
         file: 'C:\Yair\MFileName.m'
    parentage: {'subFunc'  'MFileName'}
 
K>> fType = functions(@nestedFunc)
fType = 
     function: 'MFileName/nestedFunc'
         type: 'nested'
         file: 'C:\Yair\MFileName.m'
    workspace: {[1x1 struct]}

Note that parentage and workspace are undocumented sub-fields of the returned struct: they are mentioned in the official doc page, but only in passing, without a format explanation. Also note that workspace is a cell array of a single element (contrary to the official doc – this is probably an internal bug), containing the actual workspace as a struct (fields = workspace variables). So it should be accessed as fType.workspace{1}.varName. Note that parentage and workspace are present only for certain types of function types.

Have you found any other nifty ways of retrieving function meta-info in run-time? Are you using such meta-info in an interesting manner? If so, please post a short comment below.

 
Related posts:
  1. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
  2. 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....
  3. The hgfeval function The semi-documented hgfeval function can be useful for callback chaining - this article explains how...
  4. Sparse data math info Matlab contains multiple libraries for handling sparse data. These can report very detailed internal info. ...
 

Variables Editor scrolling

$
0
0

I would like to introduce guest blogger Oleg Komarov. Oleg has gathered a reputation as a Matlab veteran with plenty of insight into the arcane corners of Matlab, originally on the CSSM newsgroup, and more recently on StackExchange (which admittedly contains more Q&As of the challenging type). Today Oleg discusses a non-trivial solution to a deceivingly-simple problem.

Introduction

I often work with datasets that in one way or another have millions of rows and several columns. Although the dimensions preclude visual-based approaches, e.g. imagine keeping all data on a spreadsheet, especially during the development and testing phases, I need to inspect the dataset at given ‘coordinates’.

As a concrete example, in my work on financial time-series I sometimes encounter a subtle irregularity that might arise from a bug in the code when you stack different series of prices. Then you calculate returns and wonder why you get -99% or +2000%.

Thankfully, the Variables Editor (VE) is very much what I would need for such inspection tasks, if it wasn’t that its usefulness is inversely proportional to the size of the data. An example would better clarify what I mean. Suppose you need to scroll to position 5677545 of your 1e8-by-1 data variable, the following screenshot illustrates how the scrollbar, pgdown/pgup or the arrow keys are not fine-tuned for such task.

Problematic Variables Editor scrolling (and the scrollto solution)

Problematic Variables Editor scrolling (and the scrollto solution)

You can easily waste minutes to mindless scrolling!

We could argue that the task is painlessly accomplished through basic logical indexing in the Command Window (CW), as the following image shows (note that I already set the display to format compact):

Sub-indexing into a large data matrix

Sub-indexing into a large data matrix

However, this approach is limited because:

  1. it displays a static snapshot of the selected region, and often precludes interaction with the data, e.g. copy-paste
  2. it requires more visual space than the VE, which either means that you need to modify your layout or scroll the CW
  3. typing in the CW can be even more tedious than scrolling the VE…

Why openvar is not a good-enough solution

In search of a solution that would retain the VE interactivity and would speed up the task of scrolling to the point of interest, I first checked if there was an API for the VE similar to that for the documents Editor. As a side-note: to date, the Editor’s API remains undocumented/unsupported, although having been published in what was then called the Desktop Blog (renamed MATLAB Spoken Here since Ken and Mike have left MathWorks and the blog focus has changed).

In any case, it turns out that there is a stub of an API for the Variables Editor, matlab.desktop.vareditor, which however comes much short of my expectations. In fact, it only goes as far as visualizing the data of some variable within a completely separate basic version of the VE. This could prove to be a valid embeddable alternative to the uitable, but it does not help us with the need to scroll to a specific data cell.

Unlucky with the VE API, I looked into openvar for an undocumented option that would let me open some variable in the VE and then scroll to the desired ‘coordinates’ – this effort proved fruitless.

A description of the solution that did work

Since the standard Matlab did not offer a programmatic solution, I started digging into the underlying Java components.

I found that one simple direct way is to open our variable of interest in the VE with openvar, retrieve the Java Desktop instance (in the same manner as we do to get the Desktop instance to customize the Editor). From this instance we can find the handle to the appropriate com.mathworks.mlwidgets.array.ArrayTable with findjobj (remember that there could be multiple ArrayTables, one for each inspected variable). Finally, we scroll to the desired position using the scrollCellToVisible() method.

Note that the Matlab object builds on the javax.swing.JViewport and provides a convenient interface as in the case of the scrolling function, since its java counterpart scrollRectToVisible() requires as input a java.awt.rectangle object rather than scalar doubles.

A succinct usage example would be:

% Create example variable
a = randn(1e8,1);
name = 'a';
 
% Open 'a' in the VE or grab focus
openvar(name)
 
% Retrieve Desktop instance and handle to client
desktop = com.mathworks.mde.desk.MLDesktop.getInstance;
varclient = desktop.getClient(name);
 
% Retrieve handle to scrollable table with findjobj
jVarTable = findjobj(varclient,'property',{'name','VariableTable'});
 
% Select, scroll and update the UI (note the zero-indexing, i.e. row-1)
row = 5677545;
col = 1;
jVarTable.setRowSelectionInterval(row-1, row-1)
jVarTable.setColumnSelectionInterval(col-1, col-1)
jVarTable.scrollCellToVisible(row-1, col-1)
jVarTable.updateUI

The scrollto utility

As most of the lines of the usage example above should already be familiar and/or self-explanatory to the followers of this blog, the next logical step is to encapsulate the snippet into a function which you can already find on the File Exchange: scrollto.

The scrollto function provides the following features:

  • Accepts subs or indices
  • You can scroll indexed variables, i.e. ‘a{1}’ or ‘a.field{2,3}’ etc.
  • Scrolling is also supported in debug mode (from ver2.00), i.e. on variables of the ‘caller’ workspace
  • Handles asynchronous rendering of the VE (see below)

and supports the following classes (should be 2D arrays):

  • Numeric and logical data – ‘VariableTable’
  • Cell arrays – ‘CellTable’
  • Timeseries – ‘TimeSeriesArrayEditorTablePanel:fDataTable’
  • Datasets (Statistics Toolbox) – ‘DatasetVariableTable’

Matlab handles different classes in the VE through different interfaces. For this reason, for each supported class I reported the ‘name’ property to use with findjobj.

Synchronization issues

Asynchronous rendering of the VE can happen in either of two cases:

  1. if the variable has never been opened in the VE, or the variable was opened but it does not exist in the workspace anymore
  2. in code that opens and interacts with the VE

Writing scrollto proved to be more than a simple wrapping effort and it is worth mentioning the workaround implemented to allow a smooth workflow. The biggest issue I faced is the asynchronous rendering of the VE. As Yair reports in his book Undocumented Secrets of Matlab-Java Programming, p. 538:

“The tight-coupling of the Variable Editor to the Desktop Workspace variables is unfortunate in some respects. … Matlab only has a single computational thread, so Matlab code has to finish before the JMI request can be handled. This means that the Variables Editor contents cannot be displayed synchronously by the Matlab code that invokes it.”

In other words, we cannot retrieve the handle to e.g. the VariableTable until the function has finished executing.

A workaround is to call openvar, wait until the focus is back to the CW, and then call scrollto. I cannot tell you how this workflow made me feel so close and yet so far from a satisfactory implementation.

The ideal flowchart of a basic wrapper around the example (see above) would have been:

Ideal scrollto workflow

Ideal scrollto workflow

Now, since we cannot retrieve the handle to the VariableTable if the VE has not rendered yet, I implemented an asynchronous second call to scrollto through a timer object that fires after the first call to scrollto has finished executing:

Asynchronous scrollto workflow

Asynchronous scrollto workflow

The result is a better experience without unexpected interruptions or breaks in the workflow.

I would like to thank Yair for his comments and guidance. Without his support, scrollto would not exist and humankind would be doomed to scroll the VE manually!

Public-service announcement

(This is Yair again):

I wish to invite you to join my online presentation (webinar) on “A Real-Time Trading System in MATLAB” in the upcoming MATLAB Computational Finance Virtual Conference next Thursday, September 19, 2013. I will be speaking at 2pm EST (8pm CEST). Registration is free and it’s a virtual conference, so there’s no need for a tie and jacket… Following a half-hour presentation, I will be answering audience questions online.

I gave an earlier version of this presentation at the Computational Finance Conference in New York on May 23, and you are welcome to look there for a preview. The presentation slides can be downloaded here. Even if you’re not interested in real-time financial trading with Matlab, you might find it interesting to see the neat things that Matlab can do using a Java API interface and a few undocumented GUI tricks.

MATLAB Computational Finance Conference 2013

 
Related posts:
  1. Accessing the Matlab Editor The Matlab Editor can be accessed programmatically, for a wide variety of possible uses - this article shows how....
  2. Non-textual editor actions The UIINSPECT utility can be used to expand EditorMacro capabilities to non-text-insertion actions. This is how:...
  3. EditorMacro – assign a keyboard macro in the Matlab editor EditorMacro is a new utility that enables setting keyboard macros in the Matlab editor. this post details its inner workings....
  4. Recovering previous editor state Recovering the previous state of the Matlab editor and its loaded documents is possible using a built-in backup config file. ...
 

Rich-contents log panel

$
0
0

I often include a log panel in Matlab applications that process data. By sending messages to the log panel, I can avoid msgbox popups and Command Window messages that interfere with the regular workflow. In Matlab, such log panels typically use a simple listbox or editbox control. The problem with this is that all text messages in the log panel look the same. Matlab does not have a documented way to highlight specific messages or words. Well, this has never stopped us before, has it? :-)

The listbox solution

I have often noted in past articles that most Matlab uicontrols support HTML formatting. We can use a listbox control for our log panel, and use HTML formatting for the various log messages, based on their severity or content. For example:

Listbox with HTML'ed items

Listbox with HTML colored 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

Rich listboxes such as this are very easy to set up and use. As I just showed, all it takes is sending an HTML string to a regular listbox. The down-side is that listboxes only display single-line messages, so if our message is too long we need to manually split it into separate listbox lines, which is rather inconvenient. Using HTML <br/> does not work since the allocated line height remains unchanged. We can fix this by playing around with the underlying Java object‘s RowHeight property, but that again is rather inconvenient.

The editbox solution

Instead of a listbox, I often use a multi-line editbox. Unfortunately, HTML is not as-easy to use in multi-line editbox contents, but as I have shown before, it is indeed possible and actually quite powerful. In fact, I am using such an editbox-based log panel’s in my online presentation at the MATLAB Computational Finance Virtual Conference tomorrow (Thursday Sep 19, 2013 at 2pm EST / 8pm CEST, see details below):

Real-time trading system demo in Matlab (click to zoom)

Real-time trading system demo in Matlab (click to zoom)

We can see in the screenshot that some log messages (the red warning message) can span multiple lines. Moreover, the panels can be interactively dragged/resized, making the multi-line log messages “flow” based on available space. So using an editbox is preferable to a listbox. The solution implemented in the demo is quite simple:

First we define the logging utility function (the icon filenames may need to be changed based on your Matlab release):

function logMessage(jEditbox,text,severity)
   % Ensure we have an HTML-ready editbox
   HTMLclassname = 'javax.swing.text.html.HTMLEditorKit';
   if ~isa(jEditbox.getEditorKit,HTMLclassname)
      jEditbox.setContentType('text/html');
   end
 
   % Parse the severity and prepare the HTML message segment
   if nargin < 3,  severity='info';  end
   switch lower(severity(1))
      case 'i',  icon = 'greenarrowicon.gif'; color='gray';
      case 'w',  icon = 'demoicon.gif';       color='black';
      otherwise, icon = 'warning.gif';        color='red';
   end
   icon = fullfile(matlabroot,'toolbox/matlab/icons',icon);
   iconTxt =['<img src="file:///',icon,'" height=16 width=16/>'];
   msgTxt = ['&nbsp;<font color=',color,'>',text,'</font>'];
   newText = [iconTxt,msgTxt];
   endPosition = jEditbox.getDocument.getLength;
   if endPosition>0, newText=['<br />' newText];  end
 
   % Place the HTML message segment at the bottom of the editbox
   currentHTML = char(jEditbox.getText);
   jEditbox.setText(strrep(currentHTML,[60 '/body>'],newText));
   endPosition = jEditbox.getDocument.getLength;
   jEditbox.setCaretPosition(endPosition); % end of content
end

Next, we initialize the log panel editbox and store the editbox’s underlying Java component (jEditbox) using the findjobj utility:

% Prepare the log editbox
hLogPanel = uicontrol('style','edit', 'max',5, 'Parent',hLeftBottomPanel, 'Units','norm', 'Position',[0,0.2,1,0.8], 'Background','w');
 
% Get the underlying Java editbox, which is contained within a scroll-panel
jScrollPanel = findjobj(hLogPanel);
try
    jScrollPanel.setVerticalScrollBarPolicy(jScrollPanel.java.VERTICAL_SCROLLBAR_AS_NEEDED);
    jScrollPanel = jScrollPanel.getViewport;
catch
    % may possibly already be the viewport, depending on release/platform etc.
end
jEditbox = handle(jScrollPanel.getView,'CallbackProperties');

Now, we can use this logging utility function to log messages in our application. For example:

logMessage(jEditbox, 'a regular info message...');
logMessage(jEditbox, 'a warning message...', 'warn');
logMessage(jEditbox, 'an error message!!!', 'error');
logMessage(jEditbox, 'a regular message again...', 'info');

Rich editbox contents (a log file)

Rich editbox contents (a log file)

HTML editboxes are normally editable, images included. In actual applications, we usually wish to prevent editing the displayed log. To do this, we simply call jEditbox.setEditable(false). Similarly, it is easy to set-up a Matlab callback-function to handle hyperlink clicks in the log panel (unlike what we might think, this is not handled automatically by the HTML processing engine):

% Prevent user editing in the log-panel
jEditbox.setEditable(false);
 
% Set-up a Matlab callback function to handle hyperlink clicks
set(jEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);

About the MATLAB Computational Finance Virtual Conference and my presentation

The MATLAB Computational Finance Virtual Conference is a one-day (Thursday Sep 19, 2013) event of hour-long presentations by industry professionals that showcase real-world examples demonstrating how financial-industry researchers and developers can excel at their jobs, improve their research and business processes, reduce costs, and mitigate risks by using Matlab. Registration to the conference is free and it’s a virtual conference, so there’s no need for a tie and jacket and you’re welcome to join…

MATLAB Computational Finance Conference 2013

My presentation on “A Real-Time Trading System in MATLAB“, is scheduled for 2pm EST / 8pm CEST. Following a half-hour presentation, I will answer audience questions online. The presentation slides can be downloaded here. Here is the recorded presentation video:

The demo system’s user interface showcases the hidden visualization and interactivity potential of Matlab for tracking order executions and charting financial time-series in real time. The undocumented features used in the demo include:

So, even if you’re not interested in real-time financial trading with Matlab, you might find it interesting to see the neat things that Matlab can do using a Java API interface and a few undocumented GUI tricks (such as the rich-contents log that I explained above).

The demo source code is provided here (tradingDemo.m and supporting files). Note that this is provided as-is, free of charge but without any warranty or support. You would naturally need IB-Matlab and an Interactive Brokers account to run it. But you can reuse parts of the source code in your Matlab programs even without an IB account or IB-Matlab.

 
Related posts:
  1. Rich Matlab editbox contents The Matlab editbox uicontrol does not handle HTML contents as do other uicontrols. In this article I show how this limitation can be removed....
  2. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
  3. Panel-level uicontrols Matlab's uipanel contains a hidden handle to the title label, which can be modified into a checkbox or radio-button control...
  4. Customizing help popup contents The built-in HelpPopup, available since Matlab R2007b, has a back-door that enables displaying arbitrary text, HTML and URL web-pages....
 

Customizing editboxes

$
0
0

As a natural follow-up to last week’s article about rich-content log panels (multi-line editbox), today I discuss some additional customizations that can be done to Matlab’s editbox control.

Matlab’s dual editbox controls

There are two distinct uicontrols called ‘editbox’ in Matlab: a single-line editbox and a multi-line editbox. Matlab automatically uses the single-line control if the Max property is set to 1 (the default value, backward compatible with early Matlab versions). If Max > 1, the multi-line editbox is used. Today’s article will focus on features shared by both the single-line and multi-line editbox controls.

Beware of a possible pitfall using Matlab’s editbox controls: when switching styles, including switching between the single-line and multi-line editbox versions, Matlab replaces the underlying Java component with a new component that has default properties. Therefore, if we need any customizations to the uicontrol, then we should ensure that they are done after setting the final uicontrol style, otherwise they will be discarded.

Underlying Java object

As discussed in many prior articles, the first step in customization is to get access to the Matlab control’s underlying Java control. This is done using the findjobj utility:

% Prepare the log editbox
hEditbox = uicontrol('Style','edit', 'String','Matlab', ...);
 
% Get the underlying Java editbox
jEditbox = findjobj(hLogPanel);
 
try
    % Multi-line editboxes are contained within a scroll-panel
    jEditbox = handle(jEditbox.getViewport.getView, 'CallbackProperties');
catch
    % probably a single-line editbox
end

Borders

As I have explained long ago, all uicontrol borders can be customized using the underlying jEditbox handle’s Border property:

% Create a new border
lineColor = java.awt.Color(1,0,0);  % =red
thickness = 3;  % pixels
roundedCorners = true;
newBorder = javax.swing.border.LineBorder(lineColor,thickness,roundedCorners);
 
% Override the default control's border
jEditbox.Border = newBorder;  % or: set(jEditbox,'Border',newBorder) or: jEditbox.setBorder(newBorder)
 
% Remove the border altogether
jEditbox.Border = [];
 
% Redraw the modified control after we have changed its appearance
jEditbox.repaint;

editbox with regular border

editbox with regular border

   
editbox with custom border

editbox with custom border

   
editbox with no border

editbox with no border


Much more complex and interesting borders can be created in much the same way. Interested readers are referred to the official documentation of Java Borders or any decent Swing textbook.

Text selection

Several jEditbox properties control the text-selection functionality:

  • SelectionStart, SelectionEnd control the characters within the displayed text that are selected (typically with some shaded background color). A value of 0 means the first character, 1 means the second character etc. Setting SelectionStart=0 and SelectionEnd=intmax selects the entire text. We can also use jEditbox.select(selectionStart,selectionEnd). For example:
    set(jEditbox, 'SelectionStart',1, 'SelectionEnd',5);
    jEditbox.select(1,5)  % equivalent alternative

    Setting the selected text

    Setting the selected text

  • SelectionColor, SelectedTextColor change the foreground and background colors of the selected text. These properties are overridden whenever the editbox gains focus, so we need to be override them in the editbox’s FocusGainedCallback:
    cbStr = ['set(gcbo,''SelectionColor'',java.awt.Color.red,' ...
                   '''SelectedTextColor'',java.awt.Color.blue)'];
    set(jEditbox, 'FocusGainedCallback', cbStr);

    Non-standard selection colors and FocusGainedCallback

    Non-standard selection colors, FocusGainedCallback

  • SelectedText is a read-only property holding the text currently selected, between the SelectionStart and SelectionEnd positions. Associated property Text holds the entire text within the editbox. Note that both these properties hold a java.lang.String object, which should be cast to a Matlab string via Matlab’s built-in char function, unless we use Matlab’s get function (which does this conversion for us automatically):
    str = char(jEditbox.getSelectedText);
    str = get(jEditbox,'SelectedText');  % equivalent alternative

Customizing the input caret

The Caret property, which is common to all Java Swing data-entry components, references a javax.swing.text.DefaultCaret object that controls the text caret appearance (this is naturally relevant only for editable editboxes).

The caret object has its own properties that can be customized. For example: BlinkRateRate, Visible and UpdatePolicy. The caret’s StateChangedCallback is invoked whenever the caret position is updated.

Some additional caret-related properties can be set using jEditbox properties: CaretColor and CaretPosition (which uses 0-based, like SelectionStart and SelectionEnd above). Here is an example that modifies the default caret color to something a bit more lively:

% Set the caret color to red
jEditbox.setCaretColor(java.awt.Color(1.0,0,0));
jEditbox.setCaretColor(java.awt.Color.red);	% an alternative

Red CaretColor

Red CaretColor

Behavior

Several properties of the jEditbox handle control the editbox behavior beyond what is available by the Matlab uicontrol:

  • Editable – (default=true) a boolean flag indicating whether or not the editbox text can be modified. Note that the Matlab HG handle (hEditbox) only allows setting the Enable property (its jEditbox Java counterpart property is called Enabled), but not to set an enabled yet uneditable control – this can only be done using the Java Editable property.
  • DisabledTextColor controls the text color (default=gray) when the editbox is disabled.
  • DragEnabled – (default=false) a boolean flag indicating whether the editbox contents can be mouse-dragged externally as a DND source (for example, onto an editor, command line or any DND target). The DropMode, DropLocation, DropTarget and TransferHandler properties enable the editbox act as a DND target, accepting externally-dragged data as input sources.
  • FocusAccelerator – (default=char(0)) sets the keyboard accelerator sequence that will cause the receiving text component to get the focus. The accelerator will be the key combination of the <Alt> key and the specified character, converted to upper-case. Any previous key accelerator setting, including menu-bar accelerators, will be superseded. A char(0) key has the effect of turning off the focus accelerator. By default, there is no focus accelerator key (i.e., an accelerator of \0=char(0)). For example, let us set the accelerator to <Alt>-E, overriding the menu-bar’s default accelerator for the Edit menu:
    >> jEditbox.setFocusAccelerator('e');
    >> jEditbox.getFocusAccelerator		% let us check...
    ans =
    E	% 'e' converted to 'E', meaning an Alt-E accelerator

Additional editbox behavior can be customized using the dozens of callback functions that jEditbox exposes. These callbacks enable modifying the appearance and behavior of the editbox based on events such as mouse movements (into/over/out-of), focus gain/loss, key-clicks (that enable input data validation) etc. I plan to describe a data input-validation function based on these callbacks, using some of the customizations shown above, in next week’s article.

Available report – “Advanced Customizations of Matlab Uicontrols”

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.

 
Related posts:
  1. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  2. Customizing uicontrol border Matlab uicontrol borders can easily be modified - this article shows how...
  3. Customizing Matlab labels Matlab's text uicontrol is not very customizable, and does not support HTML or Tex formatting. This article shows how to display HTML labels in Matlab and some undocumented customizations...
  4. Customizing menu items part 2 Matlab menu items can be customized in a variety of useful ways using their underlying Java object. ...
 

Editbox data input validation

$
0
0

Last week I explained how Matlab’s editbox control can be customized using its underlying Java component. Today I extend that article by explaining how we can use this information to provide a very user-friendly input-validation function for Matlab editboxes.

Zip-code entry validation example

Zip-code entry validation example


As before, we first need to get the Matlab control’s underlying Java control. This is done using the findjobj utility:

% Prepare the log editbox
hEditbox = uicontrol('Style','edit', 'String','Matlab', ...);
 
% Get the underlying Java editbox
jEditbox = findjobj(hLogPanel);
 
try
    % Multi-line editboxes are contained within a scroll-panel
    jEditbox = handle(jEditbox.getViewport.getView, 'CallbackProperties');
catch
    % probably a single-line editbox
end

Callbacks

Once we have the jEditbox reference handle, we can use some ~30 different event callbacks that it exposes. Some of the useful callbacks include:

  • ActionPerformedCallback – fired when is clicked in the editbox
  • CaretUpdateCallback – fired when the caret position has changed
  • KeyTypedCallback – fired whenever a keyboard button is typed when the editbox has focus

For example:

set(jEditbox, 'KeyPressedCallback',@myValidationFunction);
 
% Callback function definition
function myValidationFunction(jEditbox, eventData)
    % The following comments refer to the case of Alt-Shift-b
    keyChar = get(eventData,'KeyChar');  % or: eventData.getKeyChar  ==> 'B'
    isAltDown = get(eventData,'AltDown');  % ==> 'on'
    isAltDown = eventData.isAltDown;  % ==> true
    modifiers = get(eventData,'Modifiers');  % or: eventData.getModifiers ==> 9 = 1 (Shift) + 8 (Alt)
    modifiersDescription = char(eventData.getKeyModifiersText(modifiers));  % ==> 'Alt+Shift'
    % (now decide what to do with this key-press...)
end

Using such a validation function enables us to immediately convert typed characters into ‘*’ (in password fields) or check that the input conforms to a standard format such as a 5-digit zip code, a valid-looking email address or a valid-looking credit-card number (Luhn’s algorithm, recently featured in a video tutorial by Doug Hull). Of course, there are dedicated JIDE controls that do much of this already, but let’s not digress.

In today’s example, we shall implement a simple input-validation function for a 5-digit zip code. When the input data is invalid, the editbox will be colored red and an appropriate message will appear next to the editbox. In addition, invalid (non-digit) characters shall be rejected with a beep sound.

Zip-code validation example

To illustrate the above, let’s use an example of a 5-digit zip-code entry validation. We start by creating an empty editbox with an associated message label next to it:

figure('Color','w', 'Menubar','none');
hEditbox = uicontrol('Style','edit', 'Pos',[10,10,60,20], 'String','Matlab');  % start with an invalid string
hMessageLabel = uicontrol('Style','text', 'Pos',[80,10,200,20], 'horizontal','left', 'background','w', 'Foreground','red');

Next we get the underlying jEditbox reference and set its entry-validation callback function:

jEditbox = findjobj(hEditbox);  % single-line editbox so there's need to drill-down the scroll-pane
set(jEditbox, 'KeyPressedCallback',{@editboxValidation,hMessageLabel});

Note how we pass the message-label’s handle as an extra input parameter to the callback function.

Now we define the callback function editboxValidation and place it on the Matlab path (for example, by placing the following within editboxValidation.m in a folder that is already on your path):

% editboxValidation - ensure that an editbox input is a valid 5-digit zip code
function editboxValidation(jEditbox, eventData, hMessageLabel)
    keyChar = eventData.getKeyChar;  % see note below about how we can trick Matlab here
    if ~alldigits(keyChar) && isprintable(keyChar)
        beep;
        fixedText = strrep(char(jEditbox.getText), keyChar, '');
        jEditbox.setText(fixedText);
    end
    updateAppearance(jEditbox, hMessageLabel);
end
 
% Check whether a string only contains digits
function flag = alldigits(str)
    flag = ~isnan(str2double(str));
end
 
% Check whether a character is printable
function flag = isprintable(keyChar)
    keyVal = double(keyChar);
    flag = ~isempty(keyVal) && keyVal > 31 && keyVal < 128;
end
 
% Update the GUI appearance based on the editbox text
function updateAppearance(jEditbox, hMessageLabel)
    currentText = char(jEditbox.getText);
    if isempty(currentText)
        set(hMessageLabel, 'String','Please enter a 5-digit zip-code')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    elseif ~alldigits(currentText)
        beep;
        set(hMessageLabel, 'String','Invalid zip: should only contain digits')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    elseif length(currentText) ~= 5
        set(hMessageLabel, 'String','Invalid zip: should have exactly 5 digits')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    else
        set(hMessageLabel, 'String','');
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.gray, 1, false));
    end
end

Finally, we call the validation function directly after creating our GUI, to let the user know that the zip-code needs to be entered:

% Note how we trick Matlab by using eventData as a struct rather than a Java object
% (i.e., getKeyChar is set here to be a simple struct field, rather than a Java method)
eventData.getKeyChar = '';
editboxValidation(jEditbox,eventData,hMessageLabel)

Zip-code entry validation example

Zip-code entry validation example

Naturally, this is a very simple example, and you can easily expand it for your needs. But it does show the basic components of any input validation: checking the new data, updating the control as appropriate, and modifying the appearance of the underlying control and of other associated controls.

Available report - "Advanced Customizations of Matlab Uicontrols"

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.

 
Related posts:
  1. Rich Matlab editbox contents The Matlab editbox uicontrol does not handle HTML contents as do other uicontrols. In this article I show how this limitation can be removed....
  2. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  3. ishghandle’s undocumented input parameter The built-in function ishghandle accepts a second input argument with the expected handle type....
  4. Accessing plot brushed data Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
 

Editable combo-box

$
0
0

In previous articles, I explained how we can use findjobj to customize a Matlab uicontrol’s underlying Java control, thereby improving its appearance and functionality. My two previous articles on the Matlab editbox were a classic example of this mechanism. Unfortunately, this technique does not always work well, and an alternative mechanism needs to be used. One such case in point is the subject of today’s article.

Matlab combo-box (a.k.a. “popup-menu” or “drop-down”) controls are very simple controls that accept a list of strings from which a user can select. This is a very simple control that answers a wide range of use-cases. Unfortunately, it is quite limited. Among other limitations, we cannot modify the popup-panel’s appearance/functionality; we cannot select multiple items; and we cannot type-in a value in the control’s editbox. Today’s article will focus on the latter limitation, namely how to use an editable combo-box.

Trying to make Matlab’s standard combobox editable

We can indeed use findjobj to get a Matlab combo-box’s underlying Java control. This turns out to be a com.mathworks.hg.peer.ComboboxPeer$MLComboBox object, which extends the standard Java Swing JComboBox:

>> hCombo = uicontrol('Style','popup', 'String',{'a','b','c'});
>> jCombo = findjobj(hCombo)
jCombo =
	javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox

This jCombo control has the Editable property that we can then try to override (the default value is false):

>> jCombo.setEditable(true);
>> jCombo.Editable = true;          % equivalent alternative
>> set(jCombo,'setEditable',true);  % equivalent alternative
Editable combo-box control

Editable combo-box control

The bad news is that the moment we enter some value (as in the screenshot here) that is not already a member of the pop-up panel (i.e., the cell-array in the String property), then the control disappears and a warning message is issued to the Matlab console:

Warning: popupmenu control requires that Value be an integer within String range
Control will not be rendered until all of its parameter values are valid
(Type "warning off MATLAB:hg:uicontrol:ParameterValuesMustBeValid" to suppress this warning.)

The reason for this behavior is that when the combo-box object detects that the text field’s content match none of the popup list items, it automatically sets jCombo‘s SelectedIndex to -1 and Matlab’s corresponding HG Value property to 0. At this point the Matlab implementation kicks in, hiding the uicontrol since it considers 0 an invalid value for the Value property. This is similar to the check being done to test for an empty HG String value (=no items):

>> set(hCombo, 'string', [])
popupmenu control requires a non-empty String
Control will not be rendered until all of its parameter values are valid.

We can clear these particular warnings via:

warning('off','MATLAB:hg:uicontrol:ParameterValuesMustBeValid')

but this does not prevent the control from being hidden – it just prevents the warning from showing on the Command Window.

We can dive deeper and try to modify the underlying data model and disassociate the Java control from HG, but let’s stop at this point since there is really no point considering the fact that there is a much simpler alternative.

Note: if you do decide to make the standard Matlab uicontrol editable, read here for a related customization that I posted several years ago.

The pure-Java alternative

Rather than customizing Matlab’s uicontrol, we can easily create an identical-looking control using the standard Java Swing JComboBox, which has none of these problems/limitations. We can create and display the component in one go using the semi-documented javacomponent function:

position = [10,100,90,20];  % pixels
hContainer = gcf;  % can be any uipanel or figure handle
options = {'a','b','c'};
model = javax.swing.DefaultComboBoxModel(options);
jCombo = javacomponent('javax.swing.JComboBox', position, hContainer);jCombo.setModel(model);jCombo.setEditable(true);

We can use a variant of javacomponent to create the component with the model in one go, replacing the highlighted lines above:

jCombo = javacomponent({'javax.swing.JComboBox',model}, position, hContainer);

Once we have the control ready, all we need to do is set its ActionPerformedCallback property to our Matlab callback function and we’re pretty-much set. We can get the currently-selected text using char(jCombo.getSelectedItem) and the selected list index (0-based) using jCombo.getSelectedIndex (which returns -1 if we entered a non-listed value, 0 for the first list item, 1 for the second etc.). More information can be found here.

Lesson learnt

In the past 20+ years of my professional life as engineer and development manager, my number one rule has always been:

DON’T FIX IT, IF IT AIN’T BROKE!

But sometimes, we should also remember an alternative version:
DON’T FIX IT, IF IT’S EASIER TO REPLACE!

Available report – “Advanced Customizations of Matlab Uicontrols”

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.

 
Related posts:
  1. Using JIDE combo-boxes Matlab includes many custom JIDE combo-box controls that can be used in Matlab GUIs out of the box. ...
  2. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
  3. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  4. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
 

Using JIDE combo-boxes

$
0
0

Continuing last week’s article on customized combo-boxes (a.k.a. popup menus or drop-downs), today I discuss how we can use JIDE‘s vast array of custom professional combo-boxes in our Matlab GUI.

As I’ve already noted here in several articles, Matlab heavily uses JIDE’s library of GUI controls for its own GUI (Desktop, Editor etc.) and we can tap into this wealth of components in our own GUI. I’ve recently shown an example of this in my treeTable utility, which greatly extends Matlab’s standard uitable. After using treeTable for a while, it’s difficult to go back to using the plain standard uitable… A similar experience will undoubtedly occur after using some of JIDE’s combo-boxes.

DateSpinnerComboBox CheckBoxListComboBox ColorComboBox

Some of the JIDE combo-box controls


JIDE combo-boxes

JIDE’s combo-box controls are generally grouped in the JIDE Grids package and extend the standard Java Swing JComponent (JIDESoft actually found it easier to extend JComponent than JComboBox, but users really have nothing to complain – all the extra functionality and more have simply been reimplemented). The JIDE Grids package is included in each Matlab installation (/java/jarext/jide/jide-grids.jar under the Matlab root). In particular, JIDE Grids includes the com.jidesoft.combobox Java package, which groups the combo-box components. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

Back in 2010, I explained how we can use one of these components, DateComboBox, and its close associate DateSpinnerComboBox. Today I extend the coverage to briefly examine JIDE’s other custom combo-box controls.

Each of the following classes has both a combo-box control and a corresponding panel that is presented when the combo-box arrow button is clicked (activated). The panel is normally called xxxChooserPanel and its corresponding combo-box is called xxxComboBox. So, for example, we would have ColorComboBox coupled with ColorChooserPanel. After the combo-box is created, the panel can be accessed and customized via the combo-box’s PopupPanel property or the corresponding getPopupPanel() method. The panel can also be displayed as a standalone control, as I’ve shown in the DateComboBox article. GUI designers can choose whether to use a compact combo-box or the full-size panel control.

  • ListComboBox – a simple combo-box that accepts a list (cell array) of selectable values (e.g., string values). This is the simplest JIDE combo-box. It doesn’t add much over Matlab’s standard combo-box control except the ability to easily set the MaximumRowCount property (default value =8). On the other hand, using findjobj we can do the same thing with Matlab’s control…
  • MultilineStringComboBox – a combo box that enables entering a string item that has multiple lines of text. A similar control is StringArrayComboBox that simply formats the multi-line string differently in the result, separating the multi-lines with a ‘;’ character.
  • MultiSelectListComboBox – a combo-box that enables selecting multiple items using a combination of <Shift>-click and <Ctrl>-click
    MultiSelectListComboBox

    MultiSelectListComboBox

  • CheckBoxListComboBox – a combo-box that presents a multi-selection panel using check-boxes. It will be discussed in next week’s article.
    CheckBoxListComboBox

    CheckBoxListComboBox

  • CalculatorComboBox – a combo-box control that displays the result of simple arithmetic calculations. Possible customizations include the ability to set the calculator buttons’ size and gap, the displayed number format, the initial value etc. – all via the Calculator property that returns a customizable com.jidesoft.swing.Calculator object.
    CalculatorComboBox

    CalculatorComboBox

  • ColorComboBox – a combo-box control that enables color selection. Matlab includes a large number of color selectors, as explained in this article. Possible customizations of the ColorComboBox control include the ability to hide the color’s RGB value (ColorValueVisible property, boolean, default=true), hide the colored icon rectangle (ColorIconVisible property, boolean, default=true), make the control look like an editbox rather than a combo-box (ButtonVisible property, boolean, default=true), allow the “More colors…” features (AllowMoreColors, boolean, default=true) etc.
    ColorComboBox

    ColorComboBox

  • JideColorSplitButton – a control very similar to ColorComboBox, meant for usage in toolbars or wherever a narrow color-selection control is needed:
    JideColorSplitButton

    JideColorSplitButton

  • DateComboBox – presents a date-selection combo-box, whose attributes (day/month names, display format etc.) are taken from the system definitions. JIDE’s date-selection components were discussed in a dedicated article. Possible customizations include the ability to display an integrated time-selector sub-component (via the TimeDisplayed property: boolean, default=false and TimeFormat string), week numbers (ShowWeekNumbers, boolean, default=true), <OK> button (ShowOKButton, boolean, default=false), the <Today> button (ShowTodayButton, boolean, default=true) and the <None> button (ShowNoneButton, boolean, default=true).
    DateComboBox

    DateComboBox

  • DateSpinnerComboBox – presents a date-selection combo-box that includes both the DateComboBox and a spinner control
    DateSpinnerComboBox

    DateSpinnerComboBox

  • MonthComboBox – a month-selection combo-box, similar to DateComboBox but without the ability to select individual days, only full months
    MonthComboBox

    MonthComboBox

  • FileChooserComboBox – a combo-box that displays a file-selection window when activated. Customizations include the ability to set the CurrentDirectoryPath used by the popup window.
  • FolderChooserComboBox – a combo-box that displays a folder-selection window when activated
  • FontComboBox – a font selection combobox (Matlab has several other font-selection components that we can use, in addition to uisetfont)
    FontComboBox

    FontComboBox

  • InsetsComboBox – enables interactive definition of insets (margins)
    InsetsComboBox

    InsetsComboBox

  • TreeComboBox– a combo-box that displays selectable data in tree format (i.e., a hierarchy of items)
    TreeComboBox

    TreeComboBox

  • TableComboBox – a combo-box that displays selectable data in table format (i.e., multiple columns). The combo-box’s value is the selected table row’s left-most column value. Here’s an example:
    data = num2cell([magic(3); -magic(3)]);  % needs to be a 2D cell-array
    headers = {'one', 'two', 'three'};
    tableModel = javax.swing.table.DefaultTableModel(data, headers);
    jCombo = com.jidesoft.combobox.TableComboBox(tableModel);
    [hjCombo, hContainer] = javacomponent(jCombo, [150,300,120,20], gcf);

    TableComboBox

    TableComboBox

Integrating in Matlab GUI

To use any of these controls, we first need to initialize JIDE usage in Matlab, then create an instance of the control, and finally place it onscreen using the semi-documented javacomponent function:

% Initialize JIDE's usage within Matlab
com.mathworks.mwswing.MJUtilities.initJIDE;
 
% Display a DateChooserPanel
jCombo = javaObjectEDT(com.jidesoft.combobox.DateComboBox);  % javaObjectEDT is optional but advisable
[hjCombo, hContainer] = javacomponent(jCombo, [10,10,100,20], gcf)

Each combo-box control accepts its combo-list elements somewhat differently. For example, for DateComboBox we can specify the acceptable date-range (via DefaultDateModel) and initial date, for a FontComboBox we can specify the initial font, and for any of the list controls we need to specify the list elements (as a cell-array of strings). However, most if not all of these components have default constructors so we can initialize the controls without any inputs and let it automatically use the defaults. For example, the date-selection controls will use the current date (today) as its default value.

In most cases, we can set the control handle’s ActionPerformedCallback to process a selection event (or modification of the combo-box value via direct editing in its integrated editbox):

set(hjCombo, 'ActionPerformedCallback', @myMatlabCallbackFcn);

The selected item can in most cases be retrieved via

selectedItem = get(hjCombo,'SelectedItem');  % or: hjCombo.getselectedItem

For some combo-boxes, non-numeric results may need to be converted into Matlab strings, via the char function:

selectedItem = char(selectedItem);

Next week I plan to present a non-trivial customization of the CheckBoxListComboBox control.

Additional discussion of JIDE’s combo-boxes, and JIDE controls in general, is available in Chapter 5 of my Matlab-Java Programming book.
If you need to integrate professional-looking controls such as these in your Matlab GUI, consider hiring my consulting services.

Caution

Remember that JIDE evolves with Matlab, and so JIDE’s online documentation, which refers to the latest JIDE version, may be partially inapplicable if you use an old Matlab version. In any case, Matlab releases always lag the latest JIDE release by at least a year (e.g., Matlab R2013b uses JIDE v3.4.1 that was released in June 2012). The older your Matlab, the more such inconsistencies that you may find. For example, I believe that DateSpinnerComboBox only became available around R2010b; similarly, some control properties behave differently (or are missing altogether) in different releases. To determine the version of JIDE that you are currently using in Matlab, run the following (the result can then be compared to JIDE’s official change-log history):

>> com.jidesoft.utils.Lm.getProductVersion
ans =
3.4.1

Note that JIDE is a commercial product. We may not use it without JIDESoft’s permission outside the Matlab environment. It is my understanding however, that we can freely use it within Matlab. Note that this is not legal advise as I am an engineer, not a lawyer. If you have any licensing questions, contact sales@jidesoft.com.

 
Related posts:
  1. Editable combo-box Matlab's popup menu (combo-box) control is quite limited in its abilities. This article explains how we can work around these limitations. ...
  2. JIDE Property Grids The JIDE components pre-bundled in Matlab enable creating user-customized property grid tables...
  3. Advanced JIDE Property Grids JIDE property grids can use complex cell renderer and editor components and can signal property change events asynchronously to Matlab callbacks...
  4. Date selection components The JIDE package, pre-bundled in Matlab, contains several GUI controls for selecting dates - this article explains how they can be used...
 

Draggable plot data-tips

$
0
0

A couple of years ago, I was asked by a client to figure out a way to make Matlab plot data-tips movable. The problem was that he had a very crowded plot and Matlab’s standard data-tips are displayed immediately adjacent to the data, thereby overlapping the plot parts. Matlab’s standard data-tips enable dragging to a very limited extent (only to the 4 corners of the data-point), and in any case the displayed textbox remains directly attached to the data point.

So I developed a small utility for my client that solves this problem. I then forgot all about it until a few days ago when I came across it again. Yesterday I uploaded this draggableDataTips utility to the File Exchange, where you can download it.

draggableDataTips enables the user to interactively drag any newly-created data-tip, anywhere in the Matlab figure. A dashed line connects the dragged data-tip with the original data point. Simple, intuitive, and effective. At 300 lines, the draggableDataTips.m source code is compact and easy to follow, and you’re welcome to take a look and further customize this utility for your specific needs.

draggableDataTips utility in action

draggableDataTips utility in action


Technical implementation

The implementation of draggableDataTips relies on undocumented aspects of the data-cursor object exposed via the datacursormode function. I have already shown how these can be used to customize and control data-tips programmatically (rather than interactively). For draggableDataTips, we first get the cursor object’s meta-data classhandle (a schema.class object), then use it to find the meta-data for its hidden CurrentDataCursor property (a schema.prop object). There is also a more direct approach, using the findprop function.

Whichever alternative we choose, we finally use this object to set the property’s SetFunction meta-property. Quite straight-forward, I should say:

% Get the cursor-mode object
cursorObj = datacursormode(hFig);
 
% Alternative #1: the indirect route to the meta-property
ch = classhandle(cursorObj);
hPropIdx = strcmpi(get(ch.Properties,'Name'), 'CurrentDataCursor');
hProp = ch.Properties(hPropIdx);
 
% Alternative #2: the direct approach
hProp = findprop(cursorObj, 'CurrentDataCursor');
 
% Update the meta-property to use a custom function whenever new data-tips are created
hProp.SetFunction = @installNewMoveFcn;

This has the effect that all new data-tips that will be created from then on will call our custom installNewMoveFcn function when the data-tip object is created. This installNewMoveFcn function, in turn, simply replaces the data-tips standard default callback for mouse movement (which is used while dragging), to a new custom function textBoxUpdateFcn:

% Install a replacement callback function for datatip textbox mouse movement
function hDataTip = installNewMoveFcn(cursorObj, hDataTip)
    srcObjs = get(hDataTip.SelfListenerHandles,'SourceObject');
    for srcIdx = 1 : length(srcObjs)
        if strcmpi(srcObjs{srcIdx}.Name,'Orientation')
            hDataTip.SelfListenerHandles(srcIdx).Callback = @textBoxUpdateFcn;
            hDataTip.MarkerHandle.Marker = 'none';
            break;
        end
    end
end

The textBoxUpdateFcn function basically moves the datatip textbox to the new mouse location, without limiting its positions as Matlab’s standard default callback function did. A dashed connector line is then drawn to connect the center of the textbox with the data-point. It’s a bit long to include here, but interested readers are welcome to look at the code (lines #99 onward in draggableDataTips.m).

As can be seen from the screenshot above, standard and draggable data-tips can be used in the same plot. This is done by simply turning the draggability functionality on and off by draggableDataTips before creating a new data-tip (using either alt-click or programmatically):

draggableDataTips on    % or: draggableDataTips('on')  or: draggableDataTips(true)
draggableDataTips off   % or: draggableDataTips('off') or: draggableDataTips(false)

Notes:

  1. The actual code of draggableDataTips naturally contains more sanity checks, exception handling etc. I have only presented the core code in the snippets above, but you should always include such extra checks in any real-life program.
  2. There is a minor bug that causes the connector line to be on top of the box rather than beneath it, but aside from this all works ok. For some reason, uistack did not work. If anyone has a fix for this bug, please let me know.
  3. Did you notice that Java was not mentioned anywhere above? Mode managers, such as the data-cursor mode, use pure-Matlab functionality.

HG2

Unfortunately, when I tested draggableDataTips on HG2, Matlab’s upcoming new graphics engine, the utility failed. Data-cursors have undergone a significant reengineering in HG2 (about time!), causing multiple properties and methods to change names and functionality. But this could be overcome (see lines #43-53 in draggableDataTips.m).

However, I could not overcome the apparent fact that unlike HG1 (or more specifically, schema objects, that HG1 uses for its data-tips functionality), in HG2 (or rather, MCOS class objects) we cannot override an object’s meta-properties, specifically its SetMethod (which is the MCOS equivalent of schema.prop‘s SetFunction meta-property).

So for the moment, draggableDataTips does not work on HG2. I hope to find a solution for this by the time HG2 launches. If anyone finds a fix for the problem, please let me know. If I ever find or receive a fix, I will update this post with the relevant technical details.

For the moment there is no rush, since HG2 is still relatively far away in the distant future, and draggableDataTips works splendidly in the current HG1.

Have you used plot data-tips in some nifty way? If so, please share your experience in a comment below.

 
Related posts:
  1. Controlling plot data-tips Data-tips are an extremely useful plotting tool that can easily be controlled programmatically....
  2. Accessing plot brushed data Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
  3. Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....
  4. Undocumented scatter plot jitter Matlab's scatter plot can automatically jitter data to enable better visualization of distribution density. ...
 

Matlab numerical gotchas

$
0
0

In deference to Halloween, I thought of posting a short note on a couple of Matlab numerical gotchas. They are not really undocumented – in some cases they are specifically documented and in other cases can be inferred from the documentation. What they share in common is that for some reason they are not widely known. Their importance comes from the fact that I often encounter them in Matlab code, and they often do not immediately cause syntax error, but rather more difficult-to-diagnose incorrect results. So I thought it would be worthwhile to formally document them here:


www.mezzacotta.net/garfield

1. Inverse-trig of “invalid” values

This one came to me from Baruch Karlin:

In a program using math functions, it is easy to forget to limit the values of interim computations to the boundaries expected in the physical world. One specific example is that while we normally think of inverse trig functions (e.g., asin and acos) as returning the angles corresponding to the specified trig function result, in fact such inverse-trig functions are defined mathematically such that their range extends past the “standard” domain (-1 to +1 in the case of asin and acos):

The result is that asin(10) is just as valid in Matlab as asin(1). The results of such “invalid” values are standard complex values, which Matlab treats as regular numeric values. This is often an undesirable effect that would cause incorrect results downstream in the program code:

>> value = some_computation();
>> result = asin(value)   %value=10 in this example
result =
       1.5707963267949 -  2.99322284612638i

As the snippet shows, it is sometimes difficult to immediately see that the value variable could receive an inappropriate value, resulting in a complex result. Assuming this is undesirable, we could clamp the value:

value = some_computation();
value = min(max(real(value),-1),1);   %value is clamped to [-1,+1]
result = asin(value);   % result is assured to be real

2. Numeric (in)equalities

This is an oldie, in this case well predating Matlab, going back all the way to the early days of floating-point arithmetic. It is probably the most widely-known and yet most widely-encountered gotcha in any programming language since the days of yore. It is featured in the semi-official Matlab FAQ, which explains the reason that:

>> 1 == (3 -1.1 -0.9)
ans =
     0    %=false!
 
>> 2 -1.1 -0.9
ans =
    -1.11022302462516e-016

The workaround is to use eps whenever comparison of non-integer numeric values is needed, and indirect comparison (e.g., < or >) rather than direct ones (== or ~=).

The reader in referred to the above-mentioned FAQ, or to one of the following resources:

3. Cube root returns a complex number

This one is also an oldie from the semi-official Matlab FAQ (a bit paraphrased):

Since 81/3=2, we naturally expect to find that (-8)1/3=-2. Unfortunately we find in Matlab that:

>> (-8)^(1/3)
ans =
                1 +      1.73205080756888i

In the same way there are two solutions (plus and minus) for the square root of a positive real number, there are multiple solutions for roots of negative (and complex) numbers. If you express a number as A*e, its cube root takes the form (A1/3)*ei(θ+2kπ)/3, for k=0:2. Since -8 is 8e, θ=π or -π. Therefore, the cube roots of -8 are 2eiπ/3, 2e-iπ/3, and 2e. The last one simplifies to the expected real value of -2.

So we see that the cube root (and in general, the n-th root) always returns 3 roots (or in general, n roots), and Matlab chooses one of them, which may not necessarily be non-complex. As in the first gotcha, the resulting complex value is correct in the mathematical sense, but could well lead to erroneous results downstream in the Matlab code.

Matlab always returns the first solution counter-clockwise from the positive real axis. Armed with this knowledge, we can compute all or some particular root. For instance, if you want the negative real cube root, simply take the cube root of the absolute value of the number, and negate it. For a different wording and more information, see MathWorks Tech Solution 1-15M1N.

Joe Sababa suggested a method to find all the roots at once using roots on the polynomial, effectively solving x3+8=0 for x:

>> P=[1 0 0 8]; roots(P)  % solve x^3 + 8 = 0
ans =
                         -2                         
          0.999999999999999 +      1.73205080756888i
          0.999999999999999 -      1.73205080756888i

(note the FP inaccuracy, discussed in the previous gotcha)

An alternate method to obtain -2 as a cube root of -8 is to use the nthroot function:

>> x = nthroot(-8, 3)
x =
    -2

4. Usage of “+” and “-” in arrays

Usage of “+” and “-” operators is normally intuitive. Matlab knows when we refer to the unary operation and when to the binary one. But it gets somewhat less intuitive in numeric arrays:

>> [1 -2 3 4 5]  %unary minus
ans =
     1    -2     3     4     5
 
>> [1 - 2 3 4 5]  % binary minus
ans =
    -1     3     4     5
 
 
>> [1 +2 3 4 5]  % unary plus
ans =
     1     2     3     4     5
 
>> [1 + 2 3 4 5]  % binary plus
ans =
     3     3     4     5

As can be seen, the extra space between the operator and the number caused Matlab to change its treatment of the operator. This also applies to programmatic values such as: [value1 -value2 ...].

Teaching how to customize Excel reports via Matlab (click for details)

Teaching how to customize Excel reports via Matlab (click for details)

A few months ago I presented a Matlab training course at some company. One of the attendees tried to programmatically modify an Excel worksheet in a Matlab program by directly accessing certain worksheet cells as ‘a3′, ‘b3′ etc. He used a simple loop such as this:

for columnIdx = 1 : 5
   cellAddress = ['a' +columnIdx-1 '3'];  % should be, for example: 'c3'
   Excel.Range(cellAddress).Value = someValue;
end

Can you spot why Excel croaked when the Matlab program ran?

The workaround here is to either ensure that unary operators are directly adjacent to the values, or separate the values with a comma (or a semi-colon ; ) to prevent any misunderstanding by Matlab:

>> [1, - 2, 3, 4, 5]
ans =
     1    -2     3     4     5
 
>> [1; - 2; 3; 4; 5]
ans =
     1
    -2
     3
     4
     5

Do you have another similar gotcha that you’ve encountered? If so, please post a comment below.

(if there’s any interest, maybe I’ll follow up with some non-numeric gotchas for next year’s Halloween…)

Happy Halloween everyone!

 
Related posts:
  1. Solving a MATLAB bug by subclassing Matlab's Image Processing Toolbox's impoint function contains an annoying bug that can be fixed using some undocumented properties....
  2. Docs of old Matlab releases MathWorks recently posted archived documentation for many previous Matlab releases...
  3. Running VB code in Matlab Matlab does not natively enable running VB code, but a nice trick enables us to do just that...
  4. Matlab installation woes Matlab has some issues when installing a new version. This post discusses some of them and how to overcome them....
 
Viewing all 219 articles
Browse latest View live




Latest Images