Debugging in Matlab

The first reported bug - Source : Wikipedia

The first reported bug – Source : Wikipedia

You’ve just finished writing your latest and greatest Matlab program. You’re sure this program will solve all the world’s (or at the very least all of your) problems. Just as you run your program, you see the dreaded red error text. Looks like it’s time to do some debugging! In this post, I’m going to take you through some of the common types of errors you will see when developing your software and how to solve those problems. Of course, when you’re first starting out in Matlab, these errors seem a bit cryptic and can take some time to solve. After just a bit of practice, though, you will soon be able to quickly spot and correct your errors.

Why do we call these errors in our programs ‘bugs’ anyway?

The answer is a bit of a history lesson. In the days of early electro-mechanical computers that would take up entire rooms, there were occasions where actual insects would get caught in mechanical relays in the computer system. Of course, these bugs caused programs to malfunction. The first picture of this post is from a 1947 computer log book, which is the first recorded instance of a bug interfering with a program’s function. As time went on, relays were replaced with transistors and bugs were no longer getting stuck in computers. The name stuck though as we still refer to an error that crashes a computer program as a bug. Accordingly, the process of fixing that error is now called debugging.

First, I’ll go over a few types of typical errors and give a few examples to help you avoid them as you’re writing your programs in the future. The two main types of errors that I would like to point out are:

Compile time or syntax errors: These are errors that occur even before running a Matlab script. Often, the Matlab editor will show these errors as a red bar on the right side of the editor.

Run time errors: These errors are not apparent until after the program begins to run. As the program is running, an error occurs that does not allow the program to continue to execute.

Within these larger two types of errors, there sub-sets that I am going to explain through examples in the following section.

Let’s imagine that I am a teacher who wants to normalize all my students’ grades between some specified minimum and maximum grade (don’t worry the beauty of this blog is that I am not grading you 🙂 ). First, I will enter in all the grades, curve each exam in my grade book between the specified min and max, find the average for each student, then display each student’s final grade. Here is that code (with a few errors sprinkled in).

gradebook.m :

% each row is a particular student
% each column is an exam

test_grades = [90 91 83 76 75 87;94 85 83 81 85;96 92 91 88 89 90;...
83 79 93 69 95 88; 80 94 78 91 85 88];

curved_gradebook = zeros(size(test_grades)); %pre-allocate

% convert each exam to a curve
for i=1:length(test_grades)
   curved_exam = convert_to_curve(test_grades(i,:));
   curved_gradebook(i,:) = curved_exam;
end

% calculate mean grades for each student
avg_grades = mean(test_grades,2);

% print each student's score
for i=1:size(test_grades,1)
   fprintf('The average score for Student %i is: %4.2f \n',i,avg_grades(i));
end

In this code you see a function call to convert_to_curve to actually scale each exam.

convert_to_curve.m :

function curved_grades = convert_to_curve(exam_vector)
scale_to_max = 100;
scale_to_min = 65;
min_score = min(exam_vector);
max_score = max(exam_vector);

% normalize between -1 and 1
normalized_grades = 2(((exam_vector - min_score)./(max_score - min_score))-0.5);

% set data to new min/max
curved_grades = (normalized_grades+1)/2*(scale_to_max-scale_to_min)+scale_to_min;

As you might be able to guess from the variable names, each exam will be scaled between a minimum grade of 65 and a maximum grade of 100 (I suppose I’m a rough hypothetical grader). Just after running gradebook.m, I hear the loveable sound that is the error bell.

The first error that comes up is the following:

Error using gradebook (line 4)
Error using vertcat
Dimensions of matrices being concatenated are not consistent.

The above is a concatenation error – essentially one of the rows or columns does not have enough entries. Luckily for us, Matlab will actually point this out before even running the program.

Debug

Notice both the red bar on the left side of the screen to indicate the line number where the error occurs as well as the red squiggly mark on the row of the matrix in question. One way to prevent an error like this in the future would be to use ellipses to make some of these matrices more human readable. This way, errors like these will easily jump out. Here is a corrected version:

test_grades = [90 91 83 76 75 87;...
   94 85 83 81 85 76;...
   96 92 91 88 89 90;...
   83 79 93 69 95 88;...
   80 94 78 91 85 88];

Running the program again, we will see this :

Error: File: convert_to_curve.m Line: 10 Column: 22
Unbalanced or unexpected parenthesis or bracket. 

