Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Are these for loops efficient?

Subject: Are these for loops efficient?

From: Adam Henderson

Date: 24 Nov, 2010 11:06:04

Message: 1 of 13

Hi,

I was just wondering if this is an efficient way of coding for loops.

for i=1:1:5
    i
    for j=1:1:5
      if j~=i
      j
      else
      end
    end
end

basically I want the inside for loop to run for all values except for the current value of "i"
so if "i" equals 2 then "j" will run for 1,3,4,5. This code I have works but I'm not sure its the best way if I want to expand it to a much larger number of iterations.

Thanks
Adam

Subject: Are these for loops efficient?

From: Sean de

Date: 24 Nov, 2010 16:37:04

Message: 2 of 13

"Adam Henderson" <adam.henderson@strath.ac.uk> wrote in message <iciris$k75$1@fred.mathworks.com>...
> Hi,
>
> I was just wondering if this is an efficient way of coding for loops.
>
> for i=1:1:5
> i
> for j=1:1:5
> if j~=i
> j
> else
> end
> end
> end
>
> basically I want the inside for loop to run for all values except for the current value of "i"
> so if "i" equals 2 then "j" will run for 1,3,4,5. This code I have works but I'm not sure its the best way if I want to expand it to a much larger number of iterations.
>
> Thanks
> Adam

No it is not the most efficient way. More than likely both loops can be avoided but without seeing your interior computations we can't tell you how to do that.

Here is a better way to do what you want:
[ii jj] = find(~eye(5));
for kk = 1:length(tbl)
     icurrent = ii(kk);
     jcurrent = jj(kk);
end

But like I said, more than likely the whole thing can be vectorized.

Subject: Are these for loops efficient?

From: Matt Fig

Date: 24 Nov, 2010 18:32:04

Message: 3 of 13

"Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message
> No it is not the most efficient way. More than likely both loops can be avoided but without seeing your interior computations we can't tell you how to do that.
>
> Here is a better way to do what you want:
> [ii jj] = find(~eye(5));
> for kk = 1:length(tbl)
> icurrent = ii(kk);
> jcurrent = jj(kk);
> end
>
> But like I said, more than likely the whole thing can be vectorized.

I do agree that, depending on what is in the loops, vectorization may be the way to go. However, the approach shown by sean de is, in my experience, less efficient than the original loop. Here is a simple example:


function [] = loop_test()
% Testing loop efficiency.
N = 5000;
c1 = 0;

tic
for ii=1:1:N
    for jj=1:1:N
        if jj~=ii
            c1 = c1 + ii/jj;
        end
    end
end
toc

% Now index into a pair. Indexing takes time!
c2 = 0;

tic
[ii jj] = find(~eye(N)); % Even without timing this, time is longer!
for kk = 1:length(ii)
    c2 = c2 + ii(kk)/jj(kk);
end
toc
% END LOOP_TEST




Now from the command line (2007b, 32bit):

>> loop_test
Elapsed time is 0.717838 seconds.
Elapsed time is 2.185619 seconds.

Subject: Are these for loops efficient?

From: Sean de

Date: 24 Nov, 2010 19:08:03

Message: 4 of 13

"Matt Fig" <spamanon@yahoo.com> wrote in message <icjln4$msn$1@fred.mathworks.com>...
> "Sean de " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message
> > No it is not the most efficient way. More than likely both loops can be avoided but without seeing your interior computations we can't tell you how to do that.
> >
> > Here is a better way to do what you want:
> > [ii jj] = find(~eye(5));
> > for kk = 1:length(tbl)
> > icurrent = ii(kk);
> > jcurrent = jj(kk);
> > end
> >
> > But like I said, more than likely the whole thing can be vectorized.
>
> I do agree that, depending on what is in the loops, vectorization may be the way to go. However, the approach shown by sean de is, in my experience, less efficient than the original loop. Here is a simple example:
>
>
> function [] = loop_test()
> % Testing loop efficiency.
> N = 5000;
> c1 = 0;
>
> tic
> for ii=1:1:N
> for jj=1:1:N
> if jj~=ii
> c1 = c1 + ii/jj;
> end
> end
> end
> toc
>
> % Now index into a pair. Indexing takes time!
> c2 = 0;
>
> tic
> [ii jj] = find(~eye(N)); % Even without timing this, time is longer!
> for kk = 1:length(ii)
> c2 = c2 + ii(kk)/jj(kk);
> end
> toc
> % END LOOP_TEST
>
>
>
>
> Now from the command line (2007b, 32bit):
>
> >> loop_test
> Elapsed time is 0.717838 seconds.
> Elapsed time is 2.185619 seconds.


You are correct, that is faster, I shouldn't have posted before the first cup of coffee. It is good to get the OP thinking in terms of doing all of the work at once, though. Anyway here's a better solution for the example using bsxfun and diag, two potentially very useful tools for the OP's problem.

tic
ii = 1:N;
b = bsxfun(@rdivide,ii,ii.');
c3 = sum(b(:))-sum(diag(b));
toc
Elapsed time is 0.480515 seconds. %c1
Elapsed time is 2.907545 seconds. %c2
Elapsed time is 0.303413 seconds. %c3

Subject: Are these for loops efficient?

From: Adam Henderson

Date: 25 Nov, 2010 15:53:03

Message: 5 of 13

Thanks for the replies guys.

Im pretty sure that I will have to have loops because I need to manipulate the data im my arrays for all "i" iterations and all "j" iterations except when "i" and "j" are equal

Subject: Are these for loops efficient?

From: Bruno Luong

Date: 25 Nov, 2010 16:07:04

Message: 6 of 13

"Adam Henderson" <adam.henderson@strath.ac.uk> wrote in message <icm0ov$b6s$1@fred.mathworks.com>...
> Thanks for the replies guys.
>
> Im pretty sure that I will have to have loops because I need to manipulate the data im my arrays for all "i" iterations and all "j" iterations except when "i" and "j" are equal

That might not be a good reason.

Bruno

Subject: Are these for loops efficient?

From: dpb

Date: 25 Nov, 2010 16:03:43

Message: 7 of 13

Adam Henderson wrote:
> Thanks for the replies guys.
>
> Im pretty sure that I will have to have loops because I need to
> manipulate the data im my arrays for all "i" iterations and all "j"
> iterations except when "i" and "j" are equal

What manipulation?

Alternative approach may be do the operation on the array then replace
the diagonal.

--

Subject: Are these for loops efficient?

From: Walter Roberson

Date: 25 Nov, 2010 19:10:22

Message: 8 of 13

On 10-11-25 09:53 AM, Adam Henderson wrote:
> Thanks for the replies guys.
>
> Im pretty sure that I will have to have loops because I need to
> manipulate the data im my arrays for all "i" iterations and all "j"
> iterations except when "i" and "j" are equal

Sometimes the most efficient way is to vectorize processing for all of the
combinations, and then to throw away the diagonal. If the computation for
i == j will not actually throw an error, and will not for some reason take
much longer than the other calculations, then this approach can be worth-while.

Subject: Are these for loops efficient?

From: Adam Henderson

Date: 26 Nov, 2010 10:41:08

Message: 9 of 13

I use the loops to generate a set of ODEs. The "j" loop is used to create a vector which is summed and placed into the "i" element.

Subject: Are these for loops efficient?

From: Walter Roberson

Date: 26 Nov, 2010 16:16:23

Message: 10 of 13

On 26/11/10 4:41 AM, Adam Henderson wrote:
> I use the loops to generate a set of ODEs. The "j" loop is used to
> create a vector which is summed and placed into the "i" element.

Dunno. Sounds to me like you could have a small loop afterwards that
subtracted out the i == j contribution.

Subject: Are these for loops efficient?

From: Adam Henderson

Date: 27 Nov, 2010 13:12:03

Message: 11 of 13

Walter Roberson <roberson@hushmail.com> wrote in message <s3RHo.64377$d67.29820@newsfe16.iad>...
> On 26/11/10 4:41 AM, Adam Henderson wrote:
> > I use the loops to generate a set of ODEs. The "j" loop is used to
> > create a vector which is summed and placed into the "i" element.
>
> Dunno. Sounds to me like you could have a small loop afterwards that
> subtracted out the i == j contribution.

yeah I should have also mentioned that I use the "i" loop to make other calculations too.
Thanks for all the suggestions.

Subject: Are these for loops efficient?

From: Malcolm Lidierth

Date: 27 Nov, 2010 14:08:03

Message: 12 of 13

This might useful too. Depends on what's in those loops.

jj=1:5;
for ii=1:5
for k=jj(jj~=ii)
    disp(k);
end
end

General rules:
Put all code that can be outside the loops on the outside
Have the loop that executes fewest times on the outside.
Avoid conditional statements in inner loops

If accessing N-D matrices, treat the highest dimensions in blocks (in MATLAB/Fortran). That improves bus throughput and CPU cache memory use.

Subject: Are these for loops efficient?

From: Adam Henderson

Date: 1 Dec, 2010 19:13:05

Message: 13 of 13

"Malcolm Lidierth" <ku.ca.lck@htreidil.mloclam> wrote in message <icr3c3$n4u$1@fred.mathworks.com>...
> This might useful too. Depends on what's in those loops.
>
> jj=1:5;
> for ii=1:5
> for k=jj(jj~=ii)
> disp(k);
> end
> end
>
> General rules:
> Put all code that can be outside the loops on the outside
> Have the loop that executes fewest times on the outside.
> Avoid conditional statements in inner loops
>
> If accessing N-D matrices, treat the highest dimensions in blocks (in MATLAB/Fortran). That improves bus throughput and CPU cache memory use.

thanks, this works very well for me

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us