Mercurial > hg > ltpda
comparison m-toolbox/classes/+utils/@math/rootmusic.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 function [w_i,powers,w_mse,p_mse] = rootmusic(x,p,varargin) | |
2 %ROOTMUSIC Computes the frequencies and powers of sinusoids via the | |
3 % Root MUSIC algorithm. | |
4 % W = ROOTMUSIC(X,P) returns the vector of frequencies W of the complex | |
5 % sinusoids contained in signal vector X. W is in units of rad/sample. | |
6 % P is the number of complex sinusoids in X. If X is a data matrix, | |
7 % each row is interpreted as a separate sensor measurement or trial. | |
8 % In this case, X must have a number of columns larger than P. You can | |
9 % use the function CORRMTX to generate data matrices to be used here. | |
10 % | |
11 % W = ROOTMUSIC(R,P,'corr') returns the vector of frequencies W, for a | |
12 % signal whose correlation matrix estimate is given by the positive | |
13 % definite matrix R. Exact conjugate-symmetry of R is ensured by forming | |
14 % (R+R')/2 inside the function. The number of rows or columns of R must | |
15 % be greater than P. | |
16 % | |
17 % If P is a two element vector, P(2) is used as a cutoff for signal and | |
18 % noise subspace separation. All eigenvalues greater than P(2) times | |
19 % the smallest eigenvalue are designated as signal eigenvalues. In | |
20 % this case, the signal subspace dimension is at most P(1). | |
21 % | |
22 % F = ROOTMUSIC(...,Fs) uses the sampling frequency Fs in the computation | |
23 % and returns the vector of frequencies, F, in Hz. | |
24 % | |
25 % [W,POW] = ROOTMUSIC(...) returns in addition a vector POW containing the | |
26 % estimates of the powers of the sinusoids in X. | |
27 % | |
28 % EXAMPLES: | |
29 % s1 = RandStream.create('mrg32k3a'); | |
30 % n=0:99; | |
31 % s=exp(i*pi/2*n)+2*exp(i*pi/4*n)+exp(i*pi/3*n)+randn(s1,1,100); | |
32 % X=corrmtx(s,12,'mod'); % Estimate the correlation matrix using | |
33 % % the modified covariance method. | |
34 % [W,P] = rootmusic(X,3); | |
35 % | |
36 % See also ROOTEIG, PMUSIC, PEIG, PMTM, PBURG, PWELCH, CORRMTX, SPECTRUM. | |
37 | |
38 % Reference: Stoica, P. and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS, | |
39 % Prentice-Hall, 1997. | |
40 | |
41 % Author(s): R. Losada | |
42 % Copyright 1988-2008 The MathWorks, Inc. | |
43 % $Revision: 1.1 $ $Date: 2010/02/18 11:16:00 $ | |
44 | |
45 %%%%%%%%%%%%%%%%%%%%%%%% | |
46 % | |
47 % Added function to compute approx. MSE for the case of a unique sinusoid | |
48 % | |
49 % REFERENCES: Rao, B. Performance Analysis of Root-Music | |
50 % IEEE Trans. Acoust. Speech and Sig. Proc. 37, 1989 | |
51 % | |
52 % VERSION: $Id: rootmusic.m,v 1.1 2010/02/18 11:16:00 miquel Exp $ | |
53 % | |
54 % M Nofrarias 12/02/2010 | |
55 % | |
56 | |
57 error(nargchk(2,5,nargin,'struct')); | |
58 | |
59 xIsReal = isreal(x); | |
60 | |
61 % Check for an even number of complex sinusoids if data is real | |
62 if xIsReal && rem(p,2), | |
63 error(generatemsgid('InvalidDimensions'),'Real signals require an even number p of complex sinusoids.'); | |
64 end | |
65 | |
66 nfft = []; % Root Music doesn't use nfft, but the parser needs it | |
67 varargin = {nfft,varargin{:}}; | |
68 | |
69 [md,msg] = utils.math.music(x,p,varargin{:}); | |
70 if ~isempty(msg), error(generatemsgid('SigErr'),msg); end | |
71 | |
72 % Find the Complex Sinusoid Frequencies | |
73 w_i = compute_freqs(md.noise_eigenvects,md.p_eff,md.EVFlag,md.eigenvals); | |
74 | |
75 % Estimate the noise variance as the average of the noise subspace eigenvalues | |
76 sigma_w = sum(md.eigenvals(md.p_eff+1:end))./size(md.noise_eigenvects,2); | |
77 | |
78 % Estimate the power of the sinusoids | |
79 [powers] = compute_power(md.signal_eigenvects,md.eigenvals,w_i,md.p_eff,sigma_w,xIsReal); | |
80 | |
81 % Compute MSE | |
82 [w_mse,p_mse] = compute_mse(sigma_w,powers,length(x)); | |
83 | |
84 % Convert the estimated frequencies to Hz if Fs was specified | |
85 if ~isempty(md.Fs), | |
86 w_i = w_i*md.Fs./(2*pi); | |
87 w_mse = w_mse*(md.Fs./(2*pi))^2; | |
88 end | |
89 | |
90 %--------------------------------------------------------------------------------------------- | |
91 function w_i = compute_freqs(noise_eigenvects,p_eff,EVFlag,eigenvals) | |
92 %Compute the frequencies via the roots of the polynomial formed with the noise eigenvectors | |
93 % | |
94 % Inputs: | |
95 % | |
96 % noise_eigenvects - a matrix whose columns are the noise subspace eigenvectors | |
97 % p_eff - signal subspace dimension | |
98 % EVFlag - a flag indicating of the eigenvector methos should be used | |
99 % eigenvals - a vector with all the correlation matrix eigenvalues. | |
100 % However, we use only the noise eigenvalues as weights | |
101 % in the eigenvector method. | |
102 % | |
103 % Outputs: | |
104 % | |
105 % w_i - frequencies of the complex sinusoids | |
106 | |
107 | |
108 % compute weights | |
109 if EVFlag, | |
110 % Eigenvector method, use eigenvalues as weights | |
111 weights = eigenvals(end-size(noise_eigenvects,2)+1:end); % Use the noise subspace eigenvalues | |
112 else | |
113 weights = ones(1,size(noise_eigenvects,2)); | |
114 end | |
115 | |
116 % Form a polynomial D, consisting of a sum of polynomials given by the product of | |
117 % the noise subspace eigenvectors and the reversed and conjugated version. | |
118 D = 0; | |
119 for i = 1:length(weights), | |
120 D = D + conv(noise_eigenvects(:,i),conj(flipud(noise_eigenvects(:,i))))./weights(i); | |
121 end | |
122 | |
123 roots_D = roots(D); | |
124 % Because D is formed from the product of a polynomial and its conjugated and reversed version, | |
125 % every root of D inside the unit circle, will have a "reflected" version outside the unit circle. | |
126 % We choose to use the ones inside the unit circle, because the distance from them to the unit | |
127 % circle will be smaller than the corresponding distance for the "reflected" root. | |
128 roots_D1 = roots_D(abs(roots_D) < 1); | |
129 | |
130 % Sort the roots from closest to furthest from the unit circle | |
131 [not_used,indx] = sort(abs(abs(roots_D1)-1)); %#ok | |
132 sorted_roots = roots_D1(indx); | |
133 | |
134 % Use the first p_eff roots to determine the frequencies | |
135 w_i = angle(sorted_roots(1:p_eff)); | |
136 | |
137 %----------------------------------------------------------------------------------------------- | |
138 function [powers] = compute_power(signal_eigenvects,eigenvals,w_i,p_eff,sigma_w,xIsReal) | |
139 %COMPUTE_POWER Solves the system of linear eqs. to calculate the power of the sinusoids. | |
140 % | |
141 % Inputs: | |
142 % | |
143 % signal_eigenvects - the matrix whose columns are the signal subspace eigenvectors | |
144 % eigenvals - a vector containing all eigenvalues of the correlation matrix | |
145 % w_i - a vector of frequency estimates of the sinusoids | |
146 % p_eff - the dimension of the signal subspace | |
147 % sigma_w - the estimate of the variance of the white noise | |
148 % xIsReal - a flag indicating wether we have real or complex sinusoids | |
149 % | |
150 % Outputs: | |
151 % | |
152 % powers - a vector that contains the power of each sinusoid | |
153 | |
154 %This is just the solution of a linear system of eqs, Ax=b | |
155 | |
156 % For real sinusoids, the system of eqs. has half the number of unknowns | |
157 if xIsReal, | |
158 w_i = reshape(w_i,2,length(w_i)./2); | |
159 w_i = w_i(1,:); % Use only the positive freqs. | |
160 w_i = w_i(:); | |
161 p_eff = p_eff./2; | |
162 end | |
163 | |
164 % Form the A matrix | |
165 if length(w_i) == 1, | |
166 % FREQZ does not compute the gain at a single frequency, handle this separately | |
167 A = polyval(signal_eigenvects(:,1),exp(1i*w_i)); | |
168 else | |
169 for n = 1:p_eff, | |
170 A(:,n) = freqz(signal_eigenvects(:,n),1,w_i); | |
171 end | |
172 end | |
173 | |
174 A = abs(A.').^2; | |
175 | |
176 % Form the b vector | |
177 b = eigenvals(1:p_eff) - sigma_w; | |
178 | |
179 % The powers are simply the solution to the set of eqs. | |
180 powers = A\b; | |
181 | |
182 %-------------------------------------------------------------------------- | |
183 function [w_mse,p_mse] = compute_mse(sigma_w,powers,N) | |
184 % implements eq.30 in Reference | |
185 | |
186 L = 1; % one element array | |
187 | |
188 p_mse = 12 * (sigma_w/(powers*N*L^2)); | |
189 % first term of eq.30 in paper is to pass from frequency to DOA | |
190 % this sigma_w^2 could be wrong | |
191 w_mse = 12/(2*L)* (sigma_w^2/(powers*N*L^2)); | |
192 | |
193 % [EOF] rootmusic.m | |
194 |