diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_distortion.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_distortion.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,138 @@
+function [adm,admu,tdmu] = som_distortion(sM, D, arg1, arg2)
+
+%SOM_DISTORTION Calculate distortion measure for the map.
+%
+% [adm,admu,tdmu] = som_distortion(sMap, D, [radius], ['prob'])
+%
+%  adm = som_distortion(sMap,D);
+%  [adm,admu] = som_distortion(sMap,D);
+%  som_show(sMap,'color',admu);
+%
+%  Input and output arguments: 
+%   sMap     (struct) a map struct
+%   D        (struct) a data struct
+%            (matrix) size dlen x dim, a data matrix
+%   [radius] (scalar) neighborhood function radius to be used.
+%                     Defaults to the last radius_fin in the 
+%                     trainhist field of the map struct, or 1 if
+%                     that is missing.
+%   ['prob'] (string) If given, this argument forces the 
+%                     neigborhood function values for each map
+%                     unit to be normalized so that they sum to 1.
+%
+%   adm      (scalar) average distortion measure (sum(dm)/dlen)
+%   admu     (vector) size munits x 1, average distortion in each unit 
+%   tdmu     (vector) size munits x 1, total distortion for each unit
+%
+% The distortion measure is defined as: 
+%                                           2
+%    E = sum sum h(bmu(i),j) ||m(j) - x(i)|| 
+%         i   j    
+% 
+% where m(i) is the ith prototype vector of SOM, x(j) is the jth data
+% vector, and h(.,.) is the neighborhood function. In case of fixed
+% neighborhood and discreet data, the distortion measure can be
+% interpreted as the energy function of the SOM. Note, though, that
+% the learning rule that follows from the distortion measure is
+% different from the SOM training rule, so SOM only minimizes the
+% distortion measure approximately.
+% 
+% If the 'prob' argument is given, the distortion measure can be 
+% interpreted as an expected quantization error when the neighborhood 
+% function values give the likelyhoods of accidentally assigning 
+% vector j to unit i. The normal quantization error is a special case 
+% of this with zero incorrect assignement likelihood. 
+% 
+% NOTE: when calculating BMUs and distances, the mask of the given 
+%       map is used.
+%
+% See also SOM_QUALITY, SOM_BMUS, SOM_HITS.
+
+% Reference: Kohonen, T., "Self-Organizing Map", 2nd ed., 
+%    Springer-Verlag, Berlin, 1995, pp. 120-121.
+%
+%    Graepel, T., Burger, M. and Obermayer, K., 
+%    "Phase Transitions in Stochastic Self-Organizing Maps",
+%    Physical Review E, Vol 56, No 4, pp. 3876-3890 (1997).
+
+% Contributed to SOM Toolbox vs2, Feb 3rd, 2000 by Juha Vesanto
+% Copyright (c) by Juha Vesanto
+% http://www.cis.hut.fi/projects/somtoolbox/
+
+% Version 2.0beta juuso 030200
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% check arguments
+
+% input arguments
+if nargin < 2, error('Not enough input arguments.'); end
+
+% map
+M = sM.codebook;
+munits = prod(sM.topol.msize);
+
+% data
+if isstruct(D), D = D.data; end
+[dlen dim] = size(D);
+
+% arg1, arg2
+rad = NaN;
+normalize = 0;
+if nargin>2, 
+  if isnumeric(arg1), rad = arg1;
+  elseif ischar(arg1) & strcmp(arg1,'prob'), normalize = 0;
+  end
+end
+if nargin>3, 
+  if isnumeric(arg2), rad = arg2;
+  elseif ischar(arg2) & strcmp(arg2,'prob'), normalize = 0;
+  end
+end
+
+% neighborhood radius
+if isempty(rad) | isnan(rad), 
+  if ~isempty(sM.trainhist), rad = sM.trainhist(end).radius_fin;
+  else rad = 1; 
+  end
+end
+if rad<eps, rad = eps; end
+
+% neighborhood  
+Ud = som_unit_dists(sM.topol); 
+switch sM.neigh, 
+ case 'bubble',   H = (Ud <= rad);
+ case 'gaussian', H = exp(-(Ud.^2)/(2*rad*rad)); 
+ case 'cutgauss', H = exp(-(Ud.^2)/(2*rad*rad)) .* (Ud <= rad);
+ case 'ep',       H = (1 - (Ud.^2)/rad) .* (Ud <= rad);
+end  
+if normalize, 
+  for i=1:munits, H(:,i) = H(:,i)/sum(H(:,i)); end
+end
+
+% total distortion measure
+mu_x_1 = ones(munits,1);
+tdmu = zeros(munits,1);
+hits = zeros(munits,1);
+for i=1:dlen,
+  x = D(i,:);                        % data sample
+  known = ~isnan(x);                 % its known components
+  Dx = M(:,known) - x(mu_x_1,known); % each map unit minus the vector
+  dist2 = (Dx.^2)*sM.mask(known);    % squared distances  
+  [qerr bmu] = min(dist2);           % find BMU
+  tdmu = tdmu + dist2.*H(:,bmu);     % add to distortion measure
+  hits(bmu) = hits(bmu)+1;           % add to hits
+end 
+
+% average distortion per unit
+admu = tdmu; 
+ind = find(hits>0);
+admu(ind) = admu(ind) ./ hits(ind);
+  
+% average distortion measure
+adm = sum(tdmu)/dlen;
+
+return;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+