wolffd@0
|
1 function Cd = som_cldist(D,clinds1,clinds2,cldist,q,mask)
|
wolffd@0
|
2
|
wolffd@0
|
3 % SOM_CLDIST Distances between two clusters.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % Cd = som_cldist(Md,c1,c2,'single')
|
wolffd@0
|
6 % Cd = som_cldist(Md,c1,c2,'average')
|
wolffd@0
|
7 % Cd = som_cldist(Md,c1,c2,'complete')
|
wolffd@0
|
8 % Cd = som_cldist(Md,c1,c2,'neighf',H)
|
wolffd@0
|
9 % Cd = som_cldist(Md,c1,[],...)
|
wolffd@0
|
10 % Cd = som_cldist(D,c1,c2,'centroid',q,mask)
|
wolffd@0
|
11 % Cd = som_cldist(D,c1,c2,'ward',q,mask)
|
wolffd@0
|
12 % Cd = som_cldist(D,c1,[],...)
|
wolffd@0
|
13 %
|
wolffd@0
|
14 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
15 % D (matrix) size dlen x dim, the data set
|
wolffd@0
|
16 % (struct) map or data struct
|
wolffd@0
|
17 % Md (matrix) size dlen x dlen, mutual distance matrix, see SOM_MDIST
|
wolffd@0
|
18 % c1 (cell array) size n1 x 1, indices of clusters from which
|
wolffd@0
|
19 % the distances should be calculated, each cell
|
wolffd@0
|
20 % contains indices of vectors that belong to that
|
wolffd@0
|
21 % cluster (indices are between 1...dlen)
|
wolffd@0
|
22 % c2 (cell array) size n2 x 1, same as c1 but have the clusters
|
wolffd@0
|
23 % to which the distances should be calculated
|
wolffd@0
|
24 % (empty) c1 is used in place of c2
|
wolffd@0
|
25 % [q] (scalar) distance norm, default = 2
|
wolffd@0
|
26 % [mask] (vector) size dim x 1, the weighting mask, a vector of ones
|
wolffd@0
|
27 % by default
|
wolffd@0
|
28 % H (matrix) size dlen x dlen, neighborhood function values
|
wolffd@0
|
29 %
|
wolffd@0
|
30 % Cd (matrix) size n1 x n2, distances between the clusters
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % See also SOM_MDIST.
|
wolffd@0
|
33
|
wolffd@0
|
34 % Copyright (c) 2000 by Juha Vesanto
|
wolffd@0
|
35 % Contributed to SOM Toolbox on XXX by Juha Vesanto
|
wolffd@0
|
36 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
37
|
wolffd@0
|
38 % Version 2.0beta juuso 250800
|
wolffd@0
|
39
|
wolffd@0
|
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
41
|
wolffd@0
|
42 [dlen dim] = size(D);
|
wolffd@0
|
43 if nargin<5, q = 2; end
|
wolffd@0
|
44 if nargin<6, mask = ones(dim,1); end
|
wolffd@0
|
45 if ~iscell(clinds1), clinds1 = {clinds1}; end
|
wolffd@0
|
46 if ~isempty(clinds2) & ~iscell(clinds2), clinds2 = {clinds2}; end
|
wolffd@0
|
47
|
wolffd@0
|
48 n1 = length(clinds1);
|
wolffd@0
|
49 n2 = length(clinds2);
|
wolffd@0
|
50 if n2>0, Cd = zeros(n1,n2); else Cd = zeros(n1); end
|
wolffd@0
|
51 if n1==0, return; end
|
wolffd@0
|
52
|
wolffd@0
|
53 switch cldist,
|
wolffd@0
|
54
|
wolffd@0
|
55 % centroid distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
56 case 'centroid',
|
wolffd@0
|
57
|
wolffd@0
|
58 C1 = zeros(n1,dim); for i=1:n1, C1(i,:) = mean(D(clinds1{i},:),1); end
|
wolffd@0
|
59 C2 = zeros(n2,dim); for i=1:n2, C2(i,:) = mean(D(clinds2{i},:),1); end
|
wolffd@0
|
60 if n2==0,
|
wolffd@0
|
61 for i=1:n1-1,
|
wolffd@0
|
62 for j=i+1:n1,
|
wolffd@0
|
63 diff = C1(i,:)-C1(j,:);
|
wolffd@0
|
64 switch q,
|
wolffd@0
|
65 case 1, Cd(i,j)=abs(diff)*mask;
|
wolffd@0
|
66 case 2, Cd(i,j)=sqrt((diff.^2)*mask);
|
wolffd@0
|
67 case Inf, Cd(i,j)=max(diag(mask)*abs(diff),[],2);
|
wolffd@0
|
68 otherwise, Cd(i,j)=((abs(diff).^q)*mask).^(1/q);
|
wolffd@0
|
69 end
|
wolffd@0
|
70 end
|
wolffd@0
|
71 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
72 end
|
wolffd@0
|
73 else
|
wolffd@0
|
74 for i=1:n1,
|
wolffd@0
|
75 for j=1:n2,
|
wolffd@0
|
76 diff = C1(i,:)-C2(j,:);
|
wolffd@0
|
77 switch q,
|
wolffd@0
|
78 case 1, Cd(i,j)=abs(diff)*mask;
|
wolffd@0
|
79 case 2, Cd(i,j)=sqrt((diff.^2)*mask);
|
wolffd@0
|
80 case Inf, Cd(i,j)=max(diag(mask)*abs(diff),[],2);
|
wolffd@0
|
81 otherwise, Cd(i,j)=((abs(diff).^q)*mask).^(1/q);
|
wolffd@0
|
82 end
|
wolffd@0
|
83 end
|
wolffd@0
|
84 end
|
wolffd@0
|
85 end
|
wolffd@0
|
86
|
wolffd@0
|
87 % ward distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
88 case 'ward',
|
wolffd@0
|
89
|
wolffd@0
|
90 C1 = zeros(n1,dim); nn1 = zeros(n1,dim);
|
wolffd@0
|
91 for i=1:n1, C1(i,:) = mean(D(clinds1{i},:),1); nn1(i) = length(clinds1{i}); end
|
wolffd@0
|
92 C2 = zeros(n2,dim); nn2 = zeros(n2,dim);
|
wolffd@0
|
93 for i=1:n2, C2(i,:) = mean(D(clinds2{i},:),1); nn2(i) = length(clinds2{i}); end
|
wolffd@0
|
94 if n2==0,
|
wolffd@0
|
95 for i=1:n1-1,
|
wolffd@0
|
96 for j=i+1:n1,
|
wolffd@0
|
97 diff = C1(i,:) - C1(j,:);
|
wolffd@0
|
98 f = 2*nn1(i)*nn1(j) / (nn1(i)+nn1(j));
|
wolffd@0
|
99 switch q,
|
wolffd@0
|
100 case 1, Cd(i,j)=f*abs(diff)*mask;
|
wolffd@0
|
101 case 2, Cd(i,j)=f*sqrt((diff.^2)*mask);
|
wolffd@0
|
102 case Inf, Cd(i,j)=f*max(diag(mask)*abs(diff),[],2);
|
wolffd@0
|
103 otherwise, Cd(i,j)=f*((abs(diff).^q)*mask).^(1/q);
|
wolffd@0
|
104 end
|
wolffd@0
|
105 end
|
wolffd@0
|
106 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
107 end
|
wolffd@0
|
108 else
|
wolffd@0
|
109 for i=1:n1,
|
wolffd@0
|
110 for j=1:n2,
|
wolffd@0
|
111 diff = C1(i,:) - C2(j,:);
|
wolffd@0
|
112 f = 2*nn1(i)*nn2(j) / (nn1(i)+nn2(j));
|
wolffd@0
|
113 switch q,
|
wolffd@0
|
114 case 1, Cd(i,j)=f*abs(diff)*mask;
|
wolffd@0
|
115 case 2, Cd(i,j)=f*sqrt((diff.^2)*mask);
|
wolffd@0
|
116 case Inf, Cd(i,j)=f*max(diag(mask)*abs(diff),[],2);
|
wolffd@0
|
117 otherwise, Cd(i,j)=f*((abs(diff).^q)*mask).^(1/q);
|
wolffd@0
|
118 end
|
wolffd@0
|
119 end
|
wolffd@0
|
120 end
|
wolffd@0
|
121 end
|
wolffd@0
|
122
|
wolffd@0
|
123 % single linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
124 case 'single',
|
wolffd@0
|
125
|
wolffd@0
|
126 if n2==0,
|
wolffd@0
|
127 for i=1:n1-1,
|
wolffd@0
|
128 for j=i+1:n1,
|
wolffd@0
|
129 vd = D(clinds1{i},clinds1{j});
|
wolffd@0
|
130 fi = isfinite(vd(:));
|
wolffd@0
|
131 if any(fi), Cd(i,j) = min(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
132 end
|
wolffd@0
|
133 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
134 end
|
wolffd@0
|
135 else
|
wolffd@0
|
136 for i=1:n1,
|
wolffd@0
|
137 for j=1:n2,
|
wolffd@0
|
138 vd = D(clinds1{i},clinds2{j});
|
wolffd@0
|
139 fi = isfinite(vd(:));
|
wolffd@0
|
140 if any(fi), Cd(i,j) = min(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
141 end
|
wolffd@0
|
142 end
|
wolffd@0
|
143 end
|
wolffd@0
|
144
|
wolffd@0
|
145 % average linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
146 case 'average',
|
wolffd@0
|
147
|
wolffd@0
|
148 if n2==0,
|
wolffd@0
|
149 for i=1:n1-1,
|
wolffd@0
|
150 for j=i+1:n1,
|
wolffd@0
|
151 vd = D(clinds1{i},clinds1{j});
|
wolffd@0
|
152 fi = isfinite(vd(:));
|
wolffd@0
|
153 if any(fi), Cd(i,j) = mean(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
154 end
|
wolffd@0
|
155 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
156 end
|
wolffd@0
|
157 else
|
wolffd@0
|
158 for i=1:n1,
|
wolffd@0
|
159 for j=1:n2,
|
wolffd@0
|
160 vd = D(clinds1{i},clinds2{j});
|
wolffd@0
|
161 fi = isfinite(vd(:));
|
wolffd@0
|
162 if any(fi), Cd(i,j) = mean(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
163 end
|
wolffd@0
|
164 end
|
wolffd@0
|
165 end
|
wolffd@0
|
166
|
wolffd@0
|
167 % complete linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
168 case 'complete',
|
wolffd@0
|
169
|
wolffd@0
|
170 if n2==0,
|
wolffd@0
|
171 for i=1:n1-1,
|
wolffd@0
|
172 for j=i+1:n1,
|
wolffd@0
|
173 vd = D(clinds1{i},clinds1{j});
|
wolffd@0
|
174 fi = isfinite(vd(:));
|
wolffd@0
|
175 if any(fi), Cd(i,j) = max(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
176 end
|
wolffd@0
|
177 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
178 end
|
wolffd@0
|
179 else
|
wolffd@0
|
180 for i=1:n1,
|
wolffd@0
|
181 for j=1:n2,
|
wolffd@0
|
182 vd = D(clinds1{i},clinds2{j});
|
wolffd@0
|
183 fi = isfinite(vd(:));
|
wolffd@0
|
184 if any(fi), Cd(i,j) = max(vd(fi)); else Cd(i,j) = Inf; end
|
wolffd@0
|
185 end
|
wolffd@0
|
186 end
|
wolffd@0
|
187 end
|
wolffd@0
|
188
|
wolffd@0
|
189 % neighborhood function linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
190 case 'neighf',
|
wolffd@0
|
191
|
wolffd@0
|
192 if n2==0,
|
wolffd@0
|
193 for i=1:n1-1,
|
wolffd@0
|
194 for j=i+1:n1,
|
wolffd@0
|
195 vd = D(clinds1{i},clinds1{j});
|
wolffd@0
|
196 fi = isfinite(vd(:));
|
wolffd@0
|
197 if any(fi),
|
wolffd@0
|
198 hd = q(clinds1{i},clinds1{j});
|
wolffd@0
|
199 hd = hd(fi);
|
wolffd@0
|
200 Cd(i,j) = sum(hd.*vd(fi))/sum(hd);
|
wolffd@0
|
201 else Cd(i,j) = Inf;
|
wolffd@0
|
202 end
|
wolffd@0
|
203 end
|
wolffd@0
|
204 Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
|
wolffd@0
|
205 end
|
wolffd@0
|
206 else
|
wolffd@0
|
207 for i=1:n1,
|
wolffd@0
|
208 for j=1:n2,
|
wolffd@0
|
209 vd = D(clinds1{i},clinds2{j});
|
wolffd@0
|
210 fi = isfinite(vd(:));
|
wolffd@0
|
211 if any(fi),
|
wolffd@0
|
212 hd = q(clinds1{i},clinds2{j});
|
wolffd@0
|
213 hd = hd(fi);
|
wolffd@0
|
214 Cd(i,j) = sum(hd.*vd(fi))/sum(hd);
|
wolffd@0
|
215 else Cd(i,j) = Inf;
|
wolffd@0
|
216 end
|
wolffd@0
|
217 end
|
wolffd@0
|
218 end
|
wolffd@0
|
219 end
|
wolffd@0
|
220
|
wolffd@0
|
221 otherwise, error(['Unknown cluster distance metric: ' cldist]);
|
wolffd@0
|
222 end
|
wolffd@0
|
223
|
wolffd@0
|
224 return;
|
wolffd@0
|
225
|
wolffd@0
|
226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
227
|