2

我有以下代码,其中包含 3 个迭代的 for 循环以创建上对角矩阵,我计划在大型数据集上执行多次,并希望尽可能提高计算效率。

data = magic(3);
n = size(data,1);
W = zeros(n,n);
for i = 1:n
    for j = i:n
        if i==j
            W(i,j)=0;
        else
            for k = 1:n
                temp(1,k) = (data(i,k)-data(j,k))^2;
                sumTemp = sumTemp + temp(1,k);
            end
          W(i,j)=sqrt(sumTemp);
        end
        temp = 0;
        sumTemp = 0;        
    end
end

答案应如下所示:

[0 6.4807 9.7980
0 0 6.4807
0 0 0]

我现在正在努力工作,但我想我会把它扔在那里,以防有人有任何建议可以节省我几个小时的摆弄时间。

4

2 回答 2

1

这是我目前拥有的帽子:

data = magic(3);
n = size(data,1);
W = zeros(n,n);
for i = 1:n
  for j = i+1:n
    W(i,j)= norm(data(i,:)-data(j,:))
    %W(i,j)= sqrt(sum((data(i,:)-data(j,:)).^2));      
  end
end

我做了什么:

  • vecorized 内循环
  • 删除了未使用的 www
  • 更改了第二个循环,从 i+1 开始,因为 i=j 没有做任何事情
  • 将 sqrt((ab).^2) 替换为 norm(ab)

现在是“完整”矢量化:

data = magic(3);
n = size(data,1);
W = zeros(n,n);
tri=triu(ones(n,n),1)>0;
[i,j]=find(tri);
W(tri)=arrayfun(@(i,j)norm(data(i,:)-data(j,:)),i,j)
于 2013-10-24T18:58:44.430 回答
1

这是一个简单的解决方案bsxfun

Wfull = sqrt(squeeze(sum(bsxfun(@minus,data,permute(data,[3 2 1])).^2,2)))
W = triu(Wfull)

使用这个 where datais N-by-D, whereN是点数并且D是维度。例如,

>> data = magic(3);
>> triu(sqrt(squeeze(sum(bsxfun(@minus,data,permute(data,[3 2 1])).^2,2))))
ans =
         0    6.4807    9.7980
         0         0    6.4807
         0         0         0
>> data = magic(5); data(:,end-1:end)=[]
data =
    17    24     1
    23     5     7
     4     6    13
    10    12    19
    11    18    25
>> triu(sqrt(squeeze(sum(bsxfun(@minus,data,permute(data,[3 2 1])).^2,2))))
ans =
         0   20.8087   25.2389   22.7376   25.4558
         0         0   19.9499   19.0263   25.2389
         0         0         0   10.3923   18.3576
         0         0         0         0    8.5440
         0         0         0         0         0
>> 
于 2013-10-24T20:23:35.500 回答