A reader suggested I discuss the difference in use of MATLAB's for and while constructs.
Contents
The Scene
You want to run some code at least once, regardless of any conditions. You might want to run it more often, depending on some conditions.
At Least Once in a while
Here's a couple of solutions using a while construct, while ensuring the main chunk of code is run at least once, even if the stop condition is already met.
n = 0;
i = 1;
while true
doStuff();
if (i > n)
break;
end
i = i + 1;
n = somethingElse();
endHere's another way that inverts the logic surrounding the condition and avoids using an explicit break statement. Instead, it has to check to see that currentState is still true.
n = 0;
i = 1;
currentState = true;
while currentState
doStuff();
currentState = (i <= n);
if currentState,
i = i + 1;
n = somethingElse();
end
endI wonder if this version is any better than the first. It is one line longer so currentState can be explicitly set. This might be more readable to some of you, and less so to others.
Taking Care Using for
To make sure the code doStuff runs at least once, we need to take care using a for-loop. The reason for this is that the loop code is guaranteed to not run at all if the loop counter variable is empty. To ensure the code runs once, we need to repeat the code outside the loop. If the code being run is like this example, encapsulated in another function, then it's not so difficult to be sure we've got things right.
If instead of a single function, we have several statements to run, then we have take care to copy all of the code and ensure that we update both sets if we ever have to make some changes.
doStuff will never be run with the following code sample.
n = 0;
count = 0;
for ind = 1:n
doStuff();
count = count + 1;
endTo replicate the run-at-least-once behavior, we need to replicate the code before the loop.
n = 0;
count = 0;
doStuff();
for ind = 1:n
doStuff();
count = count + 1;
endYour Style Preferences?
I have to say that having lots of code in the body that might have to be replicated is something I would avoid. So I'd see if I could reasonably stick the bulk of the loop body code in another function. After that, I still have a slight preference for one style over the others, but I'd like to hear your thoughts first.
Which programming style do you prefer here? Using for, while with an explicit condition, while with a break, or do you have an even better code pattern? Post your thoughts here.
Get
the MATLAB code
Published with MATLAB® 7.5



Loren says:
doStuff will never be run with the following code sample.
n = 10;
count = 0;
for ind = 1:n
doStuff();
count = count + 1;
end
Why not? I tried it in my Matlab session and doStuff is called 10 times as I would expect.
Jeremy-
I will have to edit the code again. Some of the code that’s wrong! Thanks for letting me know. And it’s now fixed.
–Loren
Hi Loren,
First I avoid writing code twice if ever possible! I have just “demultiplexed” code of a student of mine where about 30 lines were repeated 4 times with only little differences. Horrible!
Second I avoid using “i” and “j” as loop counters, as they might be used as the imaginary unit in some other place.
And your second example with currentState looks a little complicated to me. I more like to use a break statement.
Regards
Markus
Hi Loren,
What about the following for-construct, which mimicks your “at least once in a while”, but is shorter
for i=1:Inf disp(i) ; % Do Stuff n = 10 * rand(1) ; % your somethingElse(); if i > n break ; end ; endJos
Although I sometimes use the duplicate-code-with-for-loop I hide my face in shame each time.
The break version would be really great, the problem is when you start nesting loops the break only exits the innermost loop. With explicit conditions you have more control of what happens when your exit condition is met.
I think the second example with a while loop is best. It is very clear that the loop is run at least once. It is also clear that the number of runs is not known in advance.
Contrasting this, the first example can be mistaken as an endless loop. A comment that explains what the programmer actually wanted to achieve by this loop would require several lines in a real world application.
I dislike the for loop example for the same reason: Usually the number of for loop runs is known and determined in advance. Again a comment would be necessary to explain what the programmer really meant.
C++ has a do{}while statement, Pascal has a repeat until statement. It would be nice to have something like this in Matlab, too.
Loren,
I agree with Okinawa, but I would go even one step further still. My preference is to use a flag variable, which allows me to test for any number of stopping conditions, and keep track of why I stopped. I took this approach from the optimization toolbox, and have found it invaluable for tracking possible occurrences when handling large sets of data.
Dan
Folks,
Thanks for your thoughtful comments.
I prefer the explicit conditions as well. It makes it possible to manage more than 1, as people stated, and it is possible to manage the details outside the loop later, if desired as well. That helps with the nested loop situation, vs. using break.
–Loren
How about for i=1:max(1,n) to guarantee at least one loop pass?
Loren, can you say anything about execution speed of for versus while? Is it possible for one version to be accelerated when the other is not?
Toby-
Acceleration typically depends on the contents of the loop statements, and not on whether you use for or while. If variables don’t change shape or type from iteration to iteration, the code has a higher chance of being accelerated.
–loren
Loren,
The question about acceleration got me thinking about a item I’ve found in the past which I really don’t understand. The profiler often reports the end statement of a loop as using a substantial amount of time (well, substantial when executed several tens of thousands of times). I thought that the end statement was really just a marker with virtually no execution time, but that doesn’t seem to be the case. Where is the time used in implementation of a for vs. a while loop. How does condition testing (while) compare against index creation (for)?
Thanks,
Dan
Regarding the use of “i”. I think using i and j as complex scalars is a bad idea. You can never trust that they haven’t been overwritten with something else (like row and column indices as they ought to be used, in my mind). For the complex sqrt(-1), I always 1i, which is always the imaginary unit no matter what your variables do.
According to me, the main difference between while and for loops in matlab is this one:
u = [];
for n=1:10
if n==3
n=n+1;
end
u = [u, n];
end
u
has not the same behavior than
u = [];
n=1;
while n
I remember how I had to modify a lot of lines of MATLAB codes when the behavior of for changed (with R14?) around 6 years ago…
oops, my two pieces of code were:
u = [];
for n=1:10
if n==3
n=n+1;
end
u = [u, n];
end
u
and
u = [];
n=1;
while n
ok, let’s try once more the while part:
u = [];
n=1;
while n<=10
if n==3
n=n+1;
end
u = [u, n];
n=n+1;
end
u
There’s a pattern I use a lot with M to address Loren’s original problem. It looks like:
work = true;
while( work )
work = false;
if
work = true;
% sometimes I put CONTINUE here for emphasis
end
end
With a bit of care, this pattern can be nested, too…
This is especially good for tasks that have a “massage something until it stops changing” flavor.
Dan,
With respect to the end statement appearing to take all the time, I will try to give you a high-level answer.
In M code, the end statement is not 100% equivalent to an end statement in C. It does more than just close the loop. There’s a loop counter that is incremented at this point to check to see if the loop is done. Next compute the loop control variable for the next iteration. Check for Ctrl-C, etc. These all take some time. In addition, assuming the JIT is operating during the for loop, when appropriate, the variables used by the JIT need to be returned back fully into the main MATLAB context.
while loops differ in when the loop expression is evaluated (at the top) vs. the for loop. So in that case, some of the time might get assigned to the while statement and not the end.
I hope this gives you enough of a flavor of what’s happening.
–Loren
Loren,
Thank you for the response. I understand now the usage of time in this stage of the program (although I wasn’t aware that ML checked for a Cntrl-C at the ends of loops - Does this mean that if I have a loop buried in my code, it’s cycle time is longest delay that I will ever have to wait for an abort to kick in? If so, then I may consider adding single pass for loops in some spots as an escape hatch.)
One other follow on question: I really started with MatLab in version 7, so my understanding of the JIT is somewhat limited. Is there a bible of JIT somewhere that explains what is acceleratable (excuse the imaginative word definition) and what is not?
Thanks,
Dan
Dan-
There are a few of my blog posts that talk about the JIT a little and you might find some discussion on the MATLAB documentation. But there’s intentionally not a lot of information. Why? Because it is a rapidly moving target and we don’t want to encourage people to program to the details of any particular version. Instead, we hope people will write readable, maintainable code that runs fast enough without having to perform contortions and that code will benefit over time with our ongoing investment in performance. If something in particular is very slow, it is worth sending the code to tech support so it can get on the development radar for performance improvements.
The thing about Cntrl-C is that if you don’t time the action, it can miss the window. So I don’t think you will necessarily get the behavior you want by rewriting your loop. Perhaps it’s worth you trying it though.
–Loren
I really like Toby Driscoll’s construct, e.g.:
n = 2; for i=1:max(1,n), disp(’hw!’); end
hw!
hw!
n = 0; for i=1:max(1,n), disp(’hw!’); end
hw!
I find it even better than the while true construct I used to prefer.
advertise to C programmers to take care with this statement
for i = 1:3
i = 1
end
it will loop three times!!! the similar code in C never will stop.
for(i=1;i
The following code runs three times and ends with i equal to 8
for i=1:3
i=i+5
end
i
I’m curious how the loop counter is actually manipulated and at what point it is checked to see if the loop end condition is satisfied. Is the i+5 actually put into a different storage location than the loop counter?
Diane-
The loop counter gets reset each time through the loop, despite what might happen within the loop.
–Loren
I am doing some nested while loops, but in the inner while loop I have a for loop inside of it, then I have a condition that needs to break the while loop but since break applies to the for loop also I wonder how I do it?, do you need a sample of it?
German-
What you may need to do is to set a variable in the inner loop (switch between true and false if you break). In the outer loop, check to see if the inner loop broke or not and act accordingly.
–Loren
Hi Loren,
I wrote a program for processing images of size 4008 x4008.
When i executed the code,the code runs for almost 2 days.Also if i change the input data as 8-bit,i do get a result but if i give the original 16-bit data as input..an error is thrown stated as out of memory exception.(Help memory)..
Actually i need several instances of the image and there was an inherent need to use several for loops.Could this cause a overhead.( it suggested me to consider preallocating for speed but there is a memory limitation along with the speed).
so i am wondering if while is better than for loop.?
I would appreciate if you could give me a light on this part.It would be great if Matlab could provide few materials about code optimization in Matlab.
Natarajan-
You have not provided enough information for me to have any insight. I recommend you contact support (link on the right side) with more details and they will help you out. Off-hand, for and while loops are neither worse nor better than each other - but used for different purposes typically.
The profiler, M-Lint, and the last 3 sections of the MATLAB documentation under Programming Fundamentals:
http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/bqjgwp9.html
have a lot of advice for code optimization.
–Loren