What functions can benefit from simple patching?
5 views (last 30 days)
This question made me think about patching MATLAB functions. I have a number of MATLAB functions that I have essentially renamed and made relatively small changes/patches to. In a couple of cases I have had to modify the existing MATLAB functions making my working installation non standard.
I was curious what MATLAB functions people tend to patch. I am interested in relatively simple patches that improve/extend functionality was maintaining the original functionality. Please do not post entire blocks of copyrighted code.
Jan on 4 Jun 2013
Edited: Jan on 4 Jun 2013
Some examples I have patched - some instances are more trivial than simple, but some are completely rewritten, which might be not matching your question exactly:
function f = filesep
f = '\'; % Does anyone process a Matlab folder from different OS?!
The same for ISPC, PATHSEP etc.
2. IND2RGB, see http://www.mathworks.co.jp/matlabcentral/fileexchange/26322-mat2im also. Here a simplified version for the forum, while I strongly suggest not to remove the consistency and type checks:
function [r, g, b] = ind2rgb(a, cm)
if ~isa(a, 'double')
a = double(a) + 1; % Switch to one based indexing
siza = size(a);
r = reshape(cm(a, 1), siza);
g = reshape(cm(a, 2), siza);
b = reshape(cm(a, 3), siza);
3. ISCELLSTR can be written as fast MEX.
4. NOW: I do not see a reason to call the M-function datenum, when the input is clock and the underlying MEX ist faster:
t = datenummx(clock);
5. RMFIELD can be simplified and cleaned, but I use the faster rmfield.mex.
6. The subfunction getJavaFrame(f) in JAVACOMPONENT wastes too much time with suppressing the warning, although a workaround is cheap:
function javaFrame = getJavaFrame(f)
javaFrame = get(handle(f), 'JavaFrame');
7. I've even patched BLANKS, because this version saves some microseconds:
function b = blanks(n)
b(1:n) = ' ';
8. TYPECAST is an M-file, which calls a MEX function. At first the error checks are much faster inside the MEX, at second CHARs, LOGICALS and arrays could be accepted also, and at third a shared data copy is more efficient than a deep copy. See: FEX: typecastx. The shared data copies let the function DataHash run 100 times faster for large arrays.
9. I'm using faster M-versions of FILEPARTS, FULLFILE and @cell/STRCAT. For the latter this C-Mex is more efficient: FEX: CStrCatStr.
10. I've created C-Mex functions FileExist and DirExist instead of EXIST(x, 'file') and EXIST(x, 'dir'). The speed was 1 argument, but the problems with handling files without paths are more important.
11. The creation of the filter parameters in BUTTER takes a lot of time. The implementation FEX: ButterParam stores the parameters persistently or even in a file, such that repeated calculations can be omitted.
12. FILTER and FILTFILT could be accelerated substantially: FEX: FilterM. Since R2011b FILTFILT uses equivalent changes, but my version of FILTER allows to filter in backward direction without the need to create a temporary copy of the data.
13. INTERP1 is very slow for a linear interpolation and it got even slower since 2011b. Some M-code can be faster already, but I use a C-Mex for this.
14. GRADIENT: FEX: DGradient.
15. MOVEFILE is slower than the equivalent Mex function FEX: FileRename.
16. There seems to be a problem with the pre-allocation in CELL2MAT. For the case that all cell elements can be concatenated to a vector, this is faster FEX: Cell2Vec.
17. NCHOOSEK is fine for educational purposes. Matt Fig's M-function Combinator and the C-Mex VChooseK are much faster.
18. For small cell strings (less than 1000 strings), the internal sorting of ISMEMBER, SETDIFF, INTERSECT and UNION needs a lot of time. A simple loop and STRCMP can be 5 times faster. And, how surprising, I tried it with a C-Mex also http://www.mathworks.com/matlabcentral/fileexchange/24380-cstrainbp to gain a speedup of upto a factor 30. But for large cell strings, sorting and a binary search is recommeded.
19. Matlab's date functions are very smart and catch problems like datenum('32-Jan-2007 19:62:63') automatically. When the format is known to be well formatted, e.g. in the output of DIR, a conversion can be tremendously faster, see DateStr2Num and DateConvert.
20. Accordingto the documentation figure(FigHandle) moves the focus to the specified figure. Unfortunately this did not work from version 5.3 to 2011b and I guess it concerns 2013a also. I gave up to wait for a bugfix and use:
function FocusToFig(ObjH, EventData) %#ok<INUSD>
% ObjH: Handle of a UICONTROL
if ~any(ishandle(ObjH)) % Catch no handle and empty ObjH
FigH = ancestor(ObjH, 'figure');
if strcmpi(get(ObjH, 'Type'), 'uicontrol')
set(ObjH, 'Enable', 'off');
set(ObjH, 'Enable', 'on');
pause(0.02); % Give the re-enabled control a chance to be rendered
% Methods according to the documentation (does not move the focus for
% keyboard events under Matlab 5.3, 6.5, 2008b, 2009a, 2011b):
set(0, 'CurrentFigure', FigH);
This function can be used as callback (therefore the ignored 2nd input) of e.g. a togglebutton, such that the figure gets the focus back directly, such that e.g. the keyboard callbacks of the figure are active again.
21. WAITBAR: Of course I use an own ProgressBar as any serious FileExchange user. ;-)
22. The input checks and the suppressing of a warning consumes more than 90% of the time in POLYFIT for the typical input sizes appearing in my projects. Then a lean version is significantly faster:
function p = fPolyFit(x, y, n)
x = x(:);
V = ones(length(x), n + 1);
for j = n:-1:1
V(:, j) = V(:, j + 1) .* x;
% Solve least squares problem:
[Q, R] = qr(V, 0);
p = transpose(R \ (transpose(Q) * y(:))); % Same as: (V \ y)'
22. SGOLAYFILT was a bottleneck in one of my programs, and, sorry when this get boring, a faster C-Mex can... : FEX: fSGolayFilt
23. When the MEAN and the STD are both required, the additional calculation of the MEAN inside STD can be omitted, when both functions are joined.
24. Shall I dare to mention, I use another C-Mex DNorm2 to calculate the 2-norm? It applies different algorithms depending on the size and dimension to operate on, such that processing neighboring elements is preferred.
Let me stop here and only add this small funny joke in SAVEPATH:
dirnames = lower(dirnames);
mlroot = lower(matlabroot);
mlr_dirs = cellfun(@(x) ismember(1, x), strfind(dirnames, mlroot));
Although I'm convinced, that nobody will suffer from the efficiency of SAVEPATH, I'd really prefer the faster and less obfuscated version:
% Conversion to lower can be omitted...
mlr_dirs = strncmpi(dirnames, matlabroot, length(matlabroot));