wolffd@0: function sD = som_normalize(sD,method,comps) wolffd@0: wolffd@0: %SOM_NORMALIZE (Re)normalize data or add new normalizations. wolffd@0: % wolffd@0: % sS = som_normalize(sS,[method],[comps]) wolffd@0: % wolffd@0: % sS = som_normalize(sD) wolffd@0: % sS = som_normalize(sS,sNorm) wolffd@0: % D = som_normalize(D,'var') wolffd@0: % sS = som_normalize(sS,'histC',[1:3 10]) wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % sS The data to which the normalization is applied. wolffd@0: % The modified and updated data is returned. wolffd@0: % (struct) data or map struct wolffd@0: % (matrix) data matrix (a matrix is also returned) wolffd@0: % [method] The normalization method(s) to add/use. If missing, wolffd@0: % or an empty variable ('') is given, the wolffd@0: % normalizations in sS are used. wolffd@0: % (string) identifier for a normalization method to be added: wolffd@0: % 'var', 'range', 'log', 'logistic', 'histD' or 'histC'. wolffd@0: % (struct) Normalization struct, or an array of such. wolffd@0: % Alternatively, a map/data struct can be given wolffd@0: % in which case its '.comp_norm' field is used wolffd@0: % (see below). wolffd@0: % (cell array) Of normalization structs. Typically, the wolffd@0: % '.comp_norm' field of a map/data struct. The wolffd@0: % length of the array must be equal to data dimension. wolffd@0: % (cellstr array) norm and denorm operations in a cellstr array wolffd@0: % which are evaluated with EVAL command with variable wolffd@0: % name 'x' reserved for the variable. wolffd@0: % [comps] (vector) the components to which the normalization is wolffd@0: % applied, default is [1:dim] ie. all components wolffd@0: % wolffd@0: % For more help, try 'type som_normalize' or check out online documentation. wolffd@0: % See also SOM_DENORMALIZE, SOM_NORM_VARIABLE, SOM_INFO. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_normalize wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Add/apply/redo normalization on data structs/sets. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % sS = som_normalize(sS) wolffd@0: % sS = som_normalize(sS,method) wolffd@0: % D = som_normalize(D,sNorm) wolffd@0: % sS = som_normalize(sS,csNorm) wolffd@0: % sS = som_normalize(...,comps) wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % This function is used to (initialize and) add, redo and apply wolffd@0: % normalizations on data/map structs/sets. If a data/map struct is given, wolffd@0: % the specified normalizations are added to the '.comp_norm' field of the wolffd@0: % struct after ensuring that all normalizations specified therein have wolffd@0: % status 'done'. SOM_NORMALIZE actually uses function SOM_NORM_VARIABLE wolffd@0: % to handle the normalization operations, and only handles the data wolffd@0: % struct/set specific stuff itself. wolffd@0: % wolffd@0: % The different normalization methods are listed below. For more wolffd@0: % detailed descriptions, see SOM_NORM_VARIABLE. wolffd@0: % wolffd@0: % method description wolffd@0: % 'var' Variance is normalized to one (linear operation). wolffd@0: % 'range' Values are normalized between [0,1] (linear operation). wolffd@0: % 'log' Natural logarithm is applied to the values: wolffd@0: % xnew = log(x-m+1) wolffd@0: % where m = min(x). wolffd@0: % 'logistic' Logistic or softmax trasformation which scales all wolffd@0: % possible values between [0,1]. wolffd@0: % 'histD' Histogram equalization, values scaled between [0,1]. wolffd@0: % 'histC' Approximate histogram equalization with partially wolffd@0: % linear operations. Values scaled between [0,1]. wolffd@0: % 'eval' freeform operations wolffd@0: % wolffd@0: % To enable undoing and applying the exactly same normalization to wolffd@0: % other data sets, normalization information is saved into a wolffd@0: % normalization struct, which has the fields: wolffd@0: % wolffd@0: % .type ; struct type, ='som_norm' wolffd@0: % .method ; normalization method, a string wolffd@0: % .params ; normalization parameters wolffd@0: % .status ; string: 'uninit', 'undone' or 'done' wolffd@0: % wolffd@0: % Normalizations are always one-variable operations. In the data and map wolffd@0: % structs the normalization information for each component is saved in the wolffd@0: % '.comp_norm' field, which is a cell array of length dim. Each cell wolffd@0: % contains normalizations for one vector component in a struct array of wolffd@0: % normalization structs. Each component may have different amounts of wolffd@0: % different kinds of normalizations. Typically, all normalizations are wolffd@0: % either 'undone' or 'done', but in special situations this may not be the wolffd@0: % case. The easiest way to check out the status of the normalizations is to wolffd@0: % use function SOM_INFO, e.g. som_info(sS,3) wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % sS The data to which the normalization is applied. wolffd@0: % (struct) Data or map struct. Before adding any new wolffd@0: % normalizations, it is ensured that the wolffd@0: % normalizations for the specified components in the wolffd@0: % '.comp_norm' field have status 'done'. wolffd@0: % (matrix) data matrix wolffd@0: % wolffd@0: % OPTIONAL INPUT ARGUMENTS wolffd@0: % wolffd@0: % method The normalization(s) to add/use. If missing, wolffd@0: % or an empty variable ('' or []) is given, the wolffd@0: % normalizations in the data struct are used. wolffd@0: % (string) Identifier for a normalization method to be added: wolffd@0: % 'var', 'range', 'log', 'logistic', 'histD' or 'histC'. The wolffd@0: % same method is applied to all specified components wolffd@0: % (given in comps). The normalizations are first wolffd@0: % initialized (for each component separately, of wolffd@0: % course) and then applied. wolffd@0: % (struct) Normalization struct, or an array of structs, which wolffd@0: % is applied to all specified components. If the wolffd@0: % '.status' field of the struct(s) is 'uninit', wolffd@0: % the normalization(s) is initialized first. wolffd@0: % Alternatively, the struct may be map or data struct wolffd@0: % in which case its '.comp_norm' field is used wolffd@0: % (see the cell array option below). wolffd@0: % (cell array) In practice, the '.comp_norm' field of wolffd@0: % a data/map struct. The length of the array wolffd@0: % must be equal to the dimension of the given wolffd@0: % data set (sS). Each cell contains the wolffd@0: % normalization(s) for one component. Only the wolffd@0: % normalizations listed in comps argument are wolffd@0: % applied though. wolffd@0: % (cellstr array) norm and denorm operations in a cellstr array wolffd@0: % which are evaluated with EVAL command with variable wolffd@0: % name 'x' reserved for the variable. wolffd@0: % wolffd@0: % comps (vector) The components to which the normalization(s) is wolffd@0: % applied. Default is to apply to all components. wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sS Modified and/or updated data. wolffd@0: % (struct) If a struct was given as input argument, the wolffd@0: % same struct is returned with normalized data and wolffd@0: % updated '.comp_norm' fields. wolffd@0: % (matrix) If a matrix was given as input argument, the wolffd@0: % normalized data matrix is returned. wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % To add (initialize and apply) a normalization to a data struct: wolffd@0: % wolffd@0: % sS = som_normalize(sS,'var'); wolffd@0: % wolffd@0: % This uses 'var'-method to all components. To add a method only to wolffd@0: % a few selected components, use the comps argument: wolffd@0: % wolffd@0: % sS = som_normalize(sS,'log',[1 3:5]); wolffd@0: % wolffd@0: % To ensure that all normalization operations have indeed been done: wolffd@0: % wolffd@0: % sS = som_normalize(sS); wolffd@0: % wolffd@0: % The same for only a few components: wolffd@0: % wolffd@0: % sS = som_normalize(sS,'',[1 3:5]); wolffd@0: % wolffd@0: % To apply the normalizations of a data struct sS to a new data set D: wolffd@0: % wolffd@0: % D = som_normalize(D,sS); wolffd@0: % or wolffd@0: % D = som_normalize(D,sS.comp_norm); wolffd@0: % wolffd@0: % To normalize a data set: wolffd@0: % wolffd@0: % D = som_normalize(D,'histD'); wolffd@0: % wolffd@0: % Note that in this case the normalization information is lost. wolffd@0: % wolffd@0: % To check out the status of normalization in a struct use SOM_INFO: wolffd@0: % wolffd@0: % som_info(sS,3) wolffd@0: % wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_denormalize Undo normalizations of a data struct/set. wolffd@0: % som_norm_variable Normalization operations for a set of scalar values. wolffd@0: % som_info User-friendly information of SOM Toolbox structs. wolffd@0: wolffd@0: % Copyright (c) 1998-2000 by the SOM toolbox programming team. wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Version 2.0beta juuso 151199 150500 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% check arguments wolffd@0: wolffd@0: error(nargchk(1, 3, nargin)); % check no. of input arguments is correct wolffd@0: wolffd@0: % sD wolffd@0: struct_mode = isstruct(sD); wolffd@0: if struct_mode, wolffd@0: switch sD.type wolffd@0: case 'som_map', D = sD.codebook; wolffd@0: case 'som_data', D = sD.data; wolffd@0: otherwise, error('Illegal struct.') wolffd@0: end wolffd@0: else wolffd@0: D = sD; wolffd@0: end wolffd@0: [dlen dim] = size(D); wolffd@0: wolffd@0: % comps wolffd@0: if nargin<3 | (ischar(comps) & strcmp(comps,'all')), wolffd@0: comps = [1:dim]; wolffd@0: end wolffd@0: if isempty(comps), return; end wolffd@0: if size(comps,1)>1, comps = comps'; end % make it a row vector wolffd@0: wolffd@0: % method wolffd@0: csNorm = cell(dim,1); wolffd@0: if nargin<2 | isempty(method), wolffd@0: if ~struct_mode, wolffd@0: warning('No normalization method given. Data left unchanged.'); wolffd@0: return; wolffd@0: end wolffd@0: method = ''; wolffd@0: else wolffd@0: % check out the given method wolffd@0: % (and if necessary, copy it for each specified component) wolffd@0: if ischar(method), wolffd@0: switch method, wolffd@0: case {'var','range','log','histD','histC','logistic'}, wolffd@0: sN = som_set('som_norm','method',method); wolffd@0: otherwise, wolffd@0: error(['Unrecognized method: ' method]); wolffd@0: end wolffd@0: for i=comps, csNorm{i} = sN; end wolffd@0: elseif isstruct(method), wolffd@0: switch method(1).type, wolffd@0: case {'som_map','som_data'}, csNorm = method(1).comp_norm; wolffd@0: case {'som_norm'}, for i=comps, csNorm{i} = method; end wolffd@0: otherwise, wolffd@0: error('Invalid struct given as normalization method.') wolffd@0: end wolffd@0: elseif iscellstr(method), wolffd@0: [dummy,sN] = som_norm_variable(1,method,'init'); wolffd@0: for i=comps, csNorm{i} = sN; end wolffd@0: elseif iscell(method), wolffd@0: csNorm = method; wolffd@0: else wolffd@0: error('Illegal method argument.') wolffd@0: end wolffd@0: % check the size of csNorm is the same as data dimension wolffd@0: if length(csNorm) ~= dim, wolffd@0: error('Given number of normalizations does not match data dimension.') wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% initialize wolffd@0: wolffd@0: % make sure all the current normalizations for current wolffd@0: % components have been done wolffd@0: if struct_mode, wolffd@0: alldone = 1; wolffd@0: for i = comps, wolffd@0: for j=1:length(sD.comp_norm{i}), wolffd@0: sN = sD.comp_norm{i}(j); wolffd@0: if ~strcmp(sN.status,'done'), wolffd@0: alldone = 0; wolffd@0: [x,sN] = som_norm_variable(D(:,i), sN, 'do'); wolffd@0: D(:,i) = x; wolffd@0: sD.comp_norm{i}(j) = sN; wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: if isempty(method), wolffd@0: if alldone, wolffd@0: warning('No ''undone'' normalizations found. Data left unchanged.'); wolffd@0: else wolffd@0: fprintf(1,'Normalizations have been redone.\n'); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% action wolffd@0: wolffd@0: % add the new normalizations to the old ones wolffd@0: for i = comps, wolffd@0: if ~isempty(csNorm{i}), wolffd@0: [x,sN] = som_norm_variable(D(:,i), csNorm{i}, 'do'); wolffd@0: D(:,i) = x; wolffd@0: if struct_mode, wolffd@0: if isempty(sD.comp_norm{i}), sD.comp_norm{i} = sN; wolffd@0: else sD.comp_norm{i} = [sD.comp_norm{i}, sN]; end wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: %% output wolffd@0: wolffd@0: if struct_mode, wolffd@0: switch sD.type wolffd@0: case 'som_map', sD.codebook = D; wolffd@0: case 'som_data', sD.data = D; wolffd@0: otherwise, error('Illegal struct.') wolffd@0: end wolffd@0: else wolffd@0: sD = D; wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: wolffd@0: