Replacing nested "for" loops

1 visualización (últimos 30 días)
Amir Akb
Amir Akb el 8 de Mayo de 2012
Hi all,
I have a set of "K" nested "for" loops, where "K" is variable. An example of my code for when K=4 is as follows:
Spectral_eff_Points=(0):(1):(20);
S=zeros(K,1);
p=zeros(K,1);
n = length(Spectral_eff_Points);
for s1_index=1:n,
S(1)=Spectral_eff_Points(s1_index);
for s2_index=1:n,
S(2)=Spectral_eff_Points(s2_index);
for s3_index=1:n,
S(3)=Spectral_eff_Points(s3_index);
for s4_index=1:n,
S(4)=Spectral_eff_Points(s4_index);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MAIN CALCULATIONS DONE HERE
for user_index=1:K
if user_index==1;
p(user_index)=(2^(S(user_index))-1)* (N/g(user_index));
else
increment=1:(user_index-1);
Sum_P_inc=sum(p(increment));
p(user_index)=(2^(S(user_index))-1)* ((N/g(user_index))+Sum_P_inc);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
end
end
end
As you can see, for large "K" and "n" values, the code will be very very slow :( Does anyone have any better way of conducting such loops, but in a much faster way?!
any help will be much appreciated.
Thanks

Respuesta aceptada

Jan
Jan el 8 de Mayo de 2012
At first clean up the current code:
% MAIN CALCULATIONS DONE HERE
p(1) = (2^S(1) - 1) * (N/g(1)); % Avoid test for ==1 in each iteration!
tmp1 = cumsum(p);
for user_index = 2:K
Sum_P_inc = tmp1(user_index - 1);
p(user_index) = (pow2(S(user_index))-1) * (N/g(user_index) + Sum_P_inc);
end
Perhaps a vectorized version is faster:
p = (pow2(S) - 1) .* (N ./ g + [0; cumsum(p(1:end-1))]);
Please test this - I do neither have your data nor can I access Matlab currently.
In a further step you can convert the K "for" loops to 1 "while" loop by using a [1 x K] vector and increment the last element until the limit is reached. Then increment the next element and reset the last one until even the first element reaches the limit.
  1 comentario
Amir Akb
Amir Akb el 8 de Mayo de 2012
Hi Jan,
Thank you very much for your time and effort to answer my question.
Just to let you know, the "clean-up" section works, and gives the same result, however, this doesn't speed the code up much.
About your second comment, would you be able to give me a bit more detail on how to convert the K for loops to a single while loop please.
Once again, many thanks for your time.

Iniciar sesión para comentar.

Más respuestas (1)

Jan
Jan el 9 de Mayo de 2012
A code example for K "loops" represented by a [1 x K] vector:
n = 3;
K = 4;
V = ones(1, K);
go = true;
while go
% The action:
disp(V);
% Increment:
V(K) = V(K) + 1;
if V(K) > n
V(K) = 1;
go = false;
for i = K-1:-1:1
V(i) = V(i) + 1;
if V(i) <= n % i.th counter not at limit
go = true;
break; % Leave "for i" loop
end
V(i) = 1; % Reset i.th counter
end
end
end
This is choosing K elements from the vector 1:n with repetition and order.
  1 comentario
Amir Akb
Amir Akb el 10 de Mayo de 2012
Dear Jan,
You just made my day!
This is exactly what i was looking for. It is much faster than having "K" nested "for" loops, and i get the same result.
I really appreciate the time you have put into replying back to my question.
All the best

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by