comparison m-toolbox/classes/@ao/whiten2D.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % WHITEN2D whiten the noise for two cross correlated time series.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: whiten2D whitens cross-correlated time-series. Whitening
5 % filters are constructed by a fitting procedure to the cross-spectrum
6 % models provided.
7 % Note: The function assumes that the input model corresponds to the
8 % one-sided csd of the data to be whitened.
9 %
10 % ALGORITHM:
11 % 1) Fit a set of partial fraction z-domain filters using
12 % utils.math.psd2wf
13 % 2) Convert to bank of mIIR filters
14 % 3) Filter time-series in parallel
15 % The filtering process is:
16 % b(1) = Filt11(a(1)) + Filt12(a(2))
17 % b(2) = Filt21(a(1)) + Filt22(a(2))
18 %
19 % CALL: b = whiten2D(a, pl) % returns whitened time-series AOs
20 % [b1,b2] = whiten2D(a1, a2, pl)
21 % [b1,b2,...,bn] = whiten2D(a1,a2,...,an, pl);
22 % Note: Input AOs must come in couples.
23 % Note: this method cannot be used as a modifier, the
24 % call a.whiten2D(pl) is forbidden.
25 %
26 % INPUT:
27 %
28 % - a is a couple of two colored noise time-series AOs
29 %
30 % OUTPUT:
31 %
32 % - b is a couple of "whitened" time-series AOs. The whitening
33 % filters used are stored in the objects procinfo field under
34 % the parameters:
35 % - b(1): 'Filt11' and 'Filt12'
36 % - b(2): 'Filt21' and 'Filt22'
37 %
38 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'whiten2D')">Parameters Description</a>
39 %
40 % VERSION: $Id: whiten2D.m,v 1.35 2011/04/08 08:56:16 hewitson Exp $
41 %
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43
44 function varargout = whiten2D(varargin)
45
46 % Check if this is a call for parameters
47 if utils.helper.isinfocall(varargin{:})
48 varargout{1} = getInfo(varargin{3});
49 return
50 end
51
52 import utils.const.*
53 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
54
55 % Collect input variable names
56 in_names = cell(size(varargin));
57 for ii = 1:nargin,in_names{ii} = inputname(ii);end
58
59 % Collect all AOs and plists
60 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
61 pl = utils.helper.collect_objects(varargin(:), 'plist', in_names);
62
63 % Decide on a deep copy or a modify
64 bs = copy(as, nargout);
65 cs = copy(as, nargout);
66 inhists = [as.hist];
67
68 % combine plists
69 pl = parse(pl, getDefaultPlist());
70 pl.getSetRandState();
71
72
73 % Extract necessary model parameters
74 csd11 = find(pl, 'csd11');
75 csd12 = find(pl, 'csd12');
76 csd21 = find(pl, 'csd21');
77 csd22 = find(pl, 'csd22');
78
79 if nargout == 0
80 error('### noisegen2D cannot be used as a modifier. Please give an output variable.');
81 end
82
83 % Check the number of input AO
84 if numel(bs)==1
85 error('!!! One input AO! The input AOs must come in pairs!');
86 end
87 % Checks that the input AOs come in pairs
88 odc = 0;
89 if rem(numel(as),2)
90 warning('The input AOs must come in pairs! Skipping AO %s during calculation', ao_invars{end});
91 odc = 1;
92 end
93
94 % Loop over input AOs to check for non time series objects
95 fsv = zeros(numel(bs),1);
96 for jj=1:numel(bs)
97 if ~isa(bs(jj).data, 'tsdata')
98 error('!!! %s expects ao/tsdata objects. ', mfilename);
99 end
100 fsv(jj,1) = bs(jj).data.fs; % collecting sampling frequencies
101 end
102 % Check that input Aos have the same sampling frequency
103 if any(diff(fsv))
104 error('!!! Sampling frequency must be the same for all input objects')
105 end
106
107 % ------------------- Coloring Noise
108
109 % ----------------------------------
110 % 1) - Fitting the models to identify the innovation filters
111
112 % Build input structure for psd2tf
113 params = struct();
114
115 params.idtp = 1;
116 params.Nmaxiter = find(pl, 'MaxIter');
117 params.minorder = find(pl, 'MinOrder');
118 params.maxorder = find(pl, 'MaxOrder');
119 params.spolesopt = find(pl, 'PoleType');
120 params.weightparam = find(pl, 'Weights');
121 params.usesym = find(pl, 'UseSym');
122 params.spy = find(pl, 'Disp');
123 params.keepvar = find(pl, 'keepvar');
124
125 % Tolerance for MSE Value
126 lrscond = find(pl, 'FITTOL');
127 % give an error for strange values of lrscond
128 if lrscond<0
129 error('!!! Negative values for FITTOL are not allowed !!!')
130 end
131 % handling data
132 lrscond = -1*log10(lrscond);
133 % give a warning for strange values of lrscond
134 if lrscond<0
135 warning('You are searching for a MSE lower than %s', num2str(10^(-1*lrscond)))
136 end
137 params.lrscond = lrscond;
138
139 % Tolerance for the MSE relative variation
140 msevar = find(pl, 'MSEVARTOL');
141 % handling data
142 msevar = -1*log10(msevar);
143 % give a warning for strange values of msevar
144 if msevar<0
145 warning('You are searching for MSE relative variation lower than %s', num2str(10^(-1*msevar)))
146 end
147 params.msevar = msevar;
148
149 if isempty(params.msevar)
150 params.ctp = 'chival';
151 else
152 params.ctp = 'chivar';
153 end
154
155 if(find(pl, 'plot'))
156 params.plot = 1;
157 else
158 params.plot = 0;
159 end
160
161 params.fs = fsv(1,1);
162 params.dterm = 0;
163
164 % get data variance
165 vars = [1 1];
166 if numel(bs)==2
167 for ii=1:numel(bs)
168 b = bs(ii).y;
169 v = var(b);
170 vars(ii) = v;
171 end
172 end
173 params.vars = vars;
174
175 % call psd2wf
176 ostruct = utils.math.psd2wf(csd11.y,csd12.y,csd21.y,csd22.y,csd11.x,params);
177
178 % ----------------------------------
179 % 2) - Convert into MIIR filters
180
181 fs = fsv(1,1);
182
183 % --- filter 1 ---
184 res = ostruct(1).res;
185 poles = ostruct(1).poles;
186 dterm = ostruct(1).dterm;
187 % construct a struct array of miir filters vectors
188 pfilts1 = [];
189 for kk=1:numel(res)
190 ft = miir(res(kk), [ 1 -poles(kk)], fs);
191 pfilts1 = [pfilts1 ft];
192 end
193 % pfilts1 = [pfilts1 miir(dterm, [1 0], fs)];
194
195 % --- filter 2 ---
196 res = ostruct(2).res;
197 poles = ostruct(2).poles;
198 dterm = ostruct(2).dterm;
199 % construct a struct array of miir filters vectors
200 pfilts2 = [];
201 for kk=1:numel(res)
202 ft = miir(res(kk), [ 1 -poles(kk)], fs);
203 pfilts2 = [pfilts2 ft];
204 end
205 % pfilts2 = [pfilts2 miir(dterm, [1 0], fs)];
206
207 % --- filter 3 ---
208 res = ostruct(3).res;
209 poles = ostruct(3).poles;
210 dterm = ostruct(3).dterm;
211 % construct a struct array of miir filters vectors
212 pfilts3 = [];
213 for kk=1:numel(res)
214 ft = miir(res(kk), [ 1 -poles(kk)], fs);
215 pfilts3 = [pfilts3 ft];
216 end
217 % pfilts3 = [pfilts3 miir(dterm, [1 0], fs)];
218
219 % --- filter 4 ---
220 res = ostruct(4).res;
221 poles = ostruct(4).poles;
222 dterm = ostruct(4).dterm;
223 % construct a struct array of miir filters vectors
224 pfilts4 = [];
225 for kk=1:numel(res)
226 ft = miir(res(kk), [ 1 -poles(kk)], fs);
227 pfilts4 = [pfilts4 ft];
228 end
229 % pfilts4 = [pfilts4 miir(dterm, [1 0], fs)];
230
231 % ----------------------------------
232 % 3) Filtering data
233
234 for jj = 1:2:numel(bs)-1-odc
235
236 bs(jj) = filter(cs(jj), pfilts1) + filter(cs(jj+1), pfilts2);
237 bs(jj+1) = filter(cs(jj), pfilts3) + filter(cs(jj+1), pfilts4);
238
239 % -----------------------------------
240 % 4) Output data
241
242 % name for this object
243 bs(jj).name = sprintf('whiten2D(%s)_c1', [ao_invars{jj} ao_invars{jj+1}]);
244 % Collect the filters into procinfo
245 bs(jj).procinfo = combine(plist('Filt11', pfilts1,'Filt12', pfilts2),as(jj).procinfo);
246 % add history
247 bs(jj).addHistory(getInfo('None'), pl, [ao_invars(:)], [inhists(:)]);
248
249 % name for this object
250 bs(jj+1).name = sprintf('whiten2D(%s)_c2', [ao_invars{jj} ao_invars{jj+1}]);
251 % Collect the filters into procinfo
252 bs(jj+1).procinfo = combine(plist('Filt21', pfilts3,'Filt22', pfilts4),as(jj+1).procinfo);
253 % add history
254 bs(jj+1).addHistory(getInfo('None'), pl, [ao_invars(:)], [inhists(:)]);
255
256 end
257
258 % clear errors
259 bs.clearErrors;
260
261 % Set output
262 if nargout == numel(bs)
263 % List of outputs
264 for ii = 1:numel(bs)
265 varargout{ii} = bs.index(ii);
266 end
267 else
268 % Single output
269 varargout{1} = bs;
270 end
271 end
272
273 %--------------------------------------------------------------------------
274 % Get Info Object
275 %--------------------------------------------------------------------------
276 function ii = getInfo(varargin)
277 if nargin == 1 && strcmpi(varargin{1}, 'None')
278 sets = {};
279 pl = [];
280 else
281 sets = {'Default'};
282 pl = getDefaultPlist;
283 end
284 % Build info object
285 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: whiten2D.m,v 1.35 2011/04/08 08:56:16 hewitson Exp $', sets, pl);
286 ii.setArgsmin(2);
287 ii.setOutmin(2);
288 ii.setModifier(false);
289 end
290
291 %--------------------------------------------------------------------------
292 % Get Default Plist
293 %--------------------------------------------------------------------------
294
295 function plout = getDefaultPlist()
296 persistent pl;
297 if exist('pl', 'var')==0 || isempty(pl)
298 pl = buildplist();
299 end
300 plout = pl;
301 end
302
303 function pl = buildplist()
304
305 pl = plist();
306
307 % CSD11
308 p = param({'csd11', 'A frequency-series AO describing the model csd11'}, paramValue.EMPTY_DOUBLE);
309 pl.append(p);
310
311 % CSD12
312 p = param({'csd12', 'A frequency-series AO describing the model csd12'}, paramValue.EMPTY_DOUBLE);
313 pl.append(p);
314
315 % CSD21
316 p = param({'csd21', 'A frequency-series AO describing the model csd21'}, paramValue.EMPTY_DOUBLE);
317 pl.append(p);
318
319 % CSD22
320 p = param({'csd22', 'A frequency-series AO describing the model csd22'}, paramValue.EMPTY_DOUBLE);
321 pl.append(p);
322
323 % MaxIter
324 p = param({'MaxIter', 'Maximum number of iterations in fit routine.'}, paramValue.DOUBLE_VALUE(30));
325 pl.append(p);
326
327 % PoleType
328 p = param({'PoleType', ['Choose the pole type for fitting:<ol>'...
329 '<li>use real starting poles</li>' ...
330 '<li>generates complex conjugate poles of the<br>'...
331 'type <tt>a.*exp(theta*pi*j)</tt><br>'...
332 'with <tt>theta = linspace(0,pi,N/2+1)</tt></li>'...
333 '<li>generates complex conjugate poles of the type<br>'...
334 '<tt>a.*exp(theta*pi*j)</tt><br>'...
335 'with <tt>theta = linspace(0,pi,N/2+2)</tt></li></ol>']}, {3, {1,2,3}, paramValue.SINGLE});
336 pl.append(p);
337
338 % MinOrder
339 p = param({'MinOrder', 'Minimum order to fit with.'}, paramValue.DOUBLE_VALUE(2));
340 pl.append(p);
341
342 % MaxOrder
343 p = param({'MaxOrder', 'Maximum order to fit with.'}, paramValue.DOUBLE_VALUE(25));
344 pl.append(p);
345
346 % Weights
347 p = param({'Weights', ['Choose weighting for the fit:<ol>'...
348 '<li>equal weights for each point</li>'...
349 '<li>weight with <tt>1/abs(model)</tt></li>'...
350 '<li>weight with <tt>1/abs(model).^2</tt></li>'...
351 '<li>weight with inverse of the square mean spread<br>'...
352 'of the model</li></ol>']}, paramValue.DOUBLE_VALUE(3));
353 pl.append(p);
354
355 % Plot
356 p = param({'Plot', 'Plot results of each fitting step.'}, paramValue.FALSE_TRUE);
357 pl.append(p);
358
359 % Disp
360 p = param({'Disp', 'Display the progress of the fitting iteration.'}, paramValue.FALSE_TRUE);
361 pl.append(p);
362
363 % MSEVARTOL
364 p = param({'MSEVARTOL', ['Mean Squared Error Variation - Check if the<br>'...
365 'realtive variation of the mean squared error is<br>'...
366 'smaller than the value specified. This<br>'...
367 'option is useful for finding the minimum of Chi-squared.']}, ...
368 paramValue.DOUBLE_VALUE(1e-2));
369 pl.append(p);
370
371 % FITTOL
372 p = param({'FITTOL', ['Mean Squared Error Value - Check if the mean<br>'...
373 'squared error value is lower than the value<br>'...
374 'specified.']}, paramValue.DOUBLE_VALUE(1e-2));
375 pl.append(p);
376
377 % UseSym
378 p = param({'UseSym', ['Use symbolic calculation in eigen-decomposition.<ul>'...
379 '<li>0 - perform double-precision calculation in the<br>'...
380 'eigendecomposition procedure to identify 2-Dim<br>'...
381 'systems and for poles stabilization</li>'...
382 '<li>1 - uses symbolic math toolbox variable precision<br>'...
383 'arithmetic in the eigen-decomposition for 2-Dim<br>'...
384 'system identification and double-precison for<br>'...
385 'poles stabilization</li>'...
386 '<li>2 - uses symbolic math toolbox variable precision<br>'...
387 'arithmetic in the eigen-decomposition for 2-Dim<br>'...
388 'system identification and for poles stabilization.']}, {1, {0,1,2}, paramValue.SINGLE});
389 pl.append(p);
390
391 % Keep var
392 p = param({'keepvar', '???'}, paramValue.TRUE_FALSE);
393 p.val.setValIndex(2);
394 pl.append(p);
395
396 end
397
398
399 % PARAMETERS:
400 %
401 % 'csd11' - a frequency-series AO describing the model csd11
402 % 'csd12' - a frequency-series AO describing the model csd12
403 % 'csd21' - a frequency-series AO describing the model csd21
404 % 'csd22' - a frequency-series AO describing the model csd22
405 %
406 % 'MaxIter' - Maximum number of iterations in fit routine
407 % [default: 30]
408 %
409 % 'PoleType' - Choose the pole type for fitting:
410 % 1 - use real starting poles
411 % 2 - generates complex conjugate poles of the
412 % type a.*exp(theta*pi*j)
413 % with theta = linspace(0,pi,N/2+1)
414 % 3 - generates complex conjugate poles of the type
415 % a.*exp(theta*pi*j)
416 % with theta = linspace(0,pi,N/2+2) [default]
417 %
418 % 'MinOrder' - Minimum order to fit with. [default: 2]
419 %
420 % 'MaxOrder' - Maximum order to fit with. [default: 25]
421 %
422 % 'Weights' - choose weighting for the fit: [default: 2]
423 % 1 - equal weights for each point
424 % 2 - weight with 1/abs(model)
425 % 3 - weight with 1/sqrt(abs(model))
426 % 4 - weight with inverse of the square mean spread
427 % of the model
428 %
429 % 'Plot' - plot results of each fitting step. [default: false]
430 %
431 % 'Disp' - Display the progress of the fitting iteration.
432 % [default: false]
433 %
434 % 'FITTOL' - Mean Squared Error Value - Check if the mean
435 % squared error value is lower than the value
436 % specified. [defalut: 1e-2]
437 %
438 % 'MSEVARTOL' - Mean Squared Error Variation - Check if the
439 % realtive variation of the mean squared error is
440 % smaller than the value specified. This
441 % option is useful for finding the minimum of Chi
442 % squared. [default: 1e-2]]
443 %
444 % 'UseSym' - Use symbolic calculation in eigendecomposition.
445 % [default: 0]
446 % 0 - perform double-precision calculation in the
447 % eigendecomposition procedure to identify 2dim
448 % systems and for poles stabilization
449 % 1 - uses symbolic math toolbox variable precision
450 % arithmetic in the eigendecomposition for 2dim
451 % system identification and double-precison for
452 % poles stabilization
453 % 2 - uses symbolic math toolbox variable precision
454 % arithmetic in the eigendecomposition for 2dim
455 % system identification and for poles
456 % stabilization