1
votes

My matrix, datamat, has X-Y coordinates:

-80.26 40.11
-80.44 40.24
-80.29 40.49
-80.45 40.48
-80.55 40.90
-80.32 40.19

I have to calculate the distances for all pairs, the number of which is 6*5/2=15. The distance is simply sqrt((x_i-x_j)^2+(y_i-y_j)^2). How do I create a vector that stores those fifteen distance values? Thanks.

1
I've edited the answer about 20 times in the last 10 minutes :-) I think I've got something reasonably optimal now. Cheers. - Colin T Bowers
Are you calculating distances along the surface of the earth? If so the standard euclidian distance formula isn't accruate. Check out the this: mathworks.com/matlabcentral/fileexchange/5256-pos2dist - slayton
Thank you, all. As slayton suggests, I have to look at the "pos2dist" function. If I fail to use the function over the Colin's code, I will ask additional questions. - Bill TP
@slayton Nonsense. Only fools and heretics believe the earth's surface is curved... - Colin T Bowers

1 Answers

1
votes

Here are two possible solutions. The first uses a single loop, but is reasonably efficient within that construct. The second is loop-less, but requires the allocation of the extra matrix A. I've done some timed runs on both (see below), and the loop-less solution performs best.

%# Your matrix
M = [-80.26 40.11;
     -80.44 40.24;
     -80.29 40.49;
     -80.45 40.48;
     -80.55 40.90;
     -80.32 40.19];

%# Get the indices of all combinations
I1 = combnk(1:size(M, 1), 2);
T = size(I1, 1);

%# Loop-based solution
Soln1 = nan(T, 1);
for n = 1:T
    Soln1(n) = sqrt((M(I1(n, 1), 1) - M(I1(n, 2), 1))^2 + (M(I1(n, 1), 2) - M(I1(n, 2), 2))^2);
end 

%# Loop-less but requires the creation of matrix A
A = M(I1', :);
A = A(2:2:end, :) - A(1:2:end, :);
Soln2 = sqrt(sum(A.^2, 2));

For a random matrix M with 100 rows, I performed 1000 iterations over each solution. The results are:

Elapsed time is 0.440229 seconds. %# Loop based solution
Elapsed time is 0.168733 seconds. %# Loop-less solution

The loop-less solution appears to be the winner.