从矩阵中的每一行减去行向量

时间:2014-05-02 23:05:18

标签: matlab matrix octave vectorization

我在尝试的任务中尝试了一些东西。我想从矩阵的每一行中减去行向量(然后对其进行进一步的计算)。 我有一个矩阵" X"尺寸m X n和另一个尺寸K x n的质心。我尝试了两个变种,

function idx = findClosestCentroids(X, centroids)
K = size(centroids, 1);
m=size(X,1);
n=size(X,2);
idx = zeros(size(X,1), 1);

% ====================== CODE ======================
% Instructions: Go over every example, find its closest centroid, and store
%               the index inside idx at the appropriate location.
%               Concretely, idx(i) should contain the index of the centroid
%               closest to example i. Hence, it should be a value in the 
%               range 1..K


%This Doesnt Work
% for i=1:m
        % temp=ones(size(centroids))*diag(X(i))-centroids;
        % temp=temp.^2;
        % [x,y]=min(sum(temp,2));
        % idx(i)=y;
% endfor


%This works!
for i=1:m
    mini=1e10;
    minin=-1;
    for j=1:K
        temp=X(i,:)-centroids(j,:);
        temp=temp.^2;
        sumx=sum(temp);
        if (sumx<mini)
            mini=sumx;
            minin=j;
        endif
    endfor
    idx(i)=minin;
endfor

% =============================================================

end

第一个有效,而第二个有效,即使是acc。我试过的,第二个是第一个的矢量化版本。请引导我完成矢量化。

2 个答案:

答案 0 :(得分:2)

如果您正在寻找MATLAB实现,请认为这可能满足您的矢量化需求 -

%%// Spread out centroids to the third dimension so that the singleton
%%// second dimension thus created could be used with bsxfun for expansion in
%%// that dimension
centroids1 = permute(centroids,[3 2 1]);

%%// Perform the much-needed subtraction 
t1 = bsxfun(@minus,X,centroids1)

%%// Perform element-wise squaring and then min-finding as required too
t2 = t1.^2
t3 = sum(t2,2)

%%// Since the expansion resulted in data in third dimension, min-finding
%%// must be along it
[mini_array,idx] = min(t3,[],3)

另外,请允许我建议在循环代码中进行编辑。如果您有兴趣在每个外部循环迭代结束时存储最小值,那么您也可以使用类似min_array(i) = mini的内容存储它,就像存储索引时一样。

答案 1 :(得分:0)

比其他答案更少并行化,但更容易阅读:

for i = 1:size(X,1)
  % z = centroids .- X(i, :); // Only Octave compatible
  z = bsxfun(@minus, centroids, X(i, :));
  zy = sum(z.^2, 2);
  [~, idx(i)] = min(zy);
end