Home > Enterprise >  MATLAB Vectorised Pairwise Distance
MATLAB Vectorised Pairwise Distance

Time:04-20

I'm struggling to vectorise a function which performs a somewhat pairwise difference between two vectors x = 2xN and v = 2xM, for some arbitrary N, M. I have this to work when N = 1, although, I would like to vectorise this function to apply to inputs with N arbitrary.

Indeed, what I want this function to do is for each column of x find the normed difference between x(:,column) (a 2x1) and v (a 2xM).

A similar post is this, although I haven't been able to generalise it.

Current implementation

function mat = vecDiff(x,v)

diffVec = bsxfun(@minus, x, v);
mat = diffVec ./ vecnorm(diffVec);

Example

x =
     1
     1

v = 
     1     3     5
     2     4     6

----
vecDiff(x,v) =
         0   -0.5547   -0.6247
   -1.0000   -0.8321   -0.7809

CodePudding user response:

Your approach can be adapted as follows to suit your needs:

  1. Permute the dimensions of either x or v so that its number of columns becomes the third dimension. I'm choosing v in the code below.
  2. This lets you exploit implicit expansion (or equivalently bsxfun) to compute a 2×M×N array of differences, where M and N are the numbers of columns of x and v.
  3. Compute the vector-wise (2-)norm along the first dimension and use implicit expansion again to normalize this array:
x = [1 4 2 -1; 1 5 3 -2];
v = [1 3 5; 2 4 6];
diffVec = x - permute(v, [1 3 2]);
diffVec = diffVec./vecnorm(diffVec, 2, 1);

You may need to apply permute differently if you want the dimensions of the output in another order.

CodePudding user response:

Suppose your two input matrices are A (a 2 x N matrix) and B (a 2 x M matrix), where each column represents a different observation (note that this is not the traditional way to represent data).

Note that the output will be of the size N x M x 2. out = zeros(N, M, 2);

We can find the distance between them using the builtin function pdist2.

dists = pdist2(A.', B.'); (with the transpositions required for the orientation of the matrices)

To get the individual x and y distances, the easiest way I can think of is using repmat:

xdists = repmat(A(1,:).', 1, M) - repmat(B(1,:), N, 1);
ydists = repmat(A(2,:).', 1, M) - repmat(B(2,:), N, 1);

And we can then normalise this by the distances found earlier:

out(:,:,1) = xdists./dists; 
out(:,:,2) = ydists./dists;

This returns a matrix out where the elements at position (i, j, :) are the components of the normed distance between A(:,i) and B(:,j).

  • Related