diff m-toolbox/m/sigproc/frequency_domain/ltpda_spsd.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/m/sigproc/frequency_domain/ltpda_spsd.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,94 @@
+% ltpda_spsd smooths a spectrum.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: ltpda_spsd smooths a spectrum.
+%
+% CALL:        [freqsOut, pow, nFreqs, sigmaP, sumMat] = ltpda_spsd(freqs, pow, linCoef, logCoef, sumMat,nFreqs)
+%
+% INPUTS:      freqsOut - frequency vector, can be left empty
+%              pow     - power spectrum (density)
+%              nFreqs  - frequency intervals used to derive averages
+%              linCoef, logCoef
+%                      - values to use to scale the smoothing
+%                        averaging filter. It will be in linCoef.NBins^logCoef.
+%                        logCoef should be 2/3 for PSD and 4/5 for PSD data
+%                        which is later plotted in ASD scale.
+%              mode   - 'keepFrequencies' convoles using a filter, leaving all
+%                        frequencies but they are correlated
+%                       'removeFrequencies' convoles using a filter, leaving
+%                        only data at some uncorrelated frequencies
+%                       'addUp' like above, but sums up instead of takin a
+%                        mean value.
+%
+% OUTPUTS:     freqs, pow : output frequency and power vector.
+%
+% <a href="matlab:web(ao.getInfo('spsd').tohtml, '-helpbrowser')">Parameter Sets</a>
+%
+% VERSION:     $Id: ltpda_spsd.m,v 1.4 2011/02/21 16:55:21 adrien Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function varargout = ltpda_spsd(varargin)
+  %% collecting inputs
+  freqs = varargin{1};
+  pow = varargin{2};
+  L = length(pow);
+  pow = reshape(pow, [L, 1]);
+  freqs = reshape(freqs, [numel(freqs), 1]);
+  linCoef = varargin{3};
+  logCoef = varargin{4};
+  if nargin >4
+    % optional inputs include the averaging matrix
+    sumMat = varargin{5};
+    nFreqs = varargin{6};
+  else
+    % averaging matrix must be computed from input data
+    [nFreqs, sumMat] = getMatrix(L, linCoef, logCoef);
+  end
+  %% evaluating output
+  computeVar = nargout>=4;
+  computeFreqs = ~isempty(freqs);
+  sumPow = sumMat * pow; % power sums
+  powOut = sumPow ./ nFreqs; % power average
+  if computeFreqs
+    freqsOut = (sumMat * freqs) ./ nFreqs; % correponding mean frequency
+  else
+    freqsOut = [];
+  end
+  if computeVar
+    nBinsEff = sumPow.^2 ./ (sumMat * pow.^2) ; % number of Chi2 variables for STD
+  else
+    nBinsEff = [];
+  end
+  
+  %% allocating output
+  varargout = {freqsOut, powOut, nFreqs, nBinsEff, sumMat};
+  
+end
+
+
+function [nFreqs, sumMat] = getMatrix(L, linCoef, logCoef)
+  %% initializing loop
+  iAvg = 1;
+  iMin = 1;
+  idxAvg = zeros(1,L); % index of corresponding average
+  widths = ceil(linCoef):ceil(linCoef * L^logCoef + 2); % proposed width of averagin filter
+  iMaxForWidths = min(L, floor( (widths./linCoef).^(1/logCoef) + widths-1 ) ); % last sample to be processed with a given filter width
+  lastWidth = find(iMaxForWidths==L,1,'first'); % width when the end fo te freq. series is reached
+  
+  %% 1st loop on filter width
+  for iiWidth = 1:lastWidth
+    NAverages = ceil( (iMaxForWidths(iiWidth)-iMin+1) / widths(iiWidth) ); % number of times the width avgWidth is going to be used
+    for kk=1:NAverages
+      %% second loop on filter iteration
+      iMax = min(L, iMin + widths(iiWidth)-1); % last sample for current average
+      idxAvg(iMin:iMax) = ones(1,iMax-iMin+1) * iAvg; % index of corresponding average
+      iMin = iMax + 1;
+      iAvg = iAvg + 1;
+    end
+  end
+
+  %% creating output data  
+  sumMat = sparse(idxAvg, 1:L, ones(1,L));
+  nFreqs = sumMat*ones(L,1);
+  
+end
\ No newline at end of file