wolffd@0
|
1 function Md = som_mdist(D,q,mask,Ne)
|
wolffd@0
|
2
|
wolffd@0
|
3 % SOM_MDIST Mutual (or pairwise) distance matrix for the given data.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % Md = som_mdist(D,[q],[mask],[Ne])
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % Md = som_mdist(D);
|
wolffd@0
|
8 % Md = som_mdist(D,Inf);
|
wolffd@0
|
9 % Md = som_mdist(D,2,Ne);
|
wolffd@0
|
10 %
|
wolffd@0
|
11 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
12 % D (matrix) size dlen x dim, the data set
|
wolffd@0
|
13 % (struct) map or data struct
|
wolffd@0
|
14 % [q] (scalar) distance norm, default = 2
|
wolffd@0
|
15 % [mask] (vector) size dim x 1, the weighting mask
|
wolffd@0
|
16 % [Ne] (matrix) size dlen x dlen, sparse matrix
|
wolffd@0
|
17 % indicating which distances should be
|
wolffd@0
|
18 % calculated (ie. less than Infinite)
|
wolffd@0
|
19 %
|
wolffd@0
|
20 % See also PDIST.
|
wolffd@0
|
21
|
wolffd@0
|
22 % Copyright (c) 2000 by Juha Vesanto
|
wolffd@0
|
23 % Contributed to SOM Toolbox on XXX by Juha Vesanto
|
wolffd@0
|
24 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
25
|
wolffd@0
|
26 % Version 2.0beta juuso 220800
|
wolffd@0
|
27
|
wolffd@0
|
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
29
|
wolffd@0
|
30 % mask
|
wolffd@0
|
31 if nargin<3, mask = []; end
|
wolffd@0
|
32
|
wolffd@0
|
33 % the data
|
wolffd@0
|
34 if isstruct(D),
|
wolffd@0
|
35 switch D.type,
|
wolffd@0
|
36 case 'som_map', if isempty(mask), mask = D.mask; end, D = D.codebook;
|
wolffd@0
|
37 case 'som_data', D = D.data;
|
wolffd@0
|
38 otherwise, error('Bad first argument');
|
wolffd@0
|
39 end
|
wolffd@0
|
40 end
|
wolffd@0
|
41 nans = sum(isnan(D),2);
|
wolffd@0
|
42 if any(nans>0),
|
wolffd@0
|
43 D(find(nans>0),:) = 0;
|
wolffd@0
|
44 warning('Distances of vectors with NaNs are not calculated.');
|
wolffd@0
|
45 end
|
wolffd@0
|
46 [dlen dim] = size(D);
|
wolffd@0
|
47
|
wolffd@0
|
48 % distance norm
|
wolffd@0
|
49 if nargin<2 | isempty(q) | isnan(q), q = 2; end
|
wolffd@0
|
50
|
wolffd@0
|
51 % mask
|
wolffd@0
|
52 if isempty(mask), mask = ones(dim,1); end
|
wolffd@0
|
53
|
wolffd@0
|
54 % connections
|
wolffd@0
|
55 if nargin<4, Ne = []; end
|
wolffd@0
|
56 if ~isempty(Ne),
|
wolffd@0
|
57 l = size(Ne,1); Ne([0:l-1]*l+[1:l]) = 1; % set diagonal elements = 1
|
wolffd@0
|
58 end
|
wolffd@0
|
59
|
wolffd@0
|
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
61
|
wolffd@0
|
62 m = mask;
|
wolffd@0
|
63 o = ones(dlen,1);
|
wolffd@0
|
64 l = dlen;
|
wolffd@0
|
65 Md = zeros(dlen);
|
wolffd@0
|
66 calculate_all = isempty(Ne);
|
wolffd@0
|
67
|
wolffd@0
|
68 if ~calculate_all, Md(Ne==0) = Inf; end
|
wolffd@0
|
69
|
wolffd@0
|
70 for i=1:l-1,
|
wolffd@0
|
71 j=(i+1):l;
|
wolffd@0
|
72 if ~calculate_all, j=find(Ne(i,j))+i; end
|
wolffd@0
|
73 C=D(j,:)-D(i*o(1:length(j)),:);
|
wolffd@0
|
74 switch q,
|
wolffd@0
|
75 case 1, Md(j,i)=abs(C)*m;
|
wolffd@0
|
76 case 2, Md(j,i)=sqrt((C.^2)*m);
|
wolffd@0
|
77 case Inf, Md(j,i)=max(diag(m)*abs(C),[],2);
|
wolffd@0
|
78 otherwise, Md(j,i)=((abs(C).^q)*m).^(1/q);
|
wolffd@0
|
79 end
|
wolffd@0
|
80 Md(i,j) = Md(j,i)';
|
wolffd@0
|
81 end
|
wolffd@0
|
82
|
wolffd@0
|
83 Md(find(nans>0),:) = NaN;
|
wolffd@0
|
84 Md(:,find(nans>0)) = NaN;
|
wolffd@0
|
85
|
wolffd@0
|
86 return;
|
wolffd@0
|
87
|
wolffd@0
|
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
89
|