I am stuck at vectorizing this tricky loop in MATLAB/Octave:
在MATLAB/Octave中,我被困在矢量化這個復雜的循環中:
[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
The code tries to factorize R into P and Q, and approaching the nearest P and Q with an update rule. For example, let 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, alpha=0.01 and beta=0.015. In my real case, I will use a huge sparse matrix R (that's why I need vectorization), and K remain small (less than 10). The goal of the whole script is producing a prediction value for every 0 elements in R, based on the non zero elements. I got this code from here, originally written in Python.
代碼試圖將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元素生成一個預測值。我從這里得到了這個代碼,最初是用Python編寫的。
2 个解决方案
#1
1
This looks like one of those cases that not all code can be vectorized. Still, you can make it a bit better than it is now.
這看起來像那些不是所有代碼都可以量化的例子。不過,你可以讓它比現在好一點。
[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
#2
1
Since the operations on P and Q are serial in nature (iterative updates) I do not think you can do much better. You can save the if in the loop:
由於P和Q的操作在本質上是串行的(迭代更新),所以我認為您不能做得更好。您可以在循環中保存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