2015-05-08 88 views
1

我正在努力向量化這個parfor循環。我想從代碼中完全刪除parfor循環,因爲當n很大時,執行需要很長時間。請參閱下面粘貼的代碼。我會感謝任何提示/建議/幫助任何人在這個論壇可以給我這個。提前謝謝了。向量化For-If-Elseif循環

% 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 

更新:非常感謝Hbderts爲您的答案,它非常幫助我。這是我終於想出來的。我仍然有問題,因爲當我插入變量的值時,我沒有得到期望的結果,因爲我已經使用了parfor循環。你能幫我看看,讓我知道我錯了嗎?提前謝謝了。

cond1 = (w >= 0); 
cond2 = (w >= 0) & (v < -rhow-beta-1);  
x(cond2) = (-beta-1-v(cond2))/rho; 

cond3 = (w>=0)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1); 
x(cond3) = w(cond3); 

cond4 = (w>=0) & (-rhow +beta - 1 < v) & (v < beta - 1); 
x(cond4) = (beta - 1 - v(cond4))/rho; 

cond5 = (w>=0) & (beta - 1 <= v) & (v <= beta + 1); 
x(cond5) = 0; 

cond6 = (~cond2); 
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); 
x(cond11) = (beta + 1 - v(cond11))/rho; 
+5

請,你INDENT代碼!您可以在Matlab中通過CTRL + A輕鬆完成; CTRL + I。 人們只需要在python中開始編程就可以學習.... –

+2

@AnderBiguri或者從啓動矢量化開始,不必擔心縮進問題;) – Divakar

+2

@Divakar確實。但是該示例代碼需要縮進。這是我的氪星石,我用無意的代碼非常緊張。 –

回答

4

您可以使用邏輯向量來索引矩陣,如MATLAB help頁所述。讓我們做一個簡單的例子:

A = [1 2 3 4]; 
ind = logical([0 1 0 1]); 
B = A(ind) 

B = 
    2 4 

你可以使用這個系統來模擬各種不同的情況下,丟棄for循環。對於第一種情況,那將是

x((w>=0)&(v<-rhow-beta-1)) = (-beta-1-v((w>=0)&(v<-rhow-beta-1)))/rho; 

讓我們來看看術語x((w>=0)&(v<-rhow-beta-1))詳細:

  • w>=0創建一個包含邏輯載體1(真),如果在w相應的條目是>=00 (否則)。
  • v<-rhow-beta-1也創建一個邏輯向量,包含true或false。
  • 這些術語之間的&是邏輯AND。有了這個,我們有一個向量,其中包含符合兩個條件的所有元素,否則爲false。
  • 使用x(...),我們從x獲得滿足上述兩個條件的所有元素。

現在我們已經有了我們想要在第一步中設置的所有元素。我們現在必須創造我們將要設定的價值觀。部分(-beta-1-v(...))/rho與以前相同。用v(...)其中...與以前相同的條件下,我們採取所有相關的v's,與他們一起進行計算並將它們保存在x的正確位置。

我們可以用所有的if-then-else子句重複這個過程。對於第二個,這將是

x((w>=0) & (-rhow–beta–1<=v) & (v<=-rhow+beta–1)) = ... 
    w((w>=0) & (-rhow-beta-1<=v) & (v<=-rhow+beta-1)); 

等等......