3

我正在尝试优化这段代码并摆脱实现的嵌套循环。我发现将矩阵应用于 pdist 函数有困难

例如,1+j // -1+j // -1+j // -1-j 是初始点,我试图通过最小距离方法检测 0.5+0.7j 到它所属的点。
任何帮助表示赞赏

function result = minDisDetector( newPoints, InitialPoints)
result = [];
for i=1:length(newPoints)
    minDistance = Inf;
    for j=1:length(InitialPoints)

        X = [real(newPoints(i)) imag(newPoints(i));real(InitialPoints(j)) imag(InitialPoints(j))];
        d = pdist(X,'euclidean');

        if d < minDistance
            minDistance = d;
            index = j;
        end
    end
    result = [result; InitialPoints(index)]; 
end     
end
4

3 回答 3

4

您可以使用中列出的高效欧几里德距离Speed-efficient classification in Matlab计算vectorized solution-

%// Setup the input vectors of real and imaginary into Mx2 & Nx2 arrays
A = [real(InitialPoints) imag(InitialPoints)];
Bt = [real(newPoints).' ; imag(newPoints).'];

%// Calculate squared euclidean distances. This is one of the vectorized
%// variations of performing efficient euclidean distance calculation using 
%// matrix multiplication linked earlier in this post.
dists = [A.^2 ones(size(A)) -2*A ]*[ones(size(Bt)) ; Bt.^2 ; Bt];

%// Find min index for each Bt & extract corresponding elements from InitialPoints
[~,min_idx] = min(dists,[],1);
result_vectorized = InitialPoints(min_idx);

newPoints使用as 400 x 1& InitialPointsas进行快速运行时测试1000 x 1

-------------------- With Original Approach
Elapsed time is 1.299187 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.000263 seconds.
于 2015-04-25T06:45:56.230 回答
0

解决方案非常简单。但是,您确实需要我的cartprod.m 函数来生成笛卡尔积。

首先为每个变量生成随机复数数据。

newPoints = exp(i * pi * rand(4,1));
InitialPoints = exp(i * pi * rand(100,1));

生成newPointsInitialPoints使用的笛卡尔积cartprod

C = cartprod(newPoints,InitialPoints);

第 1 列和第 2 列的差异是复数的距离。然后abs会找到距离的大小。

A = abs( C(:,1) - C(:,2) );

由于生成了笛卡尔积,因此它newPoints首先像这样排列变量:

 1     1
 2     1
 3     1
 4     1
 1     2
 2     2
 ...

我们需要reshape它并使用最小值min来找到最小距离。我们需要转置来找到每个 的最小值newPoints。否则,如果没有转置,我们将得到每个 的最小值InitialPoints

[m,i] = min( reshape( D, length(newPoints) , [] )' );

m给你最小值,同时i给你索引。如果您需要得到 minimum initialPoints,只需使用:

result = initialPoints( mod(b-1,length(initialPoints) + 1 );
于 2015-04-25T04:07:33.570 回答
0

可以通过使用欧几里得范数引入逐元素运算来消除嵌套循环,以计算距离,如下所示。

    result = zeros(1,length(newPoints)); % initialize result vector
    for i=1:length(newPoints)
        dist = abs(newPoints(i)-InitialPoints); %calculate distances
        [value, index] =  min(dist);
        result(i) = InitialPoints(index);
    end
于 2015-04-25T06:04:48.763 回答