diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_clspread.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_clspread.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,161 @@
+function base = som_clspread(sM,base,cldist,Ne,verbosity)
+
+% SOM_CLSPREAD Partition the given data by flooding.
+%
+%  part = som_clspread(sM,part,cldist,[Ne],[verbos])
+%
+%  Input and output arguments ([]'s are optional):
+%   sM       (struct) map or data struct
+%            (matrix) size dlen x dim, the data set            
+%   base     (vector) initial partition, where if base(i) is
+%                      0         i should be assigned to some cluster
+%                      NaN       i should not be assigned to any cluster
+%                      otherwise i belongs to cluster base(i)
+%   cldist   (string) cluster distance measure: 'single', 'average',
+%                     'complete', 'neighf', 'ward', 'centroid', 'BMU'  
+%   [Ne]     (scalar) 0 = not constrined to neighborhood
+%                     1 = constrained   
+%            (matrix) size dlen x dlen, indicating possible connections
+%   [verbos] (scalar) 1 (default) = show status bar
+%                     0  = don't
+%
+% See also SOM_CLDIST. 
+
+% 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 220800
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% input arguments
+
+q = 2; 
+
+% map/data
+if isstruct(sM), 
+  switch sM.type, 
+   case 'som_map',  M = sM.codebook; mask = sM.mask; sT = sM.topol; 
+   case 'som_data', M = sM.data; mask = []; sT = []; 
+  end
+else M = sM; mask = []; sT = []; 
+end
+[dlen dim] = size(M); 
+if isempty(mask), mask = ones(dim,1); end
+
+% simple option
+if any(strcmp(cldist,{'closest','BMU'})), 
+  i0 = find(base==0);
+  i1 = find(base>0);
+  bmus = som_bmus(M(i1,:),M(i0,:));
+  base(i0) = base(i1(bmus));
+  return; 
+end
+
+% constrained clustering
+if nargin<4, Ne = []; end
+if prod(size(Ne))==1,  
+  if Ne & isempty(sT),
+    warning('Cannot use constrained clustering.'); Ne = 0; 
+  end
+  if Ne, Ne = som_unit_neighs(sT); else Ne = []; end
+end
+if ~isempty(Ne), 
+  Ne([0:dlen-1]*dlen+[1:dlen]) = 1; % set diagonal elements = 1
+  if all(Ne(:)>0), Ne = []; end
+end
+
+if nargin<5, verbosity = 1; end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% initialize
+
+if size(base,1)==1, base = base'; end
+
+cid = unique(base(isfinite(base) & base~=0)); % cluster IDs
+nc = length(cid);    
+uind = find(base==0); % unclustered points
+nu = length(uind); 
+if nu==0, return; end
+
+% initial clusters
+clinds = cell(nc,1); for i=1:nc, clinds{i} = find(base==i); end
+clinds2 = cell(nu,1); for i=1:nu, clinds2{i} = uind(i); end
+
+% neighborhood function values
+if strcmp(cldist,'neighf')   
+  if isempty(sT), error('Cannot use neighf linkage.'); end
+  q = som_unit_dists(sT).^2; 
+  r = sM.trainhist(end).radius_fin^2; 
+  if isnan(r) | isempty(r), r = 1; end 
+  switch sM.neigh,
+   case 'bubble',   q = (q <= r);
+   case 'gaussian', q = exp(-q/(2*r));
+   case 'cutgauss', q = exp(-q/(2*r)) .* (q <= r);
+   case 'ep',       q = (1-q/r) .* (q <= r);
+  end
+end
+
+% distance of each cluster to the unclustered points
+if any(strcmp(cldist,{'single','average','complete','neighf'})), 
+  M = som_mdist(M,2,mask,Ne); 
+end 
+Cd = som_cldist(M,clinds,clinds2,cldist,q,mask); 
+			      
+% check out from Ne which of the clusters are not connected
+if ~isempty(Ne) & any(strcmp(cldist,{'centroid','ward'})),
+  Clconn = sparse(nc,nu);   
+  for i=1:nc, for j=1:nu, Clconn(i,j) = any(any(Ne(clinds{i},uind(j)))); end, end
+  Cd(Clconn==0) = Inf; 
+else
+  Clconn = []; 
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% action
+
+if verbosity,
+  nu0 = nu; 
+  h = waitbar(1-nu/nu0,'Assigning unclustered points'); % tracking
+end
+
+while 1, 
+
+  % find closest unclustered point
+  [dk,k] = min(Cd,[],2);  % min distance from each unclustered point
+  [d,c]  = min(dk);       % cluster to which it is assigned  
+  k = k(c); 
+
+  if ~isfinite(d), 
+    break; 
+  end
+
+  % add k to cluster c
+  base(uind(k)) = cid(c);   
+  clinds{c} = [clinds{c}; uind(k)];
+  
+  % remove point k
+  notk = [1:k-1,k+1:nu]; 
+  nu = nu-1; if nu<=0, break; end  
+  Cd = Cd(:,notk); 
+  uind = uind(notk); 
+  clinds2 = clinds2(notk); 
+  if ~isempty(Clconn), Clconn = Clconn(:,notk); end
+
+  % update cluster distances to c
+  Cd(c,:) = som_cldist(M,clinds(c),clinds2,cldist,q,mask); 
+  if ~isempty(Clconn), 
+    for j=1:nu, Clconn(c,j) = any(any(Ne(clinds{c},uind(j)))); end
+    Cd(c,find(Clconn(c,:)==0)) = Inf; 
+  end
+  
+  if verbosity, waitbar(1-nu/nu0,h); end % tracking
+
+end
+if verbosity, close(h); end
+
+return; 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+