High speed classification for complex vectors in MATLAB

I am trying to optimize this piece of code and get rid of the nested loop. I am at a loss to apply matrix to pdist function

For example, 1 + j // - 1 + j // - 1 + j // - 1-j are starting points and I am trying to detect 0.5 + 0.7j with the point it refers to using the minimum distance method.
any help is appreciated

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

      

+3


source to share


3 answers


You can use the efficient calculation of Euclidean distances given in for - 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);

      




Quick runtime tests with newPoints

how 400 x 1

and InitialPoints

how 1000 x 1

:

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

      

+4


source


The solution is very simple. However, you need my cartprod.m function to create a cartesian product.

First, generate random complex data for each variable.

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

      

Produce the Cartesian product newPoints

and InitialPoints

with cartprod

.

C = cartprod(newPoints,InitialPoints);

      

The difference between column 1 and column 2 is the distance in complex numbers. Then he abs

will find the distance.

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

      



Since the Cartesian product is generated so that it first rearranges the variables newPoints

as follows:

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

      

We need reshape

it and get the minimum, using min

to find the minimum distance. We need to transpose to find the min for each newPoints

. Otherwise, without transposition, we get min for each InitialPoints

.

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

      

m

gives you min and i

gives you the indices. If you need to get the minimum InitialPoints

, just use:

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

      

0


source


You can eliminate the nested loop by introducing rudimentary operations using the Euclidean norm to calculate the distance, as shown below.

    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

      

0


source







All Articles