%DISTMAHA Mahalanobis distance % % D = DISTMAHA (A,U,G) % % INPUT % A Dataset % U Mean(s) (optional; default: estimate on classes in A) % G Covariance(s) (optional; default: estimate on classes in A) % % OUTPUT % D Mahalanobis distance matrix % % DESCRIPTION % Computes the M*N Mahanalobis distance matrix of all vectors in M*K dataset % A to an N*K dataset of points U, using the covariance matrix or matrices % G. G should be either be one K*K matrix, or a K*K*N matrix containing a % covariance matrix for each point in U. % % When U and G are not specified, it estimates the C*C Mahalanobis distance % matrix between all classes in A: the distance between the means, % relative to the average per-class covariance matrix. % % SEE ALSO (PRTools Guide) % DATASETS, DISTM, PROXM, MEANCOV % Copyright: R.P.W. Duin, r.p.w.duin@37steps.com % Faculty EWI, Delft University of Technology % P.O. Box 5031, 2600 GA Delft, The Netherlands % $Id: distmaha.m,v 1.4 2010/02/08 15:31:48 duin Exp $ function d = distmaha (a,u,g) [m,k,c] = getsize(a); a = testdatasize(a); a = testdatasize(a,'features'); if (nargin == 1) % Calculate Mahalanobis distance matrix between classes in dataset: % the distance matrix between the class means, sphered using the % average covariance matrix of the per-class centered data. u = zeros(c,k); for i = 1:c J = findnlab(a,i); if (~isempty(J)) % Mean of class I. u(i,:) = mean(a(J,:),1); % Remove class mean, for later covariance calculation. a(J,:) = a(J,:) - repmat(+u(i,:),length(J),1); end end % Sphere means and calculate distance matrix. [E,V] = preig(covm(a)); u = u*E*sqrt(prinv(V)); d = distm(u); elseif (nargin == 2) % Calculate Euclidean distance between data and means. prwarning(4,'covariance matrix not specified, assuming G = I'); d = distm(a,u); elseif (nargin == 3) % Calculate distance between A and distributions specified by U and G. % Check arguments. [kg1,kg2,cg] = size(g); [cu,ku] = size(u); if any([kg1,kg2,ku] ~= k) | (cu ~= cg & cg ~= 1) error('sizes of mean(s) and covariance(s) do not match') end % Get labels of means if present, or assign labels 1:N. These are % only used in the construction of the dataset D. if (isa(u,'prdataset')), labels = getlab(u); else, labels = [1:cu]'; end % If there is only one covariance matrix, invert it here. if (cg == 1), g_inv = prinv(g); end d = zeros(m,cu); for j = 1:cu % If each mean has its own covariance matrix, invert it here. if (cg ~= 1), g_inv = prinv(g(:,:,j)); end % And calculate the standard Mahalanobis distance. d(:,j) = sum((a-repmat(+u(j,:),m,1))'.*(g_inv*(a-repmat(+u(j,:),m,1))'),1)'; end % Construct the distance matrix dataset. d = setdata(a,d,labels); d = setname(d,'Maha Dist'); else error('incorrect number of arguments') end return