wolffd@0: function [sTo] = som_label(sTo, mode, inds, labels) wolffd@0: wolffd@0: %SOM_LABEL Give/clear labels to/from map or data struct. wolffd@0: % wolffd@0: % sTo = som_label(sTo, mode, inds [, labels]) wolffd@0: % wolffd@0: % sD = som_label(sD,'add',20,'a_label'); wolffd@0: % sM = som_label(sM,'replace',[2 4],'a_label'); wolffd@0: % sM = som_label(sM,'add',som_bmus(sM,x),'BMU'); wolffd@0: % sD = som_label(sD,'prune',[1:10]'); wolffd@0: % sM = som_label(sM,'clear','all'); wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % sTo (struct) data or map struct to which the labels are put wolffd@0: % mode (string) 'add' or 'replace' or 'prune' or 'clear' wolffd@0: % inds (vector) indeces of the vectors to which the labels wolffd@0: % are put. Note: this must be a column vector! wolffd@0: % (matrix) subscript indeces to the '.labels' field. The vector wolffd@0: % is given by the first index (e.g. inds(i,1)). wolffd@0: % (string) for 'prune' and 'clear' modes, the string 'all' wolffd@0: % means that all vectors should be pruned/cleared wolffd@0: % [labels] The labels themselves. The number of rows much match wolffd@0: % the number of given indeces, except if there is either wolffd@0: % only one index or only one label. If mode is wolffd@0: % 'prune' or 'clear', labels argument is ignored. wolffd@0: % (string) Label. wolffd@0: % (string array) Each row is a label. wolffd@0: % (cell array of strings) All labels in a cell are handled wolffd@0: % as a group and are applied to the same vector given wolffd@0: % on the corresponding row of inds. wolffd@0: % wolffd@0: % Note: If there is only one label/index, it is used for each specified wolffd@0: % index/label. wolffd@0: % wolffd@0: % For more help, try 'type som_label' or check out online documentation. wolffd@0: % See also SOM_AUTOLABEL, SOM_SHOW_ADD, SOM_SHOW. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_label wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Add (or remove) labels to (from) map and data structs. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % sTo = som_label(sTo, 'clear', inds) wolffd@0: % sTo = som_label(sTo, 'prune', inds) wolffd@0: % sTo = som_label(sTo, 'add', inds, labels) wolffd@0: % sTo = som_label(sTo, 'replace', inds, labels) wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % This function can be used to give and remove labels in map and data wolffd@0: % structs. Of course the same operation could be done by hand, but this wolffd@0: % function offers an alternative and hopefully slightly user-friendlier wolffd@0: % way to do it. wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % sTo (struct) data or map struct to which the labels are put wolffd@0: % mode (string) The mode of operation. wolffd@0: % 'add' : adds the given labels wolffd@0: % 'clear' : removes labels wolffd@0: % 'replace' : replaces current labels with given wolffd@0: % labels; basically same as 'clear' wolffd@0: % followed by 'add' wolffd@0: % 'prune' : removes empty labels ('') from between wolffd@0: % non-empty labels, e.g. if the labels of wolffd@0: % a vector were {'A','','','B','','C'} wolffd@0: % they'd become {'A','B','C'}. Some empty wolffd@0: % labels may be left at the end of the list. wolffd@0: % wolffd@0: % inds Identifies the vectors to which the operation wolffd@0: % (given by mode) is applied to. wolffd@0: % (vector) Linear indexes of the vectors, size n x 1. wolffd@0: % Notice! This should be a column vector! wolffd@0: % (matrix) The labels are in a cell matrix. By giving matrix wolffd@0: % argument for inds, you can address this matrix wolffd@0: % directly. The first index gives the vector and the wolffd@0: % second index the vertical position of the label in wolffd@0: % the labels array. Size n x 2, where n is the wolffd@0: % number of labels. wolffd@0: % (string) for 'prune' and 'clear' modes, the string 'all' wolffd@0: % means that all vectors should be pruned/cleared wolffd@0: % wolffd@0: % OPTIONAL INPUT ARGUMENTS wolffd@0: % wolffd@0: % [labels] The labels themselves. The number of rows much match wolffd@0: % the number of given indeces, except if there is either wolffd@0: % only one index or only one label. wolffd@0: % (string) Label, e.g. 'label' wolffd@0: % (string array) Each row is a label, wolffd@0: % e.g. ['label1'; 'label2'; 'label3'] wolffd@0: % (cell array of strings) All labels in a cell are handled wolffd@0: % as a group and are applied to the same vector given wolffd@0: % on the corresponding row of inds. wolffd@0: % e.g. three labels: {'label1'; 'label2'; 'label3'} wolffd@0: % e.g. a group of labels: {'label1', 'label2', 'label3'} wolffd@0: % e.g. three groups: {{'la1'},{'la21','la22'},{'la3'} wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sTo (struct) the given data/map struct with modified labels wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % This is the basic way to add a label to map structure: wolffd@0: % sMap = som_label(sMap,'add',3,'label'); wolffd@0: % wolffd@0: % The following examples have identical results: wolffd@0: % sMap = som_label(sMap,'add',[4; 13], ['label1'; 'label2']); wolffd@0: % sMap = som_label(sMap,'add',[4; 13], {{'label1'};{'label2'}}); wolffd@0: % wolffd@0: % Labeling the BMU of a vector x (and removing any old labels) wolffd@0: % sMap = som_label(sMap,'replace',som_bmus(sMap,x),'BMU'); wolffd@0: % wolffd@0: % Pruning labels wolffd@0: % sMap = som_label(sMap,'prune','all'); wolffd@0: % wolffd@0: % Clearing labels from a struct wolffd@0: % sMap = som_label(sMap,'clear','all'); wolffd@0: % sMap = som_label(sMap,'clear',[1:4, 9:30]'); wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_autolabel Automatically label a map/data set. wolffd@0: % som_show Show map planes. wolffd@0: % som_show_add Add for example labels to the SOM_SHOW visualization. wolffd@0: wolffd@0: % Copyright (c) 1997-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta juuso 101199 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% check arguments wolffd@0: wolffd@0: error(nargchk(3, 4, nargin)); % check no. of input args is correct wolffd@0: wolffd@0: % sTo wolffd@0: switch sTo.type, wolffd@0: case 'som_map', [dlen dim] = size(sTo.codebook); wolffd@0: case 'som_data', [dlen dim] = size(sTo.data); wolffd@0: end wolffd@0: maxl = size(sTo.labels,2); % maximum number of labels for a single vector wolffd@0: wolffd@0: % inds wolffd@0: if ischar(inds) & strcmp(inds,'all'), wolffd@0: inds = [1:dlen]'; wolffd@0: end wolffd@0: if length(inds)>2 & size(inds,2)>2, inds = inds'; end wolffd@0: ni = size(inds,1); wolffd@0: n = ni; wolffd@0: wolffd@0: % labels wolffd@0: if nargin==4, wolffd@0: % convert labels to a cell array of cells wolffd@0: if ischar(labels), labels = cellstr(labels); end wolffd@0: if iscellstr(labels), wolffd@0: tmplab = labels; wolffd@0: nl = size(labels,1); wolffd@0: labels = cell(nl,1); wolffd@0: for i=1:nl, wolffd@0: if ~iscell(tmplab{i}) wolffd@0: if ~isempty(tmplab{i}), labels{i} = tmplab(i,:); wolffd@0: else labels{i} = {}; end wolffd@0: else wolffd@0: labels(i) = tmplab(i); wolffd@0: end wolffd@0: end wolffd@0: clear tmplab; wolffd@0: end wolffd@0: nl = size(labels,1); wolffd@0: end wolffd@0: wolffd@0: % the case of a single label/index wolffd@0: if any(strcmp(mode,{'add','replace'})), wolffd@0: n = max(nl,ni); wolffd@0: if n>1, wolffd@0: if ni==1, wolffd@0: inds = zeros(n,1)+inds(1); wolffd@0: elseif nl==1, wolffd@0: label = labels{1}; wolffd@0: labels = cell(n,1); wolffd@0: for i=1:n, labels{i} = label; end wolffd@0: elseif ni ~= nl, wolffd@0: error('The number of labels and indexes does not match.'); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% action wolffd@0: wolffd@0: switch mode, wolffd@0: case 'clear', wolffd@0: if size(inds,2)>2, wolffd@0: inds = inds(find(inds(:,2)<=maxl),:); % ignore if subindex is out-of-range wolffd@0: inds = sub2ind([dlen maxl],inds(:,1),inds(:,2)); wolffd@0: sTo.labels{inds} = []; wolffd@0: else wolffd@0: sTo.labels(inds,:) = cell(n,maxl); wolffd@0: end wolffd@0: case 'prune', wolffd@0: if size(inds,2)==1, wolffd@0: % subindex gives the index from which the pruning is started wolffd@0: inds = [inds, ones(n,1)]; % from 1 by default wolffd@0: end wolffd@0: select = ones(1,maxl); wolffd@0: for i=1:n, wolffd@0: v = inds(i,1); s = inds(i,2); select(:) = 1; wolffd@0: for j=s:maxl, select(j) = ~isempty(sTo.labels{v,j}); end wolffd@0: if ~all(select), wolffd@0: labs = cell(1,maxl); wolffd@0: labs(1:sum(select)) = sTo.labels(v,find(select)); wolffd@0: sTo.labels(v,:) = labs; wolffd@0: end wolffd@0: end wolffd@0: case 'add', wolffd@0: if size(inds,2)==1, wolffd@0: % subindex gives the index from which the adding is started wolffd@0: inds = [inds, ones(n,1)]; % from 1 by default wolffd@0: end wolffd@0: for i=1:n, wolffd@0: v = inds(i,1); s = inds(i,2); l = length(labels{i}); wolffd@0: for j=1:l, wolffd@0: while s<=size(sTo.labels,2) & ~isempty(sTo.labels{v,s}), s=s+1; end wolffd@0: sTo.labels{v,s} = labels{i}{j}; wolffd@0: s=s+1; wolffd@0: end wolffd@0: end wolffd@0: case 'replace', wolffd@0: if size(inds,2)==1, wolffd@0: % subindex gives the index from which the replacing is started wolffd@0: inds = [inds, ones(n,1)]; % from 1 by default wolffd@0: end wolffd@0: for i=1:n, wolffd@0: v = inds(i,1); s = inds(i,2); l = length(labels(i)); wolffd@0: for j=1:l, sTo.labels{v,s-1+j} = labels{i}{j}; end wolffd@0: end wolffd@0: otherwise wolffd@0: error(['Unrecognized mode: ' mode]); wolffd@0: end wolffd@0: wolffd@0: sTo.labels = remove_empty_columns(sTo.labels); wolffd@0: wolffd@0: [dlen maxl] = size(sTo.labels); wolffd@0: for i=1:dlen, wolffd@0: for j=1:maxl, wolffd@0: if isempty(sTo.labels{i,j}) & ~ischar(sTo.labels{i,j}), wolffd@0: sTo.labels{i,j} = ''; wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: return; wolffd@0: wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% subfunctions wolffd@0: wolffd@0: function labels = remove_empty_columns(labels) wolffd@0: wolffd@0: [dlen maxl] = size(labels); wolffd@0: wolffd@0: % find which columns are empty wolffd@0: cols = zeros(1,maxl); wolffd@0: for i=1:dlen, wolffd@0: for j=1:maxl, wolffd@0: cols(j) = cols(j) + ~isempty(labels{i,j}); wolffd@0: end wolffd@0: end wolffd@0: while maxl>0 & cols(maxl)==0, maxl = maxl-1; end % check starting from end wolffd@0: wolffd@0: if maxl==0, labels = cell(dlen,1); wolffd@0: elseif maxl