2015-05-08 67 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)); 

等等......