Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/som_set.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,777 @@ +function [sS, ok, msgs] = som_set(sS, varargin) + +%SOM_SET Create and check SOM Toolbox structs, give values to their fields. +% +% [sS, ok, msgs] = som_set(sS, [field, contents, ...]) +% +% sM = som_set(sM,'name','SOM#1.1'); +% [dummy,ok,msgs] = som_set(sData); +% sT = som_set('som_topol','msize',[10 10],'lattice','hexa'); +% [sTrain,ok] = som_set(sTrain,'algorithm','lininit'); +% [sN,ok,msgs] = som_set('som_norm'); +% +% Input and output arguments ([]'s are optional): +% sS the target struct +% (struct) a SOM Toolbox structure (not visualization struct) +% (string) structure identifier (see below) +% the updated/created structure is returned +% [field, (string) field to be given value to (see below) +% contents] (varies) the contents for the field +% +% ok (vector) status for each field-contents pair (1=ok) +% msgs (cellstr) status string for each field-contents pair (''=ok) +% +% There can be arbitrarily many field-contents pairs. If there +% are _no_ field-content pairs, and the first argument is a struct, +% the fields of the struct are checked for validity. +% +% Valid struct and corresponding field identifiers: +% 'som_map' : 'codebook', 'labels', 'mask', 'neigh', 'name', +% 'topol', 'msize, 'lattice', 'shape', +% 'trainhist', 'comp_names', 'comp_norm', +% 'som_data' : 'data', 'labels', 'name', 'comp_names', 'comp_norm', +% 'label_names' +% 'som_topol' : 'msize', 'lattice', 'shape' +% 'som_norm' : 'method', 'params', 'status' +% 'som_train' : 'algorithm', 'data_name', 'mask', 'neigh', +% 'radius_ini', 'radius_fin', 'alpha_ini', 'alpha_type', +% 'trainlen', 'time' +% 'som_grid' : 'lattice', 'shape', 'msize', 'coord', +% 'line', 'linecolor', 'linewidth', +% 'marker', 'markersize', 'markercolor', 'surf', +% 'label', 'labelcolor', 'labelsize' +% checking given values has not been implemented yet! +% +% For more help, try 'type som_set' or check out online documentation. +% See also SOM_INFO, SOM_MAP_STRUCT, SOM_DATA_STRUCT, SOM_VS1TO2. + +%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% som_set +% +% PURPOSE +% +% Create and set values for fields of SOM Toolbox structs (except +% visualization struct). Can also be used to check the validity of structs. +% +% SYNTAX +% +% sMap = som_set('som_map'); +% sData = som_set(sData); +% sNorm = som_set(...,'field',contents,...); +% [sTopol,ok] = som_set(sTopol,...); +% [sTrain,ok,msgs] = som_set('som_train',...); +% +% DESCRIPTION +% +% The function is used to create and set values for fields of SOM +% Toolbox structs, except visualization structs. The given values are +% first checked for validity, and if they are not valid, an error +% message is returned. The function can also be used to check the +% validity of all the fields of the struct by supplying a struct as +% the first and only argument. +% +% NOTE: Using SOM_SET to create structures does _not_ guarantee that the +% structs are valid (try e.g. sM = som_set('som_map'); som_set(sM)). The +% initial values that the function gives to the fields of the structs are +% typically invalid. It is recommended that when creating map or data +% structs, the corresponding functions SOM_MAP_STRUCT and SOM_DATA_STRUCT +% are used instead of SOM_SET. However, when giving values for the fields, +% SOM_SET tries to guarantee that the values are valid. +% +% If a string is given as the first argument, the corresponding +% structure is first created and the field-content pairs are then +% applied to it. +% +% There can be arbitrarily many field-contents pairs. The pairs +% are processed sequentially one pair at a time. For each pair, +% the validity of the contents is checked and the corresponding +% items in the returned 'ok'-vector and 'msgs'-cellstring are set. +% - if the contents is ok, the status is set to 1 and message to '' +% - if the contents is suspicious, status is set to 1, but a +% message is produced +% - if the contents is invalid, status is set to 0 and an error +% message is produced. The contents are _not_ given to the field. +% If there is only one output argument, the status and messages +% for each pair are printed to standard output. +% +% The different field-contents pairs have no effect on each other. +% If a field is given a value multiple times, the last valid one +% stays in effect. +% +% In some cases, the order of the given fields is significant. +% For example in the case of 'som_map', the validity of some fields, +% like '.comp_names', depends on the input space dimension, which is +% checked from the '.data' field (dim = size(sD.data,2) to be specific). +% Therefore, the '.data' field (or '.codebook' field in case of map +% struct) should always be given a value first. Below is a list of +% this kind of dependancies: +% +% som_map: 'comp_names', 'comp_norm', 'msize', 'topol.msize', +% 'labels' and 'mask' depend on 'codebook' +% new value for 'codebook' should have equal size to the old +% one (unless the old one was empty) +% som_data: 'comp_names' and 'comp_norm' depend on 'data' +% new value for 'data' should have equal dimension (size(data,2)) +% as the old one (unless the old one was empty) +% +% KNOWN BUGS +% +% Checking the values given to som_grid struct has not been +% implemented. Use SOM_GRID function to give the values. +% +% REQUIRED INPUT ARGUMENTS +% +% sS The struct. +% (struct) A SOM Toolbox struct. +% (string) Identifier of a SOM Toolbox struct: 'som_map', +% 'som_data', 'som_topol', 'som_norm' or 'som_train' +% +% OPTIONAL INPUT ARGUMENTS +% +% field (string) Field identifier string (see below). +% contents (varies) Value for the field (see below). +% +% Below is the list of valid field identifiers for the different +% SOM Toolbox structs. +% +% 'som_map' (map struct) +% 'codebook' : matrix, size [munits, dim] +% 'labels' : cell array of strings, +% size [munits, maximum_number_of_labels] +% 'topol' : topology struct (prod(topol.msize)=munits) +% 'mask' : vector, size [dim, 1] +% 'neigh' : string ('gaussian' or 'cutgauss' or 'bubble' or 'ep') +% 'trainhist' : struct array of train structs +% 'name' : string +% 'comp_names' : cellstr, size [dim, 1], e.g. {'c1','c2','c3'} +% 'comp_norm' : cell array, size [dim, 1], of cell arrays +% of normalization structs +% Also the following can be used (although they are fields +% of the topology struct) +% 'msize' : vector (prod(msize)=munits) +% 'lattice' : string ('rect' or 'hexa') +% 'shape' : string ('sheet' or 'cyl' or 'toroid') +% +% 'som_data' (data struct) +% 'data' : matrix, size [dlen, dim] +% 'name' : string +% 'labels' : cell array of strings, +% size [dlen, m] +% 'comp_names' : cellstr, size [dim, 1], e.g. {'c1','c2','c3'} +% 'comp_norm' : cell array, size [dim, 1], of cell arrays +% of normalization structs +% 'label_names' : cellstr, size [m, 1] +% +% 'som_topol' (topology struct) +% 'msize' : vector +% 'lattice' : string ('rect' or 'hexa') +% 'shape' : string ('sheet' or 'cyl' or 'toroid') +% +% 'som_norm' (normalization struct) +% 'method' : string +% 'params' : varies +% 'status' : string ('done' or 'undone' or 'uninit') +% +% 'som_train' (train struct) +% 'algorithm' : string ('seq' or 'batch' or 'lininit' or 'randinit') +% 'data_name' : string +% 'mask' : vector, size [dim, 1] +% 'neigh' : string ('gaussian' or 'cutgauss' or 'bubble' or 'ep') +% 'radius_ini' : scalar +% 'radius_fin' : scalar +% 'alpha_ini' : scalar +% 'alpha_type' : string ('linear' or 'inv' or 'power') +% 'trainlen' : scalar +% 'time' : string +% +% 'som_grid' (grid struct) : checking the values has not been implemented yet! +% 'lattice' : string ('rect' or 'hexa') or +% (sparce) matrix, size munits x munits +% 'shape' : string ('sheet' or 'cyl' or 'toroid') +% 'msize' : vector, size 1x2 +% 'coord' : matrix, size munits x 2 or munits x 3 +% 'line' : string (linespec, e.g. '-', or 'none') +% 'linecolor' : RGB triple or string (colorspec, e.g. 'k') or +% munits x munits x 3 (sparce) matrix or cell +% array of RGB triples +% 'linewidth' : scalar or munits x munits (sparce) matrix +% 'marker' : string (markerspec, e.g. 'o', or 'none') or +% munits x 1 cell or char array of these +% 'markersize' : scalar or munits x 1 vector +% 'markercolor' : RGB triple or string (colorspec, e.g. 'k') +% 'surf' : [], munits x 1 or munits x 3 matrix of RGB triples +% 'label' : [] or munits x 1 char array or +% munits x l cell array of strings +% 'labelcolor' : RGB triple or string (colorspec, e.g. 'g' or 'none') +% 'labelsize' : scalar +% +% OUTPUT ARGUMENTS +% +% sS (struct) the created / updated struct +% ok (vector) length = number of field-contents pairs, gives +% validity status for each pair (0=invalid, 1 otherwise) +% msgs (cellstr) length = number of field-contents pairs, gives +% error/warning message for each pair ('' if ok) +% +% EXAMPLES +% +% To create a struct: +% sM = som_set('som_map'); +% sD = som_set('som_data'); +% sTo = som_set('som_topol'); +% sTr = som_set('som_train'); +% sN = som_set('som_norm'); +% sG = som_set('som_grid'); +% +% To check the the contents of a struct: +% som_set(sS); +% [dummy,ok] = som_set(sS); +% [dummy,ok,msgs] = som_set(sS); +% +% To give values to fields: +% sTo = som_set(sTo,'msize',[10 10],'lattice','hexa','shape','toroid'); +% sM = som_set('som_map','codebook',rand(100,4),'topol',sTo); +% +% SEE ALSO +% +% som_info Prints information the given struct. +% som_map_struct Create map struct. +% som_data_struct Create data struct. +% som_topol_struct Create topology struct. +% som_train_struct Create training struct. +% som_grid Create and visualize grid struct. +% som_vs1to2 Conversion from version 1.0 structs to 2.0. +% som_vs2to1 Conversion from version 2.0 structs to 1.0. + +% Copyright (c) 1999-2000 by the SOM toolbox programming team. +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 2.0beta juuso 101199 130300 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% create struct if necessary + +if ischar(sS), + switch sS + case 'som_map', + sS=struct('type', 'som_map', ... + 'codebook', [], ... + 'topol', som_set('som_topol'), ... + 'labels', cell(1), ... + 'neigh', 'gaussian', ... + 'mask', [], ... + 'trainhist', cell(1), ... + 'name', '',... + 'comp_names', {''}, ... + 'comp_norm', cell(1)); + case 'som_data', + sS=struct('type', 'som_data', ... + 'data', [], ... + 'labels', cell(1), ... + 'name', '', ... + 'comp_names', {''}, ... + 'comp_norm', cell(1), ... + 'label_names', []); + case 'som_topol', + sS=struct('type', 'som_topol', ... + 'msize', 0, ... + 'lattice', 'hexa', ... + 'shape', 'sheet'); + case 'som_train', + sS=struct('type', 'som_train', ... + 'algorithm', '', ... + 'data_name', '', ... + 'neigh', 'gaussian', ... + 'mask', [], ... + 'radius_ini', NaN, ... + 'radius_fin', NaN, ... + 'alpha_ini', NaN, ... + 'alpha_type', 'inv', ... + 'trainlen', NaN, ... + 'time', ''); + case 'som_norm', + sS=struct('type', 'som_norm', ... + 'method', 'var', ... + 'params', [], ... + 'status', 'uninit'); + case 'som_grid', + sS=struct('type','som_grid',... + 'lattice','hexa',... + 'shape','sheet',... + 'msize',[1 1],... + 'coord',[],... + 'line','-',... + 'linecolor',[.9 .9 .9],... + 'linewidth',0.5,... + 'marker','o',... + 'markersize',6,... + 'markercolor','k',... + 'surf',[],... + 'label',[],... + 'labelcolor','g',... + 'labelsize',12); + otherwise + ok=0; msgs = {['Unrecognized struct type: ' sS]}; sS = []; + return; + end + +elseif isstruct(sS) & length(varargin)==0, + + % check all fields + fields = fieldnames(sS); + if ~any(strcmp('type',fields)), + error('The struct has no ''type'' field.'); + end + k = 0; + for i=1:length(fields), + contents = getfield(sS,fields{i}); + if ~strcmp(fields{i},'type'), + varargin{k+1} = fields{i}; + varargin{k+2} = contents; + k = k + 2; + else + if ~any(strcmp(contents, ... + {'som_map','som_data','som_topol','som_train','som_norm'})), + error(['Unknown struct type: ' contents]); + end + end + end + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% set field values + +p = ceil(length(varargin)/2); +ok = ones(p,1); +msgs = cell(p,1); + +for i=1:p, + field = varargin{2*i-1}; + content = varargin{2*i}; + msg = ''; + isok = 0; + + si = size(content); + isscalar = (prod(si)==1); + isvector = (sum(si>1)==1); + isrowvector = (isvector & si(1)==1); + if isnumeric(content), + iscomplete = all(~isnan(content(:))); + ispositive = all(content(:)>0); + isinteger = all(content(:)==ceil(content(:))); + isrgb = all(content(:)>=0 & content(:)<=1) & size(content,2)==3; + end + + switch sS.type, + case 'som_map', + [munits dim] = size(sS.codebook); + switch field, + case 'codebook', + if ~isnumeric(content), + msg = '''codebook'' should be a numeric matrix'; + elseif size(content) ~= size(sS.codebook) & ~isempty(sS.codebook), + msg = 'New ''codebook'' must be equal in size to the old one.'; + elseif ~iscomplete, + msg = 'Map codebook must not contain NaN''s.'; + else + sS.codebook = content; isok=1; + end + case 'labels', + if isempty(content), + sS.labels = cell(munits,1); isok = 1; + elseif size(content,1) ~= munits, + msg = 'Length of labels array must be equal to the number of map units.'; + elseif ~iscell(content) & ~ischar(content), + msg = '''labels'' must be a string array or a cell array/matrix.'; + else + isok = 1; + if ischar(content), content = cellstr(content); + elseif ~iscellstr(content), + l = prod(size(content)); + for j=1:l, + if ischar(content{j}), + if ~isempty(content{j}), + msg = 'Invalid ''labels'' array.'; + isok = 0; + break; + else + content{j} = ''; + end + end + end + end + if isok, sS.labels = content; end + end + case 'topol', + if ~isstruct(content), + msg = '''topol'' should be a topology struct.'; + elseif ~isfield(content,'msize') | ... + ~isfield(content,'lattice') | ... + ~isfield(content,'shape'), + msg = '''topol'' is not a valid topology struct.'; + elseif prod(content.msize) ~= munits, + msg = '''topol''.msize does not match the number of map units.'; + else + sS.topol = content; isok = 1; + end + case 'msize', + if ~isnumeric(content) | ~isvector | ~ispositive | ~isinteger, + msg = '''msize'' should be a vector with positive integer elements.'; + elseif prod(content) ~= munits, + msg = '''msize'' does not match the map size.'; + else + sS.topol.msize = content; isok = 1; + end + case 'lattice', + if ~ischar(content), + msg = '''lattice'' should be a string'; + elseif ~strcmp(content,'rect') & ~strcmp(content,'hexa'), + msg = ['Unknown lattice type: ' content]; + sS.topol.lattice = content; isok = 1; + else + sS.topol.lattice = content; isok = 1; + end + case 'shape', + if ~ischar(content), + msg = '''shape'' should be a string'; + elseif ~strcmp(content,'sheet') & ~strcmp(content,'cyl') & ... + ~strcmp(content,'toroid'), + msg = ['Unknown shape type:' content]; + sS.topol.shape = content; isok = 1; + else + sS.topol.shape = content; isok = 1; + end + case 'neigh', + if ~ischar(content), + msg = '''neigh'' should be a string'; + elseif ~strcmp(content,'gaussian') & ~strcmp(content,'ep') & ... + ~strcmp(content,'cutgauss') & ~strcmp(content,'bubble'), + msg = ['Unknown neighborhood function: ' content]; + sS.neigh = content; isok = 1; + else + sS.neigh = content; isok = 1; + end + case 'mask', + if size(content,1) == 1, content = content'; end + if ~isnumeric(content) | size(content) ~= [dim 1], + msg = '''mask'' should be a column vector (size dim x 1).'; + else + sS.mask = content; isok = 1; + end + case 'name', + if ~ischar(content), + msg = '''name'' should be a string.'; + else + sS.name = content; isok = 1; + end + case 'comp_names', + if ~iscell(content) & ~ischar(content), + msg = '''comp_names'' should be a cell string or a string array.'; + elseif length(content) ~= dim, + msg = 'Length of ''comp_names'' should be equal to dim.'; + else + if ischar(content), content = cellstr(content); end + if size(content,1)==1, content = content'; end + sS.comp_names = content; + isok = 1; + end + case 'comp_norm', + if ~iscell(content) & length(content)>0, + msg = '''comp_norm'' should be a cell array.'; + elseif length(content) ~= dim, + msg = 'Length of ''comp_norm'' should be equal to dim.'; + else + isok = 1; + for j=1:length(content), + if ~isempty(content{j}) & (~isfield(content{j}(1),'type') | ... + ~strcmp(content{j}(1).type,'som_norm')), + msg = 'Each cell in ''comp_norm'' should be either empty or type ''som_norm''.'; + isok = 0; + break; + end + end + if isok, sS.comp_norm = content; end + end + case 'trainhist', + if ~isstruct(content) & ~isempty(content), + msg = '''trainhist'' should be a struct array or empty.'; + else + isok = 1; + for j=1:length(content), + if ~isfield(content(j),'type') | ~strcmp(content(j).type,'som_train'), + msg = 'Each cell in ''trainhist'' should be of type ''som_train''.'; + isok = 0; + break; + end + end + if isok, sS.trainhist = content; end + end + otherwise, + msg = ['Invalid field for map struct: ' field]; + end + + case 'som_data', + [dlen dim] = size(sS.data); + switch field, + case 'data', + [dummy dim2] = size(content); + if prod(si)==0, + msg = '''data'' is empty'; + elseif ~isnumeric(content), + msg = '''data'' should be numeric matrix.'; + elseif dim ~= dim2 & ~isempty(sS.data), + msg = 'New ''data'' must have the same dimension as old one.'; + else + sS.data = content; isok = 1; + end + case 'labels', + if isempty(content), + sS.labels = cell(dlen,1); isok = 1; + elseif size(content,1) ~= dlen, + msg = 'Length of ''labels'' must be equal to the number of data vectors.'; + elseif ~iscell(content) & ~ischar(content), + msg = '''labels'' must be a string array or a cell array/matrix.'; + else + isok = 1; + if ischar(content), content = cellstr(content); + elseif ~iscellstr(content), + l = prod(size(content)); + for j=1:l, + if ~ischar(content{j}), + if ~isempty(content{j}), + msg = 'Invalid ''labels'' array.'; + isok = 0; j + break; + else + content{j} = ''; + end + end + end + end + if isok, sS.labels = content; end + end + case 'name', + if ~ischar(content), + msg = '''name'' should be a string.'; + else + sS.name = content; isok = 1; + end + case 'comp_names', + if ~iscell(content) & ~ischar(content), + msg = '''comp_names'' should be a cell string or a string array.'; + elseif length(content) ~= dim, + msg = 'Length of ''comp_names'' should be equal to dim.'; + else + if ischar(content), content = cellstr(content); end + if size(content,1)==1, content = content'; end + sS.comp_names = content; + isok = 1; + end + case 'comp_norm', + if ~iscell(content) & length(content)>0, + msg = '''comp_norm'' should be a cell array.'; + elseif length(content) ~= dim, + msg = 'Length of ''comp_norm'' should be equal to dim.'; + else + isok = 1; + for j=1:length(content), + if ~isempty(content{j}) & (~isfield(content{j}(1),'type') | ... + ~strcmp(content{j}(1).type,'som_norm')), + msg = 'Each cell in ''comp_norm'' should be either empty or type ''som_norm''.'; + isok = 0; + break; + end + end + if isok, sS.comp_norm = content; end + end + case 'label_names', + if ~iscell(content) & ~ischar(content) & ~isempty(content), + msg = ['''label_names'' should be a cell string, a string array or' ... + ' empty.']; + else + if ~isempty(content), + if ischar(content), content = cellstr(content); end + if size(content,1)==1, content = content'; end + end + sS.label_names = content; + isok = 1; + end + otherwise, + msg = ['Invalid field for data struct: ' field]; + end + + case 'som_topol', + switch field, + case 'msize', + if ~isnumeric(content) | ~isvector | ~ispositive | ~isinteger, + msg = '''msize'' should be a vector with positive integer elements.'; + else + sS.msize = content; isok=1; + end + case 'lattice', + if ~ischar(content), + msg = '''lattice'' should be a string'; + elseif ~strcmp(content,'rect') & ~strcmp(content,'hexa'), + msg = ['Unknown lattice type: ' content]; + sS.lattice = content; isok = 1; + else + sS.lattice = content; isok = 1; + end + case 'shape', + if ~ischar(content), + msg = '''shape'' should be a string'; + elseif ~strcmp(content,'sheet') & ~strcmp(content,'cyl') & ... + ~strcmp(content,'toroid'), + msg = ['Unknown shape type: ' content]; + sS.shape = content; isok = 1; + else + sS.shape = content; isok = 1; + end + otherwise, + msg = ['Invalid field for topology struct: ' field]; + end + + case 'som_train', + switch field, + case 'algorithm', + if ~ischar(content), + msg = '''algorithm'' should be a string.'; + else + sS.algorithm = content; isok = 1; + end + case 'data_name', + if ~ischar(content), + msg = '''data_name'' should be a string'; + else + sS.data_name = content; isok = 1; + end + case 'neigh', + if ~ischar(content), + msg = '''neigh'' should be a string'; + elseif ~isempty(content) & ~strcmp(content,'gaussian') & ~strcmp(content,'ep') & ... + ~strcmp(content,'cutgauss') & ~strcmp(content,'bubble'), + msg = ['Unknown neighborhood function: ' content]; + sS.neigh = content; isok = 1; + else + sS.neigh = content; isok = 1; + end + case 'mask', + if size(content,1) == 1, content = content'; end + dim = size(content,1); %[munits dim] = size(sS.data); + if ~isnumeric(content) | size(content) ~= [dim 1], + msg = '''mask'' should be a column vector (size dim x 1).'; + else + sS.mask = content; isok = 1; + end + case 'radius_ini', + if ~isnumeric(content) | ~isscalar, + msg = '''radius_ini'' should be a scalar.'; + else + sS.radius_ini = content; isok = 1; + end + case 'radius_fin', + if ~isnumeric(content) | ~isscalar, + msg = '''radius_fin'' should be a scalar.'; + else + sS.radius_fin = content; isok = 1; + end + case 'alpha_ini', + if ~isnumeric(content) | ~isscalar, + msg = '''alpha_ini'' should be a scalar.'; + else + sS.alpha_ini = content; isok = 1; + end + case 'alpha_type', + if ~ischar(content), + msg = '''alpha_type'' should be a string'; + elseif ~strcmp(content,'linear') & ~strcmp(content,'inv') & ... + ~strcmp(content,'power') & ~strcmp(content,'constant') & ~strcmp(content,''), + msg = ['Unknown alpha type: ' content]; + sS.alpha_type = content; isok = 1; + else + sS.alpha_type = content; isok = 1; + end + case 'trainlen', + if ~isnumeric(content) | ~isscalar, + msg = '''trainlen'' should be a scalar.'; + else + sS.trainlen = content; isok = 1; + end + case 'time', + if ~ischar(content), + msg = '''time'' should be a string'; + else + sS.time = content; isok = 1; + end + otherwise, + msg = ['Invalid field for train struct: ' field]; + end + + case 'som_norm', + switch field, + case 'method', + if ~ischar(field), + msg = '''method'' should be a string.'; + else + sS.method = content; isok = 1; + end + case 'params', + sS.params = content; isok = 1; + case 'status', + if ~ischar(content), + msg = '''status'' should be a string'; + elseif ~strcmp(content,'done') & ~strcmp(content,'undone') & ... + ~strcmp(content,'uninit'), + msg = ['Unknown status type: ' content]; + sS.status = content; isok = 1; + else + sS.status = content; isok = 1; + end + otherwise, + msg = ['Invalid field for normalization struct: ' field]; + end + + case 'som_grid', + if any(strcmp(field,{'lattice', 'shape', 'msize', 'coord',... + 'line', 'linecolor', 'linewidth', ... + 'marker', 'markersize', 'markercolor', 'surf', ... + 'label', 'labelcolor', 'labelsize'})), + warning('No checking done on field identifier or content.'); + sS = setfield(sS,field,content); + isok = 1; + else + msg = ['Invalid field for grid struct: ' field]; + end + + otherwise, + error('Unrecognized structure.'); + + end + + msgs{i} = msg; + ok(i) = isok; + +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% return + +if nargout < 2, + for i=1:p, + if ~isempty(msgs{i}), + if ~ok(i), fprintf(1,'[Error! '); + else fprintf(1,'[Notice '); + end + fprintf(1,'in setting %s] ',varargin{2*i-1}); + fprintf(1,'%s\n',msgs{i}); + end + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +