wolffd@0: function sMap = som_lininit(D, varargin) wolffd@0: wolffd@0: %SOM_LININIT Initialize a Self-Organizing Map linearly. wolffd@0: % wolffd@0: % sMap = som_lininit(D, [[argID,] value, ...]) wolffd@0: % wolffd@0: % sMap = som_lininit(D); wolffd@0: % sMap = som_lininit(D,sMap); wolffd@0: % sMap = som_lininit(D,'munits',100,'hexa'); wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % D The training data. wolffd@0: % (struct) data struct wolffd@0: % (matrix) data matrix, size dlen x dim wolffd@0: % [argID, (string) Parameters affecting the map topology are given wolffd@0: % value] (varies) as argument ID - argument value pairs, listed below. wolffd@0: % sMap (struct) map struct wolffd@0: % wolffd@0: % Here are the valid argument IDs and corresponding values. The values wolffd@0: % which are unambiguous (marked with '*') can be given without the wolffd@0: % preceeding argID. wolffd@0: % 'munits' (scalar) number of map units wolffd@0: % 'msize' (vector) map size wolffd@0: % 'lattice' *(string) map lattice: 'hexa' or 'rect' wolffd@0: % 'shape' *(string) map shape: 'sheet', 'cyl' or 'toroid' wolffd@0: % 'topol' *(struct) topology struct wolffd@0: % 'som_topol','sTopol' = 'topol' wolffd@0: % 'map' *(struct) map struct wolffd@0: % 'som_map','sMap' = 'map' wolffd@0: % wolffd@0: % For more help, try 'type som_lininit' or check out online documentation. wolffd@0: % See also SOM_MAP_STRUCT, SOM_RANDINIT, SOM_MAKE. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_lininit wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Initializes a SOM linearly along its greatest eigenvectors. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % sMap = som_lininit(D); wolffd@0: % sMap = som_lininit(D,sMap); wolffd@0: % sMap = som_lininit(D,'munits',100,'hexa'); wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % Initializes a SOM linearly. If necessary, a map struct is created wolffd@0: % first. The initialization is made by first calculating the eigenvalues wolffd@0: % and eigenvectors of the training data. Then, the map is initialized wolffd@0: % along the mdim greatest eigenvectors of the training data, where wolffd@0: % mdim is the dimension of the map grid. wolffd@0: % wolffd@0: % REFERENCES wolffd@0: % wolffd@0: % Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag, wolffd@0: % Berlin, 1995, pp. 106-107. wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % D The training data. wolffd@0: % (struct) Data struct. If this is given, its '.comp_names' and wolffd@0: % '.comp_norm' fields are copied to the map struct. wolffd@0: % (matrix) data matrix, size dlen x dim wolffd@0: % wolffd@0: % OPTIONAL INPUT ARGUMENTS wolffd@0: % wolffd@0: % argID (string) Argument identifier string (see below). wolffd@0: % value (varies) Value for the argument (see below). wolffd@0: % wolffd@0: % The optional arguments can be given as 'argID',value -pairs. If an wolffd@0: % argument is given value multiple times, the last one is used. wolffd@0: % wolffd@0: % Here are the valid argument IDs and corresponding values. The values wolffd@0: % which are unambiguous (marked with '*') can be given without the wolffd@0: % preceeding argID. wolffd@0: % 'dlen' (scalar) length of the training data wolffd@0: % 'data' (matrix) the training data wolffd@0: % *(struct) the training data wolffd@0: % 'munits' (scalar) number of map units wolffd@0: % 'msize' (vector) map size wolffd@0: % 'lattice' *(string) map lattice: 'hexa' or 'rect' wolffd@0: % 'shape' *(string) map shape: 'sheet', 'cyl' or 'toroid' wolffd@0: % 'topol' *(struct) topology struct wolffd@0: % 'som_topol','sTopol' = 'topol' wolffd@0: % 'map' *(struct) map struct wolffd@0: % 'som_map','sMap' = 'map' wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sMap (struct) The initialized map struct. wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % sMap = som_lininit(D); wolffd@0: % sMap = som_lininit(D,sMap); wolffd@0: % sMap = som_lininit(D,'msize',[10 10]); wolffd@0: % sMap = som_lininit(D,'munits',100,'rect'); wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_map_struct Create a map struct. wolffd@0: % som_randinit Initialize a map with random values. wolffd@0: % som_make Initialize and train self-organizing map. wolffd@0: wolffd@0: % Copyright (c) 1997-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 1.0beta ecco 100997 wolffd@0: % Version 2.0beta 101199 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% check arguments wolffd@0: wolffd@0: % data wolffd@0: if isstruct(D), wolffd@0: data_name = D.name; wolffd@0: comp_names = D.comp_names; wolffd@0: comp_norm = D.comp_norm; wolffd@0: D = D.data; wolffd@0: struct_mode = 1; wolffd@0: else wolffd@0: data_name = inputname(1); wolffd@0: struct_mode = 0; wolffd@0: end wolffd@0: [dlen dim] = size(D); wolffd@0: wolffd@0: % varargin wolffd@0: sMap = []; wolffd@0: sTopol = som_topol_struct; wolffd@0: sTopol.msize = 0; wolffd@0: munits = NaN; wolffd@0: i=1; wolffd@0: while i<=length(varargin), wolffd@0: argok = 1; wolffd@0: if ischar(varargin{i}), wolffd@0: switch varargin{i}, wolffd@0: case 'munits', i=i+1; munits = varargin{i}; sTopol.msize = 0; wolffd@0: case 'msize', i=i+1; sTopol.msize = varargin{i}; wolffd@0: munits = prod(sTopol.msize); wolffd@0: case 'lattice', i=i+1; sTopol.lattice = varargin{i}; wolffd@0: case 'shape', i=i+1; sTopol.shape = varargin{i}; wolffd@0: case {'som_topol','sTopol','topol'}, i=i+1; sTopol = varargin{i}; wolffd@0: case {'som_map','sMap','map'}, i=i+1; sMap = varargin{i}; sTopol = sMap.topol; wolffd@0: case {'hexa','rect'}, sTopol.lattice = varargin{i}; wolffd@0: case {'sheet','cyl','toroid'}, sTopol.shape = varargin{i}; wolffd@0: otherwise argok=0; wolffd@0: end wolffd@0: elseif isstruct(varargin{i}) & isfield(varargin{i},'type'), wolffd@0: switch varargin{i}.type, wolffd@0: case 'som_topol', wolffd@0: sTopol = varargin{i}; wolffd@0: case 'som_map', wolffd@0: sMap = varargin{i}; wolffd@0: sTopol = sMap.topol; wolffd@0: otherwise argok=0; wolffd@0: end wolffd@0: else wolffd@0: argok = 0; wolffd@0: end wolffd@0: if ~argok, wolffd@0: disp(['(som_topol_struct) Ignoring invalid argument #' num2str(i)]); wolffd@0: end wolffd@0: i = i+1; wolffd@0: end wolffd@0: wolffd@0: if length(sTopol.msize)==1, sTopol.msize = [sTopol.msize 1]; end wolffd@0: wolffd@0: if ~isempty(sMap), wolffd@0: [munits dim2] = size(sMap.codebook); wolffd@0: if dim2 ~= dim, error('Map and data must have the same dimension.'); end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% create map wolffd@0: wolffd@0: % map struct wolffd@0: if ~isempty(sMap), wolffd@0: sMap = som_set(sMap,'topol',sTopol); wolffd@0: else wolffd@0: if ~prod(sTopol.msize), wolffd@0: if isnan(munits), wolffd@0: sTopol = som_topol_struct('data',D,sTopol); wolffd@0: else wolffd@0: sTopol = som_topol_struct('data',D,'munits',munits,sTopol); wolffd@0: end wolffd@0: end wolffd@0: sMap = som_map_struct(dim, sTopol); wolffd@0: end wolffd@0: wolffd@0: if struct_mode, wolffd@0: sMap = som_set(sMap,'comp_names',comp_names,'comp_norm',comp_norm); wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% initialization wolffd@0: wolffd@0: % train struct wolffd@0: sTrain = som_train_struct('algorithm','lininit'); wolffd@0: sTrain = som_set(sTrain,'data_name',data_name); wolffd@0: wolffd@0: msize = sMap.topol.msize; wolffd@0: mdim = length(msize); wolffd@0: munits = prod(msize); wolffd@0: wolffd@0: [dlen dim] = size(D); wolffd@0: if dlen<2, wolffd@0: %if dlen==1, sMap.codebook = (sMap.codebook - 0.5)*diag(D); end wolffd@0: error(['Linear map initialization requires at least two NaN-free' ... wolffd@0: ' samples.']); wolffd@0: return; wolffd@0: end wolffd@0: wolffd@0: % compute principle components wolffd@0: if dim > 1 & sum(msize > 1) > 1, wolffd@0: % calculate mdim largest eigenvalues and their corresponding wolffd@0: % eigenvectors wolffd@0: wolffd@0: % autocorrelation matrix wolffd@0: A = zeros(dim); wolffd@0: me = zeros(1,dim); wolffd@0: for i=1:dim, wolffd@0: me(i) = mean(D(isfinite(D(:,i)),i)); wolffd@0: D(:,i) = D(:,i) - me(i); wolffd@0: end wolffd@0: for i=1:dim, wolffd@0: for j=i:dim, wolffd@0: c = D(:,i).*D(:,j); c = c(isfinite(c)); wolffd@0: A(i,j) = sum(c)/length(c); A(j,i) = A(i,j); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % take mdim first eigenvectors with the greatest eigenvalues wolffd@0: [V,S] = eig(A); wolffd@0: eigval = diag(S); wolffd@0: [y,ind] = sort(eigval); wolffd@0: eigval = eigval(flipud(ind)); wolffd@0: V = V(:,flipud(ind)); wolffd@0: V = V(:,1:mdim); wolffd@0: eigval = eigval(1:mdim); wolffd@0: wolffd@0: % normalize eigenvectors to unit length and multiply them by wolffd@0: % corresponding (square-root-of-)eigenvalues wolffd@0: for i=1:mdim, V(:,i) = (V(:,i) / norm(V(:,i))) * sqrt(eigval(i)); end wolffd@0: wolffd@0: else wolffd@0: wolffd@0: me = zeros(1,dim); wolffd@0: V = zeros(1,dim); wolffd@0: for i=1:dim, wolffd@0: inds = find(~isnan(D(:,i))); wolffd@0: me(i) = mean(D(inds,i),1); wolffd@0: V(i) = std(D(inds,i),1); wolffd@0: end wolffd@0: wolffd@0: end wolffd@0: wolffd@0: % initialize codebook vectors wolffd@0: if dim>1, wolffd@0: sMap.codebook = me(ones(munits,1),:); wolffd@0: Coords = som_unit_coords(msize,'rect','sheet'); wolffd@0: cox = Coords(:,1); Coords(:,1) = Coords(:,2); Coords(:,2) = cox; wolffd@0: for i=1:mdim, wolffd@0: ma = max(Coords(:,i)); mi = min(Coords(:,i)); wolffd@0: if ma>mi, Coords(:,i) = (Coords(:,i)-mi)/(ma-mi); else Coords(:,i) = 0.5; end wolffd@0: end wolffd@0: Coords = (Coords-0.5)*2; wolffd@0: for n = 1:munits, wolffd@0: for d = 1:mdim, wolffd@0: sMap.codebook(n,:) = sMap.codebook(n,:)+Coords(n,d)*V(:, d)'; wolffd@0: end wolffd@0: end wolffd@0: else wolffd@0: sMap.codebook = [0:(munits-1)]'/(munits-1)*(max(D)-min(D))+min(D); wolffd@0: end wolffd@0: wolffd@0: % training struct wolffd@0: sTrain = som_set(sTrain,'time',datestr(now,0)); wolffd@0: sMap.trainhist = sTrain; wolffd@0: wolffd@0: return; wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%