Error in gradebook (line 14)
curved_exam = convert_to_curve(test_grades(i,:));

I’ll do a bit of translating here, so you see what is going wrong and how to debug code when an error occurs in a sub-function. This statement is saying that the error is in line 10 of convert_to_curve.m, which is called by gradebook.m. In larger programs, it is not uncommon to see a long chain of functions that are called by a function below it. Obviously the most important part is the error reported at the top of the list, within the actual function that was called.

With this knowledge, let’s take a look at line 10 of convert_to_curve.m

Debug0

Here we see an example of a syntax error. Sometimes when converting from mathematical papers or notes, it is easy to forget that you must explicitly tell Matlab you wish to multiply two values. To fix this, you must add a * in between the 2 and the open parenthesis.

Okay, that syntax error is now fixed and there are no more red squiggly lines in my code. This means that any error I find now will be a run-time error. Sure enough, I ran the code and got another error :

Attempted to access test_grades(6,:); index out of bounds because size(test_grades)=[5,6].

Error in gradebook (line 14)

curved_exam = convert_to_curve(test_grades(i,:));

Here is an example of an indexing error. It is important to remember that the index into a vector or matrix MUST be a positive integer and if you are trying to access a number within a matrix that index position has to exist. This second condition is what is violated here, but let’s find out why.

To do so, I’ll use a debugging tool called breakpoints. Breakpoints will stop the execution of your code so that you can see the value of your variables while the code is running. To set a breakpoint, simple click just to the left of the line numbers in your code wherever you would like execution to halt. I chose to pause my code at line 14.

Debug1

Now, I run the code and it stops in the for-loop. When the code hits the breakpoint, it stops execution and now if I look at the Command Window, I see:

Debug2

What’s great about this is that you can see each of your defined variables on the right in the workspace. At this point, we have no error so we can “step-though” and go to the next breakpoint. Since this is in a loop, it will return to the same breakpoint until the loop is exited.

Debug3When in debugging mode, you can click Continue which will run until the next breakpoint is hit or you can click the Step button which will run the next line. Finally, you can Quit Debugging if you’ve found the source of your problem.

To find my problem, I kept pressing the Step button until receiving the error shown here:

Index exceeds matrix dimensions.
Error in gradebook (line 14)
curved_exam = convert_to_curve(test_grades(i,:));

So it looks like it’s that pesky i variable that’s causing the trouble. Let’s take a look a look at the workspace while in the current iteration of the for-loop.

Debug4 Ah hah! Here it shows that i has a value of 6, but the matrix test_grades only has 5 rows (i.e. only 5 students). Looking back at the for-loop shows that the variable i increases until it hits the value of length(test_grades). 

Looking at the documentation for the length function, shows that the function will return the longest dimension of the input argument. Meaning that sometimes this program will work and that is on the condition that there are more students than there are exams. I would recommend to always use the size function in these types of cases because you can specify which dimension you wish to consider. In this case, we want to loop until i=size(test_grades,1).

Finally, after all our debugging, we get the output we were after.

>> gradebook
The average score for Student 1 is: 83.67
The average score for Student 2 is: 84.00
The average score for Student 3 is: 91.00
The average score for Student 4 is: 84.50
The average score for Student 5 is: 86.00

In a future post, we will discuss a topic called error handling, which, if you can guess from the name, allows you to write code that can actually react to any particular error and fall gracefully. Debugging is certainly one of those Matlab skills that you get better at each time you write some code. So don’t despair! Hopefully these tips give you a good starting point to finding and eliminating bugs in your code.

If, despite all this, you are still stuck with an annoying bug, make sure to read the getting help post!

I am interested by your own experience, what was the worst bug you encountered?

This entry was posted in Beginners. Bookmark the permalink.

3 Responses to Debugging in Matlab

  1. Pieter van Vugt says:

    A useful addition to the article perhaps: If you use + to execute your code (or equivalently press the “run section” or “run and advance” buttons – it executes sections of code delimited by “%%” between the lines), the breakpoints will be ignored unless they are located in sub-functions.

    This little fact caused me to not use the breakpoint feature for quite a long time, until I figured it out.

    • Pieter van Vugt says:

      I mean “if you use Control+Enter”

      Putting words between pointy brackets makes them disappear in the post, apparently.

  2. Pingback: MatLab Basic 2 | New ThinKing

Leave a Reply

Your email address will not be published. Required fields are marked *