wolffd@0
|
1 function sD = som_normalize(sD,method,comps)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_NORMALIZE (Re)normalize data or add new normalizations.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % sS = som_normalize(sS,[method],[comps])
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % sS = som_normalize(sD)
|
wolffd@0
|
8 % sS = som_normalize(sS,sNorm)
|
wolffd@0
|
9 % D = som_normalize(D,'var')
|
wolffd@0
|
10 % sS = som_normalize(sS,'histC',[1:3 10])
|
wolffd@0
|
11 %
|
wolffd@0
|
12 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
13 % sS The data to which the normalization is applied.
|
wolffd@0
|
14 % The modified and updated data is returned.
|
wolffd@0
|
15 % (struct) data or map struct
|
wolffd@0
|
16 % (matrix) data matrix (a matrix is also returned)
|
wolffd@0
|
17 % [method] The normalization method(s) to add/use. If missing,
|
wolffd@0
|
18 % or an empty variable ('') is given, the
|
wolffd@0
|
19 % normalizations in sS are used.
|
wolffd@0
|
20 % (string) identifier for a normalization method to be added:
|
wolffd@0
|
21 % 'var', 'range', 'log', 'logistic', 'histD' or 'histC'.
|
wolffd@0
|
22 % (struct) Normalization struct, or an array of such.
|
wolffd@0
|
23 % Alternatively, a map/data struct can be given
|
wolffd@0
|
24 % in which case its '.comp_norm' field is used
|
wolffd@0
|
25 % (see below).
|
wolffd@0
|
26 % (cell array) Of normalization structs. Typically, the
|
wolffd@0
|
27 % '.comp_norm' field of a map/data struct. The
|
wolffd@0
|
28 % length of the array must be equal to data dimension.
|
wolffd@0
|
29 % (cellstr array) norm and denorm operations in a cellstr array
|
wolffd@0
|
30 % which are evaluated with EVAL command with variable
|
wolffd@0
|
31 % name 'x' reserved for the variable.
|
wolffd@0
|
32 % [comps] (vector) the components to which the normalization is
|
wolffd@0
|
33 % applied, default is [1:dim] ie. all components
|
wolffd@0
|
34 %
|
wolffd@0
|
35 % For more help, try 'type som_normalize' or check out online documentation.
|
wolffd@0
|
36 % See also SOM_DENORMALIZE, SOM_NORM_VARIABLE, SOM_INFO.
|
wolffd@0
|
37
|
wolffd@0
|
38 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
39 %
|
wolffd@0
|
40 % som_normalize
|
wolffd@0
|
41 %
|
wolffd@0
|
42 % PURPOSE
|
wolffd@0
|
43 %
|
wolffd@0
|
44 % Add/apply/redo normalization on data structs/sets.
|
wolffd@0
|
45 %
|
wolffd@0
|
46 % SYNTAX
|
wolffd@0
|
47 %
|
wolffd@0
|
48 % sS = som_normalize(sS)
|
wolffd@0
|
49 % sS = som_normalize(sS,method)
|
wolffd@0
|
50 % D = som_normalize(D,sNorm)
|
wolffd@0
|
51 % sS = som_normalize(sS,csNorm)
|
wolffd@0
|
52 % sS = som_normalize(...,comps)
|
wolffd@0
|
53 %
|
wolffd@0
|
54 % DESCRIPTION
|
wolffd@0
|
55 %
|
wolffd@0
|
56 % This function is used to (initialize and) add, redo and apply
|
wolffd@0
|
57 % normalizations on data/map structs/sets. If a data/map struct is given,
|
wolffd@0
|
58 % the specified normalizations are added to the '.comp_norm' field of the
|
wolffd@0
|
59 % struct after ensuring that all normalizations specified therein have
|
wolffd@0
|
60 % status 'done'. SOM_NORMALIZE actually uses function SOM_NORM_VARIABLE
|
wolffd@0
|
61 % to handle the normalization operations, and only handles the data
|
wolffd@0
|
62 % struct/set specific stuff itself.
|
wolffd@0
|
63 %
|
wolffd@0
|
64 % The different normalization methods are listed below. For more
|
wolffd@0
|
65 % detailed descriptions, see SOM_NORM_VARIABLE.
|
wolffd@0
|
66 %
|
wolffd@0
|
67 % method description
|
wolffd@0
|
68 % 'var' Variance is normalized to one (linear operation).
|
wolffd@0
|
69 % 'range' Values are normalized between [0,1] (linear operation).
|
wolffd@0
|
70 % 'log' Natural logarithm is applied to the values:
|
wolffd@0
|
71 % xnew = log(x-m+1)
|
wolffd@0
|
72 % where m = min(x).
|
wolffd@0
|
73 % 'logistic' Logistic or softmax trasformation which scales all
|
wolffd@0
|
74 % possible values between [0,1].
|
wolffd@0
|
75 % 'histD' Histogram equalization, values scaled between [0,1].
|
wolffd@0
|
76 % 'histC' Approximate histogram equalization with partially
|
wolffd@0
|
77 % linear operations. Values scaled between [0,1].
|
wolffd@0
|
78 % 'eval' freeform operations
|
wolffd@0
|
79 %
|
wolffd@0
|
80 % To enable undoing and applying the exactly same normalization to
|
wolffd@0
|
81 % other data sets, normalization information is saved into a
|
wolffd@0
|
82 % normalization struct, which has the fields:
|
wolffd@0
|
83 %
|
wolffd@0
|
84 % .type ; struct type, ='som_norm'
|
wolffd@0
|
85 % .method ; normalization method, a string
|
wolffd@0
|
86 % .params ; normalization parameters
|
wolffd@0
|
87 % .status ; string: 'uninit', 'undone' or 'done'
|
wolffd@0
|
88 %
|
wolffd@0
|
89 % Normalizations are always one-variable operations. In the data and map
|
wolffd@0
|
90 % structs the normalization information for each component is saved in the
|
wolffd@0
|
91 % '.comp_norm' field, which is a cell array of length dim. Each cell
|
wolffd@0
|
92 % contains normalizations for one vector component in a struct array of
|
wolffd@0
|
93 % normalization structs. Each component may have different amounts of
|
wolffd@0
|
94 % different kinds of normalizations. Typically, all normalizations are
|
wolffd@0
|
95 % either 'undone' or 'done', but in special situations this may not be the
|
wolffd@0
|
96 % case. The easiest way to check out the status of the normalizations is to
|
wolffd@0
|
97 % use function SOM_INFO, e.g. som_info(sS,3)
|
wolffd@0
|
98 %
|
wolffd@0
|
99 % REQUIRED INPUT ARGUMENTS
|
wolffd@0
|
100 %
|
wolffd@0
|
101 % sS The data to which the normalization is applied.
|
wolffd@0
|
102 % (struct) Data or map struct. Before adding any new
|
wolffd@0
|
103 % normalizations, it is ensured that the
|
wolffd@0
|
104 % normalizations for the specified components in the
|
wolffd@0
|
105 % '.comp_norm' field have status 'done'.
|
wolffd@0
|
106 % (matrix) data matrix
|
wolffd@0
|
107 %
|
wolffd@0
|
108 % OPTIONAL INPUT ARGUMENTS
|
wolffd@0
|
109 %
|
wolffd@0
|
110 % method The normalization(s) to add/use. If missing,
|
wolffd@0
|
111 % or an empty variable ('' or []) is given, the
|
wolffd@0
|
112 % normalizations in the data struct are used.
|
wolffd@0
|
113 % (string) Identifier for a normalization method to be added:
|
wolffd@0
|
114 % 'var', 'range', 'log', 'logistic', 'histD' or 'histC'. The
|
wolffd@0
|
115 % same method is applied to all specified components
|
wolffd@0
|
116 % (given in comps). The normalizations are first
|
wolffd@0
|
117 % initialized (for each component separately, of
|
wolffd@0
|
118 % course) and then applied.
|
wolffd@0
|
119 % (struct) Normalization struct, or an array of structs, which
|
wolffd@0
|
120 % is applied to all specified components. If the
|
wolffd@0
|
121 % '.status' field of the struct(s) is 'uninit',
|
wolffd@0
|
122 % the normalization(s) is initialized first.
|
wolffd@0
|
123 % Alternatively, the struct may be map or data struct
|
wolffd@0
|
124 % in which case its '.comp_norm' field is used
|
wolffd@0
|
125 % (see the cell array option below).
|
wolffd@0
|
126 % (cell array) In practice, the '.comp_norm' field of
|
wolffd@0
|
127 % a data/map struct. The length of the array
|
wolffd@0
|
128 % must be equal to the dimension of the given
|
wolffd@0
|
129 % data set (sS). Each cell contains the
|
wolffd@0
|
130 % normalization(s) for one component. Only the
|
wolffd@0
|
131 % normalizations listed in comps argument are
|
wolffd@0
|
132 % applied though.
|
wolffd@0
|
133 % (cellstr array) norm and denorm operations in a cellstr array
|
wolffd@0
|
134 % which are evaluated with EVAL command with variable
|
wolffd@0
|
135 % name 'x' reserved for the variable.
|
wolffd@0
|
136 %
|
wolffd@0
|
137 % comps (vector) The components to which the normalization(s) is
|
wolffd@0
|
138 % applied. Default is to apply to all components.
|
wolffd@0
|
139 %
|
wolffd@0
|
140 % OUTPUT ARGUMENTS
|
wolffd@0
|
141 %
|
wolffd@0
|
142 % sS Modified and/or updated data.
|
wolffd@0
|
143 % (struct) If a struct was given as input argument, the
|
wolffd@0
|
144 % same struct is returned with normalized data and
|
wolffd@0
|
145 % updated '.comp_norm' fields.
|
wolffd@0
|
146 % (matrix) If a matrix was given as input argument, the
|
wolffd@0
|
147 % normalized data matrix is returned.
|
wolffd@0
|
148 %
|
wolffd@0
|
149 % EXAMPLES
|
wolffd@0
|
150 %
|
wolffd@0
|
151 % To add (initialize and apply) a normalization to a data struct:
|
wolffd@0
|
152 %
|
wolffd@0
|
153 % sS = som_normalize(sS,'var');
|
wolffd@0
|
154 %
|
wolffd@0
|
155 % This uses 'var'-method to all components. To add a method only to
|
wolffd@0
|
156 % a few selected components, use the comps argument:
|
wolffd@0
|
157 %
|
wolffd@0
|
158 % sS = som_normalize(sS,'log',[1 3:5]);
|
wolffd@0
|
159 %
|
wolffd@0
|
160 % To ensure that all normalization operations have indeed been done:
|
wolffd@0
|
161 %
|
wolffd@0
|
162 % sS = som_normalize(sS);
|
wolffd@0
|
163 %
|
wolffd@0
|
164 % The same for only a few components:
|
wolffd@0
|
165 %
|
wolffd@0
|
166 % sS = som_normalize(sS,'',[1 3:5]);
|
wolffd@0
|
167 %
|
wolffd@0
|
168 % To apply the normalizations of a data struct sS to a new data set D:
|
wolffd@0
|
169 %
|
wolffd@0
|
170 % D = som_normalize(D,sS);
|
wolffd@0
|
171 % or
|
wolffd@0
|
172 % D = som_normalize(D,sS.comp_norm);
|
wolffd@0
|
173 %
|
wolffd@0
|
174 % To normalize a data set:
|
wolffd@0
|
175 %
|
wolffd@0
|
176 % D = som_normalize(D,'histD');
|
wolffd@0
|
177 %
|
wolffd@0
|
178 % Note that in this case the normalization information is lost.
|
wolffd@0
|
179 %
|
wolffd@0
|
180 % To check out the status of normalization in a struct use SOM_INFO:
|
wolffd@0
|
181 %
|
wolffd@0
|
182 % som_info(sS,3)
|
wolffd@0
|
183 %
|
wolffd@0
|
184 %
|
wolffd@0
|
185 % SEE ALSO
|
wolffd@0
|
186 %
|
wolffd@0
|
187 % som_denormalize Undo normalizations of a data struct/set.
|
wolffd@0
|
188 % som_norm_variable Normalization operations for a set of scalar values.
|
wolffd@0
|
189 % som_info User-friendly information of SOM Toolbox structs.
|
wolffd@0
|
190
|
wolffd@0
|
191 % Copyright (c) 1998-2000 by the SOM toolbox programming team.
|
wolffd@0
|
192 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
193
|
wolffd@0
|
194 % Version 2.0beta juuso 151199 150500
|
wolffd@0
|
195
|
wolffd@0
|
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
197 %% check arguments
|
wolffd@0
|
198
|
wolffd@0
|
199 error(nargchk(1, 3, nargin)); % check no. of input arguments is correct
|
wolffd@0
|
200
|
wolffd@0
|
201 % sD
|
wolffd@0
|
202 struct_mode = isstruct(sD);
|
wolffd@0
|
203 if struct_mode,
|
wolffd@0
|
204 switch sD.type
|
wolffd@0
|
205 case 'som_map', D = sD.codebook;
|
wolffd@0
|
206 case 'som_data', D = sD.data;
|
wolffd@0
|
207 otherwise, error('Illegal struct.')
|
wolffd@0
|
208 end
|
wolffd@0
|
209 else
|
wolffd@0
|
210 D = sD;
|
wolffd@0
|
211 end
|
wolffd@0
|
212 [dlen dim] = size(D);
|
wolffd@0
|
213
|
wolffd@0
|
214 % comps
|
wolffd@0
|
215 if nargin<3 | (ischar(comps) & strcmp(comps,'all')),
|
wolffd@0
|
216 comps = [1:dim];
|
wolffd@0
|
217 end
|
wolffd@0
|
218 if isempty(comps), return; end
|
wolffd@0
|
219 if size(comps,1)>1, comps = comps'; end % make it a row vector
|
wolffd@0
|
220
|
wolffd@0
|
221 % method
|
wolffd@0
|
222 csNorm = cell(dim,1);
|
wolffd@0
|
223 if nargin<2 | isempty(method),
|
wolffd@0
|
224 if ~struct_mode,
|
wolffd@0
|
225 warning('No normalization method given. Data left unchanged.');
|
wolffd@0
|
226 return;
|
wolffd@0
|
227 end
|
wolffd@0
|
228 method = '';
|
wolffd@0
|
229 else
|
wolffd@0
|
230 % check out the given method
|
wolffd@0
|
231 % (and if necessary, copy it for each specified component)
|
wolffd@0
|
232 if ischar(method),
|
wolffd@0
|
233 switch method,
|
wolffd@0
|
234 case {'var','range','log','histD','histC','logistic'},
|
wolffd@0
|
235 sN = som_set('som_norm','method',method);
|
wolffd@0
|
236 otherwise,
|
wolffd@0
|
237 error(['Unrecognized method: ' method]);
|
wolffd@0
|
238 end
|
wolffd@0
|
239 for i=comps, csNorm{i} = sN; end
|
wolffd@0
|
240 elseif isstruct(method),
|
wolffd@0
|
241 switch method(1).type,
|
wolffd@0
|
242 case {'som_map','som_data'}, csNorm = method(1).comp_norm;
|
wolffd@0
|
243 case {'som_norm'}, for i=comps, csNorm{i} = method; end
|
wolffd@0
|
244 otherwise,
|
wolffd@0
|
245 error('Invalid struct given as normalization method.')
|
wolffd@0
|
246 end
|
wolffd@0
|
247 elseif iscellstr(method),
|
wolffd@0
|
248 [dummy,sN] = som_norm_variable(1,method,'init');
|
wolffd@0
|
249 for i=comps, csNorm{i} = sN; end
|
wolffd@0
|
250 elseif iscell(method),
|
wolffd@0
|
251 csNorm = method;
|
wolffd@0
|
252 else
|
wolffd@0
|
253 error('Illegal method argument.')
|
wolffd@0
|
254 end
|
wolffd@0
|
255 % check the size of csNorm is the same as data dimension
|
wolffd@0
|
256 if length(csNorm) ~= dim,
|
wolffd@0
|
257 error('Given number of normalizations does not match data dimension.')
|
wolffd@0
|
258 end
|
wolffd@0
|
259 end
|
wolffd@0
|
260
|
wolffd@0
|
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
262 %% initialize
|
wolffd@0
|
263
|
wolffd@0
|
264 % make sure all the current normalizations for current
|
wolffd@0
|
265 % components have been done
|
wolffd@0
|
266 if struct_mode,
|
wolffd@0
|
267 alldone = 1;
|
wolffd@0
|
268 for i = comps,
|
wolffd@0
|
269 for j=1:length(sD.comp_norm{i}),
|
wolffd@0
|
270 sN = sD.comp_norm{i}(j);
|
wolffd@0
|
271 if ~strcmp(sN.status,'done'),
|
wolffd@0
|
272 alldone = 0;
|
wolffd@0
|
273 [x,sN] = som_norm_variable(D(:,i), sN, 'do');
|
wolffd@0
|
274 D(:,i) = x;
|
wolffd@0
|
275 sD.comp_norm{i}(j) = sN;
|
wolffd@0
|
276 end
|
wolffd@0
|
277 end
|
wolffd@0
|
278 end
|
wolffd@0
|
279 if isempty(method),
|
wolffd@0
|
280 if alldone,
|
wolffd@0
|
281 warning('No ''undone'' normalizations found. Data left unchanged.');
|
wolffd@0
|
282 else
|
wolffd@0
|
283 fprintf(1,'Normalizations have been redone.\n');
|
wolffd@0
|
284 end
|
wolffd@0
|
285 end
|
wolffd@0
|
286 end
|
wolffd@0
|
287
|
wolffd@0
|
288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
289 %% action
|
wolffd@0
|
290
|
wolffd@0
|
291 % add the new normalizations to the old ones
|
wolffd@0
|
292 for i = comps,
|
wolffd@0
|
293 if ~isempty(csNorm{i}),
|
wolffd@0
|
294 [x,sN] = som_norm_variable(D(:,i), csNorm{i}, 'do');
|
wolffd@0
|
295 D(:,i) = x;
|
wolffd@0
|
296 if struct_mode,
|
wolffd@0
|
297 if isempty(sD.comp_norm{i}), sD.comp_norm{i} = sN;
|
wolffd@0
|
298 else sD.comp_norm{i} = [sD.comp_norm{i}, sN]; end
|
wolffd@0
|
299 end
|
wolffd@0
|
300 end
|
wolffd@0
|
301 end
|
wolffd@0
|
302
|
wolffd@0
|
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
304 %% output
|
wolffd@0
|
305
|
wolffd@0
|
306 if struct_mode,
|
wolffd@0
|
307 switch sD.type
|
wolffd@0
|
308 case 'som_map', sD.codebook = D;
|
wolffd@0
|
309 case 'som_data', sD.data = D;
|
wolffd@0
|
310 otherwise, error('Illegal struct.')
|
wolffd@0
|
311 end
|
wolffd@0
|
312 else
|
wolffd@0
|
313 sD = D;
|
wolffd@0
|
314 end
|
wolffd@0
|
315
|
wolffd@0
|
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
317
|
wolffd@0
|
318
|
wolffd@0
|
319
|