| wolffd@0 | 1 function [x,sNorm] = som_norm_variable(x, method, operation) | 
| wolffd@0 | 2 | 
| wolffd@0 | 3 %SOM_NORM_VARIABLE Normalize or denormalize a scalar variable. | 
| wolffd@0 | 4 % | 
| wolffd@0 | 5 % [x,sNorm] = som_norm_variable(x, method, operation) | 
| wolffd@0 | 6 % | 
| wolffd@0 | 7 %   xnew = som_norm_variable(x,'var','do'); | 
| wolffd@0 | 8 %   [dummy,sN] = som_norm_variable(x,'log','init'); | 
| wolffd@0 | 9 %   [xnew,sN]  = som_norm_variable(x,sN,'do'); | 
| wolffd@0 | 10 %   xorig      = som_norm_variable(xnew,sN,'undo'); | 
| wolffd@0 | 11 % | 
| wolffd@0 | 12 %  Input and output arguments: | 
| wolffd@0 | 13 %   x         (vector) a set of values of a scalar variable for | 
| wolffd@0 | 14 %                      which the (de)normalization is performed. | 
| wolffd@0 | 15 %                      The processed values are returned. | 
| wolffd@0 | 16 %   method    (string) identifier for a normalization method: 'var', | 
| wolffd@0 | 17 %                      'range', 'log', 'logistic', 'histD', or 'histC'. | 
| wolffd@0 | 18 %                      A normalization struct with default values is created. | 
| wolffd@0 | 19 %             (struct) normalization struct, or an array of such | 
| wolffd@0 | 20 %             (cellstr) first string gives normalization operation, and the | 
| wolffd@0 | 21 %                      second gives denormalization operation, with x | 
| wolffd@0 | 22 %                      representing the variable, for example: | 
| wolffd@0 | 23 %                      {'x+2','x-2}, or {'exp(-x)','-log(x)'} or {'round(x)'}. | 
| wolffd@0 | 24 %                      Note that in the last case, no denorm operation is | 
| wolffd@0 | 25 %                      defined. | 
| wolffd@0 | 26 %   operation (string) the operation to be performed: 'init', 'do' or 'undo' | 
| wolffd@0 | 27 % | 
| wolffd@0 | 28 %   sNorm     (struct) updated normalization struct/struct array | 
| wolffd@0 | 29 % | 
| wolffd@0 | 30 % For more help, try 'type som_norm_variable' or check out online documentation. | 
| wolffd@0 | 31 % See also SOM_NORMALIZE, SOM_DENORMALIZE. | 
| wolffd@0 | 32 | 
| wolffd@0 | 33 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
| wolffd@0 | 34 % | 
| wolffd@0 | 35 % som_norm_variable | 
| wolffd@0 | 36 % | 
| wolffd@0 | 37 % PURPOSE | 
| wolffd@0 | 38 % | 
| wolffd@0 | 39 % Initialize, apply and undo normalizations on a given vector of | 
| wolffd@0 | 40 % scalar values. | 
| wolffd@0 | 41 % | 
| wolffd@0 | 42 % SYNTAX | 
| wolffd@0 | 43 % | 
| wolffd@0 | 44 %  xnew = som_norm_variable(x,method,operation) | 
| wolffd@0 | 45 %  xnew = som_norm_variable(x,sNorm,operation) | 
| wolffd@0 | 46 %  [xnew,sNorm] = som_norm_variable(...) | 
| wolffd@0 | 47 % | 
| wolffd@0 | 48 % DESCRIPTION | 
| wolffd@0 | 49 % | 
| wolffd@0 | 50 % This function is used to initialize, apply and undo normalizations | 
| wolffd@0 | 51 % on scalar variables. It is the low-level function that upper-level | 
| wolffd@0 | 52 % functions SOM_NORMALIZE and SOM_DENORMALIZE utilize to actually (un)do | 
| wolffd@0 | 53 % the normalizations. | 
| wolffd@0 | 54 % | 
| wolffd@0 | 55 % Normalizations are typically performed to control the variance of | 
| wolffd@0 | 56 % vector components. If some vector components have variance which is | 
| wolffd@0 | 57 % significantly higher than the variance of other components, those | 
| wolffd@0 | 58 % components will dominate the map organization. Normalization of | 
| wolffd@0 | 59 % the variance of vector components (method 'var') is used to prevent | 
| wolffd@0 | 60 % that. In addition to variance normalization, other methods have | 
| wolffd@0 | 61 % been implemented as well (see list below). | 
| wolffd@0 | 62 % | 
| wolffd@0 | 63 % Usually normalizations convert the variable values so that they no | 
| wolffd@0 | 64 % longer make any sense: the values are still ordered, but their range | 
| wolffd@0 | 65 % may have changed so radically that interpreting the numbers in the | 
| wolffd@0 | 66 % original context is very hard. For this reason all implemented methods | 
| wolffd@0 | 67 % are (more or less) revertible. The normalizations are monotonic | 
| wolffd@0 | 68 % and information is saved so that they can be undone. Also, the saved | 
| wolffd@0 | 69 % information makes it possible to apply the EXACTLY SAME normalization | 
| wolffd@0 | 70 % to another set of values. The normalization information is determined | 
| wolffd@0 | 71 % with 'init' operation, while 'do' and 'undo' operations are used to | 
| wolffd@0 | 72 % apply or revert the normalization. | 
| wolffd@0 | 73 % | 
| wolffd@0 | 74 % The normalization information is saved in a normalization struct, | 
| wolffd@0 | 75 % which is returned as the second argument of this function. Note that | 
| wolffd@0 | 76 % normalization operations may be stacked. In this case, normalization | 
| wolffd@0 | 77 % structs are positioned in a struct array. When applied, the array is | 
| wolffd@0 | 78 % gone through from start to end, and when undone, in reverse order. | 
| wolffd@0 | 79 % | 
| wolffd@0 | 80 %    method  description | 
| wolffd@0 | 81 % | 
| wolffd@0 | 82 %    'var'   Variance normalization. A linear transformation which | 
| wolffd@0 | 83 %            scales the values such that their variance=1. This is | 
| wolffd@0 | 84 %            convenient way to use Mahalanobis distance measure without | 
| wolffd@0 | 85 %            actually changing the distance calculation procedure. | 
| wolffd@0 | 86 % | 
| wolffd@0 | 87 %    'range' Normalization of range of values. A linear transformation | 
| wolffd@0 | 88 %            which scales the values between [0,1]. | 
| wolffd@0 | 89 % | 
| wolffd@0 | 90 %    'log'   Logarithmic normalization. In many cases the values of | 
| wolffd@0 | 91 %            a vector component are exponentially distributed. This | 
| wolffd@0 | 92 %            normalization is a good way to get more resolution to | 
| wolffd@0 | 93 %            (the low end of) that vector component. What this | 
| wolffd@0 | 94 %            actually does is a non-linear transformation: | 
| wolffd@0 | 95 %               x_new = log(x_old - m + 1) | 
| wolffd@0 | 96 %            where m=min(x_old) and log is the natural logarithm. | 
| wolffd@0 | 97 %            Applying the transformation to a value which is lower | 
| wolffd@0 | 98 %            than m-1 will give problems, as the result is then complex. | 
| wolffd@0 | 99 %            If the minimum for values is known a priori, | 
| wolffd@0 | 100 %            it might be a good idea to initialize the normalization with | 
| wolffd@0 | 101 %              [dummy,sN] = som_norm_variable(minimum,'log','init'); | 
| wolffd@0 | 102 %            and normalize only after this: | 
| wolffd@0 | 103 %              x_new = som_norm_variable(x,sN,'do'); | 
| wolffd@0 | 104 % | 
| wolffd@0 | 105 %    'logistic' or softmax normalization. This normalization ensures | 
| wolffd@0 | 106 %            that all values in the future, too, are within the range | 
| wolffd@0 | 107 %            [0,1]. The transformation is more-or-less linear in the | 
| wolffd@0 | 108 %            middle range (around mean value), and has a smooth | 
| wolffd@0 | 109 %            nonlinearity at both ends which ensures that all values | 
| wolffd@0 | 110 %            are within the range. The data is first scaled as in | 
| wolffd@0 | 111 %            variance normalization: | 
| wolffd@0 | 112 %               x_scaled = (x_old - mean(x_old))/std(x_old) | 
| wolffd@0 | 113 %            and then transformed with the logistic function | 
| wolffd@0 | 114 %               x_new = 1/(1+exp(-x_scaled)) | 
| wolffd@0 | 115 % | 
| wolffd@0 | 116 %    'histD' Discrete histogram equalization. Non-linear. Orders the | 
| wolffd@0 | 117 %            values and replaces each value by its ordinal number. | 
| wolffd@0 | 118 %            Finally, scales the values such that they are between [0,1]. | 
| wolffd@0 | 119 %            Useful for both discrete and continuous variables, but as | 
| wolffd@0 | 120 %            the saved normalization information consists of all | 
| wolffd@0 | 121 %            unique values of the initialization data set, it may use | 
| wolffd@0 | 122 %            considerable amounts of memory. If the variable can get | 
| wolffd@0 | 123 %            more than a few values (say, 20), it might be better to | 
| wolffd@0 | 124 %            use 'histC' method below. Another important note is that | 
| wolffd@0 | 125 %            this method is not exactly revertible if it is applied | 
| wolffd@0 | 126 %            to values which are not part of the original value set. | 
| wolffd@0 | 127 % | 
| wolffd@0 | 128 %    'histC' Continuous histogram equalization. Actually, a partially | 
| wolffd@0 | 129 %            linear transformation which tries to do something like | 
| wolffd@0 | 130 %            histogram equalization. The value range is divided to | 
| wolffd@0 | 131 %            a number of bins such that the number of values in each | 
| wolffd@0 | 132 %            bin is (almost) the same. The values are transformed | 
| wolffd@0 | 133 %            linearly in each bin. For example, values in bin number 3 | 
| wolffd@0 | 134 %            are scaled between [3,4[. Finally, all values are scaled | 
| wolffd@0 | 135 %            between [0,1]. The number of bins is the square root | 
| wolffd@0 | 136 %            of the number of unique values in the initialization set, | 
| wolffd@0 | 137 %            rounded up. The resulting histogram equalization is not | 
| wolffd@0 | 138 %            as good as the one that 'histD' makes, but the benefit | 
| wolffd@0 | 139 %            is that it is exactly revertible - even outside the | 
| wolffd@0 | 140 %            original value range (although the results may be funny). | 
| wolffd@0 | 141 % | 
| wolffd@0 | 142 %    'eval'  With this method, freeform normalization operations can be | 
| wolffd@0 | 143 %            specified. The parameter field contains strings to be | 
| wolffd@0 | 144 %            evaluated with 'eval' function, with variable name 'x' | 
| wolffd@0 | 145 %            representing the variable itself. The first string is | 
| wolffd@0 | 146 %            the normalization operation, and the second is a | 
| wolffd@0 | 147 %            denormalization operation. If the denormalization operation | 
| wolffd@0 | 148 %            is empty, it is ignored. | 
| wolffd@0 | 149 % | 
| wolffd@0 | 150 % INPUT ARGUMENTS | 
| wolffd@0 | 151 % | 
| wolffd@0 | 152 %   x          (vector) The scalar values to which the normalization | 
| wolffd@0 | 153 %                       operation is applied. | 
| wolffd@0 | 154 % | 
| wolffd@0 | 155 %   method              The normalization specification. | 
| wolffd@0 | 156 %              (string) Identifier for a normalization method: 'var', | 
| wolffd@0 | 157 %                       'range', 'log', 'logistic', 'histD' or 'histC'. | 
| wolffd@0 | 158 %                       Corresponding default normalization struct is created. | 
| wolffd@0 | 159 %              (struct) normalization struct | 
| wolffd@0 | 160 %              (struct array) of normalization structs, applied to | 
| wolffd@0 | 161 %                       x one after the other | 
| wolffd@0 | 162 %              (cellstr) of length | 
| wolffd@0 | 163 %              (cellstr array) first string gives normalization operation, and | 
| wolffd@0 | 164 %                       the second gives denormalization operation, with x | 
| wolffd@0 | 165 %                       representing the variable, for example: | 
| wolffd@0 | 166 %                       {'x+2','x-2}, or {'exp(-x)','-log(x)'} or {'round(x)'}. | 
| wolffd@0 | 167 %                       Note that in the last case, no denorm operation is | 
| wolffd@0 | 168 %                       defined. | 
| wolffd@0 | 169 % | 
| wolffd@0 | 170 %               note: if the method is given as struct(s), it is | 
| wolffd@0 | 171 %                     applied (done or undone, as specified by operation) | 
| wolffd@0 | 172 %                     regardless of what the value of '.status' field | 
| wolffd@0 | 173 %                     is in the struct(s). Only if the status is | 
| wolffd@0 | 174 %                     'uninit', the undoing operation is halted. | 
| wolffd@0 | 175 %                     Anyhow, the '.status' fields in the returned | 
| wolffd@0 | 176 %                     normalization struct(s) is set to approriate value. | 
| wolffd@0 | 177 % | 
| wolffd@0 | 178 %   operation  (string) The operation to perform: 'init' to initialize | 
| wolffd@0 | 179 %                       the normalization struct, 'do' to perform the | 
| wolffd@0 | 180 %                       normalization, 'undo' to undo the normalization, | 
| wolffd@0 | 181 %                       if possible. If operation 'do' is given, but the | 
| wolffd@0 | 182 %                       normalization struct has not yet been initialized, | 
| wolffd@0 | 183 %                       it is initialized using the given data (x). | 
| wolffd@0 | 184 % | 
| wolffd@0 | 185 % OUTPUT ARGUMENTS | 
| wolffd@0 | 186 % | 
| wolffd@0 | 187 %   x        (vector) Appropriately processed values. | 
| wolffd@0 | 188 % | 
| wolffd@0 | 189 %   sNorm    (struct) Updated normalization struct/struct array. If any, | 
| wolffd@0 | 190 %                     the '.status' and '.params' fields are updated. | 
| wolffd@0 | 191 % | 
| wolffd@0 | 192 % EXAMPLES | 
| wolffd@0 | 193 % | 
| wolffd@0 | 194 %  To initialize and apply a normalization on a set of scalar values: | 
| wolffd@0 | 195 % | 
| wolffd@0 | 196 %    [x_new,sN] = som_norm_variable(x_old,'var','do'); | 
| wolffd@0 | 197 % | 
| wolffd@0 | 198 %  To just initialize, use: | 
| wolffd@0 | 199 % | 
| wolffd@0 | 200 %    [dummy,sN] = som_norm_variable(x_old,'var','init'); | 
| wolffd@0 | 201 % | 
| wolffd@0 | 202 %  To undo the normalization(s): | 
| wolffd@0 | 203 % | 
| wolffd@0 | 204 %    x_orig = som_norm_variable(x_new,sN,'undo'); | 
| wolffd@0 | 205 % | 
| wolffd@0 | 206 %  Typically, normalizations of data structs/sets are handled using | 
| wolffd@0 | 207 %  functions SOM_NORMALIZE and SOM_DENORMALIZE. However, when only the | 
| wolffd@0 | 208 %  values of a single variable are of interest, SOM_NORM_VARIABLE may | 
| wolffd@0 | 209 %  be useful. For example, assume one wants to apply the normalization | 
| wolffd@0 | 210 %  done on a component (i) of a data struct (sD) to a new set of values | 
| wolffd@0 | 211 %  (x) of that component. With SOM_NORM_VARIABLE this can be done with: | 
| wolffd@0 | 212 % | 
| wolffd@0 | 213 %    x_new = som_norm_variable(x,sD.comp_norm{i},'do'); | 
| wolffd@0 | 214 % | 
| wolffd@0 | 215 %  Now, as the normalizations in sD.comp_norm{i} have already been | 
| wolffd@0 | 216 %  initialized with the original data set (presumably sD.data), | 
| wolffd@0 | 217 %  the EXACTLY SAME normalization(s) can be applied to the new values. | 
| wolffd@0 | 218 %  The same thing can be done with SOM_NORMALIZE function, too: | 
| wolffd@0 | 219 % | 
| wolffd@0 | 220 %    x_new = som_normalize(x,sD.comp_norm{i}); | 
| wolffd@0 | 221 % | 
| wolffd@0 | 222 %  Or, if the new data set were in variable D - a matrix of same | 
| wolffd@0 | 223 %  dimension as the original data set: | 
| wolffd@0 | 224 % | 
| wolffd@0 | 225 %    D_new = som_normalize(D,sD,i); | 
| wolffd@0 | 226 % | 
| wolffd@0 | 227 % SEE ALSO | 
| wolffd@0 | 228 % | 
| wolffd@0 | 229 %  som_normalize    Add/apply/redo normalizations for a data struct/set. | 
| wolffd@0 | 230 %  som_denormalize  Undo normalizations of a data struct/set. | 
| wolffd@0 | 231 | 
| wolffd@0 | 232 % Copyright (c) 1998-2000 by the SOM toolbox programming team. | 
| wolffd@0 | 233 % http://www.cis.hut.fi/projects/somtoolbox/ | 
| wolffd@0 | 234 | 
| wolffd@0 | 235 % Version 2.0beta juuso 151199 170400 150500 | 
| wolffd@0 | 236 | 
| wolffd@0 | 237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
| wolffd@0 | 238 %% check arguments | 
| wolffd@0 | 239 | 
| wolffd@0 | 240 error(nargchk(3, 3, nargin));  % check no. of input arguments is correct | 
| wolffd@0 | 241 | 
| wolffd@0 | 242 % method | 
| wolffd@0 | 243 sNorm = []; | 
| wolffd@0 | 244 if ischar(method) | 
| wolffd@0 | 245   if any(strcmp(method,{'var','range','log','logistic','histD','histC'})), | 
| wolffd@0 | 246     sNorm = som_set('som_norm','method',method); | 
| wolffd@0 | 247   else | 
| wolffd@0 | 248     method = cellstr(method); | 
| wolffd@0 | 249   end | 
| wolffd@0 | 250 end | 
| wolffd@0 | 251 if iscell(method), | 
| wolffd@0 | 252   if length(method)==1 & isstruct(method{1}), sNorm = method{1}; | 
| wolffd@0 | 253   else | 
| wolffd@0 | 254     if length(method)==1 | isempty(method{2}), method{2} = 'x'; end | 
| wolffd@0 | 255     sNorm = som_set('som_norm','method','eval','params',method); | 
| wolffd@0 | 256   end | 
| wolffd@0 | 257 else | 
| wolffd@0 | 258   sNorm = method; | 
| wolffd@0 | 259 end | 
| wolffd@0 | 260 | 
| wolffd@0 | 261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
| wolffd@0 | 262 %% action | 
| wolffd@0 | 263 | 
| wolffd@0 | 264 order = [1:length(sNorm)]; | 
| wolffd@0 | 265 if length(order)>1 & strcmp(operation,'undo'), order = order(end:-1:1); end | 
| wolffd@0 | 266 | 
| wolffd@0 | 267 for i=order, | 
| wolffd@0 | 268 | 
| wolffd@0 | 269   % initialize | 
| wolffd@0 | 270   if strcmp(operation,'init') | ... | 
| wolffd@0 | 271      (strcmp(operation,'do') & strcmp(sNorm(i).status,'uninit')), | 
| wolffd@0 | 272 | 
| wolffd@0 | 273     % case method = 'hist' | 
| wolffd@0 | 274     if strcmp(sNorm(i).method,'hist'), | 
| wolffd@0 | 275       inds = find(~isnan(x) & ~isinf(x)); | 
| wolffd@0 | 276       if length(unique(x(inds)))>20, sNorm(i).method = 'histC'; | 
| wolffd@0 | 277       else sNorm{i}.method = 'histD'; end | 
| wolffd@0 | 278     end | 
| wolffd@0 | 279 | 
| wolffd@0 | 280     switch(sNorm(i).method), | 
| wolffd@0 | 281     case 'var',   params = norm_variance_init(x); | 
| wolffd@0 | 282     case 'range', params = norm_scale01_init(x); | 
| wolffd@0 | 283     case 'log',   params = norm_log_init(x); | 
| wolffd@0 | 284     case 'logistic', params = norm_logistic_init(x); | 
| wolffd@0 | 285     case 'histD', params = norm_histeqD_init(x); | 
| wolffd@0 | 286     case 'histC', params = norm_histeqC_init(x); | 
| wolffd@0 | 287     case 'eval',  params = sNorm(i).params; | 
| wolffd@0 | 288     otherwise, | 
| wolffd@0 | 289       error(['Unrecognized method: ' sNorm(i).method]); | 
| wolffd@0 | 290     end | 
| wolffd@0 | 291     sNorm(i).params = params; | 
| wolffd@0 | 292     sNorm(i).status = 'undone'; | 
| wolffd@0 | 293   end | 
| wolffd@0 | 294 | 
| wolffd@0 | 295   % do / undo | 
| wolffd@0 | 296   if strcmp(operation,'do'), | 
| wolffd@0 | 297     switch(sNorm(i).method), | 
| wolffd@0 | 298     case 'var',   x = norm_scale_do(x,sNorm(i).params); | 
| wolffd@0 | 299     case 'range', x = norm_scale_do(x,sNorm(i).params); | 
| wolffd@0 | 300     case 'log',   x = norm_log_do(x,sNorm(i).params); | 
| wolffd@0 | 301     case 'logistic', x = norm_logistic_do(x,sNorm(i).params); | 
| wolffd@0 | 302     case 'histD', x = norm_histeqD_do(x,sNorm(i).params); | 
| wolffd@0 | 303     case 'histC', x = norm_histeqC_do(x,sNorm(i).params); | 
| wolffd@0 | 304     case 'eval',  x = norm_eval_do(x,sNorm(i).params); | 
| wolffd@0 | 305     otherwise, | 
| wolffd@0 | 306       error(['Unrecognized method: ' sNorm(i).method]); | 
| wolffd@0 | 307     end | 
| wolffd@0 | 308     sNorm(i).status = 'done'; | 
| wolffd@0 | 309 | 
| wolffd@0 | 310   elseif strcmp(operation,'undo'), | 
| wolffd@0 | 311 | 
| wolffd@0 | 312     if strcmp(sNorm(i).status,'uninit'), | 
| wolffd@0 | 313       warning('Could not undo: uninitialized normalization struct.') | 
| wolffd@0 | 314       break; | 
| wolffd@0 | 315     end | 
| wolffd@0 | 316     switch(sNorm(i).method), | 
| wolffd@0 | 317     case 'var',   x = norm_scale_undo(x,sNorm(i).params); | 
| wolffd@0 | 318     case 'range', x = norm_scale_undo(x,sNorm(i).params); | 
| wolffd@0 | 319     case 'log',   x = norm_log_undo(x,sNorm(i).params); | 
| wolffd@0 | 320     case 'logistic', x = norm_logistic_undo(x,sNorm(i).params); | 
| wolffd@0 | 321     case 'histD', x = norm_histeqD_undo(x,sNorm(i).params); | 
| wolffd@0 | 322     case 'histC', x = norm_histeqC_undo(x,sNorm(i).params); | 
| wolffd@0 | 323     case 'eval',  x = norm_eval_undo(x,sNorm(i).params); | 
| wolffd@0 | 324     otherwise, | 
| wolffd@0 | 325       error(['Unrecognized method: ' sNorm(i).method]); | 
| wolffd@0 | 326     end | 
| wolffd@0 | 327     sNorm(i).status = 'undone'; | 
| wolffd@0 | 328 | 
| wolffd@0 | 329   elseif ~strcmp(operation,'init'), | 
| wolffd@0 | 330 | 
| wolffd@0 | 331     error(['Unrecognized operation: ' operation]) | 
| wolffd@0 | 332 | 
| wolffd@0 | 333   end | 
| wolffd@0 | 334 end | 
| wolffd@0 | 335 | 
| wolffd@0 | 336 return; | 
| wolffd@0 | 337 | 
| wolffd@0 | 338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
| wolffd@0 | 339 %% subfunctions | 
| wolffd@0 | 340 | 
| wolffd@0 | 341 % linear scaling | 
| wolffd@0 | 342 | 
| wolffd@0 | 343 function p = norm_variance_init(x) | 
| wolffd@0 | 344   inds = find(~isnan(x) & isfinite(x)); | 
| wolffd@0 | 345   p = [mean(x(inds)), std(x(inds))]; | 
| wolffd@0 | 346   if p(2) == 0, p(2) = 1; end | 
| wolffd@0 | 347   %end of norm_variance_init | 
| wolffd@0 | 348 | 
| wolffd@0 | 349 function p = norm_scale01_init(x) | 
| wolffd@0 | 350   inds = find(~isnan(x) & isfinite(x)); | 
| wolffd@0 | 351   mi = min(x(inds)); | 
| wolffd@0 | 352   ma = max(x(inds)); | 
| wolffd@0 | 353   if mi == ma, p = [mi, 1]; else p = [mi, ma-mi]; end | 
| wolffd@0 | 354   %end of norm_scale01_init | 
| wolffd@0 | 355 | 
| wolffd@0 | 356 function x = norm_scale_do(x,p) | 
| wolffd@0 | 357   x = (x - p(1)) / p(2); | 
| wolffd@0 | 358   % end of norm_scale_do | 
| wolffd@0 | 359 | 
| wolffd@0 | 360 function x = norm_scale_undo(x,p) | 
| wolffd@0 | 361   x = x * p(2) + p(1); | 
| wolffd@0 | 362   % end of norm_scale_undo | 
| wolffd@0 | 363 | 
| wolffd@0 | 364 % logarithm | 
| wolffd@0 | 365 | 
| wolffd@0 | 366 function p = norm_log_init(x) | 
| wolffd@0 | 367   inds = find(~isnan(x) & isfinite(x)); | 
| wolffd@0 | 368   p = min(x(inds)); | 
| wolffd@0 | 369   % end of norm_log_init | 
| wolffd@0 | 370 | 
| wolffd@0 | 371 function x = norm_log_do(x,p) | 
| wolffd@0 | 372   x = log(x - p +1); | 
| wolffd@0 | 373   % if any(~isreal(x)), ok = 0; end | 
| wolffd@0 | 374   % end of norm_log_do | 
| wolffd@0 | 375 | 
| wolffd@0 | 376 function x = norm_log_undo(x,p) | 
| wolffd@0 | 377   x = exp(x) -1 + p; | 
| wolffd@0 | 378   % end of norm_log_undo | 
| wolffd@0 | 379 | 
| wolffd@0 | 380 % logistic | 
| wolffd@0 | 381 | 
| wolffd@0 | 382 function p = norm_logistic_init(x) | 
| wolffd@0 | 383   inds = find(~isnan(x) & isfinite(x)); | 
| wolffd@0 | 384   p = [mean(x(inds)), std(x(inds))]; | 
| wolffd@0 | 385   if p(2)==0, p(2) = 1; end | 
| wolffd@0 | 386   % end of norm_logistic_init | 
| wolffd@0 | 387 | 
| wolffd@0 | 388 function x = norm_logistic_do(x,p) | 
| wolffd@0 | 389   x = (x-p(1))/p(2); | 
| wolffd@0 | 390   x = 1./(1+exp(-x)); | 
| wolffd@0 | 391   % end of norm_logistic_do | 
| wolffd@0 | 392 | 
| wolffd@0 | 393 function x = norm_logistic_undo(x,p) | 
| wolffd@0 | 394   x = log(x./(1-x)); | 
| wolffd@0 | 395   x = x*p(2)+p(1); | 
| wolffd@0 | 396   % end of norm_logistic_undo | 
| wolffd@0 | 397 | 
| wolffd@0 | 398 % histogram equalization for discrete values | 
| wolffd@0 | 399 | 
| wolffd@0 | 400 function p = norm_histeqD_init(x) | 
| wolffd@0 | 401   inds = find(~isnan(x) & ~isinf(x)); | 
| wolffd@0 | 402   p = unique(x(inds)); | 
| wolffd@0 | 403   % end of norm_histeqD_init | 
| wolffd@0 | 404 | 
| wolffd@0 | 405 function x = norm_histeqD_do(x,p) | 
| wolffd@0 | 406   bins = length(p); | 
| wolffd@0 | 407   inds = find(~isnan(x) & ~isinf(x))'; | 
| wolffd@0 | 408   for i = inds, | 
| wolffd@0 | 409     [dummy ind] = min(abs(x(i) - p)); | 
| wolffd@0 | 410     % data item closer to the left-hand bin wall is indexed after RH wall | 
| wolffd@0 | 411     if x(i) > p(ind) & ind < bins, | 
| wolffd@0 | 412       x(i) = ind + 1; | 
| wolffd@0 | 413     else | 
| wolffd@0 | 414       x(i) = ind; | 
| wolffd@0 | 415     end | 
| wolffd@0 | 416   end | 
| wolffd@0 | 417   x = (x-1)/(bins-1); % normalization between [0,1] | 
| wolffd@0 | 418   % end of norm_histeqD_do | 
| wolffd@0 | 419 | 
| wolffd@0 | 420 function x = norm_histeqD_undo(x,p) | 
| wolffd@0 | 421   bins = length(p); | 
| wolffd@0 | 422   x = round(x*(bins-1)+1); | 
| wolffd@0 | 423   inds = find(~isnan(x) & ~isinf(x)); | 
| wolffd@0 | 424   x(inds) = p(x(inds)); | 
| wolffd@0 | 425   % end of norm_histeqD_undo | 
| wolffd@0 | 426 | 
| wolffd@0 | 427 % histogram equalization with partially linear functions | 
| wolffd@0 | 428 | 
| wolffd@0 | 429 function p = norm_histeqC_init(x) | 
| wolffd@0 | 430   % investigate x | 
| wolffd@0 | 431   inds = find(~isnan(x) & ~isinf(x)); | 
| wolffd@0 | 432   samples = length(inds); | 
| wolffd@0 | 433   xs = unique(x(inds)); | 
| wolffd@0 | 434   mi = xs(1); | 
| wolffd@0 | 435   ma = xs(end); | 
| wolffd@0 | 436   % decide number of limits | 
| wolffd@0 | 437   lims = ceil(sqrt(length(xs))); % 2->2,100->10,1000->32,10000->100 | 
| wolffd@0 | 438   % decide limits | 
| wolffd@0 | 439   if lims==1, | 
| wolffd@0 | 440     p = [mi, mi+1]; | 
| wolffd@0 | 441     lims = 2; | 
| wolffd@0 | 442   elseif lims==2, | 
| wolffd@0 | 443     p = [mi, ma]; | 
| wolffd@0 | 444   else | 
| wolffd@0 | 445     p = zeros(lims,1); | 
| wolffd@0 | 446     p(1) = mi; | 
| wolffd@0 | 447     p(end) = ma; | 
| wolffd@0 | 448     binsize = zeros(lims-1,1); b = 1; avebinsize = samples/(lims-1); | 
| wolffd@0 | 449     for i=1:(length(xs)-1), | 
| wolffd@0 | 450       binsize(b) = binsize(b) + sum(x==xs(i)); | 
| wolffd@0 | 451       if binsize(b) >= avebinsize, | 
| wolffd@0 | 452         b = b + 1; | 
| wolffd@0 | 453         p(b) = (xs(i)+xs(i+1))/2; | 
| wolffd@0 | 454       end | 
| wolffd@0 | 455       if b==(lims-1), | 
| wolffd@0 | 456         binsize(b) = samples-sum(binsize); break; | 
| wolffd@0 | 457       else | 
| wolffd@0 | 458         avebinsize = (samples-sum(binsize))/(lims-1-b); | 
| wolffd@0 | 459       end | 
| wolffd@0 | 460     end | 
| wolffd@0 | 461   end | 
| wolffd@0 | 462   % end of norm_histeqC_init | 
| wolffd@0 | 463 | 
| wolffd@0 | 464 function x = norm_histeqC_do(x,p) | 
| wolffd@0 | 465   xnew = x; | 
| wolffd@0 | 466   lims = length(p); | 
| wolffd@0 | 467   % handle values below minimum | 
| wolffd@0 | 468   r = p(2)-p(1); | 
| wolffd@0 | 469   inds = find(x<=p(1) & isfinite(x)); | 
| wolffd@0 | 470   if any(inds), xnew(inds) = 0-(p(1)-x(inds))/r; end | 
| wolffd@0 | 471   % handle values above maximum | 
| wolffd@0 | 472   r = p(end)-p(end-1); | 
| wolffd@0 | 473   inds = find(x>p(end) & isfinite(x)); | 
| wolffd@0 | 474   if any(inds), xnew(inds) = lims-1+(x(inds)-p(end))/r; end | 
| wolffd@0 | 475   % handle all other values | 
| wolffd@0 | 476   for i=1:(lims-1), | 
| wolffd@0 | 477     r0 = p(i); r1 = p(i+1); r = r1-r0; | 
| wolffd@0 | 478     inds = find(x>r0 & x<=r1); | 
| wolffd@0 | 479     if any(inds), xnew(inds) = i-1+(x(inds)-r0)/r; end | 
| wolffd@0 | 480   end | 
| wolffd@0 | 481   % scale so that minimum and maximum correspond to 0 and 1 | 
| wolffd@0 | 482   x = xnew/(lims-1); | 
| wolffd@0 | 483   % end of norm_histeqC_do | 
| wolffd@0 | 484 | 
| wolffd@0 | 485 function x = norm_histeqC_undo(x,p) | 
| wolffd@0 | 486   xnew = x; | 
| wolffd@0 | 487   lims = length(p); | 
| wolffd@0 | 488   % scale so that 0 and 1 correspond to minimum and maximum | 
| wolffd@0 | 489   x = x*(lims-1); | 
| wolffd@0 | 490 | 
| wolffd@0 | 491   % handle values below minimum | 
| wolffd@0 | 492   r = p(2)-p(1); | 
| wolffd@0 | 493   inds = find(x<=0 & isfinite(x)); | 
| wolffd@0 | 494   if any(inds), xnew(inds) = x(inds)*r + p(1); end | 
| wolffd@0 | 495   % handle values above maximum | 
| wolffd@0 | 496   r = p(end)-p(end-1); | 
| wolffd@0 | 497   inds = find(x>lims-1 & isfinite(x)); | 
| wolffd@0 | 498   if any(inds), xnew(inds) = (x(inds)-(lims-1))*r+p(end); end | 
| wolffd@0 | 499   % handle all other values | 
| wolffd@0 | 500   for i=1:(lims-1), | 
| wolffd@0 | 501     r0 = p(i); r1 = p(i+1); r = r1-r0; | 
| wolffd@0 | 502     inds = find(x>i-1 & x<=i); | 
| wolffd@0 | 503     if any(inds), xnew(inds) = (x(inds)-(i-1))*r + r0; end | 
| wolffd@0 | 504   end | 
| wolffd@0 | 505   x = xnew; | 
| wolffd@0 | 506   % end of norm_histeqC_undo | 
| wolffd@0 | 507 | 
| wolffd@0 | 508 % eval | 
| wolffd@0 | 509 | 
| wolffd@0 | 510 function p = norm_eval_init(method) | 
| wolffd@0 | 511   p = method; | 
| wolffd@0 | 512   %end of norm_eval_init | 
| wolffd@0 | 513 | 
| wolffd@0 | 514 function x = norm_eval_do(x,p) | 
| wolffd@0 | 515   x_tmp = eval(p{1}); | 
| wolffd@0 | 516   if size(x_tmp,1)>=1 & size(x,1)>=1 & ... | 
| wolffd@0 | 517      size(x_tmp,2)==1 & size(x,2)==1, | 
| wolffd@0 | 518     x = x_tmp; | 
| wolffd@0 | 519   end | 
| wolffd@0 | 520   %end of norm_eval_do | 
| wolffd@0 | 521 | 
| wolffd@0 | 522 function x = norm_eval_undo(x,p) | 
| wolffd@0 | 523   x_tmp = eval(p{2}); | 
| wolffd@0 | 524   if size(x_tmp,1)>=1 & size(x,1)>=1 & ... | 
| wolffd@0 | 525      size(x_tmp,2)==1 & size(x,2)==1, | 
| wolffd@0 | 526     x = x_tmp; | 
| wolffd@0 | 527   end | 
| wolffd@0 | 528   %end of norm_eval_undo | 
| wolffd@0 | 529 | 
| wolffd@0 | 530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
| wolffd@0 | 531 | 
| wolffd@0 | 532 | 
| wolffd@0 | 533 |