Mercurial > hg > camir-aes2014
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; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +