MATLAB Answers

0

Which standard MATLAB functions do you shadow with your own version, and why?

Asked by Oliver Woodford on 10 May 2017
Latest activity Answered by David Niles on 10 May 2018
When you have two functions on your MATLAB path with the same name, the function in the directory higher up the path gets called, and therefore shadows the function lower in the path. Generally it is not advisable to shadow standard MATLAB functions, but sometimes you might deliberately choose to do this. Which standard MATLAB functions do you shadow by default, and why?

  1 Comment

A couple of answers have focussed on a part of my question description asking "Do you...?", rather than my intended question, given in the title. To clarify, I'm interested in hearing from people who have shadowed MATLAB functions, and why. I've edited the question to reflect this.

Sign in to comment.

Tags

8 Answers

Answer by Matt J
on 10 May 2017

Do you shadow any standard MATLAB functions by default, and if so, why?
I do not (except inadvertently). It seems like a risky thing to do. I don't think you can fully anticipate how your over-ride will influence other stock MATLAB mfiles that might call it.

  1 Comment

In the case of a pure extension of functionality (i.e. behaviour for previously supported inputs remains identical) I'd hope it wouldn't influence other stock mfiles. However, some functions might rely on error catching of unsupported arguments.

Sign in to comment.


Answer by James Tursa
on 11 May 2017

I have intentionally shadowed fopen, fread, fwrite, fclose before. Options that would read/write VAX binary format numbers were inexplicably removed from MATLAB (what a needless irritation that was!), rendering working code that I had unusable. Rather than rewriting all of the working original code itself (which still worked in older versions of MATLAB), I wrote shadowing functions that picked off the VAX options and wrapped conversion code around it ... passing through everything else to the MATLAB versions. I put these shadowing functions in a directory that was not on the MATLAB path, so they only get used when I cd to that specific directory and run from there (making the shadowing deliberate and intentional for that run only).
I also often do what IA does and write replacement functions when the supplied functions don't do exactly what I want. E.g., using mex routines to allocate variables quickly (uninit), or typecast variables without making a deep copy (typecastx).

  0 Comments

Sign in to comment.


Answer by Image Analyst
on 10 May 2017

I don't. I make new functions. For example I hate how msgbox() displays a message box and then goes barreling along with your code without waiting for the user to click OK (before they added the 'modal' option), so I made my own but I call it msgboxw() instead of shadowing the built-in msgbox(). I never call the built in msgbox() anymore.

  2 Comments

I usually make new functions too. This is possible when I'm writing the code that will call this function. Shadowing is necessary when the calling code already exists, and it would be too complicated or risky to change it to use the new function.
I just had to do it again. My users needed to pick out small specks on a mostly black background. The built-in ginput() only allows black crosshairs making it very very difficult to see where the crosshairs were. Basically you could only see them if the center of the crosshairs was over a small speck. I needed to specify the color of the crosshairs, for example white, so I could see them easier. A message from tech support said that they do not have that capability yet but would add it to the requested enhancement list. So I copied ginput() to ginputWhite() and changed the BackgroundColor in line 282 from black:
crossHair(k) = uicontrol(fig, 'Style', 'text', 'Visible', 'off', 'Units', 'pixels', 'BackgroundColor', [0 0 0], 'HandleVisibility', 'off', 'HitTest', 'off'); %#ok<AGROW>
to white:
crossHair(k) = uicontrol(fig, 'Style', 'text', 'Visible', 'off', 'Units', 'pixels', 'BackgroundColor', [1 1 1], 'HandleVisibility', 'off', 'HitTest', 'off'); %#ok<AGROW>
Now I call ginputWhite() and it works fine. Such an easy thing to fix I wonder why they don't allow 'Color' as an input to ginput() especially since it's an option to many, many other functions. Especially after 30+ years of development!

Sign in to comment.


Answer by Jan
on 11 May 2017

I shadow different functions for different Matlab versions to either increase the speed or the compatibility in forward or backward direction, or the power. Examples:
  • edit: Opens a Windows Explorer window, when called with a folder
  • filesep, pathsep, ispc: Do not need branches for Windows or Linux, when I ran a Windows computer
  • groot: Replies 0 for HG1 Matlab versions, forward compatibility.
  • ind2rgb: The original implementation is too slow.
  • iscellstr: C-Mex
  • ismatrix: Forward compatibility
  • rmfield: C-Mex
  • typecast: Was slow in older versions, input types limited without need.
  • ancestor: Forward compatibility
  • isequaln: Forward compatibility
  • strread, dataread: Backward compatibility.
Under the historical Matlab 6.5 I've shadowed several arithmetic operations for single, because they either did not work or replied wrong values. I had a mystic function called ME_ also to emulate catch ME:
try
...
catch ME_, ME = ME_;
disp(ME.message);
end
ME_ stored the lasterror struct and added a .cause, stored it persistently and replied it when called with an output. With modern Matlab versions, this function was not included in the path, such that the new functionality way available in both versions.
I store these files in a different folders belonging to each Matlab version I have installed. Then my initialization function includes the needed folde dynamically on top of the path.
I tried to check the protection level of Matt Fig's https://www.mathworks.com/matlabcentral/fileexchange/17288-pass-protect and shadowed strcmp to cheat the P-coded function. Unfortunately I had a typo in the code and was not able to start the editor in consequence. Even shutting down was hard, because I call strcmp in finish.m. This told me to be very careful with shadowing.

  3 Comments

I like the idea of shadowing stock functions with faster versions. This can speed up other MATLAB functions which already use that function.
Jan:
edit: have you considered using winopen instead when you want to open a folder in Windows Explorer?
iscellstr, rmfield: Can you say a little more about what "C-Mex" means?
Jan (about ind2rgb) and Oliver:
If there are specific portions of the syntax of a function that you feel could be and/or should be faster, please let Technical Support know about the specific functions in which you're interested. That can help us prioritize performance-related refactoring work.
@Steven: I've expaned edit, because it runs when I mark a string in the command window and it is convenient to open a folder from there.
iscellstr, rmfield: I've written C-Mex functions to solve these job. iscellstr became a built-in function between 2009a and 2015b. See FEX: fRMField.
Of course I send enhancement requests to TMW.

Sign in to comment.


Answer by Walter Roberson
on 11 May 2017

On the rare occasion that I shadow a Mathworks function, I am hacking a third-party toolbox written for an older MATLAB version, and need to adapt some call that was valid in old MATLAB but not in current MATLAB. Or perhaps a call that was formerly made to a third party routine with the same name as a MATLAB function.
My preference in such cases is generally to change the original source, but if the same issue shows up in a whole bunch of places, sometimes it is easiest to provide a shadow function.
To be honest, when I do provide a shadow function, it is not uncommon that the reason is I have noticed that the person I am responding to has difficulty following change instructions, so I am looking for minimal source code changes, to save on frustration in explaining more proper fixes to the person.
The other notable case of using a shadow function is that I am assisting users who are using third-party libsvm, which uses some of the same function names as the Statistics Toolbox interface to SVM does, but with different arguments. Though in that case I am seldom writing the shadow function: just re-arranging my path so that the libsvm version gets called.

  0 Comments

Sign in to comment.


Answer by Oliver Woodford on 10 May 2017

I shadow dot and cross with my own versions, which extend the standard functionality to allow for inputs which have compatible sizes.

  2 Comments

The supplied DOT and CROSS are also quite slow for the straightforward vector cases and can easily be beaten for speed by hand-written code. E.g., 64-bit R2016b:
>> a = rand(10000000,1);
>> b = rand(10000000,1);
>> tic;x=dot(a,b);toc
Elapsed time is 0.046664 seconds.
>> tic;a.'*b;toc
Elapsed time is 0.008074 seconds.
For large vectors, I have noticed that DOT isn't the most accurate either.
I like the idea of shadowing stock functions with faster versions. This can speed up other MATLAB functions which already use that function.

Sign in to comment.


Answer by Oliver Woodford on 10 May 2017

I shadow bsxfun with my own version, which calls the builtin function bsxfun for all inputs except symbolic ones, for which I use repmat to replicate the behaviour of bsxfun. The reason for doing this is that the standard bsxfun does not support symbolic inputs (at least it didn't when I last checked!).

  0 Comments

Sign in to comment.


Answer by David Niles on 10 May 2018

I can think of two off the top of my head.
  1. log10, so that is compatible with integer data types (e.g., images). I was sick of typing y = log10(double(x)) for nearly every use of the function.
  2. graythresh, because it uses an 8-bit histogram only, and because it returns a value between 0 and 1 regardless of the scale of the input image. I wanted more control for the first issue because my data have higher bit-depth, and the second issue is just silly. I can't imagine any situation in which I would want a threshold to be on a different scale from the data that I want to use it on.

  0 Comments

Sign in to comment.