1
votes

I'm having trouble trying to visualize writing code for my problem because I'm so used to using pdist.

What I would like to do is to compute all non-absolute distances of a vector. so that my metric is just (x-y), where x and y are two values in my vector.

Typically, I would just do the following: squareform(pdist(X(:,i))

However this would return the EUCLIDEAN distance, not my distance. Is there a way to do this with pdist? Or maybe is there a different method?

Here's an example of what I'm trying to compute.

For X=[1,2,3;4,5,6;7,8,9]

For the FIRST matrix, the matrix of all differences of the elements in the first column, we should have

D=[(1-1), (1-4), (1-7); (4-1), (4-4), (4-7); (7-1), (7-4), (7-7)]

or

D=[0,-3,-6;3,0,-3;6,3,0]

1
I just fixed the distfun to do what you need. Sorry for the mistake earlier. It needed bsxfun and sum. Tested this time.chappjc
While it's useful to see that you can come up with your own metric, this isn't quite what I wanted..let me try to come up with an example. Thanks a ton for your help though.DaveNine
Also, I apologize for the confusion, I was mixed up on what I really wanted I think.DaveNine
No problem. For you example matrix of X=[1,2,3;4,5,6;7,8,9] giving the matrix D=[0,-3,-6;3,0,-3;6,3,0], I posted the loop to do that. note that you can't do this with pdist since this is not symmetric.chappjc

1 Answers

0
votes

I think you might want to use try "city block" metric of pdist:

pdist(X,'cityblock')

That's close but not quite what you need, so you can define your own distance function and use it as follows,

distfun = @(XI,XJ) sum(bsxfun(@minus,XI,XJ),2); % swap XI,XJ if needed
D = squareform(pdist(X,distfun))

Note that the non-absolute distances metric you want is not symmetric, but pdist only calculates one triangular half of the matrix and squareform forces it to be symmetric. If that's not what you want, try a loop:

>> X = [1 2 3; 4 5 6; 7 8 9];
>> D = zeros(size(X,1),size(X,1));
>> % for i=1:size(X,1), D(:,i)=sum(bsxfun(@minus,X,X(i,:)),2); end % my guess
>> % but to get the desired result, here's the appropriate loop:
>> for i=1:size(X,1), D(:,i) = sum(bsxfun(@minus,X,X(:,i)),1); end
>> disp(D)
     0    -3    -6
     3     0    -3
     6     3     0

EDIT: Solution for OP example data and desired matrix.