


PAIRDIST Computes a pairwise Euclidean distance matrix.
DISTS = PAIRDIST(X) returns a symmetric positive definite matrix DISTS
such that the DISTS(i,j) is the Euclidean distance between the vectors
X(i,:) and X(j,:). X must be a real-valued matrix.
DISTS = PAIRDIST(X,Y), where X is an M x D matrix and Y is N x D,
returns an M x N matrix DISTS such that DISTS(i,j) is the Euclidean
distance between X(i,:) and Y(j,:). X and Y must be real-valued.
DISTS = PAIRDIST(X,Y,'safe') indicates that it is possible for
the ith row of X to be identical to the jth row of Y. This uses a
slower algorithm, but guarantees that DISTS(i,j) == 0 in these cases.
The algorithm used by default utilizes the expansion
(x-y)'(x-y) == x'x + y'y - 2x'y,
because the right hand side uses fewer floating point operations.
However, round-off error with this technique can produce small but
non-zero (even negative) values when x == y. For the special case
of PAIRDIST(X), it is not necessary to specify the 'safe' flag if the
only potential zero distances are those along the diagonal of DISTS.
DISTS = PAIRDIST(..., 'nosqrt') returns DISTS as above, except that
the squared distances are returned. The algorithm to compute the
distances finds the squared distances in an intermediate step, so this
calculation is faster than returning the Euclidean distance proper.
DISTS = PAIRDIST(..., 'reuse') attempts to reuse memory from an
earlier call to PAIRDIST. When DISTS is a large matrix, the resulting
time savings can be significant. However, this option can result in
unexpected Matlab behavior for the returned variable DISTS. In
particular, clearing DISTS in the calling workspace will not release
the memory associated with that variable; to release the memory, you
must run the command 'clear functions'. Further, DISTS may be
unexpectedly modified by later calls to PAIRDIST. For example,
A = PAIRDIST(X1,Y1); % Look at the value of A(1,2)
B = PAIRDIST(X2,Y2,'reuse'); % The value of A(1,2) will change
% here even though A was not assigned
If this behavior is undesirable, make a copy of the returned distance
matrix before calling PAIRDIST again.

0001 function dists = pairdist(X,varargin) 0002 %PAIRDIST Computes a pairwise Euclidean distance matrix. 0003 % DISTS = PAIRDIST(X) returns a symmetric positive definite matrix DISTS 0004 % such that the DISTS(i,j) is the Euclidean distance between the vectors 0005 % X(i,:) and X(j,:). X must be a real-valued matrix. 0006 % 0007 % DISTS = PAIRDIST(X,Y), where X is an M x D matrix and Y is N x D, 0008 % returns an M x N matrix DISTS such that DISTS(i,j) is the Euclidean 0009 % distance between X(i,:) and Y(j,:). X and Y must be real-valued. 0010 % 0011 % DISTS = PAIRDIST(X,Y,'safe') indicates that it is possible for 0012 % the ith row of X to be identical to the jth row of Y. This uses a 0013 % slower algorithm, but guarantees that DISTS(i,j) == 0 in these cases. 0014 % The algorithm used by default utilizes the expansion 0015 % (x-y)'(x-y) == x'x + y'y - 2x'y, 0016 % because the right hand side uses fewer floating point operations. 0017 % However, round-off error with this technique can produce small but 0018 % non-zero (even negative) values when x == y. For the special case 0019 % of PAIRDIST(X), it is not necessary to specify the 'safe' flag if the 0020 % only potential zero distances are those along the diagonal of DISTS. 0021 % 0022 % DISTS = PAIRDIST(..., 'nosqrt') returns DISTS as above, except that 0023 % the squared distances are returned. The algorithm to compute the 0024 % distances finds the squared distances in an intermediate step, so this 0025 % calculation is faster than returning the Euclidean distance proper. 0026 % 0027 % DISTS = PAIRDIST(..., 'reuse') attempts to reuse memory from an 0028 % earlier call to PAIRDIST. When DISTS is a large matrix, the resulting 0029 % time savings can be significant. However, this option can result in 0030 % unexpected Matlab behavior for the returned variable DISTS. In 0031 % particular, clearing DISTS in the calling workspace will not release 0032 % the memory associated with that variable; to release the memory, you 0033 % must run the command 'clear functions'. Further, DISTS may be 0034 % unexpectedly modified by later calls to PAIRDIST. For example, 0035 % 0036 % A = PAIRDIST(X1,Y1); % Look at the value of A(1,2) 0037 % B = PAIRDIST(X2,Y2,'reuse'); % The value of A(1,2) will change 0038 % % here even though A was not assigned 0039 % 0040 % If this behavior is undesirable, make a copy of the returned distance 0041 % matrix before calling PAIRDIST again. 0042 0043 %%%%%%%%%%%%%%%%%%%%%%%%%%%% Parse Inputs %%%%%%%%%%%%%%%%%%%%%%%%%%%% 0044 Y = []; takeSqrt = 1; reuseMem = 0; useSafe = 0; 0045 while (length(varargin) > 0) 0046 tail = varargin{end}; varargin = varargin(1:end-1); % chomp last arg 0047 if (ischar(tail) && strcmpi(tail, 'nosqrt')) 0048 takeSqrt = 0; 0049 elseif (ischar(tail) && strcmpi(tail, 'reuse')), 0050 reuseMem = 1; 0051 elseif (ischar(tail) && strcmpi(tail, 'safe')), 0052 useSafe = 1; 0053 elseif (isa(tail, 'double')) 0054 Y = tail; break; % this should be the leftmost argument 0055 else 0056 error('Unknown argument.'); 0057 end 0058 end 0059 if (length(varargin) > 0), error('Too many arguments.'); end; 0060 if (isempty(Y)), Y = X; end; % self-distance computation 0061 0062 [M,D1] = size(X); 0063 [N,D2] = size(Y); 0064 if (D1~=D2), error('X and Y must have the same number of columns.'); end; 0065 if (~isreal(X) || ~isreal(Y) || ~isa(X,'double') || ~isa(Y,'double')) 0066 error('Input matrices must be real-valued matrices of type double.'); 0067 end 0068 0069 %%%%%%%%%%%%%%%%%%%%%%%%%%% Do the Computation %%%%%%%%%%%%%%%%%%%%%%%%%% 0070 dists = CORE_pairdist(X,Y,takeSqrt,reuseMem,useSafe);