summaryrefslogtreecommitdiff
path: root/macros/rooteig.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/rooteig.sci')
-rw-r--r--macros/rooteig.sci180
1 files changed, 98 insertions, 82 deletions
diff --git a/macros/rooteig.sci b/macros/rooteig.sci
index e4f59c0..1b3196e 100644
--- a/macros/rooteig.sci
+++ b/macros/rooteig.sci
@@ -14,12 +14,12 @@ function [w,pow] = rooteig(x,p,varargin)
// Input signal.
// If x is a vector, then it reprsenets one realization of the signal.
// If x is a matrix, then each row represents a separate observation of
- // the signal.
+ // the signal.
// p - int|double - scalar|2 element vector
- // p(1) is the signal subspace dimension and hence the number of
+ // p(1) is the signal subspace dimension and hence the number of
// complex exponentials in x.
- // p(2), if specified, represents a threshold that is multiplied by
- // the smallest estimated eigenvalue of the signal's correlation
+ // p(2), if specified, represents a threshold that is multiplied by
+ // the smallest estimated eigenvalue of the signal's correlation
// matrix.
// fs - int|double - scalar
// Sampling frequency (in Hz)
@@ -27,75 +27,91 @@ function [w,pow] = rooteig(x,p,varargin)
// to 1 Hz
// 'corr' flag
// If specified, x is interpreted as a correlation matrix rather than
- // a matrix of the signal data. For x to be a correlation matrix,
- // x must be a square matrix and all its eigenvalues must be
+ // a matrix of the signal data. For x to be a correlation matrix,
+ // x must be a square matrix and all its eigenvalues must be
// nonnegative
+ // Output arguments
+ // w - double - vector
+ // Estimated frequencies of the complex sinusoids
+ // pow - double - vector
+ // estimated absolute value squared amplitudes of the sinusoids at
+ // the frequencies w
//
+
+
// Examples:
// 1) 3 complex exponentials:
//
- // n=0:99;
- // s=exp(1i*pi/2*n)+2*exp(1i*pi/4*n)+exp(1i*pi/3*n)+randn(1,100);
+ // n=0:99;
+ // s=exp(1i*pi/2*n)+2*exp(1i*pi/4*n)+exp(1i*pi/3*n)+randn(1,100);
// [W,P] = rooteig(s,3);
//
+// n=0:99;
+// s=exp(1*%i*%pi/2*n)+2*exp(1*%i*%pi/4*n)+exp(1*%i*%pi/3*n)+rand(1,100,"normal");
+// exec('/home/shashi/Downloads/FOSSEE-Signal-Processing-Toolbox-master/macros/corrmtx.sci',-1);//EXECUTE CORRMTX FUNCTION PRIOR EXECUTING THIS FUNCTION
+// X = corrmtx(s,12,'mod');
+// [W,P] = rooteig(X,3);
+//
+ //EXPECTED OUTPUT:
+ //W = 0.7883
+ // 1.5674
+ // 1.0429
+//P=
+ // 4.1748
+ // 1.0572
+ // 1.2419
+
// Author
// Ayush
//
- // See also
- // corrmtx | peig | pmusic | rootmusic
+ //
//
// References
- // 1) Stoica, P. and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
+ // 1) Stoica, P. and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
// Prentice-Hall
//
//
- // Output arguments
- // w - double - vector
- // Estimated frequencies of the complex sinusoids
- // pow - double - vector
- // estimated absolute value squared amplitudes of the sinusoids at
- // the frequencies w
- //
-
+
+
funcprot(0);
-
- exec('musicBase.sci',-1);
- exec('nnls.sci',-1);
-
-
+
+ // exec('musicBase.sci',-1);
+ //exec('nnls.sci',-1);
+ //EXECUTE FUNCTIONS nnls.sci AND musicBase.sci PRIOR EXECUTING THIS FUNCTION
+
// **** checking the number of input and output arguments ****
-
+
[numOutArgs, numInArgs] = argn(0);
-
+
if numOutArgs~=1 & numOutArgs~=2 then
error(78,"rooteig");
end
-
+
if numInArgs<1 | numInArgs>4 then
error(77,"rooteig");
end
-
-
+
+
// **** parsing the input arguments ****
isFsSpecified = %F;
fs = [];
-
+
varargLength = length(varargin);
// searching for the 'corr' flag
isCorrFlag = %F;
-
+
if varargLength==0 then
stringIndices = [];
else
stringIndices = find(type(varargin(1:varargLength))==10);
end
-
+
if ~isempty(stringIndices) then
// ignoring all other strings except the corr flag
isCorrFlag = or(strcmpi(varargin(stringIndices),"corr")==0);
varargin(stringIndices) = [];
end
-
+
// varargin can have only an entry for fs
if length(varargin)==1 then
fs = varargin(1);
@@ -108,13 +124,13 @@ function [w,pow] = rooteig(x,p,varargin)
isFsSpecified = %T;
elseif length(fs)>1 then
msg = "rooteig: Wrong type for argument #4 (fs); Positive scalar expected";
- error(msg,10084);
+ error(msg,10084);
end
elseif length(varargin)>1 then
msg = "rooteig: Wrong type for argument #4 (fs); Positive scalar expected";
- error(msg,10084);
+ error(msg,10084);
end
-
+
// extracting primary input x/R
primaryInput = x;
@@ -143,7 +159,7 @@ function [w,pow] = rooteig(x,p,varargin)
end
// first argument of p must be an integer
if ~IsIntOrDouble(p(1),%T) then
- msg = "rooteig: Wrong input argument #2 p(1); " + ...
+ msg = "rooteig: Wrong input argument #2 p(1); " + ...
"positive integer expected";
error(msg,10036);
return
@@ -154,10 +170,10 @@ function [w,pow] = rooteig(x,p,varargin)
if length(p)==2 then
if ~IsIntOrDouble(p(2),%F) then
msg = "rooteig: Wrong type for argument #2 p(2); must be a scalar";
- error(msg,10053);
+ error(msg,10053);
end
end
-
+
isXReal = isreal(x)
if ~isCorrFlag then
// check that p(1) should be even if x is real
@@ -168,8 +184,8 @@ function [w,pow] = rooteig(x,p,varargin)
end
end
-
-
+
+
// **** calling pmusic ****
data= struct();
data.x = primaryInput;
@@ -185,7 +201,7 @@ function [w,pow] = rooteig(x,p,varargin)
data.isFsSpecified = isFsSpecified;
data.freqrange = "twosided";
-
+
[outData,msg] = musicBase(data);
if length(msg)~=0 then
@@ -193,52 +209,52 @@ function [w,pow] = rooteig(x,p,varargin)
msg = "rooteig: "+msg
error(msg);
end
-
+
pEffective = outData.pEffective;
eigenvals = outData.eigenvals;
-
+
w = computeFreqs(outData.noiseEigenvects,pEffective,%t,eigenvals);
-
+
if isempty(w) then
// assign all frequency and powers as -nan
w = %nan*(1:pEffective)';
pow = w;
return;
end
-
-
+
+
// **** Estimating the variance of the noise ****
// Estimate is the mean of the eigenvalues belonging to the noise subspace
sigma_noise = mean(eigenvals(pEffective+1:$));
-
+
pow = computePower(outData.signalEigenvects,eigenvals,w,pEffective,...
sigma_noise,isXReal);
-
-
+
+
// is fs is specified, convert normailized frequencies to actual frequencies
if isFsSpecified then
w = w*fs/(2*%pi);
end
-
-
+
+
endfunction
function w = computeFreqs(noiseEigenvects,pEffective,EVFlag,eigenvals)
- // Computes the frequencies of the complex sinusoids using the roots of
+ // Computes the frequencies of the complex sinusoids using the roots of
// the polynomial formed with the noise eigenvectors
//
// Parameters
- // noiseEigenvects -
+ // noiseEigenvects -
// A matrix where noise eigenvectors are represented by each column
- // pEffective -
+ // pEffective -
// The effective dimension of the signal subspace
- // EVFlag -
+ // EVFlag -
// Flag to indicate weighting to be used for rooteig
- // eigenvals -
+ // eigenvals -
// Eigenvals of the correlation matrix
//
// Output arguments
- // w -
+ // w -
// A vector with frequencies of the complex sinusoids
@@ -249,68 +265,68 @@ function w = computeFreqs(noiseEigenvects,pEffective,EVFlag,eigenvals)
else
weights = ones(numOfNoiseEigenvects,1);
end
-
+
// Form a polynomial consisting of a sum of polynomials given by the
- // product of the noise subspace eigenvectors and the reversed and
+ // product of the noise subspace eigenvectors and the reversed and
// conjugated version. (eq 8.163 from [1])
D = 0;
for i=1:numOfNoiseEigenvects
eigenvect = noiseEigenvects(:,i);
D = D + conv(eigenvect,conj(eigenvect($:-1:1)))./weights(i);
end
-
+
roots = roots(D);
-
+
// selecting the roots inside the unit circle
rootsSelected = roots(abs(roots)<1);
-
+
// sort the roots in order of increasing distance from the unit circle
[dist,indices] = gsort(abs(rootsSelected)-1);
-
+
sortedRoots = rootsSelected(indices);
-
+
if isempty(sortedRoots) then
w = [];
else
w = atan(imag(sortedRoots(1:pEffective)),real(sortedRoots(1:pEffective)));
end
-
-
+
+
endfunction
function power = computePower(signalEigenvects,eigenvals,w,pEffective,...
sigma_noise,isXReal)
-
+
if isXReal then
- // removing the negative frequencies as sinusoids will be present in
+ // removing the negative frequencies as sinusoids will be present in
// complex conjugate pairs
w = w(w>=0);
pEffective = length(w);
end
-
+
// Solving eq. 8.160 from [1] (Ap = b) where p is the power matrix
-
+
A = zeros(length(w),pEffective);
-
+
for i=1:pEffective
A(:,i) = computeFreqResponseByPolyEval(signalEigenvects(:,i), ...
w,1,%F);
end
-
+
A = (abs(A).^2)';
b = eigenvals(1:pEffective) - sigma_noise;
-
+
// Solving Ap=b with the constraint that all elements of p >=0
power = nnls(A,b+A*sqrt(%eps)*ones(pEffective,1));
-
-
+
+
endfunction
function h = computeFreqResponseByPolyEval(b,f,fs,isFsSpecified)
// returns the frequency response (h) for a digital filter with numerator b.
// The evaluation of the frequency response is done at frequency values f
-
+
f = f(:);
b = b(:);
if isFsSpecified then
@@ -319,18 +335,18 @@ function h = computeFreqResponseByPolyEval(b,f,fs,isFsSpecified)
else
w = f;
end
-
+
n = length(b);
powerMatrix = zeros(length(f),n);
powerMatrix(:,1) = 1;
for i=2:n
powerMatrix(:,i) = exp(w*(-i+1)*%i);
end
-
+
h = powerMatrix*b;
-
-endfunction
-
+
+endfunction
+
function result = IsIntOrDouble(inputNum, isPositiveCheck)
// Checks if The Input Is Integer Or Double