Mercurial > hg > camir-aes2014
comparison toolboxes/MIRtoolbox1.3.2/somtoolbox/som_set.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function [sS, ok, msgs] = som_set(sS, varargin) | |
2 | |
3 %SOM_SET Create and check SOM Toolbox structs, give values to their fields. | |
4 % | |
5 % [sS, ok, msgs] = som_set(sS, [field, contents, ...]) | |
6 % | |
7 % sM = som_set(sM,'name','SOM#1.1'); | |
8 % [dummy,ok,msgs] = som_set(sData); | |
9 % sT = som_set('som_topol','msize',[10 10],'lattice','hexa'); | |
10 % [sTrain,ok] = som_set(sTrain,'algorithm','lininit'); | |
11 % [sN,ok,msgs] = som_set('som_norm'); | |
12 % | |
13 % Input and output arguments ([]'s are optional): | |
14 % sS the target struct | |
15 % (struct) a SOM Toolbox structure (not visualization struct) | |
16 % (string) structure identifier (see below) | |
17 % the updated/created structure is returned | |
18 % [field, (string) field to be given value to (see below) | |
19 % contents] (varies) the contents for the field | |
20 % | |
21 % ok (vector) status for each field-contents pair (1=ok) | |
22 % msgs (cellstr) status string for each field-contents pair (''=ok) | |
23 % | |
24 % There can be arbitrarily many field-contents pairs. If there | |
25 % are _no_ field-content pairs, and the first argument is a struct, | |
26 % the fields of the struct are checked for validity. | |
27 % | |
28 % Valid struct and corresponding field identifiers: | |
29 % 'som_map' : 'codebook', 'labels', 'mask', 'neigh', 'name', | |
30 % 'topol', 'msize, 'lattice', 'shape', | |
31 % 'trainhist', 'comp_names', 'comp_norm', | |
32 % 'som_data' : 'data', 'labels', 'name', 'comp_names', 'comp_norm', | |
33 % 'label_names' | |
34 % 'som_topol' : 'msize', 'lattice', 'shape' | |
35 % 'som_norm' : 'method', 'params', 'status' | |
36 % 'som_train' : 'algorithm', 'data_name', 'mask', 'neigh', | |
37 % 'radius_ini', 'radius_fin', 'alpha_ini', 'alpha_type', | |
38 % 'trainlen', 'time' | |
39 % 'som_grid' : 'lattice', 'shape', 'msize', 'coord', | |
40 % 'line', 'linecolor', 'linewidth', | |
41 % 'marker', 'markersize', 'markercolor', 'surf', | |
42 % 'label', 'labelcolor', 'labelsize' | |
43 % checking given values has not been implemented yet! | |
44 % | |
45 % For more help, try 'type som_set' or check out online documentation. | |
46 % See also SOM_INFO, SOM_MAP_STRUCT, SOM_DATA_STRUCT, SOM_VS1TO2. | |
47 | |
48 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
49 % | |
50 % som_set | |
51 % | |
52 % PURPOSE | |
53 % | |
54 % Create and set values for fields of SOM Toolbox structs (except | |
55 % visualization struct). Can also be used to check the validity of structs. | |
56 % | |
57 % SYNTAX | |
58 % | |
59 % sMap = som_set('som_map'); | |
60 % sData = som_set(sData); | |
61 % sNorm = som_set(...,'field',contents,...); | |
62 % [sTopol,ok] = som_set(sTopol,...); | |
63 % [sTrain,ok,msgs] = som_set('som_train',...); | |
64 % | |
65 % DESCRIPTION | |
66 % | |
67 % The function is used to create and set values for fields of SOM | |
68 % Toolbox structs, except visualization structs. The given values are | |
69 % first checked for validity, and if they are not valid, an error | |
70 % message is returned. The function can also be used to check the | |
71 % validity of all the fields of the struct by supplying a struct as | |
72 % the first and only argument. | |
73 % | |
74 % NOTE: Using SOM_SET to create structures does _not_ guarantee that the | |
75 % structs are valid (try e.g. sM = som_set('som_map'); som_set(sM)). The | |
76 % initial values that the function gives to the fields of the structs are | |
77 % typically invalid. It is recommended that when creating map or data | |
78 % structs, the corresponding functions SOM_MAP_STRUCT and SOM_DATA_STRUCT | |
79 % are used instead of SOM_SET. However, when giving values for the fields, | |
80 % SOM_SET tries to guarantee that the values are valid. | |
81 % | |
82 % If a string is given as the first argument, the corresponding | |
83 % structure is first created and the field-content pairs are then | |
84 % applied to it. | |
85 % | |
86 % There can be arbitrarily many field-contents pairs. The pairs | |
87 % are processed sequentially one pair at a time. For each pair, | |
88 % the validity of the contents is checked and the corresponding | |
89 % items in the returned 'ok'-vector and 'msgs'-cellstring are set. | |
90 % - if the contents is ok, the status is set to 1 and message to '' | |
91 % - if the contents is suspicious, status is set to 1, but a | |
92 % message is produced | |
93 % - if the contents is invalid, status is set to 0 and an error | |
94 % message is produced. The contents are _not_ given to the field. | |
95 % If there is only one output argument, the status and messages | |
96 % for each pair are printed to standard output. | |
97 % | |
98 % The different field-contents pairs have no effect on each other. | |
99 % If a field is given a value multiple times, the last valid one | |
100 % stays in effect. | |
101 % | |
102 % In some cases, the order of the given fields is significant. | |
103 % For example in the case of 'som_map', the validity of some fields, | |
104 % like '.comp_names', depends on the input space dimension, which is | |
105 % checked from the '.data' field (dim = size(sD.data,2) to be specific). | |
106 % Therefore, the '.data' field (or '.codebook' field in case of map | |
107 % struct) should always be given a value first. Below is a list of | |
108 % this kind of dependancies: | |
109 % | |
110 % som_map: 'comp_names', 'comp_norm', 'msize', 'topol.msize', | |
111 % 'labels' and 'mask' depend on 'codebook' | |
112 % new value for 'codebook' should have equal size to the old | |
113 % one (unless the old one was empty) | |
114 % som_data: 'comp_names' and 'comp_norm' depend on 'data' | |
115 % new value for 'data' should have equal dimension (size(data,2)) | |
116 % as the old one (unless the old one was empty) | |
117 % | |
118 % KNOWN BUGS | |
119 % | |
120 % Checking the values given to som_grid struct has not been | |
121 % implemented. Use SOM_GRID function to give the values. | |
122 % | |
123 % REQUIRED INPUT ARGUMENTS | |
124 % | |
125 % sS The struct. | |
126 % (struct) A SOM Toolbox struct. | |
127 % (string) Identifier of a SOM Toolbox struct: 'som_map', | |
128 % 'som_data', 'som_topol', 'som_norm' or 'som_train' | |
129 % | |
130 % OPTIONAL INPUT ARGUMENTS | |
131 % | |
132 % field (string) Field identifier string (see below). | |
133 % contents (varies) Value for the field (see below). | |
134 % | |
135 % Below is the list of valid field identifiers for the different | |
136 % SOM Toolbox structs. | |
137 % | |
138 % 'som_map' (map struct) | |
139 % 'codebook' : matrix, size [munits, dim] | |
140 % 'labels' : cell array of strings, | |
141 % size [munits, maximum_number_of_labels] | |
142 % 'topol' : topology struct (prod(topol.msize)=munits) | |
143 % 'mask' : vector, size [dim, 1] | |
144 % 'neigh' : string ('gaussian' or 'cutgauss' or 'bubble' or 'ep') | |
145 % 'trainhist' : struct array of train structs | |
146 % 'name' : string | |
147 % 'comp_names' : cellstr, size [dim, 1], e.g. {'c1','c2','c3'} | |
148 % 'comp_norm' : cell array, size [dim, 1], of cell arrays | |
149 % of normalization structs | |
150 % Also the following can be used (although they are fields | |
151 % of the topology struct) | |
152 % 'msize' : vector (prod(msize)=munits) | |
153 % 'lattice' : string ('rect' or 'hexa') | |
154 % 'shape' : string ('sheet' or 'cyl' or 'toroid') | |
155 % | |
156 % 'som_data' (data struct) | |
157 % 'data' : matrix, size [dlen, dim] | |
158 % 'name' : string | |
159 % 'labels' : cell array of strings, | |
160 % size [dlen, m] | |
161 % 'comp_names' : cellstr, size [dim, 1], e.g. {'c1','c2','c3'} | |
162 % 'comp_norm' : cell array, size [dim, 1], of cell arrays | |
163 % of normalization structs | |
164 % 'label_names' : cellstr, size [m, 1] | |
165 % | |
166 % 'som_topol' (topology struct) | |
167 % 'msize' : vector | |
168 % 'lattice' : string ('rect' or 'hexa') | |
169 % 'shape' : string ('sheet' or 'cyl' or 'toroid') | |
170 % | |
171 % 'som_norm' (normalization struct) | |
172 % 'method' : string | |
173 % 'params' : varies | |
174 % 'status' : string ('done' or 'undone' or 'uninit') | |
175 % | |
176 % 'som_train' (train struct) | |
177 % 'algorithm' : string ('seq' or 'batch' or 'lininit' or 'randinit') | |
178 % 'data_name' : string | |
179 % 'mask' : vector, size [dim, 1] | |
180 % 'neigh' : string ('gaussian' or 'cutgauss' or 'bubble' or 'ep') | |
181 % 'radius_ini' : scalar | |
182 % 'radius_fin' : scalar | |
183 % 'alpha_ini' : scalar | |
184 % 'alpha_type' : string ('linear' or 'inv' or 'power') | |
185 % 'trainlen' : scalar | |
186 % 'time' : string | |
187 % | |
188 % 'som_grid' (grid struct) : checking the values has not been implemented yet! | |
189 % 'lattice' : string ('rect' or 'hexa') or | |
190 % (sparce) matrix, size munits x munits | |
191 % 'shape' : string ('sheet' or 'cyl' or 'toroid') | |
192 % 'msize' : vector, size 1x2 | |
193 % 'coord' : matrix, size munits x 2 or munits x 3 | |
194 % 'line' : string (linespec, e.g. '-', or 'none') | |
195 % 'linecolor' : RGB triple or string (colorspec, e.g. 'k') or | |
196 % munits x munits x 3 (sparce) matrix or cell | |
197 % array of RGB triples | |
198 % 'linewidth' : scalar or munits x munits (sparce) matrix | |
199 % 'marker' : string (markerspec, e.g. 'o', or 'none') or | |
200 % munits x 1 cell or char array of these | |
201 % 'markersize' : scalar or munits x 1 vector | |
202 % 'markercolor' : RGB triple or string (colorspec, e.g. 'k') | |
203 % 'surf' : [], munits x 1 or munits x 3 matrix of RGB triples | |
204 % 'label' : [] or munits x 1 char array or | |
205 % munits x l cell array of strings | |
206 % 'labelcolor' : RGB triple or string (colorspec, e.g. 'g' or 'none') | |
207 % 'labelsize' : scalar | |
208 % | |
209 % OUTPUT ARGUMENTS | |
210 % | |
211 % sS (struct) the created / updated struct | |
212 % ok (vector) length = number of field-contents pairs, gives | |
213 % validity status for each pair (0=invalid, 1 otherwise) | |
214 % msgs (cellstr) length = number of field-contents pairs, gives | |
215 % error/warning message for each pair ('' if ok) | |
216 % | |
217 % EXAMPLES | |
218 % | |
219 % To create a struct: | |
220 % sM = som_set('som_map'); | |
221 % sD = som_set('som_data'); | |
222 % sTo = som_set('som_topol'); | |
223 % sTr = som_set('som_train'); | |
224 % sN = som_set('som_norm'); | |
225 % sG = som_set('som_grid'); | |
226 % | |
227 % To check the the contents of a struct: | |
228 % som_set(sS); | |
229 % [dummy,ok] = som_set(sS); | |
230 % [dummy,ok,msgs] = som_set(sS); | |
231 % | |
232 % To give values to fields: | |
233 % sTo = som_set(sTo,'msize',[10 10],'lattice','hexa','shape','toroid'); | |
234 % sM = som_set('som_map','codebook',rand(100,4),'topol',sTo); | |
235 % | |
236 % SEE ALSO | |
237 % | |
238 % som_info Prints information the given struct. | |
239 % som_map_struct Create map struct. | |
240 % som_data_struct Create data struct. | |
241 % som_topol_struct Create topology struct. | |
242 % som_train_struct Create training struct. | |
243 % som_grid Create and visualize grid struct. | |
244 % som_vs1to2 Conversion from version 1.0 structs to 2.0. | |
245 % som_vs2to1 Conversion from version 2.0 structs to 1.0. | |
246 | |
247 % Copyright (c) 1999-2000 by the SOM toolbox programming team. | |
248 % http://www.cis.hut.fi/projects/somtoolbox/ | |
249 | |
250 % Version 2.0beta juuso 101199 130300 | |
251 | |
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
253 %% create struct if necessary | |
254 | |
255 if ischar(sS), | |
256 switch sS | |
257 case 'som_map', | |
258 sS=struct('type', 'som_map', ... | |
259 'codebook', [], ... | |
260 'topol', som_set('som_topol'), ... | |
261 'labels', cell(1), ... | |
262 'neigh', 'gaussian', ... | |
263 'mask', [], ... | |
264 'trainhist', cell(1), ... | |
265 'name', '',... | |
266 'comp_names', {''}, ... | |
267 'comp_norm', cell(1)); | |
268 case 'som_data', | |
269 sS=struct('type', 'som_data', ... | |
270 'data', [], ... | |
271 'labels', cell(1), ... | |
272 'name', '', ... | |
273 'comp_names', {''}, ... | |
274 'comp_norm', cell(1), ... | |
275 'label_names', []); | |
276 case 'som_topol', | |
277 sS=struct('type', 'som_topol', ... | |
278 'msize', 0, ... | |
279 'lattice', 'hexa', ... | |
280 'shape', 'sheet'); | |
281 case 'som_train', | |
282 sS=struct('type', 'som_train', ... | |
283 'algorithm', '', ... | |
284 'data_name', '', ... | |
285 'neigh', 'gaussian', ... | |
286 'mask', [], ... | |
287 'radius_ini', NaN, ... | |
288 'radius_fin', NaN, ... | |
289 'alpha_ini', NaN, ... | |
290 'alpha_type', 'inv', ... | |
291 'trainlen', NaN, ... | |
292 'time', ''); | |
293 case 'som_norm', | |
294 sS=struct('type', 'som_norm', ... | |
295 'method', 'var', ... | |
296 'params', [], ... | |
297 'status', 'uninit'); | |
298 case 'som_grid', | |
299 sS=struct('type','som_grid',... | |
300 'lattice','hexa',... | |
301 'shape','sheet',... | |
302 'msize',[1 1],... | |
303 'coord',[],... | |
304 'line','-',... | |
305 'linecolor',[.9 .9 .9],... | |
306 'linewidth',0.5,... | |
307 'marker','o',... | |
308 'markersize',6,... | |
309 'markercolor','k',... | |
310 'surf',[],... | |
311 'label',[],... | |
312 'labelcolor','g',... | |
313 'labelsize',12); | |
314 otherwise | |
315 ok=0; msgs = {['Unrecognized struct type: ' sS]}; sS = []; | |
316 return; | |
317 end | |
318 | |
319 elseif isstruct(sS) & length(varargin)==0, | |
320 | |
321 % check all fields | |
322 fields = fieldnames(sS); | |
323 if ~any(strcmp('type',fields)), | |
324 error('The struct has no ''type'' field.'); | |
325 end | |
326 k = 0; | |
327 for i=1:length(fields), | |
328 contents = getfield(sS,fields{i}); | |
329 if ~strcmp(fields{i},'type'), | |
330 varargin{k+1} = fields{i}; | |
331 varargin{k+2} = contents; | |
332 k = k + 2; | |
333 else | |
334 if ~any(strcmp(contents, ... | |
335 {'som_map','som_data','som_topol','som_train','som_norm'})), | |
336 error(['Unknown struct type: ' contents]); | |
337 end | |
338 end | |
339 end | |
340 | |
341 end | |
342 | |
343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
344 %% set field values | |
345 | |
346 p = ceil(length(varargin)/2); | |
347 ok = ones(p,1); | |
348 msgs = cell(p,1); | |
349 | |
350 for i=1:p, | |
351 field = varargin{2*i-1}; | |
352 content = varargin{2*i}; | |
353 msg = ''; | |
354 isok = 0; | |
355 | |
356 si = size(content); | |
357 isscalar = (prod(si)==1); | |
358 isvector = (sum(si>1)==1); | |
359 isrowvector = (isvector & si(1)==1); | |
360 if isnumeric(content), | |
361 iscomplete = all(~isnan(content(:))); | |
362 ispositive = all(content(:)>0); | |
363 isinteger = all(content(:)==ceil(content(:))); | |
364 isrgb = all(content(:)>=0 & content(:)<=1) & size(content,2)==3; | |
365 end | |
366 | |
367 switch sS.type, | |
368 case 'som_map', | |
369 [munits dim] = size(sS.codebook); | |
370 switch field, | |
371 case 'codebook', | |
372 if ~isnumeric(content), | |
373 msg = '''codebook'' should be a numeric matrix'; | |
374 elseif size(content) ~= size(sS.codebook) & ~isempty(sS.codebook), | |
375 msg = 'New ''codebook'' must be equal in size to the old one.'; | |
376 elseif ~iscomplete, | |
377 msg = 'Map codebook must not contain NaN''s.'; | |
378 else | |
379 sS.codebook = content; isok=1; | |
380 end | |
381 case 'labels', | |
382 if isempty(content), | |
383 sS.labels = cell(munits,1); isok = 1; | |
384 elseif size(content,1) ~= munits, | |
385 msg = 'Length of labels array must be equal to the number of map units.'; | |
386 elseif ~iscell(content) & ~ischar(content), | |
387 msg = '''labels'' must be a string array or a cell array/matrix.'; | |
388 else | |
389 isok = 1; | |
390 if ischar(content), content = cellstr(content); | |
391 elseif ~iscellstr(content), | |
392 l = prod(size(content)); | |
393 for j=1:l, | |
394 if ischar(content{j}), | |
395 if ~isempty(content{j}), | |
396 msg = 'Invalid ''labels'' array.'; | |
397 isok = 0; | |
398 break; | |
399 else | |
400 content{j} = ''; | |
401 end | |
402 end | |
403 end | |
404 end | |
405 if isok, sS.labels = content; end | |
406 end | |
407 case 'topol', | |
408 if ~isstruct(content), | |
409 msg = '''topol'' should be a topology struct.'; | |
410 elseif ~isfield(content,'msize') | ... | |
411 ~isfield(content,'lattice') | ... | |
412 ~isfield(content,'shape'), | |
413 msg = '''topol'' is not a valid topology struct.'; | |
414 elseif prod(content.msize) ~= munits, | |
415 msg = '''topol''.msize does not match the number of map units.'; | |
416 else | |
417 sS.topol = content; isok = 1; | |
418 end | |
419 case 'msize', | |
420 if ~isnumeric(content) | ~isvector | ~ispositive | ~isinteger, | |
421 msg = '''msize'' should be a vector with positive integer elements.'; | |
422 elseif prod(content) ~= munits, | |
423 msg = '''msize'' does not match the map size.'; | |
424 else | |
425 sS.topol.msize = content; isok = 1; | |
426 end | |
427 case 'lattice', | |
428 if ~ischar(content), | |
429 msg = '''lattice'' should be a string'; | |
430 elseif ~strcmp(content,'rect') & ~strcmp(content,'hexa'), | |
431 msg = ['Unknown lattice type: ' content]; | |
432 sS.topol.lattice = content; isok = 1; | |
433 else | |
434 sS.topol.lattice = content; isok = 1; | |
435 end | |
436 case 'shape', | |
437 if ~ischar(content), | |
438 msg = '''shape'' should be a string'; | |
439 elseif ~strcmp(content,'sheet') & ~strcmp(content,'cyl') & ... | |
440 ~strcmp(content,'toroid'), | |
441 msg = ['Unknown shape type:' content]; | |
442 sS.topol.shape = content; isok = 1; | |
443 else | |
444 sS.topol.shape = content; isok = 1; | |
445 end | |
446 case 'neigh', | |
447 if ~ischar(content), | |
448 msg = '''neigh'' should be a string'; | |
449 elseif ~strcmp(content,'gaussian') & ~strcmp(content,'ep') & ... | |
450 ~strcmp(content,'cutgauss') & ~strcmp(content,'bubble'), | |
451 msg = ['Unknown neighborhood function: ' content]; | |
452 sS.neigh = content; isok = 1; | |
453 else | |
454 sS.neigh = content; isok = 1; | |
455 end | |
456 case 'mask', | |
457 if size(content,1) == 1, content = content'; end | |
458 if ~isnumeric(content) | size(content) ~= [dim 1], | |
459 msg = '''mask'' should be a column vector (size dim x 1).'; | |
460 else | |
461 sS.mask = content; isok = 1; | |
462 end | |
463 case 'name', | |
464 if ~ischar(content), | |
465 msg = '''name'' should be a string.'; | |
466 else | |
467 sS.name = content; isok = 1; | |
468 end | |
469 case 'comp_names', | |
470 if ~iscell(content) & ~ischar(content), | |
471 msg = '''comp_names'' should be a cell string or a string array.'; | |
472 elseif length(content) ~= dim, | |
473 msg = 'Length of ''comp_names'' should be equal to dim.'; | |
474 else | |
475 if ischar(content), content = cellstr(content); end | |
476 if size(content,1)==1, content = content'; end | |
477 sS.comp_names = content; | |
478 isok = 1; | |
479 end | |
480 case 'comp_norm', | |
481 if ~iscell(content) & length(content)>0, | |
482 msg = '''comp_norm'' should be a cell array.'; | |
483 elseif length(content) ~= dim, | |
484 msg = 'Length of ''comp_norm'' should be equal to dim.'; | |
485 else | |
486 isok = 1; | |
487 for j=1:length(content), | |
488 if ~isempty(content{j}) & (~isfield(content{j}(1),'type') | ... | |
489 ~strcmp(content{j}(1).type,'som_norm')), | |
490 msg = 'Each cell in ''comp_norm'' should be either empty or type ''som_norm''.'; | |
491 isok = 0; | |
492 break; | |
493 end | |
494 end | |
495 if isok, sS.comp_norm = content; end | |
496 end | |
497 case 'trainhist', | |
498 if ~isstruct(content) & ~isempty(content), | |
499 msg = '''trainhist'' should be a struct array or empty.'; | |
500 else | |
501 isok = 1; | |
502 for j=1:length(content), | |
503 if ~isfield(content(j),'type') | ~strcmp(content(j).type,'som_train'), | |
504 msg = 'Each cell in ''trainhist'' should be of type ''som_train''.'; | |
505 isok = 0; | |
506 break; | |
507 end | |
508 end | |
509 if isok, sS.trainhist = content; end | |
510 end | |
511 otherwise, | |
512 msg = ['Invalid field for map struct: ' field]; | |
513 end | |
514 | |
515 case 'som_data', | |
516 [dlen dim] = size(sS.data); | |
517 switch field, | |
518 case 'data', | |
519 [dummy dim2] = size(content); | |
520 if prod(si)==0, | |
521 msg = '''data'' is empty'; | |
522 elseif ~isnumeric(content), | |
523 msg = '''data'' should be numeric matrix.'; | |
524 elseif dim ~= dim2 & ~isempty(sS.data), | |
525 msg = 'New ''data'' must have the same dimension as old one.'; | |
526 else | |
527 sS.data = content; isok = 1; | |
528 end | |
529 case 'labels', | |
530 if isempty(content), | |
531 sS.labels = cell(dlen,1); isok = 1; | |
532 elseif size(content,1) ~= dlen, | |
533 msg = 'Length of ''labels'' must be equal to the number of data vectors.'; | |
534 elseif ~iscell(content) & ~ischar(content), | |
535 msg = '''labels'' must be a string array or a cell array/matrix.'; | |
536 else | |
537 isok = 1; | |
538 if ischar(content), content = cellstr(content); | |
539 elseif ~iscellstr(content), | |
540 l = prod(size(content)); | |
541 for j=1:l, | |
542 if ~ischar(content{j}), | |
543 if ~isempty(content{j}), | |
544 msg = 'Invalid ''labels'' array.'; | |
545 isok = 0; j | |
546 break; | |
547 else | |
548 content{j} = ''; | |
549 end | |
550 end | |
551 end | |
552 end | |
553 if isok, sS.labels = content; end | |
554 end | |
555 case 'name', | |
556 if ~ischar(content), | |
557 msg = '''name'' should be a string.'; | |
558 else | |
559 sS.name = content; isok = 1; | |
560 end | |
561 case 'comp_names', | |
562 if ~iscell(content) & ~ischar(content), | |
563 msg = '''comp_names'' should be a cell string or a string array.'; | |
564 elseif length(content) ~= dim, | |
565 msg = 'Length of ''comp_names'' should be equal to dim.'; | |
566 else | |
567 if ischar(content), content = cellstr(content); end | |
568 if size(content,1)==1, content = content'; end | |
569 sS.comp_names = content; | |
570 isok = 1; | |
571 end | |
572 case 'comp_norm', | |
573 if ~iscell(content) & length(content)>0, | |
574 msg = '''comp_norm'' should be a cell array.'; | |
575 elseif length(content) ~= dim, | |
576 msg = 'Length of ''comp_norm'' should be equal to dim.'; | |
577 else | |
578 isok = 1; | |
579 for j=1:length(content), | |
580 if ~isempty(content{j}) & (~isfield(content{j}(1),'type') | ... | |
581 ~strcmp(content{j}(1).type,'som_norm')), | |
582 msg = 'Each cell in ''comp_norm'' should be either empty or type ''som_norm''.'; | |
583 isok = 0; | |
584 break; | |
585 end | |
586 end | |
587 if isok, sS.comp_norm = content; end | |
588 end | |
589 case 'label_names', | |
590 if ~iscell(content) & ~ischar(content) & ~isempty(content), | |
591 msg = ['''label_names'' should be a cell string, a string array or' ... | |
592 ' empty.']; | |
593 else | |
594 if ~isempty(content), | |
595 if ischar(content), content = cellstr(content); end | |
596 if size(content,1)==1, content = content'; end | |
597 end | |
598 sS.label_names = content; | |
599 isok = 1; | |
600 end | |
601 otherwise, | |
602 msg = ['Invalid field for data struct: ' field]; | |
603 end | |
604 | |
605 case 'som_topol', | |
606 switch field, | |
607 case 'msize', | |
608 if ~isnumeric(content) | ~isvector | ~ispositive | ~isinteger, | |
609 msg = '''msize'' should be a vector with positive integer elements.'; | |
610 else | |
611 sS.msize = content; isok=1; | |
612 end | |
613 case 'lattice', | |
614 if ~ischar(content), | |
615 msg = '''lattice'' should be a string'; | |
616 elseif ~strcmp(content,'rect') & ~strcmp(content,'hexa'), | |
617 msg = ['Unknown lattice type: ' content]; | |
618 sS.lattice = content; isok = 1; | |
619 else | |
620 sS.lattice = content; isok = 1; | |
621 end | |
622 case 'shape', | |
623 if ~ischar(content), | |
624 msg = '''shape'' should be a string'; | |
625 elseif ~strcmp(content,'sheet') & ~strcmp(content,'cyl') & ... | |
626 ~strcmp(content,'toroid'), | |
627 msg = ['Unknown shape type: ' content]; | |
628 sS.shape = content; isok = 1; | |
629 else | |
630 sS.shape = content; isok = 1; | |
631 end | |
632 otherwise, | |
633 msg = ['Invalid field for topology struct: ' field]; | |
634 end | |
635 | |
636 case 'som_train', | |
637 switch field, | |
638 case 'algorithm', | |
639 if ~ischar(content), | |
640 msg = '''algorithm'' should be a string.'; | |
641 else | |
642 sS.algorithm = content; isok = 1; | |
643 end | |
644 case 'data_name', | |
645 if ~ischar(content), | |
646 msg = '''data_name'' should be a string'; | |
647 else | |
648 sS.data_name = content; isok = 1; | |
649 end | |
650 case 'neigh', | |
651 if ~ischar(content), | |
652 msg = '''neigh'' should be a string'; | |
653 elseif ~isempty(content) & ~strcmp(content,'gaussian') & ~strcmp(content,'ep') & ... | |
654 ~strcmp(content,'cutgauss') & ~strcmp(content,'bubble'), | |
655 msg = ['Unknown neighborhood function: ' content]; | |
656 sS.neigh = content; isok = 1; | |
657 else | |
658 sS.neigh = content; isok = 1; | |
659 end | |
660 case 'mask', | |
661 if size(content,1) == 1, content = content'; end | |
662 dim = size(content,1); %[munits dim] = size(sS.data); | |
663 if ~isnumeric(content) | size(content) ~= [dim 1], | |
664 msg = '''mask'' should be a column vector (size dim x 1).'; | |
665 else | |
666 sS.mask = content; isok = 1; | |
667 end | |
668 case 'radius_ini', | |
669 if ~isnumeric(content) | ~isscalar, | |
670 msg = '''radius_ini'' should be a scalar.'; | |
671 else | |
672 sS.radius_ini = content; isok = 1; | |
673 end | |
674 case 'radius_fin', | |
675 if ~isnumeric(content) | ~isscalar, | |
676 msg = '''radius_fin'' should be a scalar.'; | |
677 else | |
678 sS.radius_fin = content; isok = 1; | |
679 end | |
680 case 'alpha_ini', | |
681 if ~isnumeric(content) | ~isscalar, | |
682 msg = '''alpha_ini'' should be a scalar.'; | |
683 else | |
684 sS.alpha_ini = content; isok = 1; | |
685 end | |
686 case 'alpha_type', | |
687 if ~ischar(content), | |
688 msg = '''alpha_type'' should be a string'; | |
689 elseif ~strcmp(content,'linear') & ~strcmp(content,'inv') & ... | |
690 ~strcmp(content,'power') & ~strcmp(content,'constant') & ~strcmp(content,''), | |
691 msg = ['Unknown alpha type: ' content]; | |
692 sS.alpha_type = content; isok = 1; | |
693 else | |
694 sS.alpha_type = content; isok = 1; | |
695 end | |
696 case 'trainlen', | |
697 if ~isnumeric(content) | ~isscalar, | |
698 msg = '''trainlen'' should be a scalar.'; | |
699 else | |
700 sS.trainlen = content; isok = 1; | |
701 end | |
702 case 'time', | |
703 if ~ischar(content), | |
704 msg = '''time'' should be a string'; | |
705 else | |
706 sS.time = content; isok = 1; | |
707 end | |
708 otherwise, | |
709 msg = ['Invalid field for train struct: ' field]; | |
710 end | |
711 | |
712 case 'som_norm', | |
713 switch field, | |
714 case 'method', | |
715 if ~ischar(field), | |
716 msg = '''method'' should be a string.'; | |
717 else | |
718 sS.method = content; isok = 1; | |
719 end | |
720 case 'params', | |
721 sS.params = content; isok = 1; | |
722 case 'status', | |
723 if ~ischar(content), | |
724 msg = '''status'' should be a string'; | |
725 elseif ~strcmp(content,'done') & ~strcmp(content,'undone') & ... | |
726 ~strcmp(content,'uninit'), | |
727 msg = ['Unknown status type: ' content]; | |
728 sS.status = content; isok = 1; | |
729 else | |
730 sS.status = content; isok = 1; | |
731 end | |
732 otherwise, | |
733 msg = ['Invalid field for normalization struct: ' field]; | |
734 end | |
735 | |
736 case 'som_grid', | |
737 if any(strcmp(field,{'lattice', 'shape', 'msize', 'coord',... | |
738 'line', 'linecolor', 'linewidth', ... | |
739 'marker', 'markersize', 'markercolor', 'surf', ... | |
740 'label', 'labelcolor', 'labelsize'})), | |
741 warning('No checking done on field identifier or content.'); | |
742 sS = setfield(sS,field,content); | |
743 isok = 1; | |
744 else | |
745 msg = ['Invalid field for grid struct: ' field]; | |
746 end | |
747 | |
748 otherwise, | |
749 error('Unrecognized structure.'); | |
750 | |
751 end | |
752 | |
753 msgs{i} = msg; | |
754 ok(i) = isok; | |
755 | |
756 end | |
757 | |
758 | |
759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
760 %% return | |
761 | |
762 if nargout < 2, | |
763 for i=1:p, | |
764 if ~isempty(msgs{i}), | |
765 if ~ok(i), fprintf(1,'[Error! '); | |
766 else fprintf(1,'[Notice '); | |
767 end | |
768 fprintf(1,'in setting %s] ',varargin{2*i-1}); | |
769 fprintf(1,'%s\n',msgs{i}); | |
770 end | |
771 end | |
772 end | |
773 | |
774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
775 | |
776 | |
777 |