www.gusucode.com > MATLAB高阶累积量工具箱 > MATLAB高阶累积量工具箱/MATLAB高阶累积量工具箱/hosa/harmest.m
function [Pxx,ar1,ar2] = harmest(y,maxlag,p_order,flag,nfft,norder) %HARMEST Frequencies of harmonics in colored Gaussian noise. % [Pxx,ar1,ar2] = harmest(y,maxlag,p_order,flag,nfft,norder) % y - data matrix [nsamp x nrecs] % maxlag - number of cumulant lags to compute [default = nsamp/12] % p_order - order to use (dimension of signal subspace) % user will be prompted if p_order <= 0 % flag - 'biased' or 'unbiased' % nfft - fft length for spectra [default = 256] % norder - cumulant order to use: 2 or 4 [default = 4] % % Pxx - a nfft x 7 matrix of spectral estimates % ar1 - estimated parameters for the AR method. % ar2 - estimated parameters for the min-norm method % % The seven columns of Pxx contain the spectral estimates based on % the Eigenvector, Music, Pisarenko, ML, AR, periodogram methods, % and the minimum-norm method. % % Copyright (c) 1991-98 by United Signals & Systems, Inc. and The MathWorks, Inc. % $Revision: 1.6 $ % A. Swami January 20, 1993; August 8, 1994 % RESTRICTED RIGHTS LEGEND % Use, duplication, or disclosure by the Government is subject to % restrictions as set forth in subparagraph (c) (1) (ii) of the % Rights in Technical Data and Computer Software clause of DFARS % 252.227-7013. % Manufacturer: United Signals & Systems, Inc., P.O. Box 2374, % Culver City, California 90231. % % This material may be reproduced by or for the U.S. Government pursuant % to the copyright license under the clause at DFARS 252.227-7013. % --------- Parameter checks --------------------------------- [nsamp,nrecs] = size(y); if (nsamp == 1) nsamp = nrecs; nrecs = 1; y = y(:); end if (exist('p_order') ~=1) p_order = 0; end if (exist('flag') ~= 1) flag = 'biased'; end if (flag(1) ~= 'b') flag = 'unbiased'; end if (exist('maxlag') ~= 1) maxlag = nsamp/12; end if (exist('nfft') ~= 1) nfft = 256; end if (exist('norder') ~= 1) norder = 4; end if (norder ~= 2 & norder ~= 4) error('cumulant order - norder - should be 2 or 4') end Pxx = zeros(nfft,7); % ------------ estimate second/fourth-order cumulants -------------- if (norder == 4) M = maxlag; cum_4y = cumest(y,4,M,nsamp,0,flag,0,0); cum_4y = (cum_4y(M+1:2*M+1) + conj(cum_4y(M+1:-1:1)) )/2; cum_4y = cum_4y/cum_4y(1); Amat = toeplitz(conj(cum_4y),cum_4y); else Amat = zeros(maxlag+1,maxlag+1); ind = [0:-1:-maxlag]; for n=maxlag+1:nsamp xf = y(n+ind,:); xb = conj(flipud(xf)); Amat = Amat + xf * xf' + xb * xb'; end mu = mean(mean(y)); Amat = Amat - mu*mu'; % remove mean Amat = Amat / ( nrecs*(nsamp-maxlag) ); end [U,S,V] = svd(Amat); sval = diag(S); % ----------- how many harmonics ? ------------------------- hold off, clf, set(gcf,'Name', ... ['Hosa HARMEST - cum-order=', int2str(norder)] ) ls = length(sval); plot(1:ls, sval,'-', 1:ls,sval,'go'), grid on title(['sval: cum-',int2str(norder)]) drawnow p = p_order; while (p <= 0 | p > ls ) p = input([' enter order to use [1,' int2str(ls) '] ---> ']); if (isempty(p)) p = 0; end end % ---------- Noise subspace methods -------------- M = maxlag+1; nvec = M - p; mfft = nfft/2; wte = ones(nvec,1) ./ sval(p+1:M); Pvm = V(:,p+1:M) * V(:,p+1:M)'; Pve = V(:,p+1:M) * diag(wte) * V(:,p+1:M)'; psum = zeros(nfft,2); psum(1,1) = sum(diag(Pve)); psum(1,2) = sum(diag(Pvm)); for k=1:maxlag psum(k+1,1) = sum(diag(Pve,k)); psum(nfft-k+1,1) = sum(diag(Pve,-k)); psum(k+1,2) = sum(diag(Pvm,k)); psum(nfft-k+1,2) = sum(diag(Pvm,-k)); end Pxx(:,1:2) = ones(nfft,2) ./ real(fft(psum,nfft)); [u1,s1,v1] = svd(Amat(1:p+1,1:p+1)); v1 = v1(:,p+1); Pxx(:,3) = ones(nfft,1) ./ abs(fft(conj(v1),nfft)).^2; % ------------ signal subspace method ----------------------------- % mlcapon for k=1:p Pxx(:,4) = Pxx(:,4) + abs(fft(conj(V(:,k))/sqrt(sval(k)),nfft)) .^ 2; end % --------- AR method ----------------------------------------------- % --------- SVD low-rank approximation (a la Cadzow) ---------------- Amat = U(:,1:p) * diag(sval(1:p)) * (V(:,1:p))'; Ahat = []; [m,n] = size(U); for k=p+1:n Ahat = [Ahat; Amat(:,k-p:k)]; end % force unity modulus solution avec = [1; -Ahat(:,2:p+1) \ Ahat(:,1)]; avec = conj(avec); if (exist('debug') == 1) ncol = floor((p+2)/2); nflip = floor((p+1)/2); Ahat(:,1:nflip) = Ahat(:,1:nflip) + Ahat(:,p+1:-1:p+2-nflip); avec = Ahat(:,2:ncol) \ Ahat(:,1); avec = [1; -avec]; avec = [avec; avec(nflip:-1:1)]; end ar1 = avec; Pxx(:,5) = ones(nfft,1) ./ abs(fft(avec,nfft)) .^2; % ----------- The periodogram estimate ---------------------- ind = [1:nsamp]'; for k=1:nrecs ys = y(ind); ys = ys - mean(ys); Yf = fft(ys,nfft) / nsamp; Pxx(:,6) = Pxx(:,6) + Yf .* conj(Yf); ind = ind + nsamp; end Pxx(:,6) = Pxx(:,6) / nrecs; Pxx(1,6) = Pxx(2,6); % dynamic range problems, else % ----------------- Minimum-norm method ------------------- gvec = U(1,1:p).'; gmat = U(2:length(sval),1:p); ar2 = [1; - conj(gmat) * gvec / (1 - gvec' * gvec)]; Pxx(:,7) = fft(ar2, nfft); Pxx(:,7) = ones(nfft,1) ./ ( Pxx(:,7) .* conj(Pxx(:,7)) ) ; % ----------- Display estimates --------------------- waxis = [-mfft:mfft-1]/nfft; Pxx = Pxx([mfft+1:nfft,1:mfft],:); % - scale to max abs of unity for plots only spmax = max(Pxx); spmax = ones(1,length(spmax)) ./ spmax; clf, subplot(421), plot(1:ls, sval,'-', 1:ls,sval,'g.'), grid on title(['sval: cum-',int2str(norder)]) subplot(422), plot(waxis,10*log10(Pxx(:,6)*spmax(6))), title('pxx'),grid on subplot(423), plot(waxis,10*log10(Pxx(:,1)*spmax(1))), ylabel('eig'),grid on subplot(424), plot(waxis,10*log10(Pxx(:,2)*spmax(2))), ylabel('music'),grid on subplot(425), plot(waxis,10*log10(Pxx(:,3)*spmax(3))), ylabel('pisar'),grid on subplot(426), plot(waxis,10*log10(Pxx(:,4)*spmax(4))), ylabel('ml'),grid on subplot(427), plot(waxis,10*log10(Pxx(:,5)*spmax(5))), ylabel('ar'),grid on subplot(428), plot(waxis,10*log10(Pxx(:,7)*spmax(7))), ylabel('min-norm'), grid on return