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