如何为这个matlab做矢量化;for loop";?

如何为这个matlab做矢量化;for loop";?,matlab,vectorization,Matlab,Vectorization,我有一些matlab代码如下,构建KNN相似权重矩阵 [D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1); D = D < threshold; W = zeros(n, n); for i=1:size(I,2) W(I(:,i), i) = D(:,i); W(i, I(:,i)) = D(:,i)'; end 但未能获得正确的值 我在这里添加了测试用例: n = 5; D = [ 1 1

我有一些matlab代码如下,构建KNN相似权重矩阵

[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
D = D < threshold;
W = zeros(n, n);
for i=1:size(I,2)
    W(I(:,i), i) = D(:,i);
    W(i, I(:,i)) = D(:,i)';
end
但未能获得正确的值

我在这里添加了测试用例:

n = 5;

D = [
 1     1     1     1     1
 0     1     1     1     1
 0     0     0     0     0
];

I = [
 1     2     3     4     5
 5     4     5     2     3
 3     1     1     1     1
];

有一些未定义的变量使得很难检查它在做什么,但这应该与for循环相同:

D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
D = D < threshold;
W = zeros(n);

% set the diagonal values
W(sub2ind(size(X), I(1, :), I(1, :))) = D(1,:);
% set the other values
W(sub2ind(size(W), I(2, :), 1:size(I, 2))) = D(2, :);
W(sub2ind(size(W), 1:size(I, 2), I(2, :))) = D(2, :).';
D,I]=pdist2(X,X,'squaredeuclidean','minister',k+1);
D=D<阈值;
W=零(n);
%设置对角线值
W(sub2ind(size(X),I(1,:),I(1,:)=D(1,:);
%设置其他值
W(sub2ind(size(W),I(2,:),1:size(I,2))=D(2,:);
W(sub2ind(size(W),1:size(I,2),I(2,:))=D(2,:);

我拆分了方向,它现在可以与您的测试用例一起使用。

有一些未定义的变量使得很难检查它在做什么,但这应该与for循环的作用相同:

D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
D = D < threshold;
W = zeros(n);

% set the diagonal values
W(sub2ind(size(X), I(1, :), I(1, :))) = D(1,:);
% set the other values
W(sub2ind(size(W), I(2, :), 1:size(I, 2))) = D(2, :);
W(sub2ind(size(W), 1:size(I, 2), I(2, :))) = D(2, :).';
D,I]=pdist2(X,X,'squaredeuclidean','minister',k+1);
D=D<阈值;
W=零(n);
%设置对角线值
W(sub2ind(size(X),I(1,:),I(1,:)=D(1,:);
%设置其他值
W(sub2ind(size(W),I(2,:),1:size(I,2))=D(2,:);
W(sub2ind(size(W),1:size(I,2),I(2,:))=D(2,:);

我分割了方向,它现在适用于您的测试用例。

您可以使用线性索引进行一些裁剪,但是如果您的矩阵很大,那么您应该只使用
D
的非零分量。以下复制了D的所有值

W = zeros(n);
W(reshape(sub2ind([n,n],I,[1;1;1]*[1:n]),1,[])) = reshape(D,1,[]);

您可以使用线性索引进行一些裁剪,但是如果您的矩阵很大,那么您应该只使用
D
的非零分量。以下复制了D的所有值

W = zeros(n);
W(reshape(sub2ind([n,n],I,[1;1;1]*[1:n]),1,[])) = reshape(D,1,[]);
一种可能的解决办法:

idx1 = reshape(1:n*n,n,n).';
idx2 = bsxfun(@plus,I,0:n:n*size(I,2)-1);

W=zeros(n,n);
W(idx2) = D;
W(idx1(idx2)) = D;
这里假设您重复地想要计算
D
I
,所以只计算
idx
一次并重复使用它

n = 5;
idx1 = reshape(1:n*n,n,n).';
%for k = 1 : 1000
    %[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
    %D = D < threshold;
    idx2 = bsxfun(@plus,I,0:n:n*size(I,2)-1);   
    W=zeros(n,n);
    W(idx2) = D;
    W(idx1(idx2)) = D;
%end
一种可能的解决办法:

idx1 = reshape(1:n*n,n,n).';
idx2 = bsxfun(@plus,I,0:n:n*size(I,2)-1);

W=zeros(n,n);
W(idx2) = D;
W(idx1(idx2)) = D;
这里假设您重复地想要计算
D
I
,所以只计算
idx
一次并重复使用它

n = 5;
idx1 = reshape(1:n*n,n,n).';
%for k = 1 : 1000
    %[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
    %D = D < threshold;
    idx2 = bsxfun(@plus,I,0:n:n*size(I,2)-1);   
    W=zeros(n,n);
    W(idx2) = D;
    W(idx1(idx2)) = D;
%end

谢谢你的帮助。我已经尝试了你的代码,并将其与origin循环进行了比较。W的一些条目不一样。谢谢您的帮助。我已经尝试了你的代码,并将其与origin循环进行了比较。W的某些条目不相同。