我在MATLAB中基于欧几里德距离计算相似度矩阵。我的代码如下:
for i=1:N % M,N is the size of the matrix x for whose elements I am computing similarity matrix
for j=1:N
D(i,j) = sqrt(sum(x(:,i)-x(:,j)).^2)); % D is the similarity matrix
end
end
可以帮助优化这个=减少for循环,因为我的矩阵x
的维度为256x30000
。
非常感谢!
- 阿迪蒂亚
答案 0 :(得分:5)
在matlab中执行此操作的函数称为pdist。不幸的是,它很慢,并没有考虑Matlabs矢量化能力。
以下是我为项目编写的代码。让我知道你得到什么样的速度。
Qx=repmat(dot(x,x,2),1,size(x,1));
D=sqrt(Qx+Qx'-2*x*x');
请注意,这仅适用于您的数据点位于行中且尺寸为列的情况。例如,假设我使用x = rand(256,100000)在我的Mac上有256个数据点和100000个维度,上面的代码在大约半秒内产生256x256矩阵。
答案 1 :(得分:1)
可能有更好的方法,但我注意到的第一件事是你可以通过利用对称性D(i,j)==D(i,j)
您还可以使用函数norm(x(:,i)-x(:,j),2)
答案 2 :(得分:1)
我认为这就是你要找的东西。
D=zeros(N);
jIndx=repmat(1:N,N,1);iIndx=jIndx'; %'# fix SO's syntax highlighting
D(:)=sqrt(sum((x(iIndx(:),:)-x(jIndx(:),:)).^2,2));
在这里,我假设距离向量x
被初始化为NxM
数组,其中M
是系统的维数,N
是点数。因此,如果您的订购不同,则必须相应地进行更改。
答案 3 :(得分:0)
首先,你计算的数量是你需要的两倍,因为D将是对称的。您不需要单独计算(i,j)条目和(j,i)条目。将您的内部循环更改为for j=1:i
,并添加该循环的正文D(j,i)=D(i,j);
在那之后,代码的功能实际上没有多少冗余,所以你唯一需要改进的地方是将它并行化:如果你有并行计算工具箱,将你的外部循环转换为parfor
和在运行它之前,请说matlabpool(n)
,其中n
是要使用的线程数。