diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_hits.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_hits.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,217 @@
+function [hits] = som_hits(sMap, sData, mode)
+
+%SOM_HITS Calculate the response of the given data on the map.
+%
+% hits = som_hits(sMap, sData, [mode])
+%
+%   h = som_hits(sMap,sData);
+%   h = som_hits(sMap,sData,'fuzzy');
+%
+%  Input and output arguments ([]'s are optional): 
+%   sMap     (struct) map struct
+%            (matrix) codebook matrix, size munits x dim
+%   sData    (struct) data struct
+%            (matrix) data matrix, size dlen x dim
+%   [mode]   (string) 'crisp' (default), 'kernel', 'fuzzy'
+%
+%   hits     (vector) the number of hits in each map unit, length = munits
+%
+% The response of the data on the map can be calculated e.g. in
+% three ways, selected with the mode argument: 
+%  'crisp'    traditional hit histogram
+%  'kernel'   a sum of dlen neighborhood kernels, where kernel
+%             is positioned on the BMU of each data sample. The 
+%             neighborhood function is sMap.neigh and the
+%             neighborhood width is sMap.trainhist(end).radius_fin
+%             or 1 if this is empty or NaN
+%  'fuzzy'    fuzzy response calculated by summing 1./(1+(q/a)^2)
+%             for each data sample, where q is a vector containing
+%             distance from the data sample to each map unit and 
+%             a is average quantization error
+% 
+% For more help, try 'type som_hits' or check out online documentation.
+% See also SOM_AUTOLABEL, SOM_BMUS.    
+
+%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% som_hits
+%
+% PURPOSE
+%
+% Calculate the response of the given data on the map.
+%
+% SYNTAX
+%
+%  hits = som_hits(sMap, sData)
+%  hits = som_hits(M, D)
+%  hits = som_hits(..., mode)
+%
+% DESCRIPTION
+%
+% Returns a vector indicating the response of the map to the data.
+% The response of the data on the map can be calculated e.g. in
+% three ways, selected with the mode argument: 
+%  'crisp'    traditional hit histogram: how many times each map unit 
+%             was the BMU for the data set
+%  'kernel'   a sum of neighborhood kernels, where a kernel
+%             is positioned on the BMU of each data sample. The 
+%             neighborhood function is sMap.neigh and the
+%             neighborhood width is sMap.trainhist(end).radius_fin
+%             or 1 if this is not available 
+%  'fuzzy'    fuzzy response calculated by summing 
+%
+%                            1
+%                       ------------
+%                       1 +  (q/a)^2
+%
+%             for each data sample, where q is a vector containing
+%             distance from the data sample to each map unit and 
+%             a is average quantization error
+%
+% REQUIRED INPUT ARGUMENTS
+%
+%   sMap              The vectors from among which the BMUs are searched
+%                     for. These must not have any unknown components (NaNs).
+%            (struct) map struct
+%            (matrix) codebook matrix, size munits x dim
+%                     
+%   sData             The data vector(s) for which the BMUs are searched.
+%            (struct) data struct
+%            (matrix) data matrix, size dlen x dim
+%
+% OPTIONAL INPUT ARGUMENTS
+%
+%   mode     (string) The respond mode: 'crisp' (default), 'kernel'
+%                     or 'fuzzy'. 'kernel' can only be used if 
+%                     the first argument (sMap) is a map struct.                     
+% 
+% OUTPUT ARGUMENTS
+% 
+%   hits     (vector) The number of hits in each map unit.
+%
+% EXAMPLES
+%
+%  hits = som_hits(sM,D);
+%  hits = som_hits(sM,D,'kernel');
+%  hits = som_hits(sM,D,'fuzzy');
+%
+% SEE ALSO
+% 
+%  som_bmus      Find BMUs and quantization errors for a given data set.
+
+% Copyright (c) 1997-2000 by the SOM toolbox programming team.
+% http://www.cis.hut.fi/projects/somtoolbox/
+
+% Version 1.0beta juuso 220997
+% Version 2.0beta juuso 161199
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% check arguments
+
+error(nargchk(2, 3, nargin));  % check no. of input args is correct
+
+if isstruct(sMap), 
+  switch sMap.type, 
+   case 'som_map', munits = prod(sMap.topol.msize);
+   case 'som_data', munits = size(sMap.data,1);
+   otherwise, 
+    error('Illegal struct for 1st argument.')
+  end
+else 
+  munits = size(sMap,1); 
+end
+hits = zeros(munits,1);
+
+if nargin<3, mode = 'crisp'; end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% action
+
+% calculate BMUs
+[bmus,qerrs] = som_bmus(sMap,sData,1);
+
+switch mode, 
+case 'crisp',    
+
+ % for each unit, check how many hits it got
+ for i=1:munits, hits(i) = sum(bmus == i); end
+   
+case 'kernel',
+
+ % check that sMap really is a map 
+ if ~isstruct(sMap) & ~strcmp(sMap.type,'som_map'), 
+   error('Kernel mode can only be used for maps.');
+ end	   
+
+ % calculate neighborhood kernel  
+ Ud = som_unit_dists(sMap.topol).^2;
+ sTrain = sMap.trainhist(end); 
+ if ~isempty(sTrain), 
+   rad = sTrain.radius_fin; 
+   if isempty(rad) | isnan(rad), rad = 1; end 
+ else 
+   rad = 1; 
+ end    
+ rad = rad^2;
+ if rad==0, rad = eps; end % to avoid divide-by-0 errors
+ switch sTrain.neigh, 
+  case 'bubble',   H = (Ud<=rad); 
+  case 'gaussian', H = exp(-Ud/(2*rad)); 
+  case 'cutgauss', H = exp(-Ud/(2*rad)) .* (Ud<=rad);
+  case 'ep',       H = (1-Ud/rad) .* (Ud<=rad);
+ end
+ 
+ % weight hits with neighborhood kernel
+ hits = sum(H(bmus,:),1)';
+   
+case 'fuzzy',	
+
+ % extract the two matrices (M, D) and the mask
+ mask = [];
+ if isstruct(sMap), 
+   if strcmp(sMap.type,'som_data'), M = sMap.data; 
+   else M = sMap.codebook; mask = sMap.mask;
+   end
+ else M = sMap;
+ end
+ if any(isnan(M(:))), 
+   error('Data in first argument must not have any NaNs.'); 
+ end
+
+ if isstruct(sData), 
+   switch sData.type, 
+    case 'som_map', 
+     D = sData.codebook; 
+     if isempty(mask), mask = sData.mask; end
+    case 'som_data', D = sData.data;
+    otherwise, error('Illegal 2nd argument.');
+   end	
+ else D = sData;
+ end
+ [dlen dim] = size(D);   
+ if isempty(mask), mask = ones(dim,1); end
+
+ % scaling factor   
+ a = mean(qerrs).^2;
+ 
+ % calculate distances & bmus
+ % (this is better explained in som_batchtrain and som_bmus)
+ Known = ~isnan(D); D(find(~Known)) = 0; % unknown components  
+ blen = min(munits,dlen); % block size 
+ W1 = mask*ones(1,blen); W2 = ones(munits,1)*mask'; D = D'; Known = Known';
+ i0 = 0; 
+ while i0+1<=dlen,    
+   inds = [(i0+1):min(dlen,i0+blen)]; i0 = i0+blen; % indeces   
+   Dist = (M.^2)*(W1(:,1:length(inds)).*Known(:,inds)) ...
+	  + W2*(D(:,inds).^2) ...
+	  - 2*M*diag(mask)*D(:,inds); % squared distances
+   hits = hits + sum(1./(1+Dist/a),2);   
+ end  
+ 
+ otherwise, 
+  error(['Unknown mode: ' mode]);
+  
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+