Interesting for loop behavior

23 views
Skip to first unread message

Michael Robbins

unread,
Apr 18, 2001, 9:57:26 AM4/18/01
to
K>> for issue=current_list disp(issue); disp('---'); end
57
86
86
148

---
K>> for issue=current_list(:)' disp(issue); disp('---'); end
57

---
86

---
86

---
148

---

Michael Robbins, CFA
Director, Debt Capital Markets
CIBC World Markets Corp., Canadian Imperial Bank of Commerce
New York, NY USA
michael...@us.cibc.com , rob...@bloomberg.net

Chris Hayhurst

unread,
Apr 18, 2001, 10:08:58 AM4/18/01
to
"for" expects a row vector not a column vector so if your variable
current_list is a column then the behaviour is as you noticed. This
behaviour can be useful - it allows you to loop over the columns of a matrix
very easily e.g.

>> for issue=magic(3) disp(issue); disp('---'); end
8
3
4

---
1
5
9

---
6
7
2

---

Chris Hayhurst
The MathWorks
chay...@mathworks.co.uk

Michael Robbins <michael...@us.cibc.com> wrote in message
news:a3hD6.1480$D4.1...@www.newsranger.com...

Duane Hanselman

unread,
Apr 18, 2001, 4:38:06 PM4/18/01
to
FOR Loops take columns at a time. For example

K=eye(4);

for i=K
% code
end

During the i-th iteration, i contains the i-th column of K!

When you write for i=1:24
the right hand side of the equal sign is a row vector, so in the i-th
iteration i is the i-th column of the created row vector.
for i=(1:24)' performs the for loop once since the right hand side has one
column!

See pages 163 to 167 in Mastering MATLAB 6.

While Loops and If-Then-Else constructs have vector oriented operation as
well! See the rest of Chapter 10 for more info.

--
Duane Hanselman
Mastering MATLAB 6
ISBN 0-13-019468-9
www.eece.maine.edu/mm


Michael Robbins <michael...@us.cibc.com> wrote in message
news:a3hD6.1480$D4.1...@www.newsranger.com...

Peter J. Acklam

unread,
Apr 19, 2001, 7:49:39 AM4/19/01
to
"Chris Hayhurst" <chay...@mathworks.co.uk> writes:

> "for" expects a row vector not a column vector so if your
> variable current_list is a column then the behaviour is as you
> noticed. This behaviour can be useful - it allows you to loop
> over the columns of a matrix very easily e.g.

You say it can be useful, and perhaps you are right,
but does someone actually ever use this feature?

(In a "real" program, that is.)

Peter

--
for i=['jamh';'unaa';'sotc';'ttlk';' hae';' ebr';' r '];
i=i'; i=deblank(i); fprintf('%s ',i); end; fprintf('\n');

Joe Skrap

unread,
Apr 19, 2001, 11:33:39 AM4/19/01
to
"Peter J. Acklam" wrote:

> "Chris Hayhurst" <chay...@mathworks.co.uk> writes:
>
> > "for" expects a row vector not a column vector so if your
> > variable current_list is a column then the behaviour is as you
> > noticed. This behaviour can be useful - it allows you to loop
> > over the columns of a matrix very easily e.g.
>
> You say it can be useful, and perhaps you are right,
> but does someone actually ever use this feature?
>
> (In a "real" program, that is.)

In a "real" program I wouldn't use a for loop :~)
On the other hand, in the unlikely occasion that you *had* to (God
forbid) loop over all the elements of a matrix, you can actually gain
from using this trick to first loop over the columns and then loop
within each column:

>> x=rand(1000);

>> tic,for n=1:1000,for m=1:1000,x(n,m);end,end,toc

elapsed_time =

12.4241

>> tic,for n=x,for m=n.',m;end,end,toc

elapsed_time =

3.1942


Notice that changing the order of looping in the first scenario, so that
you run down the columns instead, does not offer much improvement:

>> tic,for m=1:1000,for n=1:1000,x(n,m);end,end,toc

elapsed_time =

12.4097

Using a dummy variable to store each column of x (which at first sight
would seem like an equivalent trick) still offers negligible
improvement:

>> tic,for n=1:1000,y=x(:,n);for m=1:1000,y(m);end,end,toc

