wolffd@0
|
1 function [sTo] = som_label(sTo, mode, inds, labels)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_LABEL Give/clear labels to/from map or data struct.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % sTo = som_label(sTo, mode, inds [, labels])
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % sD = som_label(sD,'add',20,'a_label');
|
wolffd@0
|
8 % sM = som_label(sM,'replace',[2 4],'a_label');
|
wolffd@0
|
9 % sM = som_label(sM,'add',som_bmus(sM,x),'BMU');
|
wolffd@0
|
10 % sD = som_label(sD,'prune',[1:10]');
|
wolffd@0
|
11 % sM = som_label(sM,'clear','all');
|
wolffd@0
|
12 %
|
wolffd@0
|
13 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
14 % sTo (struct) data or map struct to which the labels are put
|
wolffd@0
|
15 % mode (string) 'add' or 'replace' or 'prune' or 'clear'
|
wolffd@0
|
16 % inds (vector) indeces of the vectors to which the labels
|
wolffd@0
|
17 % are put. Note: this must be a column vector!
|
wolffd@0
|
18 % (matrix) subscript indeces to the '.labels' field. The vector
|
wolffd@0
|
19 % is given by the first index (e.g. inds(i,1)).
|
wolffd@0
|
20 % (string) for 'prune' and 'clear' modes, the string 'all'
|
wolffd@0
|
21 % means that all vectors should be pruned/cleared
|
wolffd@0
|
22 % [labels] The labels themselves. The number of rows much match
|
wolffd@0
|
23 % the number of given indeces, except if there is either
|
wolffd@0
|
24 % only one index or only one label. If mode is
|
wolffd@0
|
25 % 'prune' or 'clear', labels argument is ignored.
|
wolffd@0
|
26 % (string) Label.
|
wolffd@0
|
27 % (string array) Each row is a label.
|
wolffd@0
|
28 % (cell array of strings) All labels in a cell are handled
|
wolffd@0
|
29 % as a group and are applied to the same vector given
|
wolffd@0
|
30 % on the corresponding row of inds.
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % Note: If there is only one label/index, it is used for each specified
|
wolffd@0
|
33 % index/label.
|
wolffd@0
|
34 %
|
wolffd@0
|
35 % For more help, try 'type som_label' or check out online documentation.
|
wolffd@0
|
36 % See also SOM_AUTOLABEL, SOM_SHOW_ADD, SOM_SHOW.
|
wolffd@0
|
37
|
wolffd@0
|
38 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
39 %
|
wolffd@0
|
40 % som_label
|
wolffd@0
|
41 %
|
wolffd@0
|
42 % PURPOSE
|
wolffd@0
|
43 %
|
wolffd@0
|
44 % Add (or remove) labels to (from) map and data structs.
|
wolffd@0
|
45 %
|
wolffd@0
|
46 % SYNTAX
|
wolffd@0
|
47 %
|
wolffd@0
|
48 % sTo = som_label(sTo, 'clear', inds)
|
wolffd@0
|
49 % sTo = som_label(sTo, 'prune', inds)
|
wolffd@0
|
50 % sTo = som_label(sTo, 'add', inds, labels)
|
wolffd@0
|
51 % sTo = som_label(sTo, 'replace', inds, labels)
|
wolffd@0
|
52 %
|
wolffd@0
|
53 % DESCRIPTION
|
wolffd@0
|
54 %
|
wolffd@0
|
55 % This function can be used to give and remove labels in map and data
|
wolffd@0
|
56 % structs. Of course the same operation could be done by hand, but this
|
wolffd@0
|
57 % function offers an alternative and hopefully slightly user-friendlier
|
wolffd@0
|
58 % way to do it.
|
wolffd@0
|
59 %
|
wolffd@0
|
60 % REQUIRED INPUT ARGUMENTS
|
wolffd@0
|
61 %
|
wolffd@0
|
62 % sTo (struct) data or map struct to which the labels are put
|
wolffd@0
|
63 % mode (string) The mode of operation.
|
wolffd@0
|
64 % 'add' : adds the given labels
|
wolffd@0
|
65 % 'clear' : removes labels
|
wolffd@0
|
66 % 'replace' : replaces current labels with given
|
wolffd@0
|
67 % labels; basically same as 'clear'
|
wolffd@0
|
68 % followed by 'add'
|
wolffd@0
|
69 % 'prune' : removes empty labels ('') from between
|
wolffd@0
|
70 % non-empty labels, e.g. if the labels of
|
wolffd@0
|
71 % a vector were {'A','','','B','','C'}
|
wolffd@0
|
72 % they'd become {'A','B','C'}. Some empty
|
wolffd@0
|
73 % labels may be left at the end of the list.
|
wolffd@0
|
74 %
|
wolffd@0
|
75 % inds Identifies the vectors to which the operation
|
wolffd@0
|
76 % (given by mode) is applied to.
|
wolffd@0
|
77 % (vector) Linear indexes of the vectors, size n x 1.
|
wolffd@0
|
78 % Notice! This should be a column vector!
|
wolffd@0
|
79 % (matrix) The labels are in a cell matrix. By giving matrix
|
wolffd@0
|
80 % argument for inds, you can address this matrix
|
wolffd@0
|
81 % directly. The first index gives the vector and the
|
wolffd@0
|
82 % second index the vertical position of the label in
|
wolffd@0
|
83 % the labels array. Size n x 2, where n is the
|
wolffd@0
|
84 % number of labels.
|
wolffd@0
|
85 % (string) for 'prune' and 'clear' modes, the string 'all'
|
wolffd@0
|
86 % means that all vectors should be pruned/cleared
|
wolffd@0
|
87 %
|
wolffd@0
|
88 % OPTIONAL INPUT ARGUMENTS
|
wolffd@0
|
89 %
|
wolffd@0
|
90 % [labels] The labels themselves. The number of rows much match
|
wolffd@0
|
91 % the number of given indeces, except if there is either
|
wolffd@0
|
92 % only one index or only one label.
|
wolffd@0
|
93 % (string) Label, e.g. 'label'
|
wolffd@0
|
94 % (string array) Each row is a label,
|
wolffd@0
|
95 % e.g. ['label1'; 'label2'; 'label3']
|
wolffd@0
|
96 % (cell array of strings) All labels in a cell are handled
|
wolffd@0
|
97 % as a group and are applied to the same vector given
|
wolffd@0
|
98 % on the corresponding row of inds.
|
wolffd@0
|
99 % e.g. three labels: {'label1'; 'label2'; 'label3'}
|
wolffd@0
|
100 % e.g. a group of labels: {'label1', 'label2', 'label3'}
|
wolffd@0
|
101 % e.g. three groups: {{'la1'},{'la21','la22'},{'la3'}
|
wolffd@0
|
102 %
|
wolffd@0
|
103 % OUTPUT ARGUMENTS
|
wolffd@0
|
104 %
|
wolffd@0
|
105 % sTo (struct) the given data/map struct with modified labels
|
wolffd@0
|
106 %
|
wolffd@0
|
107 % EXAMPLES
|
wolffd@0
|
108 %
|
wolffd@0
|
109 % This is the basic way to add a label to map structure:
|
wolffd@0
|
110 % sMap = som_label(sMap,'add',3,'label');
|
wolffd@0
|
111 %
|
wolffd@0
|
112 % The following examples have identical results:
|
wolffd@0
|
113 % sMap = som_label(sMap,'add',[4; 13], ['label1'; 'label2']);
|
wolffd@0
|
114 % sMap = som_label(sMap,'add',[4; 13], {{'label1'};{'label2'}});
|
wolffd@0
|
115 %
|
wolffd@0
|
116 % Labeling the BMU of a vector x (and removing any old labels)
|
wolffd@0
|
117 % sMap = som_label(sMap,'replace',som_bmus(sMap,x),'BMU');
|
wolffd@0
|
118 %
|
wolffd@0
|
119 % Pruning labels
|
wolffd@0
|
120 % sMap = som_label(sMap,'prune','all');
|
wolffd@0
|
121 %
|
wolffd@0
|
122 % Clearing labels from a struct
|
wolffd@0
|
123 % sMap = som_label(sMap,'clear','all');
|
wolffd@0
|
124 % sMap = som_label(sMap,'clear',[1:4, 9:30]');
|
wolffd@0
|
125 %
|
wolffd@0
|
126 % SEE ALSO
|
wolffd@0
|
127 %
|
wolffd@0
|
128 % som_autolabel Automatically label a map/data set.
|
wolffd@0
|
129 % som_show Show map planes.
|
wolffd@0
|
130 % som_show_add Add for example labels to the SOM_SHOW visualization.
|
wolffd@0
|
131
|
wolffd@0
|
132 % Copyright (c) 1997-2000 by the SOM toolbox programming team.
|
wolffd@0
|
133 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
134
|
wolffd@0
|
135 % Version 2.0beta juuso 101199
|
wolffd@0
|
136
|
wolffd@0
|
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
138 %% check arguments
|
wolffd@0
|
139
|
wolffd@0
|
140 error(nargchk(3, 4, nargin)); % check no. of input args is correct
|
wolffd@0
|
141
|
wolffd@0
|
142 % sTo
|
wolffd@0
|
143 switch sTo.type,
|
wolffd@0
|
144 case 'som_map', [dlen dim] = size(sTo.codebook);
|
wolffd@0
|
145 case 'som_data', [dlen dim] = size(sTo.data);
|
wolffd@0
|
146 end
|
wolffd@0
|
147 maxl = size(sTo.labels,2); % maximum number of labels for a single vector
|
wolffd@0
|
148
|
wolffd@0
|
149 % inds
|
wolffd@0
|
150 if ischar(inds) & strcmp(inds,'all'),
|
wolffd@0
|
151 inds = [1:dlen]';
|
wolffd@0
|
152 end
|
wolffd@0
|
153 if length(inds)>2 & size(inds,2)>2, inds = inds'; end
|
wolffd@0
|
154 ni = size(inds,1);
|
wolffd@0
|
155 n = ni;
|
wolffd@0
|
156
|
wolffd@0
|
157 % labels
|
wolffd@0
|
158 if nargin==4,
|
wolffd@0
|
159 % convert labels to a cell array of cells
|
wolffd@0
|
160 if ischar(labels), labels = cellstr(labels); end
|
wolffd@0
|
161 if iscellstr(labels),
|
wolffd@0
|
162 tmplab = labels;
|
wolffd@0
|
163 nl = size(labels,1);
|
wolffd@0
|
164 labels = cell(nl,1);
|
wolffd@0
|
165 for i=1:nl,
|
wolffd@0
|
166 if ~iscell(tmplab{i})
|
wolffd@0
|
167 if ~isempty(tmplab{i}), labels{i} = tmplab(i,:);
|
wolffd@0
|
168 else labels{i} = {}; end
|
wolffd@0
|
169 else
|
wolffd@0
|
170 labels(i) = tmplab(i);
|
wolffd@0
|
171 end
|
wolffd@0
|
172 end
|
wolffd@0
|
173 clear tmplab;
|
wolffd@0
|
174 end
|
wolffd@0
|
175 nl = size(labels,1);
|
wolffd@0
|
176 end
|
wolffd@0
|
177
|
wolffd@0
|
178 % the case of a single label/index
|
wolffd@0
|
179 if any(strcmp(mode,{'add','replace'})),
|
wolffd@0
|
180 n = max(nl,ni);
|
wolffd@0
|
181 if n>1,
|
wolffd@0
|
182 if ni==1,
|
wolffd@0
|
183 inds = zeros(n,1)+inds(1);
|
wolffd@0
|
184 elseif nl==1,
|
wolffd@0
|
185 label = labels{1};
|
wolffd@0
|
186 labels = cell(n,1);
|
wolffd@0
|
187 for i=1:n, labels{i} = label; end
|
wolffd@0
|
188 elseif ni ~= nl,
|
wolffd@0
|
189 error('The number of labels and indexes does not match.');
|
wolffd@0
|
190 end
|
wolffd@0
|
191 end
|
wolffd@0
|
192 end
|
wolffd@0
|
193
|
wolffd@0
|
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
195 %% action
|
wolffd@0
|
196
|
wolffd@0
|
197 switch mode,
|
wolffd@0
|
198 case 'clear',
|
wolffd@0
|
199 if size(inds,2)>2,
|
wolffd@0
|
200 inds = inds(find(inds(:,2)<=maxl),:); % ignore if subindex is out-of-range
|
wolffd@0
|
201 inds = sub2ind([dlen maxl],inds(:,1),inds(:,2));
|
wolffd@0
|
202 sTo.labels{inds} = [];
|
wolffd@0
|
203 else
|
wolffd@0
|
204 sTo.labels(inds,:) = cell(n,maxl);
|
wolffd@0
|
205 end
|
wolffd@0
|
206 case 'prune',
|
wolffd@0
|
207 if size(inds,2)==1,
|
wolffd@0
|
208 % subindex gives the index from which the pruning is started
|
wolffd@0
|
209 inds = [inds, ones(n,1)]; % from 1 by default
|
wolffd@0
|
210 end
|
wolffd@0
|
211 select = ones(1,maxl);
|
wolffd@0
|
212 for i=1:n,
|
wolffd@0
|
213 v = inds(i,1); s = inds(i,2); select(:) = 1;
|
wolffd@0
|
214 for j=s:maxl, select(j) = ~isempty(sTo.labels{v,j}); end
|
wolffd@0
|
215 if ~all(select),
|
wolffd@0
|
216 labs = cell(1,maxl);
|
wolffd@0
|
217 labs(1:sum(select)) = sTo.labels(v,find(select));
|
wolffd@0
|
218 sTo.labels(v,:) = labs;
|
wolffd@0
|
219 end
|
wolffd@0
|
220 end
|
wolffd@0
|
221 case 'add',
|
wolffd@0
|
222 if size(inds,2)==1,
|
wolffd@0
|
223 % subindex gives the index from which the adding is started
|
wolffd@0
|
224 inds = [inds, ones(n,1)]; % from 1 by default
|
wolffd@0
|
225 end
|
wolffd@0
|
226 for i=1:n,
|
wolffd@0
|
227 v = inds(i,1); s = inds(i,2); l = length(labels{i});
|
wolffd@0
|
228 for j=1:l,
|
wolffd@0
|
229 while s<=size(sTo.labels,2) & ~isempty(sTo.labels{v,s}), s=s+1; end
|
wolffd@0
|
230 sTo.labels{v,s} = labels{i}{j};
|
wolffd@0
|
231 s=s+1;
|
wolffd@0
|
232 end
|
wolffd@0
|
233 end
|
wolffd@0
|
234 case 'replace',
|
wolffd@0
|
235 if size(inds,2)==1,
|
wolffd@0
|
236 % subindex gives the index from which the replacing is started
|
wolffd@0
|
237 inds = [inds, ones(n,1)]; % from 1 by default
|
wolffd@0
|
238 end
|
wolffd@0
|
239 for i=1:n,
|
wolffd@0
|
240 v = inds(i,1); s = inds(i,2); l = length(labels(i));
|
wolffd@0
|
241 for j=1:l, sTo.labels{v,s-1+j} = labels{i}{j}; end
|
wolffd@0
|
242 end
|
wolffd@0
|
243 otherwise
|
wolffd@0
|
244 error(['Unrecognized mode: ' mode]);
|
wolffd@0
|
245 end
|
wolffd@0
|
246
|
wolffd@0
|
247 sTo.labels = remove_empty_columns(sTo.labels);
|
wolffd@0
|
248
|
wolffd@0
|
249 [dlen maxl] = size(sTo.labels);
|
wolffd@0
|
250 for i=1:dlen,
|
wolffd@0
|
251 for j=1:maxl,
|
wolffd@0
|
252 if isempty(sTo.labels{i,j}) & ~ischar(sTo.labels{i,j}),
|
wolffd@0
|
253 sTo.labels{i,j} = '';
|
wolffd@0
|
254 end
|
wolffd@0
|
255 end
|
wolffd@0
|
256 end
|
wolffd@0
|
257
|
wolffd@0
|
258 return;
|
wolffd@0
|
259
|
wolffd@0
|
260
|
wolffd@0
|
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
262 %% subfunctions
|
wolffd@0
|
263
|
wolffd@0
|
264 function labels = remove_empty_columns(labels)
|
wolffd@0
|
265
|
wolffd@0
|
266 [dlen maxl] = size(labels);
|
wolffd@0
|
267
|
wolffd@0
|
268 % find which columns are empty
|
wolffd@0
|
269 cols = zeros(1,maxl);
|
wolffd@0
|
270 for i=1:dlen,
|
wolffd@0
|
271 for j=1:maxl,
|
wolffd@0
|
272 cols(j) = cols(j) + ~isempty(labels{i,j});
|
wolffd@0
|
273 end
|
wolffd@0
|
274 end
|
wolffd@0
|
275 while maxl>0 & cols(maxl)==0, maxl = maxl-1; end % check starting from end
|
wolffd@0
|
276
|
wolffd@0
|
277 if maxl==0, labels = cell(dlen,1);
|
wolffd@0
|
278 elseif maxl<size(labels,2), labels = labels(:,1:maxl);
|
wolffd@0
|
279 else % ok
|
wolffd@0
|
280 end
|
wolffd@0
|
281 % end of remove_empty_columns
|
wolffd@0
|
282
|
wolffd@0
|
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|