Replacing nested "for" loops

1 回表示 (過去 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 Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by