elapsed_time =

11.8738


/K (Just another hacklimizer)


Peter J. Acklam

unread,
Apr 19, 2001, 1:50:20 PM4/19/01
to
Joe Skrap <joes...@hotmail.com> writes:

> In a "real" program I wouldn't use a for loop :~) On the other
> hand, in the unlikely occasion that you *had* to (God forbid)

> loop over all the elements of a matrix, [...]

Well, yes, but the whole point here is that we don't loop over
each element in a matrix, but loop over the columns, and do that
by letting the loop variable contain each column.

> [...] you can actually gain from using this trick to first loop


> over the columns and then loop within each column:
>
> >> x=rand(1000);
>
> >> tic,for n=1:1000,for m=1:1000,x(n,m);end,end,toc

Yes, it's always a good idea to loop over lower dimensions faster
than higher dimensions.

But why are you creating the vector 1:1000 over and over again? I
would create it only once:

tic;
v = 1:1000;
for n=v,
for m=v,
x(m,n);
end
end
toc;

Joe Skrap

unread,
Apr 19, 2001, 3:18:36 PM4/19/01
to
"Peter J. Acklam" wrote:

You are missing the point. I intended to show the difference between
indexed vs. non-indexed access of the contents of x (the part that you
sniped out).

As for for acting columnwise, I guess it is consistent with the way
other vector functions act on matrices. I.e. if I want the largest of
bunch of numbers I use max(x). If however x is a matrix max acts
columnwise. In the same spirit if I want loop through a bunch of numbers
I use for n=x... If x is a matrix for acts columnwise. As for
applications: anywhere the columns of a matrix are (physical) vectors
use for v=x... instead of for n=1:100;v=x(:,n)...


/K


Peter J. Acklam

unread,
Apr 19, 2001, 5:30:27 PM4/19/01
to
Joe Skrap <joes...@hotmail.com> writes:

> You are missing the point. I intended to show the difference
> between indexed vs. non-indexed access of the contents of x
> (the part that you sniped out).

*suitably humbled* :-)

You are right -- I missed your point. I didn't know about
this, so thanks!

Cleve Moler

unread,
Apr 19, 2001, 8:19:24 PM4/19/01
to
In article <wk8zkxr...@math.uio.no>,

Peter J. Acklam <jac...@math.uio.no> wrote:
>"Chris Hayhurst" <chay...@mathworks.co.uk> writes:
>
>> "for" expects a row vector not a column vector so if your
>> variable current_list is a column then the behaviour is as you
>> noticed. This behaviour can be useful - it allows you to loop
>> over the columns of a matrix very easily e.g.
>
>You say it can be useful, and perhaps you are right,
>but does someone actually ever use this feature?
>
>(In a "real" program, that is.)
>
>Peter

I will admit to:

a) "Inventing" this "clever" feature in the original MATLAB, and
b) Never using it for anything useful.

-- Cleve
mo...@mathworks.com

Joris Portegies Zwart

unread,
Apr 20, 2001, 6:04:37 AM4/20/01
to
On 19 Apr 2001 20:19:24 -0400, mo...@mathworks.com (Cleve Moler)
wrote:

I have a suspicion that any algorithm which can be implemented using
this 'clever' for-loop can always be vectorized, and probably without
any major programming effort.

Does anybody have a counter-example? Just curious,

Joris


-----
Joris Portegies Zwart
http://www.science.uva.nl/~portegie/

Loren Shure

unread,
Apr 20, 2001, 7:28:44 AM4/20/01
to
In article <wkr8yob...@math.uio.no>, jac...@math.uio.no says...

> Joe Skrap <joes...@hotmail.com> writes:
>
> > In a "real" program I wouldn't use a for loop :~) On the other
> > hand, in the unlikely occasion that you *had* to (God forbid)
> > loop over all the elements of a matrix, [...]
>
> Well, yes, but the whole point here is that we don't loop over
> each element in a matrix, but loop over the columns, and do that
> by letting the loop variable contain each column.
>
> > [...] you can actually gain from using this trick to first loop
> > over the columns and then loop within each column:
> >
> > >> x=rand(1000);
> >
> > >> tic,for n=1:1000,for m=1:1000,x(n,m);end,end,toc
>
> Yes, it's always a good idea to loop over lower dimensions faster
> than higher dimensions.
>
> But why are you creating the vector 1:1000 over and over again? I
> would create it only once:
>
> tic;
> v = 1:1000;
> for n=v,
> for m=v,
> x(m,n);
> end
> end
> toc;

