MATLAB中复杂向量的快速有效分类

MATLAB中复杂向量的快速有效分类,matlab,optimization,vectorization,nested-loops,pdist,Matlab,Optimization,Vectorization,Nested Loops,Pdist,我试图优化这段代码,并摆脱实现的嵌套循环。我发现将矩阵应用于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(Initia

我试图优化这段代码,并摆脱实现的嵌套循环。我发现将矩阵应用于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
function result=minDisDetector(newPoints,InitialPoints)
结果=[];
对于i=1:长度(新点)
心灵距离=Inf;
对于j=1:长度(初始点)
X=[real(newPoints(i))imag(newPoints(i));real(InitialPoints(j))imag(InitialPoints(j))];
d=pdist(X,'欧几里德');
如果d
解决方案非常简单。但是,您确实需要我来生成笛卡尔积

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

newPoints = exp(i * pi * rand(4,1));
InitialPoints = exp(i * pi * rand(100,1));
使用
cartprod
生成
newPoints
InitialPoints
的笛卡尔积

C = cartprod(newPoints,InitialPoints);
第1列和第2列的差异是复数形式的距离。然后,
abs
将找到距离的大小

A = abs( C(:,1) - C(:,2) );
因为笛卡尔积是生成的,所以它首先像这样排列
新点
变量:

 1     1
 2     1
 3     1
 4     1
 1     2
 2     2
 ...
我们需要对它进行
整形
并使用
min
获得最小距离。我们需要转置来找到每个
新点的最小值。否则,如果没有转置,我们将获得每个
初始点的最小值

[m,i] = min( reshape( D, length(newPoints) , [] )' );
m
提供最小值,而
i
提供索引。如果需要获得最小的
初始点
,只需使用:

result = initialPoints( mod(b-1,length(initialPoints) + 1 );

可以通过使用欧几里德范数引入元素操作来消除嵌套循环,以计算如下所示的距离

    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

对于矢量化解决方案,可以使用中列出的高效欧几里德距离计算-

%// 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);

使用
新点作为
400 x 1
初始点作为
1000 x 1
进行快速运行时测试:

-------------------- With Original Approach
Elapsed time is 1.299187 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.000263 seconds.

InitialPoints
newPoints
的大小是多少?每个集合中任意两个点之间的最小距离?你可以通过矢量化消除一个循环:我有一个更好的方法,但它取决于点的尺寸。点是复杂的点大小为1--4,8,16,64个新点的大小很大,但此解决方案本质上是@brodroll的参考。我的引用使用1
cellfun
循环来生成笛卡尔积,而不使用任何显式循环。此外,如果我没有弄错的话,
abs
已经计算了幅值,这意味着在您的解决方案中实际上不需要
^
sqrt
总和。这提醒了我,我需要为代码添加一个重塑:3@krisdestruction谢谢,我不知道
abs
返回复数的模。可能不是最快的解决方案,但我确实认为这个实现是简单和简洁的。简明将是Divakar的答案看起来正确而且非常快速+1也许您可以包括每个操作的一些功能?另外,您是否有理由执行
[real(newPoints)。';imag(newPoints)。]而不是
[real(newPoints)imag(newPoints)]?@我想应该是一样的。添加了一些注释,但要了解更多信息,我认为该链接必须是实际的参考,因为它有许多详细信息需要真正解释其背后的工作原理。@确切地说,基本上是平方距离。@ousamakanawati如果这是最适合您的解决方案,请不要忘记接受它。谢谢