comparison m-toolbox/classes/@ao/gapfillingoptim.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 % GAPFILLINGOPTIM fills possible gaps in data.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: GAPFILLINGOPTIM minimizes a chi square based on the signal's
5 % expected PSD. It uses ao/optSubtraction for the small scale
6 % algorithm, optSubstitution for the large scale algorithm.
7 %
8 % CALL: [aoGapsFilled, plOut, aoP, aoPini, aoWindow, aoWindowShift] = ao.gapfilling(plist)
9 %
10 % INPUTS: ao_data - data segment with the signal to reconstitue
11 % pl - parameter list
12 %
13 % OUTPUTS: aoGapsFilled - data segment containing ao_data, with filled data gaps
14 % plOut - output plist containing the output of
15 % gapFillingOptim
16 % aoP, aoPini - final and initial frequency PSD used to weight
17 % the optimal problem
18 % aoWindow - window used for estmating spectrum
19 % aoWindowShift - shifted window used for optimizing spectrum
20 %
21 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'gapfillingoptim')">Parameters Description</a>
22 %
23 % VERSION: $Id: gapfillingoptim.m,v 1.27 2011/06/11 14:11:27 adrien Exp $
24 %
25 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26
27 function varargout = gapfillingoptim(varargin)
28 % y ycalib fs isgap iscalib freq_weight ncalib ndata nfft ngaps
29 %%% Check if this is a call for parameters
30 if utils.helper.isinfocall(varargin{:})
31 varargout{1} = getInfo(varargin{3});
32 return
33 end
34
35 %% Collect input variable names
36 in_names = cell(size(varargin));
37 for ii = 1:nargin,in_names{ii} = inputname(ii);end
38
39 % Collect all AOs
40 [aos, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
41 pli = utils.helper.collect_objects(varargin(:), 'plist', in_names);
42
43 % Get default parameters
44 pl = combine(pli, getDefaultPlist);
45
46 %% declaring global optData variable
47 clear global optData
48 global optData
49
50 %% getting time-series to fill, and usefull data (frequencies, number of frequencies... )
51 if numel(aos)==0
52 error('Nothing to fill gaps!')
53 elseif numel(aos)>1
54 error('The filling algorithm only works for one single signal at a time')
55 end
56 optData.nData = numel(aos.y);
57 optData.yNorm = norm(aos.y) / optData.nData;
58 optData.y = aos.y / optData.yNorm;
59 optData.Ts = 1/aos(1).fs;
60 optData.nFreqs = floor(optData.nData/2)+1;
61 optData.freqs = linspace(0, 1/(2*optData.Ts), optData.nFreqs);
62 optData.keepFreqs = [true(1,sum(optData.nFreqs)) false(1,sum(optData.nFreqs)-1)];
63
64 %% finding gaps
65 aoGaps = pl.find('isgap');
66 if isempty(aoGaps)
67 error('no gap vector provided!')
68 elseif isequal(aoGaps,'zeros')
69 optData.isGap = (aos.y==0);
70 elseif numel(isempty(aoGaps))>1
71 error('please provide only one gap vector!')
72 elseif isa(aoGaps.y, 'double')
73 optData.isGap = (aoGaps.y==0);
74 elseif isa(aoGaps.y, 'logical')
75 optData.isGap = aoGaps.y;
76 else
77 error('wrong type for parameter "isGap"')
78 end
79 optData.gapsPos = find(optData.isGap);
80 optData.nGaps = numel(optData.gapsPos);
81 clear aoGaps
82
83 %% checking number of gaps is not zero
84 if numel(optData.gapsPos)==0
85 error('No gap to fill!')
86 end
87 if numel(optData.isGap) ~= optData.nData
88 error('gap vector is not the same length as the gapped vector!')
89 end
90
91 %% produce LF window
92 Win = find(pl, 'Win');
93 if isa(Win, 'plist')
94 Win = ao( combine(plist( 'length', optData.nData), Win) );
95 optData.lfWin = Win.y;
96 elseif isa(Win, 'ao')
97 if ~isa(Win.data, 'tsdata')
98 error('An ao window should be a time series')
99 end
100 optData.lfWin = Win.y;
101 if ~length(optData.lfWin)==optData.nData
102 error('signals and windows don''t have the same length')
103 end
104 else
105 error('input option Win is not acceptable (not a plist nor an ao)!')
106 end
107
108 %% produce HF window
109 [shiftVals, shiftCounts, winHF, winsHfShift] = makeHFWindows(optData.nData, optData.gapsPos);
110 optData.nShifts = numel(shiftVals);
111 optData.shiftVals = shiftVals;
112 optData.shiftCounts = shiftCounts;
113 optData.hfWin = winHF;
114 optData.win = optData.lfWin .* optData.hfWin;
115 optData.winsHfShift = winsHfShift;
116 optData.winsShift = winsHfShift;
117 for iiShift = 1:(2*optData.nShifts)
118 optData.winsShift(:, iiShift) = optData.winsHfShift(:, iiShift) .* optData.lfWin;
119 end
120 clear shiftVals shiftCounts winHF winsHfShift
121
122 %% get initial M coefficient matrix
123 M = pl.find('coefs');
124 if isempty(M)
125 M = zeros(1,optData.nGaps);
126 end
127
128 %% detrending (with a windowing agains HF noise)
129 trends = [ones(optData.nData,1) linspace(-1,1,optData.nData).' ]; % two orthogonal vectors to subtract
130 trendsWindowed = trends .* [optData.win optData.win]; % windowing is applied to estimate trends
131 yWindowed = optData.y .* optData.win; % windowing is applied to de-trened data to be consistent
132 optData.trend = pinv(trendsWindowed) * yWindowed; % solution of the least-square problem
133 trendCorrection = trends * optData.trend; % trend is removed from the data while filling gaps. It is re-added later on.
134 optData.y = optData.y - trendCorrection; % detrended vector
135 optData.y(optData.gapsPos) = zeros(size(optData.gapsPos)); % setting to zero the gap-data
136
137 %% get sPSD averaging linear-scaling averaging-width coefficient
138 optData.linCoef = pl.find('linCoef');
139 optData.logCoef = pl.find('logCoef');
140
141 %% get MAX/EXP iterations termination conditions
142 iterMax = pl.find('iterMax');
143 optData.criterion = pl.find('fitCriterion');
144 normCriterion = pl.find('normCriterion');
145 normCoefs = pl.find('normCoefs');
146
147 %% set optim CVG options
148 options.MaxFunEvals = pl.find('maxCall');
149 options.Display = pl.find('display');
150 options.TolFun = min( pl.find('normCriterion'), 1e-12 );
151 options.TolX = min( pl.find('normCoefs'), 1e-14 );
152 options.MaxIter = pl.find('maxCall');
153 doHessian = pl.find('Hessian');
154 if ~isempty(doHessian)
155 error('Hessian option is now deactivated as it is too demanding computationaly')
156 end
157
158 %% computing various useful quantities used for the criterion computation
159 weightingMethod =pl.find('weightingMethod');
160 switch weightingMethod
161 case 'pzmodel'
162 weightModel = pl.find('pzmodelWeight');
163 if numel(weightModel) ~= 1
164 error('there should be only one pzmodel')
165 end
166 weight = weightModel.resp(optData.freqs);
167 weight = abs(weight).^2;
168 Ploc = weight.y;
169 [freqsAvg, pAvg, nFreqsAvg, nDofs, sumMat] = ltpda_spsd(optData.freqs, Ploc, optData.linCoef, optData.logCoef); %#ok<ASGLU>
170 case 'ao'
171 weight =pl.find('aoWeight');
172 if numel(weight)~=1
173 error('there should be as many pzmodels as weighted entries')
174 end
175 if ~isa(weight.data, 'tsdata')
176 error('if the weight is an ao, it should be a FSdata')
177 elseif length(weight.y)==optData.nFreqs
178 error(['length of FS weight is not length of the FFT vector : ' num2str(length(weight.y)) 'instead of ' num2str(optData.nFreqs)])
179 else
180 Ploc = weight.y;
181 [freqsAvg, pAvg, nFreqsAvg, nDofs, sumMat] = ltpda_spsd(optData.freqs, Ploc, optData.linCoef, optData.logCoef); %#ok<ASGLU>
182 end
183 case 'residual'
184 [pAvg, freqsAvg, powSigma, sumMat, nFreqsAvg ] = computeWeight( optData.y, M, optData.gapsPos, optData.freqs);
185 otherwise
186 error('weighting method requested does not exist!')
187 end
188
189 %% Maximization Expectation iteration loop
190 for i_iter = 1:iterMax
191 utils.helper.msg(utils.const.msg.PROC3, ['starting iteration ', num2str(i_iter)]);
192
193 %% setting weight in optData
194 optData.sumMat = sumMat;
195 optData.nFreqsAvg = nFreqsAvg;
196 optData.powInv = pAvg.^-1;
197 optData.logProbaDensityFactor = - nFreqsAvg * log(2) - gammaln(nFreqsAvg);
198
199 %% initializing historical outputs
200 if i_iter==1 % storing intial weight
201 Pini = pAvg;
202 MHist(1,:) = reshape(M, [1, numel(M)] );
203 end
204 fValIni = optimalCriterion(M);
205
206 %% minimizing the criterion
207 switch lower(optData.criterion)
208 case 'ftest'
209 M = solveProblemFTest( optData.gapsPos, optData.powInv, optData.nFreqsAvg); % very fast direct solver in this case
210 fval = optimalCriterion(M);
211 case 'ftest-nohfwin'
212 M = solveProblemFTestNoHFWin( optData.gapsPos, optData.powInv, optData.nFreqsAvg); % very fast direct solver in this case
213 fval = optimalCriterion(M);
214 otherwise
215 M = solveProblemFTest( optData.gapsPos, optData.powInv, optData.nFreqsAvg); % initialize with fast solver (with the wrong criterion, but it doesn't matter so much)
216 [M, fval] = fminunc(@optimalCriterion,M,options); % further non-linear minimzation steps with correct criterion
217 end
218
219 %% updating weight
220 [pAvg, freqsAvg] = computeWeight(optData.y, M, optData.gapsPos, optData.freqs);
221
222 %% store history
223 fValHist(i_iter) = fval/fValIni; %#ok<AGROW>
224 MHist(i_iter+1,:) = reshape(M, [1, numel(M)] ); %#ok<AGROW>
225
226 %% deciding whether to pursue or not ME (=bootstrap) iterations
227 if strcmpi( weightingMethod, 'pzmodel')
228 display('One iteration for Pzmodel weighting only')
229 break
230 elseif strcmpi( weightingMethod, 'ao')
231 display('One iteration for ao weighting only')
232 break
233 elseif norm(fValHist(i_iter)-1) < normCriterion
234 display(['Iterations stopped at iteration ' num2str(i_iter) ' because criterion did not make enough progress (see parameter "normCriterion")'])
235 break
236 elseif i_iter == iterMax
237 display(['Iterations stopped at maximum number of iterations ' num2str(i_iter) ' (see parameter "iterMax")'])
238 break
239 elseif norm(MHist(i_iter+1,:)-MHist(i_iter,:))<normCoefs
240 display(['Iterations stopped at iteration ' num2str(i_iter) ' because parameters did not make enough progress (see parameter "normCoefs")'])
241 break
242 end
243 end % ending loop over MAX/EXP iterations
244
245 %% creating output plist
246 plOut = plist;
247 p = param({ 'criterion' , 'last value of the criterion in the last optimization'}, fval );
248 plOut.append(p);
249 p = param({ 'M' , 'Best fitting value'}, (M + trendCorrection(optData.gapsPos).') * optData.yNorm );
250 plOut.append(p);
251
252 %% creating output aos for weights
253 aoP = ao( fsdata(freqsAvg, pAvg * (optData.yNorm^2 * optData.Ts / optData.nData) ) );
254 aoP.setName('final weight');
255 aoP.setXunits('Hz');
256 aoP.setYunits(aos.yunits^2 * unit('Hz^-1'));
257 aoP.setDescription(['final weight for gap-filling after ' num2str(i_iter) ' iterations (identical to )']);
258 aoP.setT0(aos.t0);
259
260 aoPini = ao( fsdata(freqsAvg, Pini * (optData.yNorm^2 * optData.Ts / optData.nData) ) );
261 aoPini.setName('initial weight');
262 aoPini.setXunits('Hz');
263 aoPini.setYunits(aos.yunits^2 * unit('Hz^-1'));
264 aoPini.setDescription(['initial weight for gap-filling']);
265 aoPini.setT0(aos.t0);
266
267 %% creating filled output
268 aoGapsFilled = ao( plist('yvals', ( trendCorrection + substitution( optData.y, M, optData.gapsPos)) * optData.yNorm, 'fs', 1/optData.Ts, 'type', 'tsdata' ));
269 aoGapsFilled.setName('filled time-series');
270 aoGapsFilled.setXunits('s');
271 aoGapsFilled.setYunits(aos.yunits);
272 aoGapsFilled.setDescription(['Filled time-series using the criteiron: ' optData.criterion ]);
273 aoGapsFilled.setT0(aos.t0);
274 aoGapsFilled.addHistory( getInfo('None'), pl , ao_invars, aos.hist );
275
276 %% creating output windows
277 aoWindow = ao( plist('yvals', optData.win, 'fs', 1/optData.Ts, 'type', 'tsdata' ));
278 aoWindow.setName('initial window used to evaluate the spectrum');
279 aoWindow.setXunits('s');
280 aoWindow.setT0(aos.t0);
281 aoWindow.addHistory( getInfo('None'), pl , ao_invars, aos.hist );
282
283 if strcmpi(optData.criterion,'FTest-NoHfWin')
284 aoWindowShift = ao( plist('yvals', optData.lfWin, 'fs', 1/optData.Ts, 'type', 'tsdata' ));
285 else
286 aoWindowShift = ao( plist('yvals', optData.winsShift(:, 1) , 'fs', 1/optData.Ts, 'type', 'tsdata' ));
287 end
288 aoWindowShift.setName('window used to optimize the spectrum');
289 aoWindowShift.setXunits('s');
290 aoWindowShift.setDescription(['one of the ' num2str(optData.nShifts) ' windows involved in the criterion']);
291 aoWindowShift.setT0(aos.t0);
292 aoWindowShift.addHistory( getInfo('None'), pl , ao_invars, aos.hist );
293
294 %% assigning output
295 varargout = {aoGapsFilled, plOut, aoP, aoPini, aoWindow, aoWindowShift};
296
297 %% clearing optData from global workspace
298 clear global optData
299
300 end
301
302 %% usefull function to compute the weights from the residual
303 function [powAvgs, freqsAvg, powStd, sumMat, nFreqsAvg] = computeWeight(Y, M, gapsPos, freqs)
304 global optData
305 yFilled = substitution( Y, M, gapsPos);
306 if strcmpi(optData.criterion,'FTest-NoHfWin')
307 win = optData.lfWin;
308 else
309 win = optData.win;
310 end
311 errDft = fft( yFilled .* win, optData.nData);
312 errDft = errDft(optData.keepFreqs); % removing aliased frequencies
313 pow = imag(errDft).^2 + real(errDft).^2; % power
314
315 [freqsAvg, powAvgs, nFreqsAvg, nDofs, sumMat] = ltpda_spsd(freqs, pow, optData.linCoef, optData.logCoef);
316 powStd = powAvgs./sqrt(nDofs);
317 end
318
319 %% optimal criterion
320 function j = optimalCriterion(M)
321 global optData
322 j = 0;
323 yFilled = substitution(optData.y, M, optData.gapsPos);
324 if strcmpi(optData.criterion, 'FTest-NoHfWin')
325 errDft = fft( yFilled .* optData.lfWin, optData.nData); % FFT algirthm gets DFT, only a LF window is used here
326 errDft = errDft(optData.keepFreqs); % keeping positive frequencies
327 pow = imag(errDft).^2 + real(errDft).^2; % PSD of signal
328 powSum = optData.sumMat * pow; % binning frequencies as in sPSD
329 j = sum( powSum .* optData.powInv ); % summing FTest
330 elseif strcmpi(optData.criterion, 'FTest')
331 for iiWin=1:numel(optData.nShifts)
332 for iiDirection = [0 1] % positive/negative window shift
333 errDft = fft( yFilled .* optData.winsShift(:, 2*iiWin-1+iiDirection), optData.nData); % FFT algirthm gets DFT
334 errDft = errDft(optData.keepFreqs); % keeping positive frequencies
335 pow = imag(errDft).^2 + real(errDft).^2; % PSD of signal
336 powSum = optData.sumMat * pow; % binning frequencies as in sPSD
337 j = j + sum( powSum .* optData.powInv ) * optData.shiftCounts(iiWin);
338 end
339 end
340 elseif strcmpi(optData.criterion, 'Chi2')
341 for iiWin=1:numel(optData.nShifts)
342 for iiDirection = [0 1] % positive/negative window shift
343 errDft = fft( yFilled .* optData.winsShift(:, 2*iiWin-1+iiDirection), optData.nData); % FFT algirthm gets DFT
344 errDft = errDft(optData.keepFreqs); % keeping positive frequencies
345 pow = imag(errDft).^2 + real(errDft).^2; % PSD of signal
346 powSum = optData.sumMat * pow; % binning frequencies as in sPSD
347 normlzChi2Sum = (2*powSum) .* optData.powInv; % divide the sum by the expected average of each terms, so the chi2 is normalized
348 logProbaDensities = optData.logProbaDensityFactor + (optData.nFreqsAvg-1).*log(normlzChi2Sum) - normlzChi2Sum/2 ; % here computing log of probability
349 j = j - sum(logProbaDensities); % better than taking product of probabilities
350 end
351 end
352 else
353 error(['criterion badly specified' optData.criterion])
354 end
355 end
356
357 %% function subtituting gaps in time-series
358 function Y = substitution( Y, M, gapsPos)
359 Y(gapsPos) = M;
360 end
361
362 %% Direct solver for "FTest" quadratic criterion
363 function [M, hessian] = solveProblemFTest( gapsPos, powAvgInv, nFreqsAvg)
364 global optData
365 computeDuration = 1.3e-8 * 2 * optData.nShifts * numel(gapsPos)^2 * sum(nFreqsAvg);
366 display(['expected time for linear solver: ' num2str(computeDuration) 's'])
367 gapsPhase = exp( -1i*2*pi * (gapsPos-1)/numel(optData.y) ); % FFT value of a gap sample at base frequency
368 nGaps = numel(gapsPos); % number of gaps
369 nAvgs = numel(nFreqsAvg); % number of frequency bins
370 B = zeros(nGaps,1);
371 A = zeros(nGaps,nGaps);
372 %% frequency weighted criterion
373 for iiWin=1:numel(optData.nShifts) % loop on different shifts for HF window
374 for iiDirection = [0 1] % positive/negative window shift
375 W = optData.winsShift(:, 2*iiWin-1+iiDirection);
376 errDft = fft( optData.y .* W, optData.nData); % FFT algirthm gets DFT
377 errDft = errDft(optData.keepFreqs); % keeping positive frequencies
378 gapsAmplitude = W(gapsPos); % amplitude of gaps once windowed
379 gapsPhaseAtFreq = gapsPhase.^0; % FTF at fundamental : it is only the mean value
380 iiFreq = 0; % frequency (before averaging with binning)
381 for iiFreqAvg = 1:nAvgs % loop on frequency bins
382 BLocal = zeros(nGaps,1);
383 ALocal = zeros(nGaps,nGaps);
384 for iiFreqInAvg = 1:nFreqsAvg(iiFreqAvg) % loop on frequencies inside frequency bin
385 iiFreq = iiFreq + 1; % current frequency index (starting with 1!)
386 gapDFT = reshape( gapsAmplitude .* gapsPhaseAtFreq , [nGaps,1]); % DFT of each windowed gap data at the frequency number iiFreq-1
387 % gapDFT = reshape( gapsAmplitude .* gapsPhase.^(iiFreq-1) , [nGaps,1]); % DFT of each windowed gap data at the frequency number iiFreq-1
388 gapsPhaseAtFreq = gapsPhaseAtFreq .* gapsPhase; % updating phase for future DFT samples at next frequency
389 BLocal = BLocal + 2 * real( gapDFT * conj(errDft(iiFreq)) );
390 ALocal = ALocal + 2 * real( gapDFT * gapDFT' );
391 end
392 B = B + BLocal * powAvgInv(iiFreqAvg);
393 A = A + ALocal * powAvgInv(iiFreqAvg);
394 end
395 end
396 end
397 M = (-pinv(A)*B) .'; % solving least-square problem A*M+B=0
398 hessian = A; % this is also the hessian of my criterion
399 end
400
401 %% Direct solver for "FTest" quadratic criterion with no windowing on each gap
402 function [M, hessian] = solveProblemFTestNoHFWin( gapsPos, powAvgInv, nFreqsAvg)
403 global optData
404 computeDuration = 1.3e-8 * numel(gapsPos)^2 * sum(nFreqsAvg);
405 display(['expected time for linear solver: ' num2str(computeDuration) 's'])
406 gapsPhase = exp( -1i*2*pi * (gapsPos-1)/numel(optData.y) ); % FFT value of a gap sample at base frequency
407 nGaps = numel(gapsPos); % number of gaps
408 nAvgs = numel(nFreqsAvg); % number of frequency bins
409 B = zeros(nGaps,1);
410 A = zeros(nGaps,nGaps);
411 %% frequency weighted criterion
412 if strcmpi(optData.criterion, 'FTest-NoHfWin') % retrieving corresponding window
413 W = optData.lfWin;
414 else
415 W = optData.winsShift(:, 2*iiWin-1+iiDirection);
416 end
417 errDft = fft( optData.y .* W, optData.nData); % FFT algirthm gets DFT
418 errDft = errDft(optData.keepFreqs); % keeping positive frequencies
419 gapsAmplitude = W(gapsPos); % amplitude of gaps once windowed
420 gapsPhaseAtFreq = gapsPhase.^0; % FTF at fundamental : it is only the mean value
421 iiFreq = 0; % frequency (before averaging with binning)
422 for iiFreqAvg = 1:nAvgs % loop on frequency bins
423 BLocal = zeros(nGaps,1);
424 ALocal = zeros(nGaps,nGaps);
425 for iiFreqInAvg = 1:nFreqsAvg(iiFreqAvg) % loop on frequencies inside frequency bin
426 iiFreq = iiFreq + 1; % current frequency index (starting with 1!)
427 gapDFT = reshape( gapsAmplitude .* gapsPhaseAtFreq , [nGaps,1]); % DFT of each windowed gap data at the frequency number iiFreq-1
428 % gapDFT = reshape( gapsAmplitude .* gapsPhase.^(iiFreq-1) , [nGaps,1]); % DFT of each windowed gap data at the frequency number iiFreq-1
429 gapsPhaseAtFreq = gapsPhaseAtFreq .* gapsPhase; % updating phase for future DFT samples at next frequency
430 BLocal = BLocal + 2 * real( gapDFT * conj(errDft(iiFreq)) );
431 ALocal = ALocal + 2 * real( gapDFT * gapDFT' );
432 end
433 B = B + BLocal * powAvgInv(iiFreqAvg);
434 A = A + ALocal * powAvgInv(iiFreqAvg);
435 end
436 M = (-pinv(A)*B) .'; % solving least-square problem A*M+B=0
437 hessian = A; % this is also the hessian of my criterion
438 end
439
440 %% function computing the high-frequency window and all its shifted components
441 function [shiftVals, shiftCounts, winHF, winsHfShift] = makeHFWindows(ndata, gapsPos)
442 gapsPos = [1; gapsPos; ndata];
443 diffGapsPos = diff(gapsPos); % distance between consecutive gaps
444 %% detecting segments and corresponding lengths
445 beginSegments = gapsPos([diffGapsPos>1; false])+1;
446 endSegments = gapsPos([false; diffGapsPos>1])-1;
447 segmentsLength = endSegments-beginSegments+1;
448 %% statitstics on segment (half) length
449 timeShifts = floor(segmentsLength/2); % windows will be shifted by +/- half a segment
450 [shiftCounts, shiftVals] = hist(timeShifts, 1:ndata);
451 shiftVals = shiftVals(shiftCounts>0);
452 shiftCounts = shiftCounts(shiftCounts>0);
453 %% making main window
454 winHF = zeros(ndata,1);
455 for iiSegment=1:numel(segmentsLength) % a window for each segment
456 phaseLocal = linspace(0, 2*pi, segmentsLength(iiSegment)+2).'; % building phase vector
457 winLocal = 0.5 * (1 - cos(phaseLocal)); % making window
458 winHF(beginSegments(iiSegment):endSegments(iiSegment)) = winLocal( 2:end-1 ); % assigning window to corresponding segment
459 end
460 %% making all time-shifted windows
461 winsHfShift = zeros( ndata, 2*numel(shiftVals) );
462 for iiShift=1:numel(shiftVals)
463 winsHfShift(:, 2*iiShift-1) = circshift(winHF, shiftVals(iiShift)).';
464 winsHfShift(:, 2*iiShift) = circshift(winHF, -shiftVals(iiShift)).';
465 end
466 end
467
468 %--------------------------------------------------------------------------
469 % Get Info Object
470 %--------------------------------------------------------------------------
471 function ii = getInfo(varargin)
472 if nargin == 1 && strcmpi(varargin{1}, 'None')
473 sets = {};
474 pls = [];
475 else
476 sets = {'Default'};
477 pls = getDefaultPlist;
478 end
479 % Build info object
480 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: gapfillingoptim.m,v 1.27 2011/06/11 14:11:27 adrien Exp $', sets, pls);
481 end
482
483 %--------------------------------------------------------------------------
484 % Get Default Plist
485 %--------------------------------------------------------------------------
486 function plout = getDefaultPlist()
487 persistent pl;
488 if exist('pl', 'var')==0 || isempty(pl)
489 pl = buildplist();
490 end
491 plout = pl;
492 end
493
494 function pl = buildplist()
495
496 pl = plist();
497
498 % isgap
499 p = param({'isgap', ['Logical ao giving position of gaps. If not<br>'...
500 'specified, gaps are positionned where there are zeros.']}, {1, {'zeros', ao}, paramValue.SINGLE});
501 pl.append(p);
502
503 % large scale or small scale algorithm?
504 p = param({'scale', 'large scale or small scale algorithm'}, {1, {'large scale', 'small scale'}, paramValue.SINGLE});
505 pl.append(p);
506
507 % initial coefficients for subtraction initialization
508 p = param({ 'coefs' , 'initial subtracted coefficients, must be a nY*nU double array. If not provided zeros are assumed'}, [] );
509 pl.append(p);
510
511 % weighting scheme
512 p = param({ 'weightingMethod' , 'choose to define a frequency weighting scheme'}, {1, {'residual', 'ao', 'pzmodel'}, paramValue.SINGLE} );
513 pl.append(p);
514
515 p = param({ 'aoWeight' , 'ao to define a frequency weighting scheme (if chosen in ''weightingMethod'')'}, ao.initObjectWithSize(0,0) );
516 pl.append(p);
517
518 p = param({ 'pzmodelWeight' , 'pzmodel to define a frequency weighting scheme (if chosen in ''weightingMethod'')'}, pzmodel.initObjectWithSize(0,0) );
519 pl.append(p);
520
521 p = param({ 'lincoef' , 'linear coefficient for scaling frequencies in chi2'}, 20 );
522 pl.append(p);
523
524 p = param({ 'logcoef' , 'logarithmic coefficient for scaling frequencies in chi2'}, 0.0 );
525 pl.append(p);
526
527 p = param({'fitCriterion' , 'criterion to fit the amplitude spectra (increasing quality, increasing time)'}, {2, {'FTest-NoHfWin' 'FTest' 'chi2'}, paramValue.SINGLE});
528 pl.append(p);
529
530 % iterations convergence stop criterion
531 p = param({ 'iterMax' , 'max number of Mex/Exp iterations (only makes sense for "FTest-NoHfWin" fitting criteiron)'}, 1 );
532 pl.append(p);
533
534 p = param({ 'normCoefs' , 'tolerance on inf norm of coefficient update '}, 1e-12 );
535 pl.append(p);
536
537 p = param({ 'normCriterion' , 'tolerance on norm of criterion variation'}, 1e-5 );
538 pl.append(p);
539
540 % windowing options
541 p = param({ 'win' , 'window to operate FFT, may be a plist/ao'}, plist('win', 'levelledHanning', 'PSLL', 200, 'levelOrder', 2 ) );
542 pl.append(p);
543
544 % display
545 p = param({ 'display' , 'choose how much to display of the optimizer output'}, {1, {'off', 'iter', 'final'}, paramValue.SINGLE} );
546 pl.append(p);
547
548 % optimizer options
549 p = param({ 'maxcall' , 'maximum number of calls to the criterion function'}, 50000 );
550 pl.append(p);
551
552 end