annotate toolboxes/MIRtoolbox1.3.2/somtoolbox/som_cldist.m @ 0:cc4b1211e677 tip

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