2012-06-04 25 views
1

我被困在MATLAB /八度矢量化這個棘手的循環:你將如何矢量化這個嵌套循環在matlab /八度?

[nr, nc] = size(R); 
P = rand(nr, K); 
Q = rand(K, nc); 

for i = 1:nr 
    for j = 1:nc 
     if R(i,j) > 0 
      eij = R(i,j) - P(i,:)*Q(:,j); 
      for k = 1:K 
      P(i,k) = P(i,k) + alpha * (2 * eij * Q(k,j) - beta * P(i,k)); 
      Q(k,j) = Q(k,j) + alpha * (2 * eij * P(i,k) - beta * Q(k,j)); 
      end 
     end 
    end 
end 

代碼試圖與R因式分解成P和Q,並接近最近的P和Q與更新規則。例如,令R = [3 4 0 1 1; 0 1 0 4 4; 5 4 3 1 0; 0 0 5 4 3; 5 3 0 2 1],K = 2,α= 0.01和β= 0.015。在我的真實情況下,我將使用一個巨大的稀疏矩陣R(這就是爲什麼我需要矢量化),並且K仍然很小(小於10)。整個腳本的目標是基於非零元素爲R中每0個元素產生一個預測值。我從here得到了這個代碼,最初是用Python編寫的。

+2

你能描述一下這個代碼是幹什麼的,而不是要我們來解碼你的代碼? –

+0

(順便說一下,'endfor'和'endif'不在Matlab支持。) –

+0

取代ENDFOR和ENDIF與在Matlab –

回答

1

這看起來像的,並非所有的代碼進行矢量化的案例之一。儘管如此,你仍然可以比現在好一點。

[nr, nc] = size(R); 
P = rand(nr, K); 
Q = rand(K, nc); 

for i = 1:nr 
    for j = 1:nc 
     if R(i,j) > 0 
      eij = R(i,j) - P(i,:)*Q(:,j); 
      P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:)); 
      Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j)); 
     end 
    end 
end 
+0

它與矢量化內部循環好一點,但問題是,其他兩個循環的貢獻最大數量的環,具有大尺寸的R. –

1

由於對PQ的操作在本質上(迭代更新)串行我不認爲你可以做得更好。您可以在迴路中保存if

[nr, nc] - size(R); 
P = rand(nr, K); 
Q = rand(K, nc); 

[nzi nzj] = find(R > 0); 
for ii=1:numel(nzi) 
    i = nzi(ii); 
    j = nzj(ii); 
    eij = R(i,j) - P(i,:)*Q(:,j); 
    P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:)); 
    Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j)); 
end