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
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+