Vectorize For-If-Elseif Loop

조회 수: 21(최근 30일)
Chimalume Atuchukwu
Chimalume Atuchukwu 2015년 5월 10일
편집: Chimalume Atuchukwu 2015년 5월 10일
I am struggling with vectorizing this parfor loop. I want to completely remove the parfor loop from the code as it is taking a long time to execute when n is large. Please see the code pasted below. The vectorization I have done so far is also posted below. I will appreciate if any person in this forum can help me look at the vectorized codes and let me know where I got it wrong. Many thanks in advance.
% Initialization and precomputations
% w is an n x 1 vector
% beta: any number larger than 0. Usually set to 1.
f = zeros(n,1);
x = w;
y = w;
rho = 1;
v = f (rho*y);
rhow = rho*w;
n = length(w);
parfor i = 1 : n
if w(i) >= 0
if v(i) < -rhow(i) beta – 1
x(i) = (-beta -1 -v(i))/rho;
elseif (-rhow(i) beta 1 <= v(i)) && (v(i) <= -rhow(i) + beta 1)
x(i) = w(i);
elseif (-rhow(i) + beta 1 < v(i)) && (v(i) < beta 1)
x(i) = (beta 1 -v(i))/rho;
elseif (beta 1 <= v(i)) && (v(i) <= beta + 1)
x(i) = 0;
else
x(i) = (beta + 1 v(i))/rho;
end
else
if v(i) < -beta -1
x(i) = (-beta -1 v(i))/rho;
elseif (-beta 1 <= v(i) )&& (v(i) <= -beta + 1)
x(i) = 0;
elseif (-beta + 1 < v(i)) && (v(i) < -rhow(i) beta + 1)
x(i) = (-beta + 1 v(i))/rho;
elseif (-rhow(i) beta + 1 <= v(i)) && (v(i) <= -rhow(i) + beta + 1)
x(i) = w(i);
else
x(i) = (beta + 1 v(i))/rho;
end
end
end
===================================================================================
cond1 = (w >= 0);
cond2 = (cond1) & (v < -rhow-beta-1);
x(cond2) = (-beta-1-v(cond2))/rho;
cond3 = (cond1)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1);
x(cond3) = w(cond3);
cond4 = (cond1) & (-rhow +beta - 1 < v) & (v < beta - 1);
x(cond4) = (beta - 1 - v(cond4))/rho;
cond5 = (cond1) & (beta - 1 <= v) & (v <= beta + 1);
x(cond5) = 0;
cond6 = (cond1) & (~(v < -rhow -beta - 1));
x(cond6) = (beta + 1 - v(cond6))/rho;
cond7 = ((~cond1) & (v < -beta -1));
x(cond7) = (-beta -1 - v(cond7))/rho;
cond8 = ((~cond1) & (-beta - 1 <= v) & (v <= -beta + 1));
x(cond8) = 0;
cond9 = ((~cond1) & (-beta + 1 < v) & (v < -rhow - beta + 1));
x(cond9) = (-beta + 1 - v(cond9))/rho;
cond10 = ((~cond1) & (-rhow - beta + 1 <= v) & (v <= -rhow + beta + 1));
x(cond10) = w(cond10);
cond11 = ((~cond1) & (~(v < -beta - 1)));
x(cond11) = (beta + 1 - v(cond11))/rho;

채택된 답변

Walter Roberson
Walter Roberson 2015년 5월 10일
Construct your selection criteria and store it in a variable, and then use the same selector on both the left and right side.
For example,
cond1 = (w >= 0) & (v < -rhow-beta-1);
x(cond1) = (-beta-1-v(cond1))/rho;
And remember, white-space is free but the time of the humans trying to understand the code isn't.
  댓글 수: 2
Walter Roberson
Walter Roberson 2015년 5월 10일
Instead of continually recalculating w>=0 such as in your current cond2
cond2 = (w >= 0) & (v < -rhow-beta-1);
take advantage of the fact that you have already calculated it and stored it in cond1:
cond2 = cond1 & (v < -rhow-beta-1);
Your cond6 is broken. ~cond2 is ~(cond1 & (v < -rhow-beta-1)) which is (~cond1) | ~(v < -rhow-beta-1)) which is true if cond1 is false or if v is in the next range over. If I read correctly, your cond6 should be
cond6 = cond1 & v(i) > beta + 1;
You have a similar problem for your cond11; it looks to me that it should be
cond11 = ~cond1 & v > -rhow(i) + beta + 1;
If I were doing the implementing I would probably use histc() in the two-output version to classify the range that v was in, and then (for example)
[counts, binnum] = histc(v, [-inf, -rhow-beta-1, -rhow(i) + beta 1, beta 1, beta + 1, inf]);
cond2 = cond1 & binnum == 1;
cond3 = cond2 & binnum == 2;
and so on.

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

추가 답변(0개)

Community Treasure Hunt

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

Start Hunting!

Translated by