annotate 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
rev   line source
wolffd@0 1 function base = som_clspread(sM,base,cldist,Ne,verbosity)
wolffd@0 2
wolffd@0 3 % SOM_CLSPREAD Partition the given data by flooding.
wolffd@0 4 %
wolffd@0 5 % part = som_clspread(sM,part,cldist,[Ne],[verbos])
wolffd@0 6 %
wolffd@0 7 % Input and output arguments ([]'s are optional):
wolffd@0 8 % sM (struct) map or data struct
wolffd@0 9 % (matrix) size dlen x dim, the data set
wolffd@0 10 % base (vector) initial partition, where if base(i) is
wolffd@0 11 % 0 i should be assigned to some cluster
wolffd@0 12 % NaN i should not be assigned to any cluster
wolffd@0 13 % otherwise i belongs to cluster base(i)
wolffd@0 14 % cldist (string) cluster distance measure: 'single', 'average',
wolffd@0 15 % 'complete', 'neighf', 'ward', 'centroid', 'BMU'
wolffd@0 16 % [Ne] (scalar) 0 = not constrined to neighborhood
wolffd@0 17 % 1 = constrained
wolffd@0 18 % (matrix) size dlen x dlen, indicating possible connections
wolffd@0 19 % [verbos] (scalar) 1 (default) = show status bar
wolffd@0 20 % 0 = don't
wolffd@0 21 %
wolffd@0 22 % See also SOM_CLDIST.
wolffd@0 23
wolffd@0 24 % Copyright (c) 2000 by Juha Vesanto
wolffd@0 25 % Contributed to SOM Toolbox on XXX by Juha Vesanto
wolffd@0 26 % http://www.cis.hut.fi/projects/somtoolbox/
wolffd@0 27
wolffd@0 28 % Version 2.0beta juuso 220800
wolffd@0 29
wolffd@0 30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 31 %% input arguments
wolffd@0 32
wolffd@0 33 q = 2;
wolffd@0 34
wolffd@0 35 % map/data
wolffd@0 36 if isstruct(sM),
wolffd@0 37 switch sM.type,
wolffd@0 38 case 'som_map', M = sM.codebook; mask = sM.mask; sT = sM.topol;
wolffd@0 39 case 'som_data', M = sM.data; mask = []; sT = [];
wolffd@0 40 end
wolffd@0 41 else M = sM; mask = []; sT = [];
wolffd@0 42 end
wolffd@0 43 [dlen dim] = size(M);
wolffd@0 44 if isempty(mask), mask = ones(dim,1); end
wolffd@0 45
wolffd@0 46 % simple option
wolffd@0 47 if any(strcmp(cldist,{'closest','BMU'})),
wolffd@0 48 i0 = find(base==0);
wolffd@0 49 i1 = find(base>0);
wolffd@0 50 bmus = som_bmus(M(i1,:),M(i0,:));
wolffd@0 51 base(i0) = base(i1(bmus));
wolffd@0 52 return;
wolffd@0 53 end
wolffd@0 54
wolffd@0 55 % constrained clustering
wolffd@0 56 if nargin<4, Ne = []; end
wolffd@0 57 if prod(size(Ne))==1,
wolffd@0 58 if Ne & isempty(sT),
wolffd@0 59 warning('Cannot use constrained clustering.'); Ne = 0;
wolffd@0 60 end
wolffd@0 61 if Ne, Ne = som_unit_neighs(sT); else Ne = []; end
wolffd@0 62 end
wolffd@0 63 if ~isempty(Ne),
wolffd@0 64 Ne([0:dlen-1]*dlen+[1:dlen]) = 1; % set diagonal elements = 1
wolffd@0 65 if all(Ne(:)>0), Ne = []; end
wolffd@0 66 end
wolffd@0 67
wolffd@0 68 if nargin<5, verbosity = 1; end
wolffd@0 69
wolffd@0 70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 71 %% initialize
wolffd@0 72
wolffd@0 73 if size(base,1)==1, base = base'; end
wolffd@0 74
wolffd@0 75 cid = unique(base(isfinite(base) & base~=0)); % cluster IDs
wolffd@0 76 nc = length(cid);
wolffd@0 77 uind = find(base==0); % unclustered points
wolffd@0 78 nu = length(uind);
wolffd@0 79 if nu==0, return; end
wolffd@0 80
wolffd@0 81 % initial clusters
wolffd@0 82 clinds = cell(nc,1); for i=1:nc, clinds{i} = find(base==i); end
wolffd@0 83 clinds2 = cell(nu,1); for i=1:nu, clinds2{i} = uind(i); end
wolffd@0 84
wolffd@0 85 % neighborhood function values
wolffd@0 86 if strcmp(cldist,'neighf')
wolffd@0 87 if isempty(sT), error('Cannot use neighf linkage.'); end
wolffd@0 88 q = som_unit_dists(sT).^2;
wolffd@0 89 r = sM.trainhist(end).radius_fin^2;
wolffd@0 90 if isnan(r) | isempty(r), r = 1; end
wolffd@0 91 switch sM.neigh,
wolffd@0 92 case 'bubble', q = (q <= r);
wolffd@0 93 case 'gaussian', q = exp(-q/(2*r));
wolffd@0 94 case 'cutgauss', q = exp(-q/(2*r)) .* (q <= r);
wolffd@0 95 case 'ep', q = (1-q/r) .* (q <= r);
wolffd@0 96 end
wolffd@0 97 end
wolffd@0 98
wolffd@0 99 % distance of each cluster to the unclustered points
wolffd@0 100 if any(strcmp(cldist,{'single','average','complete','neighf'})),
wolffd@0 101 M = som_mdist(M,2,mask,Ne);
wolffd@0 102 end
wolffd@0 103 Cd = som_cldist(M,clinds,clinds2,cldist,q,mask);
wolffd@0 104
wolffd@0 105 % check out from Ne which of the clusters are not connected
wolffd@0 106 if ~isempty(Ne) & any(strcmp(cldist,{'centroid','ward'})),
wolffd@0 107 Clconn = sparse(nc,nu);
wolffd@0 108 for i=1:nc, for j=1:nu, Clconn(i,j) = any(any(Ne(clinds{i},uind(j)))); end, end
wolffd@0 109 Cd(Clconn==0) = Inf;
wolffd@0 110 else
wolffd@0 111 Clconn = [];
wolffd@0 112 end
wolffd@0 113
wolffd@0 114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 115 %% action
wolffd@0 116
wolffd@0 117 if verbosity,
wolffd@0 118 nu0 = nu;
wolffd@0 119 h = waitbar(1-nu/nu0,'Assigning unclustered points'); % tracking
wolffd@0 120 end
wolffd@0 121
wolffd@0 122 while 1,
wolffd@0 123
wolffd@0 124 % find closest unclustered point
wolffd@0 125 [dk,k] = min(Cd,[],2); % min distance from each unclustered point
wolffd@0 126 [d,c] = min(dk); % cluster to which it is assigned
wolffd@0 127 k = k(c);
wolffd@0 128
wolffd@0 129 if ~isfinite(d),
wolffd@0 130 break;
wolffd@0 131 end
wolffd@0 132
wolffd@0 133 % add k to cluster c
wolffd@0 134 base(uind(k)) = cid(c);
wolffd@0 135 clinds{c} = [clinds{c}; uind(k)];
wolffd@0 136
wolffd@0 137 % remove point k
wolffd@0 138 notk = [1:k-1,k+1:nu];
wolffd@0 139 nu = nu-1; if nu<=0, break; end
wolffd@0 140 Cd = Cd(:,notk);
wolffd@0 141 uind = uind(notk);
wolffd@0 142 clinds2 = clinds2(notk);
wolffd@0 143 if ~isempty(Clconn), Clconn = Clconn(:,notk); end
wolffd@0 144
wolffd@0 145 % update cluster distances to c
wolffd@0 146 Cd(c,:) = som_cldist(M,clinds(c),clinds2,cldist,q,mask);
wolffd@0 147 if ~isempty(Clconn),
wolffd@0 148 for j=1:nu, Clconn(c,j) = any(any(Ne(clinds{c},uind(j)))); end
wolffd@0 149 Cd(c,find(Clconn(c,:)==0)) = Inf;
wolffd@0 150 end
wolffd@0 151
wolffd@0 152 if verbosity, waitbar(1-nu/nu0,h); end % tracking
wolffd@0 153
wolffd@0 154 end
wolffd@0 155 if verbosity, close(h); end
wolffd@0 156
wolffd@0 157 return;
wolffd@0 158
wolffd@0 159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 160
wolffd@0 161