When you have a bug that occurs in a script of function that takes a long time to run, you can use this technique to get to the bug faster in MATLAB.
By
Doug Hull
Doug first used MATLAB in 1994, could not figure it out until he got some help in 1995. He is now dedicated to making sure that no one else wastes a year of their life not knowing MATLAB like he did.
A closely related technique to this one is using “cell mode,” which is one of my favorite MATLAB desktop innovations ever. Create a cell around the really slow part, and then another cell around the buggy part. Run the slow cell first. Then you can repeatedly run and debug the buggy part, without running the slow part over and over again.
I like that method also, but I have one concern with it. It is possible to change the initial state in the troublesome cell. Then any changes that you make to the code might not have the intended effect.
If you are confident this is not the case, then the cell mode technique is even faster to implement.
When I’m doing this instead of commenting out the slow code (even with %{ %} group comments) or keeping it in a different cell, I’ll often move the cell I’m working on into an entirely seperate file, with a load of the “known good run” as Doug does. That way I keep the main codebase clean (as it ever is) and can save “experiments” elsewhere before merging.
This is a technique I use often; many times I have some code to pre-process raw data (ie, extract features from a video), and it’s not necessary to repeat it all the time.
Instead of commenting/uncommenting the whole code, I use a simple flag that is easy to toggle by commenting/uncommenting (Ctrl+R, Ctrl+T), and the following structure:
% recalculate_whatever = true;
recalculate_whatever = false;
if recalculate_whatever
%long calculation
%...
save whatever data1 data2 ...
else
load whatever data1 data2 ...
end
%code that uses data1, etc
%...
That is an excellent plan. Reminds me of something I do like having a variable “Verbose” and setting up some debugging DISP commands inside if blocks throughout the code.
What I have done in the past is use a global variable ‘VERBOSE’ and have a debugging function that mirrors fprintf syntax (which I call log_debug to match our C++ code):
%——————————-
function log_debug(varargin)
global VERBOSE
if (VERBOSE)
fprintf(1, varargin{:});
end
end
%——————————-
Example usage:
>> whos
>> log_debug(‘One %d two %d three %d\n’, 1, 2, 3)
>> global VERBOSE
>> VERBOSE = true;
>> log_debug(‘One %d two %d three %d\n’, 1, 2, 3)
One 1 two 2 three 3
>>
That reminds me, I had a DDISP command that sourced a global VERBOSE. If verbose was one, the DDISP would DISP whatever I gave DDISP, otherwise it would do nothing.
Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and Timberland Boots UKI hope you post again soon.
Leave a Reply
About
Doug Hull is a proud MathWorker who is on a mission to help you with MATLAB.
Pretty simple but heaven help me if it ever occurred to me. I guess that is why you wear that pimp hat.
@Oscar,
It comes from years of debugging other people’s code… I do miss that hat, leather shrinks in the sun apparently! :(
-Doug
Nifty and short. I like it. (Both the hat and the video).
–DA
A closely related technique to this one is using “cell mode,” which is one of my favorite MATLAB desktop innovations ever. Create a cell around the really slow part, and then another cell around the buggy part. Run the slow cell first. Then you can repeatedly run and debug the buggy part, without running the slow part over and over again.
@cyclist
I like that method also, but I have one concern with it. It is possible to change the initial state in the troublesome cell. Then any changes that you make to the code might not have the intended effect.
If you are confident this is not the case, then the cell mode technique is even faster to implement.
Doug
When I’m doing this instead of commenting out the slow code (even with %{ %} group comments) or keeping it in a different cell, I’ll often move the cell I’m working on into an entirely seperate file, with a load of the “known good run” as Doug does. That way I keep the main codebase clean (as it ever is) and can save “experiments” elsewhere before merging.
This is a technique I use often; many times I have some code to pre-process raw data (ie, extract features from a video), and it’s not necessary to repeat it all the time.
Instead of commenting/uncommenting the whole code, I use a simple flag that is easy to toggle by commenting/uncommenting (Ctrl+R, Ctrl+T), and the following structure:
@Jotaf
That is an excellent plan. Reminds me of something I do like having a variable “Verbose” and setting up some debugging DISP commands inside if blocks throughout the code.
Thanks,
Doug
@dhull
What I have done in the past is use a global variable ‘VERBOSE’ and have a debugging function that mirrors fprintf syntax (which I call log_debug to match our C++ code):
%——————————-
function log_debug(varargin)
global VERBOSE
if (VERBOSE)
fprintf(1, varargin{:});
end
end
%——————————-
Example usage:
>> whos
>> log_debug(‘One %d two %d three %d\n’, 1, 2, 3)
>> global VERBOSE
>> VERBOSE = true;
>> log_debug(‘One %d two %d three %d\n’, 1, 2, 3)
One 1 two 2 three 3
>>
@Rodney,
That reminds me, I had a DDISP command that sourced a global VERBOSE. If verbose was one, the DDISP would DISP whatever I gave DDISP, otherwise it would do nothing.
Doug
Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and Timberland Boots UKI hope you post again soon.