Archive for the ‘Undocumented function’ Category

New information on HG2

Monday, May 10th, 2010

Last week I posted a couple of articles on the undocumented feature function and Matlab’s apparent move towards a class-based Handle-Graphics system called HG2.

Apparently I caused a bit of a stir…

This is normally a weekly blog. But I wanted to share some additional relevant information as well as some interesting tips I received in private communications. Please note that much of the following is speculation or guesswork and may be incorrect or even entirely wacky. Please read the following with more than the usual grain of skepticism…

UDD

A bit of historical background: Matlab’s existing Handle Graphics system is based on UDD (Unified Data Definition?) objects. Prior to Matlab Release 12 (a.k.a. 6.0) back in 2000, Matlab was written exclusively in C and HG and Simulink used differing approaches to objects in the MathWorks codebase. UDD was then added for R12 using C++ code with C wrappers for internal use by the MathWorks developers. UDD enabled a new unified approach for HG and Simulink (recall the major overhaul to the Matlab interface in that release, which also modified the GUI to be Java-based). While the HG handles remained numeric, behind the scenes they relied on the new UDD system, which remained undocumented.

Matlab users who wished to leverage UDD classes could (and still can) access it via some undocumented interface functions: handle, handle.listener, handle.event, classhandle, schema.prop, schema.class, schema.event (and other schema.* functions), findprop, findclass, findevent and several others. Some of these functions were mentioned in past articles on this blog, and others will perhaps be explained in future articles. You can find numerous mentions and usage examples of UDD in the Matlab codebase that is part of each Matlab installation.

In /toolbox/matlab/helptools/+helpUtils/@HelpProcess/getHelpText.m we can see a related feature (feature(‘SearchUUDClassesForHelp’, flag)) which can apparently be used to allow access to the h1 line and help text for UDD methods. Unfortunately, I have not found any relevant UDD candidates for this. I would be very happy to hear if you know of any objects/methods which have a UDD help section.

MCOS

Perhaps Matlab’s Class Object System (MCOS), first introduced in R14 (a.k.a. 7.0, released in 2004) grew out of the UDD beginnings, and perhaps it was developed separately. The fact is that it shared several terms and concepts (“schema”, properties meta-data, events) with UDD, although no direct interaction between UDD and MCOS exists, AFAIK.

As an interesting side-note, MCOS was introduced as an opt-in beta-testing feature in R14SP2 (7.0.4, released in 2005). This beta feature cannot be found in the official online version of the R14SP2 release notes, but can be found in the hardcover version pages 10-11:
New syntax and features for creating and working with classes in MATLAB. For R14SP2, these features are at a Beta level. If you are interested in being a Beta tester for these features, see “Beta Test the MATLAB Class System” on page 11.

Beta Test the MATLAB Class System. MATLAB 7.0.4 includes a Beta version of new syntax and features for working with classes in MATLAB, which simplify and expand object-oriented programming capabilities in MATLAB. Participation in this Beta program is open only to customers who are current
on their maintenance for MATLAB. Trial passcodes will not be made available for this Beta test. If you are interested in being a Beta tester for these features, register on the MathWorks Web site, at http://www.mathworks.com/products/beta/r14sp2/signup_newfeatures.html. (needless to say, this webpage was since removed…)

The MCOS syntax has changed between releases and was not very stable, until it was formally introduced in R2008a (a.k.a. 7.6, released in 2008). You can look at /toolbox/matlab/iofun/@memmapfile/memmapfile.m to see the MCOS evolution from R14 onward.

HG2

The new HG2 appears to be a merger of MCOS and UDD, using MCOS infrastructure for UDD classes and properties, finally throwing away the old numeric handles and C wrappers for the more powerful object-oriented approach.

For the transition period between HG and HG2, there seems to be a dedicated feature: feature(‘HGtoCOS’, handle) apparently converts a UDD (“HG”) handle into an HG2 (“COS”) handle. You can also use feature(‘HGtoCOS’, 0) to obtain an MCOS object of the desktop (=handle 0). Here is a sample result on a Matlab 2009 release:

>> hFig = figure
hFig =
     1
 
>> fmcos = feature('HGtoCOS', hFig)
fmcos =
 
  gbtmcos.figure handle
 
  Package: gbtmcos
 
  Properties:
                 Alphamap: [1x64 double]
             BeingDeleted: 'off'
               BusyAction: 'queue'
            ButtonDownFcn: []
                 Children: [0x1 double]
                 Clipping: 'on'
          CloseRequestFcn: 'closereq'
                    Color: [0.8000 0.8000 0.8000]
                 Colormap: [64x3 double]
                      ...  (all the regular figure properties)

Note that in that here, the new object package was called GBTMCOS – perhaps meaning a GBT version of the MCOS system. This corresponds to the feature(‘useGBT2′) that I reported in the features article. I have absolutely no idea what GBT stands for, whether it is a synonym for HG2 or not exactly, and what the differences are between GBT1.5 and GBT2. In any case, in R2010a, the same feature(‘HGtoCOS’, handle) code returns a ui.figure object: “GBTMCOS” was simply renamed “UI”.

I do not know how to convert an HG2 back to a UDD/HG handle. None of the following appears to work:

>> fmcos.getdoubleimpl
ans =
    -1
 
>> fmcos.double
ans =
on
 
>> double(fmcos)
ans =
    -1
 
>> handle(fmcos)
??? Error using ==> handle
Cannot convert to handle.

I would love to hear any additional information on these subjects, either anonymously or on record. You can use either a direct mail (see link at the top-right of this page) or the comments section.

Matlab’s HG2 mechanism

Friday, May 7th, 2010

A few days ago I posted a lengthy article about Matlab’s undocumented feature function. In it, I mentioned a feature called HG2, that I believe merits a dedicated article, due to its potential high impact on future Matlab releases.

HG2, which presumably stands for “Handle Graphics 2nd generation”, was already reported in the past as an undocumented hidden figure property (UseHG2). In normal Matlab usage, this boolean property is ‘off’:

>> get(gcf,'usehg2')
ans =
off

HG2 is mentioned in quite a few Matlab files:

  • clf.m, hgload.m, ishg2figure.m, datetick.m, linkdata.m, linkplotfunc.m, cameratoolbar, /bin/registry/handle_graphics.xml, /ja/xlate and many more
  • uimodemanager.m (and others) temporarily disables a ‘MATLAB:handle:hg2′ warning
  • defaulterrorcallback.m mentions ‘MATLAB:HG2:SceneNode’ and ‘MATLAB:HG2:Property’
  • getplotbrowserproptable.m mentions several special HG2 types (hg2.Line, hg2.Lineseries, hg2.Patch etc.)
  • There’s even a dedicated /toolbox/matlab/graphics/private/ishg2figure.m function that determines whether a figure contains any HG2 graphics based on the existence of ‘hg2peer’ appdata (getappdata(fig,’hg2peer’)).
  • /toolbox/matlab/plottools/@objutil/@eventmanager/schema.m (and a few others) has the following comment:
     % may contain either UDD or MCOS listeners during the hg2 migration.

Obviously, much effort was invested in HG2 functionality. The fact that HG2 has been under development at least since 2007 (when I first discovered and reported it) seems to indicate a major upheaval in Matlab’s Handle Graphics mechanism. This hunch is reinforced by cryptic comments made by MathWorks personnel over the past few years that they are indeed looking at the HG system, which in their opinion is nearing its limitations. Perhaps I’m mixing unrelated stuff here, but it does make sense in light of Matlab’s push of its OOP class system over the past few releases.

To preview this HG2 system, we need to turn it on. Unfortunately, when we set the figure’s UseHG2 to ‘on’ there doesn’t seem to be any visible effect. However, this changes after we use the corresponding ‘UseHG2′ feature using the feature function (this caused lots of nasty-looking errors in past releases but works ok in R2010a):

>> feature('usehg2',1)

The /ja/xlate file (which is used in conjunction with the undocumented xlate function to translates Matlab messages from English to Japanese) has another key to unlocking HG2: This file contains the following message: “feature(‘useGBT2′) is only available when Matlab is started with -hgVersion 2 option.“. So let’s do as the xlate message advises and start a new Matlab session with the undocumented “-hgVersion 2″ command-line option. Now feature(‘usehg2′) is true by default and we can test the HG2 system.

