wolffd@0: function sC = som_clstruct(Z,varargin) wolffd@0: wolffd@0: %SOM_CLSTRUCT Create a clustering struct or set its field values. wolffd@0: % wolffd@0: % sC = som_clstruct(Z, [argID, value, ...]) wolffd@0: % wolffd@0: % Z = linkage(pdist(sM.codebook)); wolffd@0: % sC = som_clstruct(Z); wolffd@0: % sC = som_clstruct(sC,'coord',som_vis_coords(lattice,msize)); wolffd@0: % sC = som_clstruct(sC,'color',som_colorcode(sM)); wolffd@0: % sC = som_clstruct(sC,'base',sC.base(som_bmus(sM,sD))); wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % Z (matrix) size clen-1 x 3, where clen is the number of wolffd@0: % base clusters. This is a clustering matrix wolffd@0: % similar to that produced by LINKAGE in wolffd@0: % Statistical Toolbox. See SOM_LINKAGE. wolffd@0: % (struct) clustering struct (as produced by this function) wolffd@0: % [argID, (string) See below. Each pair is the fieldname and wolffd@0: % value] (varies) the value to be given to that field. wolffd@0: % wolffd@0: % sC (struct) clustering struct wolffd@0: % wolffd@0: % The clustering struct is based on the assumption that there wolffd@0: % is a base partitioning of the SOM (or data) which is saved in wolffd@0: % the .base field of the struct. Then a hierarchical clustering wolffd@0: % is applied to this base partitioning. The results are saved to wolffd@0: % .tree field of the struct. Each cluster (base and combined) wolffd@0: % has also three properties: height, coordinate and color, which wolffd@0: % are used in the visualizations. The fields of the struct are: wolffd@0: % .type (string) 'som_clustering' wolffd@0: % .name (string) Identifier for the clustering. wolffd@0: % .tree (matrix) Size clen-1 x 3, as argument Z above. wolffd@0: % .base (vector) Size dlen x 1, the basic groups of data wolffd@0: % forming the base clusters, e.g. as a result wolffd@0: % of partitive clustering. Allowed values are wolffd@0: % 1:clen indicating the base cluster wolffd@0: % to which the data belongs to. wolffd@0: % NaN indicating that the data has wolffd@0: % been ignored in the clustering wolffd@0: % By default [1:clen]. wolffd@0: % .height (vector) Size 2*clen-1 x 1, (clustering) height for each wolffd@0: % cluster. By default 0 for each base cluster and wolffd@0: % .tree(:,3) for the others. wolffd@0: % .coord (matrix) Size 2*clen-1 x *, coordinate for each cluster, wolffd@0: % By default the coordinates are set so that wolffd@0: % the base clusters are ordered on a line, and the wolffd@0: % position of each combined cluster is average of wolffd@0: % the base clusters that constitute it. wolffd@0: % .color (matrix) Size 2*clen-1 x 3, color for each cluster. wolffd@0: % By default the colors are set so that the wolffd@0: % base clusters are ordered on a line, like above, wolffd@0: % and then colors are assigned from the 'hsv' wolffd@0: % colormap to the base clusters. The color wolffd@0: % of each combined cluster is average as above. wolffd@0: % wolffd@0: % Height, coord and color can also be specified in alternate forms: wolffd@0: % 'height' (vector) size 2*clen-1 x 1, if given explicitly wolffd@0: % size clen-1 x 1, specified heights of the wolffd@0: % combined clusters (the base cluster heights wolffd@0: % are all = 0) wolffd@0: % size 0 x 0, default value is used wolffd@0: % 'coord' (matrix) size 2*clen-1 x *, if given explicitly wolffd@0: % size clen x *, to give coordinates for base wolffd@0: % clusters; the coordinate of combined clusters wolffd@0: % are averaged from these wolffd@0: % size dlen x *, to give coordinates of the wolffd@0: % original data: the cluster coordinates are wolffd@0: % averaged from these based on base clusters wolffd@0: % size 0 x 0, default value is used wolffd@0: % 'color' (matrix) as 'coord' wolffd@0: % wolffd@0: % See also SOM_CLPLOT, SOM_CLVALIDITY, SOM_CLGET, SOM_CLLINKAGE. wolffd@0: wolffd@0: % Copyright (c) 2000 by the SOM toolbox programming team. wolffd@0: % Contributed to SOM Toolbox on XXX by Juha Vesanto wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta juuso 180800 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: if isstruct(Z), wolffd@0: base = Z.base; wolffd@0: color = Z.color; wolffd@0: coord = Z.coord; wolffd@0: height = Z.height; wolffd@0: name = Z.name; wolffd@0: Z = Z.tree; wolffd@0: else wolffd@0: base = []; wolffd@0: color = []; wolffd@0: coord = []; wolffd@0: height = []; wolffd@0: name = ''; wolffd@0: end wolffd@0: clen = size(Z,1)+1; wolffd@0: wolffd@0: i=1; wolffd@0: while i<=length(varargin), wolffd@0: argok = 1; wolffd@0: if ischar(varargin{i}), wolffd@0: switch varargin{i}, wolffd@0: case 'tree', i=i+1; Z = varargin{i}; clen = size(Z,1)+1; wolffd@0: case 'base', i=i+1; base = varargin{i}; wolffd@0: case 'color', i=i+1; color = varargin{i}; wolffd@0: case 'coord', i=i+1; coord = varargin{i}; wolffd@0: case 'height', i=i+1; height = varargin{i}; wolffd@0: case 'name', i=i+1; name = varargin{i}; wolffd@0: otherwise argok=0; wolffd@0: end wolffd@0: else argok = 0; wolffd@0: end wolffd@0: if ~argok, disp(['(som_clstruct) Ignoring invalid argument #' num2str(i+1)]); end wolffd@0: i = i+1; wolffd@0: end wolffd@0: wolffd@0: if isempty(base), wolffd@0: dlen = clen; wolffd@0: base = 1:dlen; wolffd@0: else wolffd@0: dlen = length(base); wolffd@0: if any(base)>clen | any(base)<1, error('Incorrect base partition vector.'); end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% analysis of hierarchy wolffd@0: wolffd@0: % order of base clusters wolffd@0: order = 2*clen-1; wolffd@0: nonleaves = 1; wolffd@0: while any(nonleaves), wolffd@0: j = nonleaves(1); wolffd@0: ch = Z(order(j)-clen,1:2); wolffd@0: if j==1, oleft = []; else oleft = order(1:(j-1)); end wolffd@0: if j==length(order), oright = []; else oright = order((j+1):length(order)); end wolffd@0: order = [oleft, ch, oright]; wolffd@0: nonleaves = find(order>clen); wolffd@0: end wolffd@0: wolffd@0: % base cluster indeces for each non-base cluster wolffd@0: basecl = cell(clen-1,1); wolffd@0: for i=1:clen-1, wolffd@0: c1 = Z(i,1); if c1>clen, c1 = basecl{c1-clen}; end wolffd@0: c2 = Z(i,2); if c2>clen, c2 = basecl{c2-clen}; end wolffd@0: basecl{i} = [c1 c2]; wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% set coordinates, color and height and make the struct wolffd@0: wolffd@0: % coordinates wolffd@0: if size(coord,1)==2*clen-1, % this is ok already wolffd@0: else wolffd@0: if size(coord,1)==0, % the default wolffd@0: [dummy,coord] = sort(order); wolffd@0: coord = coord'; wolffd@0: elseif size(coord,1)==dlen & dlen>clen, % coordinates given for original data wolffd@0: codata = coord; wolffd@0: coord = zeros(clen,size(coord,2)); wolffd@0: for i=1:clen, coord(i,:) = mean(codata(find(base==i),:),1); end wolffd@0: end wolffd@0: if size(coord,1)==clen, % average from base clusters wolffd@0: coord = [coord; zeros(clen-1,size(coord,2))]; wolffd@0: for i=1:clen-1, coord(i+clen,:) = mean(coord(basecl{i},:),1); end wolffd@0: else wolffd@0: error('Incorrect coordinate matrix.'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % color wolffd@0: if size(color,1)==2*clen-1, % this is ok already wolffd@0: else wolffd@0: if size(color,1)==0, % the default wolffd@0: color(order,:) = hsv(length(order)); wolffd@0: elseif size(color,1)==dlen & dlen>clen, % colors given for original data wolffd@0: codata = color; wolffd@0: color = zeros(clen,3); wolffd@0: for i=1:clen, color(i,:) = mean(codata(find(base==i),:),1); end wolffd@0: end wolffd@0: if size(color,1)==clen, % average from base clusters wolffd@0: color = [color; zeros(clen-1,3)]; wolffd@0: for i=1:clen-1, color(i+clen,:) = mean(color(basecl{i},:),1); end wolffd@0: else wolffd@0: error('Incorrect color matrix.'); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % height wolffd@0: if isempty(height), wolffd@0: height = [zeros(clen,1); Z(:,3)]; wolffd@0: elseif length(height)==clen-1, wolffd@0: if size(height,2)==clen-1, height = height'; end wolffd@0: height = [zeros(clen,1); height]; wolffd@0: elseif length(height)~=2*clen-1, wolffd@0: error('Incorrect height vector.'); wolffd@0: end wolffd@0: wolffd@0: % make the struct wolffd@0: sC = struct('type','som_clustering',... wolffd@0: 'name',name,'base',base,'tree',Z,... wolffd@0: 'color',color,'coord',coord,'height',height); wolffd@0: return; wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: