Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_umat.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_umat.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,362 @@ +function U = som_umat(sMap, varargin) + +%SOM_UMAT Compute unified distance matrix of self-organizing map. +% +% U = som_umat(sMap, [argID, value, ...]) +% +% U = som_umat(sMap); +% U = som_umat(M,sTopol,'median','mask',[1 1 0 1]); +% +% Input and output arguments ([]'s are optional): +% sMap (struct) map struct or +% (matrix) the codebook matrix of the map +% [argID, (string) See below. The values which are unambiguous can +% value] (varies) be given without the preceeding argID. +% +% U (matrix) u-matrix of the self-organizing map +% +% Here are the valid argument IDs and corresponding values. The values which +% are unambiguous (marked with '*') can be given without the preceeding argID. +% 'mask' (vector) size dim x 1, weighting factors for different +% components (same as BMU search mask) +% 'msize' (vector) map grid size +% 'topol' *(struct) topology struct +% 'som_topol','sTopol' = 'topol' +% 'lattice' *(string) map lattice, 'hexa' or 'rect' +% 'mode' *(string) 'min','mean','median','max', default is 'median' +% +% NOTE! the U-matrix is always calculated for 'sheet'-shaped map and +% the map grid must be at most 2-dimensional. +% +% For more help, try 'type som_umat' or check out online documentation. +% See also SOM_SHOW, SOM_CPLANE. + +%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% som_umat +% +% PURPOSE +% +% Computes the unified distance matrix of a SOM. +% +% SYNTAX +% +% U = som_umat(sM) +% U = som_umat(...,'argID',value,...) +% U = som_umat(...,value,...) +% +% DESCRIPTION +% +% Compute and return the unified distance matrix of a SOM. +% For example a case of 5x1 -sized map: +% m(1) m(2) m(3) m(4) m(5) +% where m(i) denotes one map unit. The u-matrix is a 9x1 vector: +% u(1) u(1,2) u(2) u(2,3) u(3) u(3,4) u(4) u(4,5) u(5) +% where u(i,j) is the distance between map units m(i) and m(j) +% and u(k) is the mean (or minimum, maximum or median) of the +% surrounding values, e.g. u(3) = (u(2,3) + u(3,4))/2. +% +% Note that the u-matrix is always calculated for 'sheet'-shaped map and +% the map grid must be at most 2-dimensional. +% +% REFERENCES +% +% Ultsch, A., Siemon, H.P., "Kohonen's Self-Organizing Feature Maps +% for Exploratory Data Analysis", in Proc. of INNC'90, +% International Neural Network Conference, Dordrecht, +% Netherlands, 1990, pp. 305-308. +% Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag, +% Berlin, 1995, pp. 117-119. +% Iivarinen, J., Kohonen, T., Kangas, J., Kaski, S., "Visualizing +% the Clusters on the Self-Organizing Map", in proceedings of +% Conference on Artificial Intelligence Research in Finland, +% Helsinki, Finland, 1994, pp. 122-126. +% Kraaijveld, M.A., Mao, J., Jain, A.K., "A Nonlinear Projection +% Method Based on Kohonen's Topology Preserving Maps", IEEE +% Transactions on Neural Networks, vol. 6, no. 3, 1995, pp. 548-559. +% +% REQUIRED INPUT ARGUMENTS +% +% sM (struct) SOM Toolbox struct or the codebook matrix of the map. +% (matrix) The matrix may be 3-dimensional in which case the first +% two dimensions are taken for the map grid dimensions (msize). +% +% OPTIONAL INPUT ARGUMENTS +% +% argID (string) Argument identifier string (see below). +% value (varies) Value for the argument (see below). +% +% The optional arguments are given as 'argID',value -pairs. If the +% value is unambiguous, it can be given without the preceeding argID. +% If an argument is given value multiple times, the last one is used. +% +% Below is the list of valid arguments: +% 'mask' (vector) mask to be used in calculating +% the interunit distances, size [dim 1]. Default is +% the one in sM (field sM.mask) or a vector of +% ones if only a codebook matrix was given. +% 'topol' (struct) topology of the map. Default is the one +% in sM (field sM.topol). +% 'sTopol','som_topol' (struct) = 'topol' +% 'msize' (vector) map grid dimensions +% 'lattice' (string) map lattice 'rect' or 'hexa' +% 'mode' (string) 'min', 'mean', 'median' or 'max' +% Map unit value computation method. In fact, +% eval-function is used to evaluate this, so +% you can give other computation methods as well. +% Default is 'median'. +% +% OUTPUT ARGUMENTS +% +% U (matrix) the unified distance matrix of the SOM +% size 2*n1-1 x 2*n2-1, where n1 = msize(1) and n2 = msize(2) +% +% EXAMPLES +% +% U = som_umat(sM); +% U = som_umat(sM.codebook,sM.topol,'median','mask',[1 1 0 1]); +% U = som_umat(rand(10,10,4),'hexa','rect'); +% +% SEE ALSO +% +% som_show show the selected component planes and the u-matrix +% som_cplane draw a 2D unified distance matrix + +% Copyright (c) 1997-2000 by the SOM toolbox programming team. +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 1.0beta juuso 260997 +% Version 2.0beta juuso 151199, 151299, 200900 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% check arguments + +error(nargchk(1, Inf, nargin)); % check no. of input arguments is correct + +% sMap +if isstruct(sMap), + M = sMap.codebook; + sTopol = sMap.topol; + mask = sMap.mask; +elseif isnumeric(sMap), + M = sMap; + si = size(M); + dim = si(end); + if length(si)>2, msize = si(1:end-1); + else msize = [si(1) 1]; + end + munits = prod(msize); + sTopol = som_set('som_topol','msize',msize,'lattice','rect','shape','sheet'); + mask = ones(dim,1); + M = reshape(M,[munits,dim]); +end +mode = 'median'; + +% varargin +i=1; +while i<=length(varargin), + argok = 1; + if ischar(varargin{i}), + switch varargin{i}, + % argument IDs + case 'mask', i=i+1; mask = varargin{i}; + case 'msize', i=i+1; sTopol.msize = varargin{i}; + case 'lattice', i=i+1; sTopol.lattice = varargin{i}; + case {'topol','som_topol','sTopol'}, i=i+1; sTopol = varargin{i}; + case 'mode', i=i+1; mode = varargin{i}; + % unambiguous values + case {'hexa','rect'}, sTopol.lattice = varargin{i}; + case {'min','mean','median','max'}, mode = varargin{i}; + otherwise argok=0; + end + elseif isstruct(varargin{i}) & isfield(varargin{i},'type'), + switch varargin{i}(1).type, + case 'som_topol', sTopol = varargin{i}; + case 'som_map', sTopol = varargin{i}.topol; + otherwise argok=0; + end + else + argok = 0; + end + if ~argok, + disp(['(som_umat) Ignoring invalid argument #' num2str(i+1)]); + end + i = i+1; +end + +% check +[munits dim] = size(M); +if prod(sTopol.msize)~=munits, + error('Map grid size does not match the number of map units.') +end +if length(sTopol.msize)>2, + error('Can only handle 1- and 2-dimensional map grids.') +end +if prod(sTopol.msize)==1, + warning('Only one codebook vector.'); U = []; return; +end +if ~strcmp(sTopol.shape,'sheet'), + disp(['The ' sTopol.shape ' shape of the map ignored. Using sheet instead.']); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% initialize variables + +y = sTopol.msize(1); +x = sTopol.msize(2); +lattice = sTopol.lattice; +shape = sTopol.shape; +M = reshape(M,[y x dim]); + +ux = 2 * x - 1; +uy = 2 * y - 1; +U = zeros(uy, ux); + +calc = sprintf('%s(a)',mode); + +if size(mask,2)>1, mask = mask'; end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% u-matrix computation + +% distances between map units + +if strcmp(lattice, 'rect'), % rectangular lattice + + for j=1:y, for i=1:x, + if i<x, + dx = (M(j,i,:) - M(j,i+1,:)).^2; % horizontal + U(2*j-1,2*i) = sqrt(mask'*dx(:)); + end + if j<y, + dy = (M(j,i,:) - M(j+1,i,:)).^2; % vertical + U(2*j,2*i-1) = sqrt(mask'*dy(:)); + end + if j<y & i<x, + dz1 = (M(j,i,:) - M(j+1,i+1,:)).^2; % diagonals + dz2 = (M(j+1,i,:) - M(j,i+1,:)).^2; + U(2*j,2*i) = (sqrt(mask'*dz1(:))+sqrt(mask'*dz2(:)))/(2 * sqrt(2)); + end + end + end + +elseif strcmp(lattice, 'hexa') % hexagonal lattice + + for j=1:y, + for i=1:x, + if i<x, + dx = (M(j,i,:) - M(j,i+1,:)).^2; % horizontal + U(2*j-1,2*i) = sqrt(mask'*dx(:)); + end + + if j<y, % diagonals + dy = (M(j,i,:) - M(j+1,i,:)).^2; + U(2*j,2*i-1) = sqrt(mask'*dy(:)); + + if rem(j,2)==0 & i<x, + dz= (M(j,i,:) - M(j+1,i+1,:)).^2; + U(2*j,2*i) = sqrt(mask'*dz(:)); + elseif rem(j,2)==1 & i>1, + dz = (M(j,i,:) - M(j+1,i-1,:)).^2; + U(2*j,2*i-2) = sqrt(mask'*dz(:)); + end + end + end + end + +end + +% values on the units + +if (uy == 1 | ux == 1), + % in 1-D case, mean is equal to median + + ma = max([ux uy]); + for i = 1:2:ma, + if i>1 & i<ma, + a = [U(i-1) U(i+1)]; + U(i) = eval(calc); + elseif i==1, U(i) = U(i+1); + else U(i) = U(i-1); % i==ma + end + end + +elseif strcmp(lattice, 'rect') + + for j=1:2:uy, + for i=1:2:ux, + if i>1 & j>1 & i<ux & j<uy, % middle part of the map + a = [U(j,i-1) U(j,i+1) U(j-1,i) U(j+1,i)]; + elseif j==1 & i>1 & i<ux, % upper edge + a = [U(j,i-1) U(j,i+1) U(j+1,i)]; + elseif j==uy & i>1 & i<ux, % lower edge + a = [U(j,i-1) U(j,i+1) U(j-1,i)]; + elseif i==1 & j>1 & j<uy, % left edge + a = [U(j,i+1) U(j-1,i) U(j+1,i)]; + elseif i==ux & j>1 & j<uy, % right edge + a = [U(j,i-1) U(j-1,i) U(j+1,i)]; + elseif i==1 & j==1, % top left corner + a = [U(j,i+1) U(j+1,i)]; + elseif i==ux & j==1, % top right corner + a = [U(j,i-1) U(j+1,i)]; + elseif i==1 & j==uy, % bottom left corner + a = [U(j,i+1) U(j-1,i)]; + elseif i==ux & j==uy, % bottom right corner + a = [U(j,i-1) U(j-1,i)]; + else + a = 0; + end + U(j,i) = eval(calc); + end + end + +elseif strcmp(lattice, 'hexa') + + for j=1:2:uy, + for i=1:2:ux, + if i>1 & j>1 & i<ux & j<uy, % middle part of the map + a = [U(j,i-1) U(j,i+1)]; + if rem(j-1,4)==0, a = [a, U(j-1,i-1) U(j-1,i) U(j+1,i-1) U(j+1,i)]; + else a = [a, U(j-1,i) U(j-1,i+1) U(j+1,i) U(j+1,i+1)]; end + elseif j==1 & i>1 & i<ux, % upper edge + a = [U(j,i-1) U(j,i+1) U(j+1,i-1) U(j+1,i)]; + elseif j==uy & i>1 & i<ux, % lower edge + a = [U(j,i-1) U(j,i+1)]; + if rem(j-1,4)==0, a = [a, U(j-1,i-1) U(j-1,i)]; + else a = [a, U(j-1,i) U(j-1,i+1)]; end + elseif i==1 & j>1 & j<uy, % left edge + a = U(j,i+1); + if rem(j-1,4)==0, a = [a, U(j-1,i) U(j+1,i)]; + else a = [a, U(j-1,i) U(j-1,i+1) U(j+1,i) U(j+1,i+1)]; end + elseif i==ux & j>1 & j<uy, % right edge + a = U(j,i-1); + if rem(j-1,4)==0, a=[a, U(j-1,i) U(j-1,i-1) U(j+1,i) U(j+1,i-1)]; + else a = [a, U(j-1,i) U(j+1,i)]; end + elseif i==1 & j==1, % top left corner + a = [U(j,i+1) U(j+1,i)]; + elseif i==ux & j==1, % top right corner + a = [U(j,i-1) U(j+1,i-1) U(j+1,i)]; + elseif i==1 & j==uy, % bottom left corner + if rem(j-1,4)==0, a = [U(j,i+1) U(j-1,i)]; + else a = [U(j,i+1) U(j-1,i) U(j-1,i+1)]; end + elseif i==ux & j==uy, % bottom right corner + if rem(j-1,4)==0, a = [U(j,i-1) U(j-1,i) U(j-1,i-1)]; + else a = [U(j,i-1) U(j-1,i)]; end + else + a=0; + end + U(j,i) = eval(calc); + end + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% normalization between [0,1] + +% U = U - min(min(U)); +% ma = max(max(U)); if ma > 0, U = U / ma; end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +