Replacing nested "for" loops

조회 수: 2 (최근 30일)
Amir Akb
Amir Akb 2012년 5월 8일
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

채택된 답변

Jan
Jan 2012년 5월 8일
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
Amir Akb
Amir Akb 2012년 5월 8일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2012년 5월 9일
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
Amir Akb
Amir Akb 2012년 5월 10일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by