Matlab looks basically the same in HG2 as in HG1. All the regular graphic functions behave just as we would expect from the existing (HG1) implementation. There are two major differences though:

  • the figure toolbars/menubars are missing and cannot be shown, even when the relevant figure properties are set. Without a menubar and toobar, Matlab figures are extremely less useful than their HG1 counterparts. This problem does not occur in HG2-enabled figures in the regular Matlab session (i.e., without using the “-hgVersion 2″ command-line option)
  • all the HG handles are now Matlab class handles rather than numeric values (These class handles are similar to those returned today (in HG1) using the undocumented handle function). There’s an exception to this rule: in regular Matlab sessions (i.e., without using the “-hgVersion 2″ command-line option), after setting the ‘UseHG2′ feature on, the returned figure handle is numeric rather than a class handle (but if you now plot within this figure you get the class object handles). Here’s the output from the “-hgVersion 2″ Matlab session:
    >> hFig = figure
    hFig = 
    	ui.Figure
     
    >> hLine = plot(1:5)
    hLine = 
    	hg2.Lineseries
     
    >> get(hLine,'Parent')
    ans = 
    	hg2.Axes
     
    >> findprop(gcf,'Tag')
    ans = 
      meta.property handle
      Package: meta
     
      Properties:
                       Name: 'Tag'
                Description: 'Tag PropInfo'
        DetailedDescription: ''
                  GetAccess: 'public'
                  SetAccess: 'public'
                  Dependent: 1
                   Constant: 0
                   Abstract: 0
                  Transient: 0
                     Hidden: 0
              GetObservable: 1
              SetObservable: 1
                   AbortSet: 0
                  GetMethod: []
                  SetMethod: []
                 HasDefault: 0
              DefiningClass: [1x1 meta.class]
      Methods, Events, Superclasses
     
    >> methods(gcf)
     
    Methods for class ui.Figure:
     
    Figure                  disp                    get                     horzcat                 lt                      subsasgn                
    addlistener             double                  getParentImpl           ishghandlewithargs      ne                      vertcat                 
    addprop                 eq                      getSceneViewer          ishghandlewoargs        notify                  
    applydefaultproperties  findobj                 getdisp                 isvalid                 reset                   
    cat                     findprop                gt                      java                    set                     
    delete                  ge                      hgclose                 le                      setdisp                 
     
    Static methods:
     
    getDefaultObject        
     
    >> methods(gcf,'-full')
     
    Methods for class ui.Figure:
     
    ui.Figure lhs1 Figure(rhs0)
    event.listener L addlistener(handle sources, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, meta.property propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, string propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    event.proplistener L addlistener(handle sources, cell propertyname, char vector eventname, function_handle scalar callback)  % Inherited from hg2utils.HGHandle
    meta.property prop addprop(handle scalar object, string propname)  % Inherited from dynamicprops
    applydefaultproperties(HGHandle object, rhs1)  % Inherited from hg2utils.HGHandle
    HeterogeneousHandle lhs3 cat(double rhs0, rhs1, rhs2)  % Inherited from HeterogeneousHandle
    delete(handle obj)  % Inherited from handle
    disp(object)  % Inherited from hg2utils.HGHandle
    lhs1 double(handle object)  % Inherited from hg2utils.HGHandle
    logical TF eq(A, B)  % Inherited from hg2utils.HGHandle
    handle output findobj(handle object, varargin)  % Inherited from hg2utils.HGHandle
    meta.property prop findprop(handle scalar object, string propname)  % Inherited from handle
    logical TF ge(A, B)  % Inherited from handle
    varargout get(hgsetget object, rhs1)  % Inherited from hg2utils.HGHandle
    Static HeterogeneousHandle lhs0 getDefaultObject  % Inherited from hg2utils.HGHandle
    lhs2 getParentImpl(handle scalar object, rhs1)  % Inherited from hg2utils.HGObject
    lhs2 getSceneViewer(handle scalar object, rhs1)  % Inherited from ui.UISceneViewerParent
    getdisp(hgsetget rhs0)  % Inherited from hgsetget
    logical TF gt(A, B)  % Inherited from handle
    hgclose(handle scalar object)
    HeterogeneousHandle lhs2 horzcat(rhs0, rhs1)  % Inherited from HeterogeneousHandle
    lhs2 ishghandlewithargs(handle scalar object, rhs1)  % Inherited from hg2utils.HGObject
    lhs1 ishghandlewoargs(handle scalar object)  % Inherited from hg2utils.HGObject
    logical validity isvalid(handle obj)  % Inherited from handle
    j java(JavaVisible scalar h)  % Inherited from JavaVisible
    logical TF le(A, B)  % Inherited from handle
    logical TF lt(A, B)  % Inherited from handle
    logical TF ne(A, B)  % Inherited from hg2utils.HGHandle
    notify(handle sources, string eventname, event.EventData scalar eventdata)  % Inherited from handle
    notify(handle sources, string eventname)  % Inherited from handle
    reset(handle scalar object)  % Inherited from hg2utils.HGHandle
    varargout set(hgsetget object, rhs1)  % Inherited from hg2utils.HGHandle
    setdisp(hgsetget rhs0)  % Inherited from hgsetget
    varargout subsasgn(rhs0, rhs1, rhs2, rhs3)  % Inherited from HeterogeneousHandle
    HeterogeneousHandle lhs2 vertcat(rhs0, rhs1)  % Inherited from HeterogeneousHandle

The latest Matlab releases have shown how the Matlab handle class can be extended using user-created derived classes. It stands to reason that so do all the new HG2 objects. This would theoretically enable Matlab programmers to customize graphic objects appearance to suit their needs in a more intuitive manner than possible using HG1.

Many mysteries remain:

  • is it possible to mix HG1 and HG2 objects in the same figure?
  • can we switch between HG1 and HG2 in the same Matlab session (I got some crashes…)?
  • why is there a need for the separate feature options ‘UseHG2′, ‘UseGBT2′ and ‘HGUsingMatlabClasses’?
  • why is there a need for “-hgVersion 2″ Matlab sessions if we can simply use feature(‘UseHG2′)?
  • is it possible to restore the figure menubar and toolbar in “-hgVersion 2″ Matlab sessions?
  • is it indeed possible to extend HG2 objects using user-defined classes? and if so, can we modify the appearance/behavior beyond what is available in the existing list of HG2 properties?
  • beyond changing numeric handles into class handles, are there any actual benefits to the HG2 system over HG1?
  • what is the difference between HG2, GBT2 and GBT1.5 (which are mentioned together as separate entities in cameratoolbar.m)?

HG2 is still buggy, which explains why it is still not officially released. For example, the inspect(gca) function crashes Matlab, figure toolbars/menubars are missing, and some properties that are available in HG1 are missing in HG2. Also, we can add Java components to a Matlab figure using javacomponent as in HG1 (the returned container handles is a ui.HGJavaComponent class handle), but we get an error when we close the figure…

Still, with all this effort invested into HG2 I believe that it is only a matter of time before HG2 becomes officially released. This could happen perhaps even as soon as the upcoming R2010b release, but with the current state as seen above I suspect it will not happen before 2011. Also, my gut feeling is that Matlab will define any release that includes HG2 as a major release and we will finally have Matlab 8.0.

I would dearly love to hear any further information anyone discovers about HG2 and related issues. Please share your findings by email or in the comments section below.

Undocumented feature() function

Tuesday, May 4th, 2010

Taking a short break from Java-related stuff in Matlab, I wanted to share and expand a reply I posted a short while ago on the StackOverflow forum, in response to a reader’s request to explain Matlab’s feature function. This article uses pure Matlab and is absolutely unrelated to Java, so those of you who are Java-phobic can be at ease trying this at home…

feature is an entirely undocumented and unsupported Matlab function, and unlike most other undocumented Matlab functions it actually does often change without prior notice between Matlab releases, so be very careful when using this function in your code.

feature accepts two arguments: the name of the feature and an optional new value. This is similar to get/set functions: When only one argument is supplied, Matlab returns the current feature value (like get), otherwise the value is modified (like set). In some rare cases (feature(‘timing’)), a third input argument is sometimes expected.

Feature names are case-insensitive. The built-in function system_dependent appears to be a synonym for feature (not exactly – some system_dependent features are unavailable in feature…). We can find several references to system_dependent online, mostly for old Matlab releases. There’s even an entry in the official Matlab FAQ (which has no usful info), and I’ve seen online references going all the way back to 1993…

One of the very rare official comments about this function says:

The system_dependent function is an unpublished function that we use for a variety of crufty things. It will most certainly change from time to time and possibly even go away completely. The system_dependent function performs different functionality on each of the platforms supported by MATLAB.

Several feature options have been reported over the years, mainly on the CSSM forum and also seen in the installed Matlab code base, as listed below (the code references are from the latest Matlab release – 7.10, aka R2010a). Note that many of these features may not work on your platform:

  • feature(‘usehg2′,flag) – this apparently relates to a new Handle-Graphics implementation that is under development for the past few years (I think I saw references to HG2 as far back as 2007, possibly earlier). HG2 is automatically active when Matlab is started with -hgVersion 2 option. It appears that the numeric HG handles have been replaced with their object-oriented (Matlab class system) handle counterparts in HG2 (today these class-system handles can be gotten using the handle function). Some handle properties are not implemented in HG2, and some GUI elements appear missing (figure menubar and toolbar, for example), but the basic plots look similar to our familiar HG. If anyone has any further information about HG2 I would love to hear it…
  • feature(‘useGBT2′) – “feature(‘useGBT2′) is only available when Matlab is started with -hgVersion 2 option.” – In /ja/xlate:15419; also see in: clf.m
  • feature(‘HGUsingMatlabClasses’) – see hgrc.m, subplot.m, title.m, xlabel.m, ylabel.m, zlabel.m, mesh.m, surf.m, colorbar.m etc. etc.
  • feature(‘JavaFigures’) – see propedit.m; disabled since R2007a when native (non-Java) Matlab figures were disabled.
  • feature(‘UseJava’) – see usejava.m
  • feature(‘ClearJava’,1) – see javaclasspath.m
  • feature(‘SetPrecision’) – accepts values 24, 53 or 64
  • feature(‘SetRound’) – accepts values 0, 0.5, Inf or -Inf
  • feature(‘NewPrintAPI’) – see \toolbox\matlab\graphics\private\setup.m
  • feature(‘accel’,’on/off’) – see here and here.
  • feature(‘GetOS’) – see ver.m
  • feature(‘GetWinSys’) – see ver.m
  • feature(‘GetPid’) – returns the Matlab process ID (well, actually the PID of its JVM but that’s the same PID as Matlab’s). Also see the similar java.lang.management.ManagementFactory.getRuntimeMXBean.getName.char. This latter function returns the PID mangled with the computer name (for example: ‘1234@My-desktop’).
  • feature(‘NumCores’) – returns the number of CPU cores seen by Matlab
  • feature(‘MemStats’), feature(‘DumpMem’), feature(‘ProcessMem’) – these are memory reports that are even recommended by official MathWorks tech notes (1,2), newsletter and technical solutions (1,2). Numerous references to these features can be found online.
  • feature(‘CheckMallocMemoryUsage’) – see this official technical paper
  • feature(‘CheckMallocHeapWalk’) – see here
  • feature(‘ShowCommandWindow’) – see here = commandwindow
  • feature(‘LogDir’) – see here = tempdir
  • feature(‘HotLinks’) – used to disable hyperlinks in the Command Window. This is used by Word notebooks (see mwMatlabEval macro in the Microsoft Word template file %matlabroot%\notebook\pc\M-BOOK.DOT). Also see: info.m, mlint.m, doclink.m, guidefunc.m, displayEndOfDemoMessage.m
  • feature(‘UseOldFileDialogs’) – see toolbox\matlab\uitools\private\usejavadialog.m
  • feature(‘timing’) – For example: cpucount = feature(‘timing’,'cpucount’); There are several other 2nd arg options, as explained by the following informative error message:
    >> feature timing
    ??? Error using ==> feature
    Choose second argument from:
      'resolution_tictoc'  - Resolution of Tic/Toc clock in sec (double)
      'overhead_tictoc'    - Overhead of Tic/Toc command in sec (double)
      'cpucount'           - Current CPU cycles used (uint64) [Using utCPUcount]
      'getcpuspeed_tictoc' - Stored CPU cycles/sec (double) [Used by tic/toc]
      'cpuspeed'           - Current CPU cycles/sec (double) [Simple MathWorks]
      'winperfcount'       - Current CPU cycles used (uint64) [Windows call]
      'winperfspeed'       - Current CPU cycles/sec (double) [Windows call]
      'wintime'            - Current Windows time (uint32) [Windows call]
                             units: msec since startup [Wraps]
      'wintimeofday'       - Current time of day converted to file time (unit64)[Windows call]
                             units: 100 nsec since 01-Jan-1601 (UTC)
      'clocks_per_sec'     - clock() speed in cycles/sec [CLOCKS_PER_SEC]
     
    Choose second and third arguments from:
      'cpuspeed', double num             - Current CPU cycles/sec (double) [MathWorks - num iterations]
      'setcpuspeed_tictoc', double speed - Set the CPU cycles/sec [Used by tic/toc]
       uint64 arg2, uint64 arg3          - uint64 difference = arg2 - arg3 (uint64)
  • feature(‘memtic’), feature(‘memtoc’) – possibly related to feature(‘timing’); mentioned in /ja/xlate:5780-5781
  • feature(‘locale’) – see mlint.m, mtree.m, helpmenufcn.m
  • feature(‘DefaultCharacterSet’) – see here
  • feature(‘COM_SafeArraySingleDim’) – explained here and here.
  • feature(‘COM_ActxProgidCheck’,flag) – see /help/techdoc/helpsearch/_533.cfs
  • feature(‘FigureTools’) – see domymenu.m
  • feature(‘TimeSeriesTools’,1) – see /help/techdoc/helpsearch/_533.cfs
  • feature(‘launch_activation’, ‘forcecheck’) – see StudentActivationStatus.m
  • feature(‘EightyColumns’,flag) – see matlabrc.m
  • feature(‘GetSharedLibExt’) – see loadlibrary.m and /toolbox/matlab/audiovideo/private/privateMMReaderPluginSearch.m
  • feature(‘GetDefaultPrinter’) – see printdlg.m, printopt.m
  • feature(‘GetPrinterInfo’) – see pagesetupdlg.m
  • feature(‘GetPrinterColor’) – see /toolbox/matlab/graphics/private/defaultprtcolor.m
  • feature(‘GetSpecifiedPrinterPort’,printerName) – see /toolbox/matlab/graphics/private/send.m
  • feature(‘ShowFigureWindows’) – see printjob.m, printtables.m, /toolbox/matlab/graphics/private/warnfiguredialog.m
  • feature(‘SearchUDDClassesForHelp’) – see /toolbox/matlab/helptools/+helpUtils/@HelpProcess/getHelpText.m
  • feature(‘AutomationServer’) – see notebook.m, enableservice.m = enableservice(‘AutomationServer’, true)
  • feature(‘EnableDDE’,flag) – see enableservice.m = enableservice(‘DDEServer’, true)
  • feature(‘GetUserWorkFolder’) – see userpath.m, savepath.m
  • feature(‘DirsAddedFreeze’), feature(‘DirsAddedUnfreeze’) – see addpath.m
  • feature(‘ToolboxFreeze’), feature(‘ToolboxUnfreeze’) – explained here
  • feature(‘DirChangeHandleWarn’) – accepts ‘always’, ‘once’, ‘never’ or ’status’. Mentioned in an official Matlab technical solution and also in changeNotificationAdvanced.m.
  • feature(‘DirReloadMsg’) – accepts ‘on’, ‘off’ or ’status’. See changeNotificationAdvanced.m and here.
  • feature(‘RemoteCWDPolicy’) – accepts ‘Reload’, ‘TimecheckDir’, ‘TimecheckDirFile’, ‘TimecheckFile, ‘None’ or ’status’. See changeNotification.m and here.
  • feature(‘RemotePathPolicy’) – accepts ‘Reload’, ‘TimecheckDir’, ‘TimecheckDirFile’, ‘TimecheckFile, ‘None’ or ’status’. See changeNotification.m, here and this official technical solution.
  • feature(‘GetPref’,prefName) – returns the system preference value for the requested preference name in the global prefs file ([prefdir,'/matlab.prf']) that is explained here.
  • feature(‘IsDebugMode’) – mentioned here and several other online places
  • feature(‘ForceFramesOnBottom’) – mentioned here

Oddly, some features are only accessible via system_dependent, and not via feature:

  • system_dependent(‘builtinEditor’,flag) – see matlabrc.m
  • system_dependent(‘miedit’,filename) – referenced here, here and in edit.m. See matlabrc.m.
  • system_dependent(4,…) – See cedit.m, arrayviewfunc.m, dbmex.m, mexdebug.m. In addition to 4, I have seen references to features #2, 7-14, 44, 45, 1000-1003.
  • system_dependent(12,flag) – See %matlabroot%\notebook\pc\M-BOOK.DOT macro InitFromSavedSettings.

The following are OpenGL-related features that are used in the opengl.m function:

  • feature(‘OpenglMode’)
  • feature(‘OpenGLLoadStatus’)
  • feature(‘UseMesaSoftwareOpenGL’,1)- unix only
  • feature(‘UseGenericOpengl’,1)
  • feature(‘GetOpenglInfo’) = opengl(‘info’)
  • feature(‘GetOpenglData’) = opengl(‘data’)
  • feature(‘OpenGLVerbose’,1)

If you lasted this far you deserve a special treat: Last but not least we have feature(‘dwim’). Unfortunately, this feature sometimes fails on some systems…

Have you discovered or used any interesting feature? If so, please do share them in the comments section below

Inactive Control Tooltips & Event Chaining

Wednesday, February 24th, 2010

Once again, I welcome guest blogger Matt Whitaker, who continues his series of articles.

In my last post I explored some tips on tooltips. One of these tips involved displaying tooltips on disabled uicontrols. I explained that displaying tooltips on inactive controls is problematic since Matlab appears to intercept mouse events to these inactive controls, so even setting the tooltip on the underlying Java object will not work: The java object appears not to receive the mouse-hover event and therefore does not “know” that it’s time to display the tooltip.

When Yair and I deliberated this issue, he pointed me to his comment on a previous article showing an undocumented Java technique (Java also has some…) for forcing a tooltip to appear using the ActionMap of the uicontrol’s underlying Java object to get at a postTip action. We discussed using a WindowButtonMotionFcn callback to see if the mouse was above the inactive control, then triggering the forced tooltip display. Yair then went on to remind me and I quote: “you’ll need to chain existing WindowButtonMotionFcn callbacks and take into account ModeManagers that override them.”

Frankly, having written code previously that handles callback chaining, I would rather poke myself in the eye with a fork!

The Image Processing Toolbox has the nice pair of iptaddcallback and iptremovecallback functions that largely handle these issues. But for general Matlab, there seemed to be no alternative until I remembered that events trigger callbacks. I decided to use a listener for the WindowButtonMotion event to detect the mouse motion. Event listeners were briefly explained two weeks ago and deserve a dedicated future article. The advantage of using an event listener is that we don’t disturb any existing WindowButtonMotionFcn callback. We still need to be somewhat careful that our listeners don’t do conflicting things, but it’s a lot easier than trying to manage everything through the single WindowButtonMotionFcn.

A demonstration of this appears below with some comments following (note that this code uses the FindJObj utility):

function inactiveBtnToolTip
  %Illustrates how to make a tooltip appear on an inactive control
  h = figure('WindowButtonMotionFcn',@windowMotion,'Pos',[400,400,200,200]);
  col = get(h,'color');
  lbl = uicontrol('Style','text', 'Pos',[10,160,120,20], ...
                  'Background',col, 'HorizontalAlignment','left');
  btn = uicontrol('Parent',h, 'String','Button', ...
                  'Enable','inactive', 'Pos',[10,40,60,20]);
  uicontrol('Style','check', 'Parent',h, 'String','Enable button tooltip', ...
            'Callback',@chkTooltipEnable, 'Value',1, ...
            'Pos',[10,80,180,20], 'Background',col);
  drawnow;
 
  %create the tooltip and postTip action
  jBtn = findjobj(btn);
  import java.awt.event.ActionEvent;
  javaMethodEDT('setToolTipText',jBtn,'This button is inactive');
  actionMap = javaMethodEDT('getActionMap',jBtn);
  action = javaMethodEDT('get',actionMap,'postTip');
  actionEvent = ActionEvent(jBtn, ActionEvent.ACTION_PERFORMED, 'postTip');
 
  %get the extents plus 2 pixels of the control to compare to the mouse position
  btnPos = getpixelposition(btn)+[-2,-2,4,4]; %give a little band around the control
  left = btnPos(1);
  right = sum(btnPos([1,3]));
  btm = btnPos(2);
  top =  sum(btnPos([2,4]));
 
  % add a listener on mouse movement events
  tm = javax.swing.ToolTipManager.sharedInstance; %tooltip manager
  pointListener = handle.listener(h,'WindowButtonMotionEvent',@figMouseMove);
 
  %inControl is a flag to prevent multiple triggers of the postTip action
  %while mouse remains in the button
  inControl = false;
 
  function figMouseMove(src,evtData) %#ok
    %get the current point
    cPoint = evtData.CurrentPoint;
 
    if cPoint(1) >= left && cPoint(1) <= right &&...
       cPoint(2) >= btm  && cPoint(2) <= top
 
      if ~inControl %we just entered
        inControl = true;
        action.actionPerformed(actionEvent); %show the tooltip
      end %if
    else
      if inControl %we just existed
        inControl = false;
        %toggle to make it disappear when leaving button
        javaMethodEDT('setEnabled',tm,false);
        javaMethodEDT('setEnabled',tm,true);
      end %if
    end %if
  end %gpMouseMove
 
  function windowMotion(varargin)
    %illustrate that we can still do a regular window button motion callback
    set(lbl,'String',sprintf('Mouse position: %d, %d',get(h,'CurrentPoint')));
    drawnow;
  end %windowMotion
 
  function chkTooltipEnable(src,varargin)
    if get(src,'Value')
      set(pointListener,'Enable','on');
    else
      set(pointListener,'Enable','off');
    end %if
  end %chkTooltipEnable
end %inactiveBtnToolTip

Tooltip on an inactive button

Tooltip on an inactive button

Comments on the code:

  1. The code illustrates that we can successfully add an additional listener to listen for mouse motion events while still carrying out the original WindowButtonMotionFcn callback. This makes chaining callbacks much easier.
  2. The handle.listener object has an Enable property that we can use to temporarily turn the listener on and off. This can be seen in the chkTooltipEnable() callback for the check box in the code above. If we wanted to permanently remove the listener we would simply use delete(pointListener). Note that addlistener adds a hidden property to the object being listened to, so that the listener is tied to the object’s lifecycle. If you create a listener directly using handle.listener you are responsible for it’s disposition. Unfortunately, addlistener fails for HG handles on pre-R2009 Matlab releases, so we use handle.listener directly.
  3. The code illustrates a good practice when tracking rapidly firing events like mouse movement of handling reentry into the callback while it is still processing a previous callback. Here we use a flag called inControl to prevent the postTip action being continuously fired while the mouse remains in the control.
  4. I was unable to determine if there is any corresponding action for the postTip to dismiss tips so I resorted to using the ToolTipManager to toggle its own Enable property to cleanly hide the tooltip as the mouse leaves the control.

Each Matlab callback has an associated event with it. Some of the ones that might be immediately useful at the figure-level are WindowButtonDown, WindowButtonUp, WindowKeyPress, and WindowKeyRelease. They can all be accessed through handle.listener or addlistener as in the code above.

Unfortunately, events do not always have names that directly correspond to the callback names. In order to see the list of available events for a particular Matlab object, use the following code, which relies on another undocumented function – classhandle. Here we list the events for gcf:

>> get(get(classhandle(handle(gcf)),'Events'),'Name')
ans = 
    'SerializeEvent'
    'FigureUpdateEvent'
    'ResizeEvent'
    'WindowKeyReleaseEvent'
    'WindowKeyPressEvent'
    'WindowButtonUpEvent'
    'WindowButtonDownEvent'
    'WindowButtonMotionEvent'
    'WindowPostChangeEvent'
    'WindowPreChangeEvent'

Note that I have made extensive use of the javaMethodEDT function to execute Java methods that affect swing components on Swing’s Event Dispatch Thread. I plan to write about this and related functions in my next article.

uiundo – Matlab’s undocumented undo/redo manager

Thursday, October 29th, 2009

Whenever we have a Matlab GUI containing user-modifiable controls (edit boxes, sliders, toggle buttons etc.), we may wish to include an undo/redo feature. This would normally be a painful programming task. Luckily, there is an undocumented built-in Matlab support for this functionality via the uiundo function. Note that uiundo and its functionality is not Java-based but rather uses Matlab’s classes and the similarly-undocumented schema-based object-oriented approach.

A couple of months ago, I explained how to customize the figure toolbar. In that article, I used the undocumented uiundo function as a target for the toolbar customization and promised to explain its functionality later. I would now like to explain uiundo and its usage.

The uiundo function is basically an accessor for Matlab’s built-in undo/redo manager object. It is located in the uitools folder (%MATLABROOT%\toolbox\matlab\uitools) and its @uiundo sub-folder. To use uiundo, simply define within each uicontrol’s callback function (where we normally place our application GUI logic) the name of the undo/redo action, what should be done to undo the action, and what should be done if the user wished to redo the action after undoing it. uiundo then takes care of adding this data to the figure’s undo/redo options under Edit in the main figure menu.

For example, let’s build a simple GUI consisting of a slider that controls the value of an edit box:

hEditbox = uicontrol('style','edit', 'position',[20,60,40,40]); 
set(hEditbox, 'Enable','off', 'string','0');
hSlider = uicontrol('style','slider','userdata',hEditbox);
callbackStr = 'set(get(gcbo,''userdata''),''string'',num2str(get(gcbo,''value'')))';
set(hSlider,'Callback',callbackStr);

Simple GUI with slider update of a numeric value

Simple GUI with slider update of a numeric value

Now, let’s attach undo/redo actions to the slider’s callback. First, place the following in test_uiundo.m:

% Main callback function for slider updates
function test_uiundo(varargin)
 
  % Update the edit box with the new value
  hEditbox = get(gcbo,'userdata');
  newVal = get(gcbo,'value');
  set(hEditbox,'string',num2str(newVal));
 
  % Retrieve and update the stored previous value
  oldVal = getappdata(gcbo,'oldValue');
  if isempty(oldVal),  oldVal=0;  end
  setappdata(gcbo,'oldValue',newVal);
 
  % Prepare an undo/redo action
  cmd.Name = sprintf('slider update (%g to %g)',oldVal,newVal);
 
  % Note: the following is not enough since it only
  %       updates the slider and not the editbox...
  %cmd.Function        = @set;                  % Redo action
  %cmd.Varargin        = {gcbo,'value',newVal};
  %cmd.InverseFunction = @set;                  % Undo action
  %cmd.InverseVarargin = {gcbo,'value',oldVal};
 
  % This takes care of the update problem...
  cmd.Function        = @internal_update;       % Redo action
  cmd.Varargin        = {gcbo,newVal,hEditbox};
  cmd.InverseFunction = @internal_update;       % Undo action
  cmd.InverseVarargin = {gcbo,oldVal,hEditbox};
 
  % Register the undo/redo action with the figure
  uiundo(gcbf,'function',cmd);
end
 
% Internal update function to update slider & editbox
function internal_update(hSlider,newValue,hEditbox)
  set(hSlider,'value',newValue);
  set(hEditbox,'string',num2str(newValue));
end

And now let’s point the slider’s callback to our new function:

>> set(hSlider,'Callback',@test_uiundo);

Undo/redo functionality integrated in the figure

Undo/redo functionality integrated in the figure

We can also invoke the current Undo and Redo actions programmatically, by calling uiundo with the ‘execUndo’ and ‘execRedo’ arguments:

uiundo(hFig,'execUndo');
uiundo(hFig,'execRedo');

When invoking the current Undo and Redo actions programmatically, we can ensure that this action would be invoked only if it is a specific action that is intended:

uiundo(hFig,'execUndo','Save data');  % should equal cmd.Name

We can use this approach to attach programmatic undo/redo actions to new toolbar or GUI buttons. The code for this was given in the above-mentioned article. Here is the end-result:


Undo/redo functionality integrated in the figure toolbar

Undo/redo functionality integrated in the figure toolbar

Undo/redo functionality integrated in the figure toolbar


In my next post, due next week, I will explore advanced customizations of this functionality.

ismembc – undocumented helper function

Wednesday, April 8th, 2009

Matlab has a variety of internal helper functions which are used by the main (documented) functions. Some of these helper functions are undocumented and unsupported, but may be helpful in their own right – not just as internal support functions.

In this post I want to present Matlab’s built-in ismembc helper function. This function is used within the stock Matlab ismember and setxor functions for fast processing of the core ismember functionality in “regular” cases: arrays of sorted, non-sparse, non-NaN data in which we’re only interested in the logical membership information (not the index locations of the found members). In such cases, ismembc can be used directly, saving ismember’s sanity-checks overhead. ismembc uses the same interface (two inputs, single logical output) as ismember and can be a drop-in replacement for ismember for these “regular” cases.

The performance improvement may be significant: In a recent post, MathWorks’ Loren Shure presented different approaches for fast data retrieval, highlighting the ismember function. Let’s compare:

>> % Initial setup
>> n=2e6; a=ceil(n*rand(n,1)); b=ceil(n*rand(n,1));

>> % Run ismember several times, to rule-out JIT compilation overheads
>> tic;ismember(a,b);toc;
Elapsed time is 2.882907 seconds.
>> tic;ismember(a,b);toc;
Elapsed time is 2.818318 seconds.
>> tic;ismember(a,b);toc;
Elapsed time is 3.005967 seconds.

>> % Now use ismembc:
>> tic;ismembc(a,b);toc;
Elapsed time is 0.162108 seconds.
>> tic;ismembc(a,b);toc;
Elapsed time is 0.204108 seconds.
>> tic;ismembc(a,b);toc;
Elapsed time is 0.156963 seconds.

ismembc is actually a MEX file (%matlabroot%\toolbox\matlab\ops\ismembc.mexw32). Its source code is included in the same folder (%matlabroot%\toolbox\matlab\ops\ismembc.cpp) and is actually very readable. From the source code comments we learn that the comment in setxor about ismembc usage is misleading: that comment stated that the inputs must be real, but the source-code indicates that imaginary numbers are also accepted and that only the real-part should be sorted.

ismembc should not be used carelessly: as noted, its inputs must be sorted non-sparse non-NaN values. In the general case we should either ensure this programmatically (as done in setxor) or use ismember, which handles this for us.

The nice thing about ismembc is that its source code (ismembc.cpp) is included, so even if future Matlab releases stop using this function, you can always mex-compile the source code and use it.

Readers interested in ismembc might also be interested in its sibling help function, ismembc2, which is also a mex file located (with source-code) in the same folder as ismembc. Whereas ismembc returns an array of logical values, ismembc2 returns the index locations of the found members.