



CORE_PAIRDIST Core computational routine for PAIRDIST.
D = CORE_PAIRDIST(X,Y,TAKESQRT,REUSEMEM),
given an M x P matrix X and an N x P matrix Y, returns the M x N
matrix D such that D(i,j) = || X(i,:) - Y(j,:) ||, where ||.|| means
the Euclidean 2-norm. The next 2 values are required (0 or 1) flags
such that:
TAKESQRT - If 0, D(i,j) = ||X(i,:)-Y(j,:)||^2 rather than the
magnitude of the distance.
REUSE - If 1 and if M and N are the same as (or smaller than)
their values in the previous call to this function,
attempt to reuse memory rather than reallocating space
for D. **See WARNING below**
WARNING: Setting the REUSE flag is not guaranteed to have an effect.
If it does work, setting REUSE to 1 can result in unexpected behavior
for the returned Matlab variable D. First, clearing D will not free
the memory associated with it (i.e., the memory will not become
available for other Matlab variables). To fully free this memory
without restarting Matlab, type "clear CORE_pairdist". Second,
CORE_PAIRDIST retains a handle to D and can alter its contents on
later calls, potentially unexpectedly. See the help for PAIRDIST for
an example.
CONDITIONS
----------
X and Y must be REAL 2-D arrays of type DOUBLE.
X and Y must have the same number of columns.
TAKESQRT and REUSEMEM must each be either 0 or 1 and of type DOUBLE.

0001 function D = CORE_pairdist(X,Y,takesqrt,reuse,useSafe) 0002 %CORE_PAIRDIST Core computational routine for PAIRDIST. 0003 % D = CORE_PAIRDIST(X,Y,TAKESQRT,REUSEMEM), 0004 % given an M x P matrix X and an N x P matrix Y, returns the M x N 0005 % matrix D such that D(i,j) = || X(i,:) - Y(j,:) ||, where ||.|| means 0006 % the Euclidean 2-norm. The next 2 values are required (0 or 1) flags 0007 % such that: 0008 % TAKESQRT - If 0, D(i,j) = ||X(i,:)-Y(j,:)||^2 rather than the 0009 % magnitude of the distance. 0010 % REUSE - If 1 and if M and N are the same as (or smaller than) 0011 % their values in the previous call to this function, 0012 % attempt to reuse memory rather than reallocating space 0013 % for D. **See WARNING below** 0014 % 0015 % WARNING: Setting the REUSE flag is not guaranteed to have an effect. 0016 % If it does work, setting REUSE to 1 can result in unexpected behavior 0017 % for the returned Matlab variable D. First, clearing D will not free 0018 % the memory associated with it (i.e., the memory will not become 0019 % available for other Matlab variables). To fully free this memory 0020 % without restarting Matlab, type "clear CORE_pairdist". Second, 0021 % CORE_PAIRDIST retains a handle to D and can alter its contents on 0022 % later calls, potentially unexpectedly. See the help for PAIRDIST for 0023 % an example. 0024 % 0025 % CONDITIONS 0026 % ---------- 0027 % X and Y must be REAL 2-D arrays of type DOUBLE. 0028 % X and Y must have the same number of columns. 0029 % TAKESQRT and REUSEMEM must each be either 0 or 1 and of type DOUBLE. 0030 0031 %%%%%%%%%%%%%%%%%%%%%%%%%%% Prep inputs %%%%%%%%%%%%%%%%%%%%%%%%%% 0032 normsqrX = sum(X.^2,2); 0033 normsqrY = sum(Y.^2,2); 0034 0035 [N,P1] = size(X); % not going to check P1==P2 out of stubbornness -- 0036 [M,P2] = size(Y); % CORE_ functions are described as not doing error checking 0037 0038 0039 %%%%%%%%%%%%%%%%%%%%%%%%% Distance Calculation %%%%%%%%%%%%%%%%%%%%%%% 0040 % dist(x,y)^2 = (x-y)'(x-y) = x'x + y'y - 2 x'y, 0041 % Note that we do this in two steps for memory efficiency (i.e., computing 0042 % z = x'x + y'y - 2x'y all at once requires 4 matrices of size z to be in 0043 % memory at the same time, while breaking it up only requires 2 matrices at 0044 % any given time. Still inefficient, i know . . . thats why there's a MEX 0045 % alternative). 0046 D = [normsqrX * ones(1,M)]; 0047 D = D + [ones(N,1) * normsqrY']; 0048 D = D - (2 * X * Y'); 0049 0050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% Postprocess %%%%%%%%%%%%%%%%%%%%%%%%%%%% 0051 if (takesqrt), D = sqrt(D); end; 0052 0053 0054 return; 0055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% TEST CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0058 % %%% (requires the Statistics toolbox 0059 % X = randn(1000,10); 0060 % tic; D1 = CORE_pairdist(X,X,1,0); t(1) = toc; 0061 % tic; D2 = squareform(pdist(X,'euclidean')); t(2) = toc; 0062 % printf('\nCORE_pairdist took %5.3f sec and equivalent native code took %5.3f sec.', t(1), t(2)); 0063 % printf('The RMS error between the two results was %6.4g.\n', sqrt(mean((D1(:)-D2(:)).^2)));