Last week I touched on the difference between using 1:N and [1:N] as the expression in a for statement. I have gotten enough more questions recently on how for works in MATLAB that it seems time for its own post.
The most common use of for is when we want to do something a certain known number of times and we decide to not vectorize the code. In this context, we often know the total number of times, N and can write code like this:
N = 3; for ind = 1:N disp(ind) end
1 2 3
The for loop uses each column of the expression as the temporary loop variable. When MATLAB was designed, Cleve tells me, he chose : to create row vectors since 1:N is a natural expression and he expected : to be involved frequently in setting up loops.
From the early days of MATLAB, we could also use a matrix (and these days an N-dimensional array) as the loop expression. In these cases, MATLAB iterates on the columns (collapsing all dimensions >1 to be virtual columns).
A = reshape(1:6,3,2); count = 0; % display loop counter and transpose of loop expression for ind = A count = count+1; disp([count, ind']) end
1 1 2 3 2 4 5 6
For the benefit of those who didn't read last week's post, I repeat an interesting MATLAB tidbit. You can have your for loop go to Infinity in MATLAB if you don't insist on precalculating the vector to iterate over.
for ind = 1:Inf disp(ind) if ind>=2 disp('Stopping now') break end end ind
1 2 Stopping now ind = 2
The scope of the loop counter in MATLAB's for loop is not like other laguages as far as I know. You can reassign values to the counter inside the loop and yet the loop will, in certain ways, proceed as if that reassignment hadn't happened. Let's look at some examples.
for ind = 1:3 disp(ind) end ind
1 2 3 ind = 3
In this case, we don't try any funny business and we see we can use the final value of ind past the end of the for loop. This was true as well for the case in which we had the loop counter go to Inf.
MATLAB will continue marching through the loop even if, inside, the loop variable gets disturbed, unless you do something like above and break out when a condition is met (or, of course, if there's an error). Watch this example:
for ind = 1:3 ind ind = 10 end ind
ind = 1 ind = 10 ind = 2 ind = 10 ind = 3 ind = 10 ind = 10
I reset ind inside the loop, and yet when the loop continues on its next pass, it reverts to using the loop expression to determine whether or not the for loop is complete.
With the introduction of the JIT/Accelerator in MATLAB 6.5, for loops often do not exact a large performance penalty as they had in the past. I can think of situations in which using for makes lots of sense, even though MATLAB is a vector-oriented language.
- code can't be vectorized
- takes too much memory if vectorized
- code with loop is clearer and more maintainable
The main blunder people make using for loops is assigning output to an array that is not preallocated before the loop begins. This results in MATLAB constantly needing to reallocate memory for an array that is typically one element larger each time through the loop. If you're not careful, this memory allocation time can overwhelm the time of the calculation. One pattern I have seen that doesn't flagrantly preallocate the output (but does intrinsically) is when you have the loop go in reverse.
N = 7; for ind = N:-1:1 B(ind) = ind if ind <= N-1 break; end end
B = 0 0 0 0 0 0 7 B = 0 0 0 0 0 6 7
When, how, and why do you use for loops? Do you know of other perils to watch out for? Post your thoughts here.
Published with MATLAB® 7.2
コメントを残すには、ここ をクリックして MathWorks アカウントにサインインするか新しい MathWorks アカウントを作成します。