wolffd@0: function Md = som_mdist(D,q,mask,Ne) wolffd@0: wolffd@0: % SOM_MDIST Mutual (or pairwise) distance matrix for the given data. wolffd@0: % wolffd@0: % Md = som_mdist(D,[q],[mask],[Ne]) wolffd@0: % wolffd@0: % Md = som_mdist(D); wolffd@0: % Md = som_mdist(D,Inf); wolffd@0: % Md = som_mdist(D,2,Ne); wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % D (matrix) size dlen x dim, the data set wolffd@0: % (struct) map or data struct wolffd@0: % [q] (scalar) distance norm, default = 2 wolffd@0: % [mask] (vector) size dim x 1, the weighting mask wolffd@0: % [Ne] (matrix) size dlen x dlen, sparse matrix wolffd@0: % indicating which distances should be wolffd@0: % calculated (ie. less than Infinite) wolffd@0: % wolffd@0: % See also PDIST. wolffd@0: wolffd@0: % Copyright (c) 2000 by Juha Vesanto wolffd@0: % Contributed to SOM Toolbox on XXX by Juha Vesanto wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta juuso 220800 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: % mask wolffd@0: if nargin<3, mask = []; end wolffd@0: wolffd@0: % the data wolffd@0: if isstruct(D), wolffd@0: switch D.type, wolffd@0: case 'som_map', if isempty(mask), mask = D.mask; end, D = D.codebook; wolffd@0: case 'som_data', D = D.data; wolffd@0: otherwise, error('Bad first argument'); wolffd@0: end wolffd@0: end wolffd@0: nans = sum(isnan(D),2); wolffd@0: if any(nans>0), wolffd@0: D(find(nans>0),:) = 0; wolffd@0: warning('Distances of vectors with NaNs are not calculated.'); wolffd@0: end wolffd@0: [dlen dim] = size(D); wolffd@0: wolffd@0: % distance norm wolffd@0: if nargin<2 | isempty(q) | isnan(q), q = 2; end wolffd@0: wolffd@0: % mask wolffd@0: if isempty(mask), mask = ones(dim,1); end wolffd@0: wolffd@0: % connections wolffd@0: if nargin<4, Ne = []; end wolffd@0: if ~isempty(Ne), wolffd@0: l = size(Ne,1); Ne([0:l-1]*l+[1:l]) = 1; % set diagonal elements = 1 wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: m = mask; wolffd@0: o = ones(dlen,1); wolffd@0: l = dlen; wolffd@0: Md = zeros(dlen); wolffd@0: calculate_all = isempty(Ne); wolffd@0: wolffd@0: if ~calculate_all, Md(Ne==0) = Inf; end wolffd@0: wolffd@0: for i=1:l-1, wolffd@0: j=(i+1):l; wolffd@0: if ~calculate_all, j=find(Ne(i,j))+i; end wolffd@0: C=D(j,:)-D(i*o(1:length(j)),:); wolffd@0: switch q, wolffd@0: case 1, Md(j,i)=abs(C)*m; wolffd@0: case 2, Md(j,i)=sqrt((C.^2)*m); wolffd@0: case Inf, Md(j,i)=max(diag(m)*abs(C),[],2); wolffd@0: otherwise, Md(j,i)=((abs(C).^q)*m).^(1/q); wolffd@0: end wolffd@0: Md(i,j) = Md(j,i)'; wolffd@0: end wolffd@0: wolffd@0: Md(find(nans>0),:) = NaN; wolffd@0: Md(:,find(nans>0)) = NaN; wolffd@0: wolffd@0: return; wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: