1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- % sq_dist - a function to compute a matrix of all pairwise squared distances
- % between two sets of vectors, stored in the columns of the two matrices, a
- % (of size D by n) and b (of size D by m). If only a single argument is given
- % or the second matrix is empty, the missing matrix is taken to be identical
- % to the first.
- %
- % Usage: C = sq_dist(a, b)
- % or: C = sq_dist(a) or equiv.: C = sq_dist(a, [])
- %
- % Where a is of size Dxn, b is of size Dxm (or empty), C is of size nxm.
- %
- % Copyright (c) by Carl Edward Rasmussen and Hannes Nickisch, 2010-12-13.
- function C = sq_dist(a, b)
- % borrowed from gpml-toolbox of Rasmussen and Nikkisch
- % see http://www.gaussianprocess.org/gpml/code/matlab/doc/
- if nargin<1 || nargin>3 || nargout>1, error('Wrong number of arguments.'); end
- bsx = exist('bsxfun','builtin'); % since Matlab R2007a 7.4.0 and Octave 3.0
- if ~bsx, bsx = exist('bsxfun'); end % bsxfun is not yes "builtin" in Octave
- [D, n] = size(a);
- % Computation of a^2 - 2*a*b + b^2 is less stable than (a-b)^2 because numerical
- % precision can be lost when both a and b have very large absolute value and the
- % same sign. For that reason, we subtract the mean from the data beforehand to
- % stabilise the computations. This is OK because the squared error is
- % independent of the mean.
- if nargin==1 % subtract mean
- mu = mean(a,2);
- if bsx
- a = bsxfun(@minus,a,mu);
- else
- a = a - repmat(mu,1,size(a,2));
- end
- b = a; m = n;
- else
- [d, m] = size(b);
- if d ~= D, error('Error: column lengths must agree.'); end
- mu = (m/(n+m))*mean(b,2) + (n/(n+m))*mean(a,2);
- if bsx
- a = bsxfun(@minus,a,mu); b = bsxfun(@minus,b,mu);
- else
- a = a - repmat(mu,1,n); b = b - repmat(mu,1,m);
- end
- end
- if bsx % compute squared distances
- C = bsxfun(@plus,sum(a.*a,1)',bsxfun(@minus,sum(b.*b,1),2*a'*b));
- else
- C = repmat(sum(a.*a,1)',1,m) + repmat(sum(b.*b,1),n,1) - 2*a'*b;
- end
- C = max(C,0); % numerical noise can cause C to negative i.e. C > -1e-14
|