Though this was not Joe's point, one reason to NOT create the vector v
first is if it's very large. In for loops, the indices are created on
the fly when the : notation is seen, rather than first creating the whole
vector. That way, if you are doing something a squillion times, but
dumping results into a scalar, MATLAB will not unnecessarily run out of
memory on you.

--Loren

Peter J. Acklam

unread,
Apr 20, 2001, 8:16:16 AM4/20/01
to
lo...@mathworks.com (Loren Shure) writes:

> [...] one reason to NOT create the vector v first is if it's


> very large. In for loops, the indices are created on the fly
> when the : notation is seen, rather than first creating the
> whole vector. That way, if you are doing something a squillion
> times, but dumping results into a scalar, MATLAB will not
> unnecessarily run out of memory on you.

Good point, indeed. I never noticed this feature until Matlab 6.
Is it new or has it been around for a while? (I know it was
introduced to Perl very recently.)

I think it's very useful. Certain loops may run for an unknown
number of time, and it's convenient to be able to say

for i = 1:Inf ... end

so one doesn't need to explicitly increment a loop counter.

Joe Skrap

unread,
Apr 20, 2001, 9:14:57 AM4/20/01
to
Joris Portegies Zwart wrote:

> I have a suspicion that any algorithm which can be implemented using
> this 'clever' for-loop can always be vectorized, and probably without
> any major programming effort.
>
> Does anybody have a counter-example? Just curious,
>
> Joris
>

I would be interested to hear about your definition of vectorization. In
some sense a for loop using this feature would be vectorized since it
acts on vectors.

/K


Joris Portegies Zwart

unread,
Apr 20, 2001, 12:15:52 PM4/20/01
to
On Fri, 20 Apr 2001 15:14:57 +0200, Joe Skrap <joes...@hotmail.com>
wrote:

Good point. I would say that for me 'vectorized' simply means not
using any for loops. Or, equivalently, that instead of iterating over
the elements of a matrix, the operation is performed on the matrix as
a whole.

Michael Robbins

unread,
Apr 20, 2001, 12:39:37 PM4/20/01
to
>Good point. I would say that for me 'vectorized' simply means not
>using any for loops. Or, equivalently, that instead of iterating over
>the elements of a matrix, the operation is performed on the matrix as
>a whole.

I would guess there are degrees of vectorization. This would not be fully
vectorized.

Joe Skrap

unread,
Apr 20, 2001, 1:07:25 PM4/20/01
to
Joris Portegies Zwart wrote:

I would tend to use the term vectorized as a loose synonymous to paralelized
i.e. a piece of code that N CPUs could equally distribute among themselves.
This definition does not cover all the interesting cases of hacklamization
but gives nonetheless the feeling that for loops should be avoided in favor
of functions that act on vectors

Loren Shure

unread,
Apr 20, 2001, 2:31:37 PM4/20/01
to
In article <wkelunw...@math.uio.no>, jac...@math.uio.no says...

>
> Good point, indeed. I never noticed this feature until Matlab 6.
> Is it new or has it been around for a while? (I know it was
> introduced to Perl very recently.)

I don't remember when we introduced this, but no later than some version
of MATLAB 5, I think, certainly before the current version.

--Loren

Peter J. Acklam

unread,
Apr 20, 2001, 4:20:39 PM4/20/01
to
Joe Skrap <joes...@hotmail.com> writes:

> Joris Portegies Zwart wrote:
>
> > Good point. I would say that for me 'vectorized' simply means
> > not using any for loops. Or, equivalently, that instead of
> > iterating over the elements of a matrix, the operation is
> > performed on the matrix as a whole.
>

> I would tend to use the term vectorized as a loose synonymous to
> paralelized i.e. a piece of code that N CPUs could equally
> distribute among themselves.

That's the definition I use too. I know some people let
"vectorize" mean "remove any for-loop", but I think that
definition is too loose.

Peter J. Acklam

unread,
Apr 20, 2001, 4:20:46 PM4/20/01
to
port...@science.uva.nl (Joris Portegies Zwart) writes:

> I have a suspicion that any algorithm which can be implemented
> using this 'clever' for-loop can always be vectorized, and
> probably without any major programming effort.
>
> Does anybody have a counter-example? Just curious,

Well, then you can start with vectorizing my signature. :-)

It is possible, and it doesn't require "major programming effort",
but it is ceratinly going to be more messy than it is now. What
makes it tricky is the fact that the words have different lengths.

J Portegies Zwart

unread,
Apr 23, 2001, 6:10:44 AM4/23/01
to

Well,

I think I found a rather nice solution:

i =['jamh';'unaa';'sotc';'ttlk';' hae';' ebr';' r '];
fprintf([sscanf([i ; repmat(' ', 1, size(i, 2))], '%s%c') '\n']);

But it wasn't exactly as trivial as I thought it would be... :-)

Apart from that, this wasn't exactly the application I had in mind,
though I'm sure somebody could conjure up a similar but numerical
problem.

Regards,

Joris

Pete Boettcher

unread,
Apr 23, 2001, 9:42:09 AM4/23/01
to
jac...@math.uio.no (Peter J. Acklam) writes:

> "Chris Hayhurst" <chay...@mathworks.co.uk> writes:
>
> > "for" expects a row vector not a column vector so if your
> > variable current_list is a column then the behaviour is as you
> > noticed. This behaviour can be useful - it allows you to loop
> > over the columns of a matrix very easily e.g.
>
> You say it can be useful, and perhaps you are right,
> but does someone actually ever use this feature?
>
> (In a "real" program, that is.)

I think most of us would use the more transparent:

for i = 1:size(Y, 2)
x = Y(:, i);
% do something with x
end

instead of

for x = Y
% do stuff
end

Although I must admit, the second option looks quite appealing to the
vectorizer's eye.

-PB

Pete Boettcher

unread,
Apr 23, 2001, 9:46:26 AM4/23/01
to
jac...@math.uio.no (Peter J. Acklam) writes:

> lo...@mathworks.com (Loren Shure) writes:
>
> > [...] one reason to NOT create the vector v first is if it's
> > very large. In for loops, the indices are created on the fly
> > when the : notation is seen, rather than first creating the
> > whole vector. That way, if you are doing something a squillion
> > times, but dumping results into a scalar, MATLAB will not
> > unnecessarily run out of memory on you.
>
> Good point, indeed. I never noticed this feature until Matlab 6.
> Is it new or has it been around for a while? (I know it was
> introduced to Perl very recently.)

I never realized this... good features. Just another data point:

Octave has a "range" data type, which ALWAYS stores : notation vectors
in unexpanded form, until a function needs it to be expanded. Good
design IMO.

-PB

Peter J. Acklam

unread,
Apr 23, 2001, 10:38:58 AM4/23/01
to
J Portegies Zwart <portegi...@fel.tno.nl> writes:

> "Peter J. Acklam" wrote:
> >
> > port...@science.uva.nl (Joris Portegies Zwart) writes:
> >
> > > I have a suspicion that any algorithm which can be
> > > implemented using this 'clever' for-loop can always be
> > > vectorized, and probably without any major programming
> > > effort.
> > >
> > > Does anybody have a counter-example? Just curious,
> >
> > Well, then you can start with vectorizing my signature. :-)
>

> [...] this wasn't exactly the application I had in mind, though


> I'm sure somebody could conjure up a similar but numerical
> problem.

Well, you said "any algorithm", and that pretty much
covers everything. :-)

Peter J. Acklam

unread,
Apr 23, 2001, 10:39:21 AM4/23/01
to
Pete Boettcher <boet...@ll.mit.edu> writes:

> I think most of us would use the more transparent:
>
> for i = 1:size(Y, 2)
> x = Y(:, i);
> % do something with x
> end
>
> instead of
>
> for x = Y
> % do stuff
> end

Yep, but the last loop is actually equivalent to

for i = 1 : prod(size(Y))/size(Y,1)
x = Y(:,i);
...
end

which, in the 2D case, reduces the first loop above.

Reply all
Reply to author
Forward
0 new messages