diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_cldist.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/som_cldist.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,227 @@
+function Cd = som_cldist(D,clinds1,clinds2,cldist,q,mask)
+
+% SOM_CLDIST Distances between two clusters.
+% 
+%   Cd = som_cldist(Md,c1,c2,'single')
+%   Cd = som_cldist(Md,c1,c2,'average')
+%   Cd = som_cldist(Md,c1,c2,'complete')
+%   Cd = som_cldist(Md,c1,c2,'neighf',H)
+%   Cd = som_cldist(Md,c1,[],...)
+%   Cd = som_cldist(D,c1,c2,'centroid',q,mask)
+%   Cd = som_cldist(D,c1,c2,'ward',q,mask)
+%   Cd = som_cldist(D,c1,[],...)
+%
+%  Input and output arguments ([]'s are optional):
+%   D        (matrix) size dlen x dim, the data set
+%            (struct) map or data struct
+%   Md       (matrix) size dlen x dlen, mutual distance matrix, see SOM_MDIST
+%   c1       (cell array) size n1 x 1, indices of clusters from which 
+%                     the distances should be calculated, each cell
+%                     contains indices of vectors that belong to that
+%                     cluster (indices are between 1...dlen)
+%   c2       (cell array) size n2 x 1, same as c1 but have the clusters
+%                     to which the distances should be calculated
+%            (empty)  c1 is used in place of c2
+%   [q]      (scalar) distance norm, default = 2
+%   [mask]   (vector) size dim x 1, the weighting mask, a vector of ones
+%                     by default
+%   H        (matrix) size dlen x dlen, neighborhood function values
+%
+%   Cd       (matrix) size n1 x n2, distances between the clusters
+%
+% See also SOM_MDIST. 
+
+% Copyright (c) 2000 by Juha Vesanto
+% Contributed to SOM Toolbox on XXX by Juha Vesanto
+% http://www.cis.hut.fi/projects/somtoolbox/
+ 
+% Version 2.0beta juuso 250800
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+[dlen dim] = size(D); 
+if nargin<5, q = 2; end
+if nargin<6, mask = ones(dim,1); end
+if ~iscell(clinds1), clinds1 = {clinds1}; end
+if ~isempty(clinds2) & ~iscell(clinds2), clinds2 = {clinds2}; end
+
+n1 = length(clinds1); 
+n2 = length(clinds2); 
+if n2>0, Cd = zeros(n1,n2); else Cd = zeros(n1); end
+if n1==0, return; end
+
+switch cldist, 
+  
+ % centroid distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+ case 'centroid',  
+
+  C1 = zeros(n1,dim); for i=1:n1, C1(i,:) = mean(D(clinds1{i},:),1); end
+  C2 = zeros(n2,dim); for i=1:n2, C2(i,:) = mean(D(clinds2{i},:),1); end
+  if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	diff = C1(i,:)-C1(j,:); 
+	switch q, 
+	 case 1,    Cd(i,j)=abs(diff)*mask;
+	 case 2,    Cd(i,j)=sqrt((diff.^2)*mask);  
+	 case Inf,  Cd(i,j)=max(diag(mask)*abs(diff),[],2);
+	 otherwise, Cd(i,j)=((abs(diff).^q)*mask).^(1/q);
+	end   
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	diff = C1(i,:)-C2(j,:); 
+	switch q, 
+	 case 1,    Cd(i,j)=abs(diff)*mask;
+	 case 2,    Cd(i,j)=sqrt((diff.^2)*mask);  
+	 case Inf,  Cd(i,j)=max(diag(mask)*abs(diff),[],2);
+	 otherwise, Cd(i,j)=((abs(diff).^q)*mask).^(1/q);
+	end   
+      end
+    end
+  end
+
+ % ward distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case 'ward',
+
+  C1 = zeros(n1,dim); nn1 = zeros(n1,dim); 
+  for i=1:n1, C1(i,:) = mean(D(clinds1{i},:),1); nn1(i) = length(clinds1{i}); end
+  C2 = zeros(n2,dim); nn2 = zeros(n2,dim); 
+  for i=1:n2, C2(i,:) = mean(D(clinds2{i},:),1); nn2(i) = length(clinds2{i}); end
+  if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	diff = C1(i,:) - C1(j,:); 
+	f = 2*nn1(i)*nn1(j) / (nn1(i)+nn1(j)); 
+	switch q, 
+	 case 1,    Cd(i,j)=f*abs(diff)*mask;
+	 case 2,    Cd(i,j)=f*sqrt((diff.^2)*mask);  
+	 case Inf,  Cd(i,j)=f*max(diag(mask)*abs(diff),[],2);
+	 otherwise, Cd(i,j)=f*((abs(diff).^q)*mask).^(1/q);
+	end   
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	diff = C1(i,:) - C2(j,:); 
+	f = 2*nn1(i)*nn2(j) / (nn1(i)+nn2(j)); 
+	switch q, 
+	 case 1,    Cd(i,j)=f*abs(diff)*mask;
+	 case 2,    Cd(i,j)=f*sqrt((diff.^2)*mask);  
+	 case Inf,  Cd(i,j)=f*max(diag(mask)*abs(diff),[],2);
+	 otherwise, Cd(i,j)=f*((abs(diff).^q)*mask).^(1/q);
+	end   
+      end
+    end
+  end  
+
+ % single linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case 'single',
+
+  if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	vd = D(clinds1{i},clinds1{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = min(vd(fi)); else Cd(i,j) = Inf; end
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	vd = D(clinds1{i},clinds2{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = min(vd(fi)); else Cd(i,j) = Inf; end
+      end
+    end
+  end
+
+ % average linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case 'average',
+  
+  if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	vd = D(clinds1{i},clinds1{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = mean(vd(fi)); else Cd(i,j) = Inf; end
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	vd = D(clinds1{i},clinds2{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = mean(vd(fi)); else Cd(i,j) = Inf; end
+      end
+    end
+  end
+    
+ % complete linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+ case 'complete',
+ 
+   if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	vd = D(clinds1{i},clinds1{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = max(vd(fi)); else Cd(i,j) = Inf; end
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	vd = D(clinds1{i},clinds2{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), Cd(i,j) = max(vd(fi)); else Cd(i,j) = Inf; end
+      end
+    end
+  end
+ 
+ % neighborhood function linkage distance %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+ case 'neighf',
+  
+  if n2==0, 
+    for i=1:n1-1, 
+      for j=i+1:n1, 
+	vd = D(clinds1{i},clinds1{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), 
+	  hd = q(clinds1{i},clinds1{j}); 
+	  hd = hd(fi); 
+	  Cd(i,j) = sum(hd.*vd(fi))/sum(hd); 	  
+	else Cd(i,j) = Inf; 
+	end
+      end
+      Cd([(i+1):n1],i) = Cd(i,[(i+1):n1])';
+    end
+  else
+    for i=1:n1, 
+      for j=1:n2, 
+	vd = D(clinds1{i},clinds2{j}); 
+	fi = isfinite(vd(:));
+	if any(fi), 
+	  hd = q(clinds1{i},clinds2{j}); 
+	  hd = hd(fi); 
+	  Cd(i,j) = sum(hd.*vd(fi))/sum(hd); 	  
+	else Cd(i,j) = Inf; 
+	end
+      end
+    end
+  end
+
+ otherwise, error(['Unknown cluster distance metric: ' cldist]); 
+end
+  
+return;
+  
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+