?? psd.m
字號:
function [Pxx, Pxxc, f] = psd(varargin)
%PSD Power Spectral Density estimate.
% Pxx = PSD(X,NFFT,Fs,WINDOW) estimates the Power Spectral Density of
% signal vector X using Welch's averaged periodogram method. X is
% divided into overlapping sections, each of which is detrended, then
% windowed by the WINDOW parameter, then zero-padded to length NFFT.
% The magnitude squared of the length NFFT DFTs of the sections are
% averaged to form Pxx. Pxx is length NFFT/2+1 for NFFT even, (NFFT+1)/2
% for NFFT odd, or NFFT if the signal X is complex. If you specify a
% scalar for WINDOW, a Hanning window of that length is used. Fs is the
% sampling frequency which doesn't affect the spectrum estimate but is
% used for scaling of plots.
%
% [Pxx,F] = PSD(X,NFFT,Fs,WINDOW,NOVERLAP) returns a vector of frequen-
% cies the same size as Pxx at which the PSD is estimated, and overlaps
% the sections of X by NOVERLAP samples.
%
% [Pxx, Pxxc, F] = PSD(X,NFFT,Fs,WINDOW,NOVERLAP,P) where P is a scalar
% between 0 and 1, returns the P*100% confidence interval for Pxx.
%
% PSD(X,...,DFLAG), where DFLAG can be 'linear', 'mean' or 'none',
% specifies a detrending mode for the prewindowed sections of X.
% DFLAG can take the place of any parameter in the parameter list
% (besides X) as long as it is last, e.g. PSD(X,'mean');
%
% PSD with no output arguments plots the PSD in the current figure window,
% with confidence intervals if you provide the P parameter.
%
% The default values for the parameters are NFFT = 256 (or LENGTH(X),
% whichever is smaller), NOVERLAP = 0, WINDOW = HANNING(NFFT), Fs = 2,
% P = .95, and DFLAG = 'none'. You can obtain a default parameter by
% leaving it off or inserting an empty matrix [], e.g. PSD(X,[],10000).
%
% See also CSD, COHERE, TFE, PMEM, PMTM, PMUSIC.
% ETFE, SPA, and ARX in the Identification Toolbox.
% Author(s): T. Krauss, 3-26-93
% Copyright (c) 1988-98 by The MathWorks, Inc.
% $Revision: 1.27 $ $Date: 1997/12/02 18:37:07 $
% The units on the power spectra Pxx and Pyy are such that, using
% Parseval's theorem:
%
% SUM(Pxx)/LENGTH(Pxx) = SUM(X.^2)/LENGTH(X) = COV(X)
%
% The RMS value of the signal is the square root of this.
% If the input signal is in Volts as a function of time, then
% the units on Pxx are Volts^2*seconds = Volt^2/Hz.
%
% Here are the covariance, RMS, and spectral amplitude values of
% some common functions:
% Function Cov=SUM(Pxx)/LENGTH(Pxx) RMS Pxx
% a*sin(w*t) a^2/2 a/sqrt(2) a^2*LENGTH(Pxx)/4
%Normal: a*rand(t) a^2 a a^2
%Uniform: a*rand(t) a^2/12 a/sqrt(12) a^2/12
%
% For example, a pure sine wave with amplitude A has an RMS value
% of A/sqrt(2), so A = SQRT(2*SUM(Pxx)/LENGTH(Pxx)).
%
% See Page 556, A.V. Oppenheim and R.W. Schafer, Digital Signal
% Processing, Prentice-Hall, 1975.
error(nargchk(1,7,nargin))
x = varargin{1};
[msg,nfft,Fs,window,noverlap,p,dflag]=psdchk(varargin(2:end),x);
error(msg)
% compute PSD
window = window(:);
n = length(x); % Number of data points
nwind = length(window); % length of window
if n < nwind % zero-pad x if it has length less than the window length
x(nwind)=0; n=nwind;
end
x = x(:); % Make sure x is a column vector
% this line must be AFTER the zero-padding in
% case x is a scalar
k = fix((n-noverlap)/(nwind-noverlap)); % Number of windows
% (k = fix(n/nwind) for noverlap=0)
if 0
disp(sprintf(' x = (length %g)',length(x)))
disp(sprintf(' y = (length %g)',length(y)))
disp(sprintf(' nfft = %g',nfft))
disp(sprintf(' Fs = %g',Fs))
disp(sprintf(' window = (length %g)',length(window)))
disp(sprintf(' noverlap = %g',noverlap))
if ~isempty(p)
disp(sprintf(' p = %g',p))
else
disp(' p = undefined')
end
disp(sprintf(' dflag = ''%s''',dflag))
disp(' --------')
disp(sprintf(' k = %g',k))
end
index = 1:nwind;
KMU = k*norm(window)^2; % Normalizing scale factor ==> asymptotically unbiased
% KMU = k*sum(window)^2;% alt. Nrmlzng scale factor ==> peaks are about right
Spec = zeros(nfft,1); Spec2 = zeros(nfft,1);
for i=1:k
if strcmp(dflag,'none')
xw = window.*(x(index));
elseif strcmp(dflag,'linear')
xw = window.*detrend(x(index));
else
xw = window.*detrend(x(index),0);
end
index = index + (nwind - noverlap);
Xx = abs(fft(xw,nfft)).^2;
Spec = Spec + Xx;
Spec2 = Spec2 + abs(Xx).^2;
end
% Select first half
if ~any(any(imag(x)~=0)), % if x is not complex
if rem(nfft,2), % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
Spec = Spec(select);
Spec2 = Spec2(select);
% Spec = 4*Spec(select); % double the signal content - essentially
% folding over the negative frequencies onto the positive and adding.
% Spec2 = 16*Spec2(select);
else
select = (1:nfft)';
end
freq_vector = (select - 1)*Fs/nfft;
% find confidence interval if needed
if (nargout == 3)|((nargout == 0)&~isempty(p)),
if isempty(p),
p = .95; % default
end
% Confidence interval from Kay, p. 76, eqn 4.16:
% (first column is lower edge of conf int., 2nd col is upper edge)
confid = Spec*chi2conf(p,k)/KMU;
if noverlap > 0
disp('Warning: confidence intervals inaccurate for NOVERLAP > 0.')
end
end
Spec = Spec*(1/KMU); % normalize
% set up output parameters
if (nargout == 3),
Pxx = Spec;
Pxxc = confid;
f = freq_vector;
elseif (nargout == 2),
Pxx = Spec;
Pxxc = freq_vector;
elseif (nargout == 1),
Pxx = Spec;
elseif (nargout == 0),
if ~isempty(p),
P = [Spec confid];
else
P = Spec;
end
newplot;
plot(freq_vector,10*log10(abs(P))), grid on
xlabel('Frequency'), ylabel('Power Spectrum Magnitude (dB)');
end
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -