【问题标题】:Matlab: how can I perform row operations without brute-force for loop?Matlab:如何在没有暴力循环的情况下执行行操作?
【发布时间】:2016-07-13 11:39:40
【问题描述】:

我需要做这样的功能:

N1 = size(X,1);
N2 = size(Xtrain,1);
Dist = zeros(N1,N2);

    for i=1:N1
        for j=1:N2
            Dist(i,j)=D-sum(X(i,:)==Xtrain(j,:));
        end
    end

(X和Xtrain是稀疏逻辑矩阵)

它运行良好并通过了测试,但我认为它不是非常理想且编写良好的解决方案。

如何使用一些内置的 Matlab 函数来改进该函数?我是 Matlab 的新手,所以我不知道是否真的有机会让它变得更好。

【问题讨论】:

  • 是的,我知道 pdist2(X,Xtrain,'hamming').*D 工作正常,但我想要别的东西。我正在学习 Matlab,想知道是否可以用更好的方法替换 for 循环语句。
  • 你可以把它写成一个for循环,每次迭代向量化整个列。您甚至可以在没有任何循环的情况下进行计算,但这会涉及多次重复数据会消耗更多的内存。但同样,pdist2 有什么问题?
  • 如何将它作为一个 for 循环迭代来完成?我已经尝试过了,但无法实现。 pdist2 没有任何问题,最终我可能会使用该功能来完成。我只是想了解 Matlab 中的矩阵和向量运算,我想知道我该怎么做,例如。使用矢量化操作(如您所述)。
  • 在下面查看我的几个实现的答案

标签: matlab for-loop matrix sum sparse-matrix


【解决方案1】:

您想了解向量化,这里有一些代码来研究比较这种成对距离的不同实现。

首先我们构建两个二进制矩阵作为输入(其中每一行都是一个实例):

m = 5;
n = 4;
p = 3;
A = double(rand(m,p) > 0.5);
B = double(rand(n,p) > 0.5);

1。对每对实例进行双循环

D0 = zeros(m,n);
for i=1:m
    for j=1:n
        D0(i,j) = sum(A(i,:) ~= B(j,:)) / p;
    end
end

2。 PDIST2

D1 = pdist2(A, B, 'hamming');

3。针对所有其他实例对每个实例进行单循环

D2 = zeros(m,n);
for i=1:n
    D2(:,i) = sum(bsxfun(@ne, A, B(i,:)), 2) ./ p;
end

4。使用网格索引进行矢量化,全部针对所有

D3 = zeros(m,n);
[x,y] = ndgrid(1:m,1:n);
D3(:) = sum(A(x(:),:) ~= B(y(:),:), 2) ./ p;

5。三维矢量化,全部反对所有

D4 = sum(bsxfun(@ne, A, reshape(B.',[1 p n])), 2) ./ p;
D4 = permute(D4, [1 3 2]);

最后我们比较所有方法是否相等

assert(isequal(D0,D1,D2,D3,D4))

【讨论】:

  • 注意向量化方法会创建大型中间数组,如果输入矩阵足够大,可能会引发内存不足错误。就空间而言,它的顺序是m*n*p。单循环有m*n 空间,而双循环只占用m 空间(真的是min(m,n),因为我们可以遍历行或列,无论是更小的空间)
  • 注意:其他距离函数也可以这样做。这是欧几里得距离:stackoverflow.com/q/7696734/97160
  • 谢谢!我将分析所有这些解决方案,
猜你喜欢
  • 2015-02-12
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多