www.gusucode.com > signal 工具箱matlab源码程序 > signal/private/computeperiodogram.m
function [Pxx,F,RPxx,Fc] = computeperiodogram(x,win,nfft,esttype,Fs,options) %COMPUTEPERIODOGRAM Periodogram spectral estimation. % This function is used to calculate the Power Spectrum Sxx, and the % Cross Power Spectrum Sxy. % % Sxx = COMPUTEPERIODOGRAM(X,WIN,NFFT) where x is a vector returns the % Power Spectrum over the whole Nyquist interval, [0, 2pi). % % Sxy = COMPUTEPERIODOGRAM({X,Y},WIN,NFFT) returns the Cross Power % Spectrum over the whole Nyquist interval, [0, 2pi). % % Inputs: % X - Signal vector or a cell array of two elements containing % two signal vectors. % WIN - Window % NFFT - Number of frequency points (FFT) or vector of % frequencies at which periodogram is desired % ESTTYPE - A string indicating the type of window compensation to % be done. The choices are: % 'ms' - compensate for Mean-square (Power) Spectrum; % maintain the correct power peak heights. % 'power' - compensate for Mean-square (Power) Spectrum; % maintain the correct power peak heights. % 'psd' - compensate for Power Spectral Density (PSD); % maintain correct area under the PSD curve. % REASSIGN - A logical (boolean) indicating whether or not to perform % frequency reassignment % % Output: % Sxx - Power spectrum [Power] over the whole Nyquist interval. % or % Sxy - Cross power spectrum [Power] over the whole Nyquist % interval. % % F - (vector) list frequencies analyzed % RSxx - reassigned power spectrum [Power] over Nyquist interval % has same size as Sxx. Empty when 'reassigned' option % not present. % Fc - center of gravity frequency estimates. Same size as % Sxx. Empty when 'reassigned' option not present. % % Copyright 1988-2015 The MathWorks, Inc. narginchk(5,7); if nargin<6 reassign = false; range = 'twosided'; else reassign = options.reassign; range = options.range; end % use normalized frequencies when Fs is empty if isempty(Fs) Fs = 2*pi; end % Validate inputs and convert row vectors to column vectors. [x,~,y,is2sig,win] = validateinputs(x,win,nfft); % Window the data xw = bsxfun(@times,x,win); % Compute the periodogram power spectrum [Power] estimate % A 1/N factor has been omitted since it cancels [Xx,F] = computeDFT(xw,nfft,Fs); if reassign xtw = bsxfun(@times,x,dtwin(win,Fs)); Xxc = computeDFT(xtw,nfft,Fs); Fc = -imag(Xxc ./ Xx); Fc(~isfinite(Fc)) = 0; Fc = bsxfun(@plus,F,Fc); end % if two signals are used, we are being called from welch and are not % performing reassignment. if is2sig yw = bsxfun(@times,y,win); end % Evaluate the window normalization constant. A 1/N factor has been % omitted since it will cancel below. if any(strcmpi(esttype,{'ms','power'})) if reassign if isscalar(nfft) U = nfft*(win'*win); else U = numel(win)*(win'*win); end else % The window is convolved with every power spectrum peak, therefore % compensate for the DC value squared to obtain correct peak heights. U = sum(win)^2; end else U = win'*win; % compensates for the power of the window. end if is2sig [Yy,F] = computeDFT(yw,nfft,Fs); % We use bsxfun here because Yy can be a single vector or a matrix Pxx = bsxfun(@times,Xx,conj(Yy))/U; % Cross spectrum. else Pxx = Xx.*conj(Xx)/U; % Auto spectrum. end % Perform reassignment if reassign RPxx = reassignPeriodogram(Pxx, F, Fc, nfft, range); else RPxx = []; Fc = []; end %-------------------------------------------------------------------------- function [x,Lx,y,is2sig,win] = validateinputs(x,win,~) % Validate the inputs to computexperiodogram and convert row vectors to % column vectors for backwards compatiblility with R2014a and prior % releases % Set defaults and convert to row vectors to columns. y = []; is2sig= false; win = win(:); Lw = length(win); % Determine if one or two signal vectors was specified. if iscell(x), if length(x) > 1, y = x{2}; if isvector(y) y = y(:); end is2sig = true; end x = x{1}; end if isvector(x) x = x(:); end Lx = size(x,1); if is2sig, Ly = size(y,1); if Lx ~= Ly, error(message('signal:computeperiodogram:invalidInputSignalLength')) end if size(x,2)~=1 && size(y,2)~=1 && size(x,2) ~= size(y,2) error(message('signal:computeperiodogram:MismatchedNumberOfChannels')) end end if Lx ~= Lw, error(message('signal:computeperiodogram:invalidWindow', 'WINDOW')) end if (numel(x)<2 || numel(size(x))>2) error(message('signal:computeperiodogram:NDMatrixUnsupported')) end % ------------------------------------------------------------------------- function RP = reassignPeriodogram(P, f, fcorr, nfft, range) % for each column input of Sxx, reassign the power additively % independently. nChan = size(P,2); nf = numel(f); fmin = f(1); fmax = f(end); % compute the destination row for each spectral estimate % allow cyclic frequency reassignment only if we have a full spectrum if isscalar(nfft) && strcmp(range,'twosided') rowIdx = 1+mod(round((fcorr(:)-fmin)*(nf-1)/(fmax-fmin)),nf); else rowIdx = 1+round((fcorr(:)-fmin)*(nf-1)/(fmax-fmin)); end % compute the destination column for each spectral estimate colIdx = repmat(1:nChan,nf,1); % reassign the estimates that fit inside the frequency range P = P(:); idx = find(rowIdx>=1 & rowIdx<=nf); RP = accumarray([rowIdx(idx) colIdx(idx)], P(idx), [nf nChan]); % ------------------------------------------------------------------------- function Wdt = dtwin(w,Fs) % differentiate window in time domain via cubic spline interpolation % compute the piecewise polynomial representation of the window % and fetch the coefficients n = numel(w); pp = spline(1:n,w); [breaks,coefs,npieces,order,dim] = unmkpp(pp); % take the derivative of each polynomial and evaluate it over the same % samples as the original window ppd = mkpp(breaks,repmat(order-1:-1:1,dim*npieces,1).*coefs(:,1:order-1),dim); Wdt = ppval(ppd,(1:n)').*(Fs/(2*pi));