N)
51 | H(:,(N+2):(K+1)) = [];
52 | end
53 | % Partition H matrix
54 | H1 = H(1:(M+1),:); % M+1 by N+1
55 | h1 = H((M+2):(K+1),1); % K-M by 1
56 | H2 = H((M+2):(K+1),2:(N+1)); % K-M by N
57 | a = [1; -H2\h1].';
58 | b = c*a*H1.';
59 |
60 |
--------------------------------------------------------------------------------
/matlab_test_files/aryule.m:
--------------------------------------------------------------------------------
1 | function [a,e,k] = aryule( x, p)
2 | %ARYULE AR parameter estimation via Yule-Walker method.
3 | % A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR
4 | % parametric signal model estimate of vector X using the Yule-Walker
5 | % (autocorrelation) method. ORDER is the model order of the AR system.
6 | % This method solves the Yule-Walker equations by means of the Levinson-
7 | % Durbin recursion.
8 | %
9 | % [A,E] = ARYULE(...) returns the final prediction error E (the variance
10 | % estimate of the white noise input to the AR model).
11 | %
12 | % [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients.
13 | %
14 | % % Example:
15 | % % Estimate model order using decay of reflection coefficients.
16 | %
17 | % rng default;
18 | % y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1));
19 | %
20 | % % Create AR(2) process
21 | % [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10);
22 | %
23 | % % Fit AR(10) model
24 | % stem(reflect_coeffs); axis([-0.05 10.5 -1 1]);
25 | % title('Reflection Coefficients by Lag'); xlabel('Lag');
26 | % ylabel('Reflection Coefficent');
27 | %
28 | % See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY.
29 |
30 | % Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
31 | % Macmillan, 1988, Chapter 5
32 | % M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING,
33 | % John Wiley & Sons, 1996, Chapter 8
34 |
35 | % Author(s): R. Losada
36 | % Copyright 1988-2004 The MathWorks, Inc.
37 | % $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $
38 |
39 | error(nargchk(2,2,nargin,'struct'))
40 |
41 | % Check the input data type. Single precision is not supported.
42 | try
43 | chkinputdatatype(x,p);
44 | catch ME
45 | throwAsCaller(ME);
46 | end
47 |
48 | [mx,nx] = size(x);
49 | if isempty(x) || length(x) < p || min(mx,nx) > 1,
50 | error(message('signal:aryule:InvalidDimensions'));
51 | elseif isempty(p) || ~(p == round(p))
52 | error(message('signal:aryule:MustBeInteger'))
53 | end
54 | if issparse(x)
55 | error(message('signal:aryule:Sparse'))
56 | end
57 |
58 | R = xcorr(x,p,'biased');
59 | [a,e,k] = levinson(R(p+1:end),p);
60 |
61 |
62 |
--------------------------------------------------------------------------------
/matlab_test_files/aryule_test.m:
--------------------------------------------------------------------------------
1 | function [a,e,k] = aryule( x, p)
2 | %ARYULE AR parameter estimation via Yule-Walker method.
3 | % A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR
4 | % parametric signal model estimate of vector X using the Yule-Walker
5 | % (autocorrelation) method. ORDER is the model order of the AR system.
6 | % This method solves the Yule-Walker equations by means of the Levinson-
7 | % Durbin recursion.
8 | %
9 | % [A,E] = ARYULE(...) returns the final prediction error E (the variance
10 | % estimate of the white noise input to the AR model).
11 | %
12 | % [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients.
13 | %
14 | % % Example:
15 | % % Estimate model order using decay of reflection coefficients.
16 | %
17 | % rng default;
18 | % y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1));
19 | %
20 | % % Create AR(2) process
21 | % [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10);
22 | %
23 | % % Fit AR(10) model
24 | % stem(reflect_coeffs); axis([-0.05 10.5 -1 1]);
25 | % title('Reflection Coefficients by Lag'); xlabel('Lag');
26 | % ylabel('Reflection Coefficent');
27 | %
28 | % See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY.
29 |
30 | % Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
31 | % Macmillan, 1988, Chapter 5
32 | % M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING,
33 | % John Wiley & Sons, 1996, Chapter 8
34 |
35 | % Author(s): R. Losada
36 | % Copyright 1988-2004 The MathWorks, Inc.
37 | % $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $
38 |
39 | error(nargchk(2,2,nargin,'struct'))
40 |
41 | % Check the input data type. Single precision is not supported.
42 | %try
43 | % chkinputdatatype(x,p);
44 | %catch ME
45 | % throwAsCaller(ME);
46 | %end
47 |
48 | [mx,nx] = size(x);
49 | if isempty(x) || length(x) < p || min(mx,nx) > 1,
50 | error(message('signal:aryule:InvalidDimensions'));
51 | elseif isempty(p) || ~(p == round(p))
52 | error(message('signal:aryule:MustBeInteger'))
53 | end
54 | if issparse(x)
55 | error(message('signal:aryule:Sparse'))
56 | end
57 |
58 | R = xcorr(x,p,'biased');
59 | [a,e,k] = levinson(R(p+1:end),p);
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/by_hand_code/pade.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """ This file is a Python translation of the MATLAB file pade.m
3 |
4 | Python version by RDL 10 Jan 2012
5 | Copyright notice from pade.m:
6 | copyright 1996, by M.H. Hayes. For use with the book
7 | "Statistical Digital Signal Processing and Modeling"
8 | (John Wiley & Sons, 1996).
9 | """
10 |
11 | import sys
12 | import numpy as np
13 |
14 | from convm import convm
15 |
16 | def pade(x, p, q):
17 | """Model a signal using the Padé approximation method
18 |
19 | Usage: [a,b] = pade(x,p,q)
20 |
21 | The input sequence x is modeled as the unit sample response of
22 | a filter having a system function of the form
23 | H(z) = B(z)/A(z)
24 | The polynomials B(z) and A(z) are formed from the vectors
25 | b=[b(0), b(1), ... b(q)]
26 | a=[1 , a(1), ... a(p)]
27 | The input q defines the number of zeros in the model
28 | and p defines the number of poles.
29 |
30 | This comes from Hayes, p. 138
31 |
32 | """
33 | if p+q >= len(x):
34 | print('ERROR: model order too large')
35 | sys.exit(1)
36 |
37 | # Set up the convolution matrices
38 | X = convm(x[:], p+1)
39 | Xq = X[q+1:q+p+1, 1:p+1]
40 |
41 | # Solve for the denominator coefficients
42 | if p>0:
43 | a = -np.linalg.lstsq(Xq, x[q+1:q+p+1])[0]
44 | a = np.insert(a, 0, 1)
45 | else:
46 | a = np.array(1)
47 |
48 | # Solve for the numerator coefficients
49 | b = np.dot(X[0:q+1,0:p+1], a)
50 |
51 | return (a.flatten(),b.flatten())
52 |
53 | #function [a,b] = pade(x,p,q)
54 | #x = x(:);
55 | #X = convm(x,p+1);
56 | #Xq = X(q+2:q+p+1,2:p+1);
57 | #a = [1;-Xq\X(q+2:q+p+1,1)];
58 | #b = X(1:q+1,1:p+1)*a;
59 |
60 |
61 | def main():
62 | """Just a test driver, compare with Hayes pp. 138-140"""
63 | x = np.array([1, 1.5, 0.75, 0.375, 0.1875, 0.0938])
64 | pq_array = [(2,0), (0,2), (1,1)]
65 | for i in xrange(len(pq_array)):
66 | p,q = pq_array[i]
67 | print('For p={} q={}:'.format(p,q))
68 | a,b = pade(x, p, q)
69 | print('a: {}\nb: {}'.format(a,b))
70 |
71 | if __name__ == '__main__':
72 | main()
73 |
74 |
--------------------------------------------------------------------------------
/src/aryule_matlab_vs_python.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 22:26 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 |
9 | Test our python aryule vs the MatlabTM aryule
10 |
11 | MATLAB testing code from:
12 | http://www.music.mcgill.ca/~gary/307/matlab/predict.m
13 | """
14 | from matlabpipe import MatlabPipe
15 | import numpy as np
16 | from aryule import aryule
17 |
18 | OKGREEN = '\033[92m'
19 | FAIL = '\033[91m'
20 | ENDC = '\033[0m'
21 |
22 | if __name__ == '__main__':
23 | matlab = MatlabPipe(matlab_version='2013a')
24 | matlab.open()
25 |
26 | cmd = """A=[1 -2.7607 3.8106 -2.6535 0.9238];
27 | y=filter(1,A,0.2*randn(1024,1));
28 | [ar_coeffs, e, k]=aryule(y,4);"""
29 | out = matlab.eval(cmd)
30 | # Get matlab inputs
31 | matlab_A = matlab.get('A')
32 | matlab_y = matlab.get('y')
33 | # Get matlab output of aryule
34 | matlab_ar_coeffs = matlab.get('ar_coeffs')
35 | matlab_e = matlab.get('e')
36 | matlab_k = matlab.get('k')
37 |
38 |
39 | # Use same inputs on python aryule
40 | [py_ar_coeffs, py_e, py_k] = aryule(matlab_y, 4)
41 |
42 | # Check if we get the same result
43 | print "\nMatlab ar_coeffs vs Python ar_coeffs"
44 | if np.allclose(matlab_ar_coeffs, py_ar_coeffs): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
45 | print OKGREEN + "Coincident results!" + ENDC
46 | else:
47 | print FAIL +"Different results..." + ENDC
48 | print matlab_ar_coeffs
49 | print py_ar_coeffs
50 |
51 |
52 | print "\nMatlab e vs Python e"
53 | if np.allclose(matlab_e, py_e): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
54 | print OKGREEN + "Coincident results!" + ENDC
55 | else:
56 | print FAIL +"Different results..." + ENDC
57 | print matlab_e
58 | print py_e
59 |
60 | print "\nMatlab k vs Python k"
61 | if np.allclose(matlab_k, py_k): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
62 | print OKGREEN + "Coincident results!" + ENDC
63 | else:
64 | print FAIL +"Different results..." + ENDC
65 | print matlab_k
66 | print py_k
67 |
--------------------------------------------------------------------------------
/src/by_hand_code/impz.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 5 17:48:01 2014
5 |
6 | @author: Sammy Pfeiffer
7 | This file contains a python implementation of impz matlab function
8 | """
9 | from scipy import zeros
10 | from scipy.signal import lfilter
11 | import numpy as np
12 |
13 | def impz(b,a):
14 | """Pseudo implementation of the impz method of MATLAB"""
15 | #% Compute time vector
16 | # M = 0; NN = [];
17 | # if isempty(N)
18 | # % if not specified, determine the length
19 | # if isTF
20 | # N = impzlength(b,a,.00005);
21 | # else
22 | # N = impzlength(b,.00005);
23 | # end
24 | p = np.roots(a)
25 | N = stableNmarginal_length(p, 0.00005, 0)
26 | N = len(b) * len(b) * len(b) # MATLAB AUTOFINDS THE SIZE HERE...
27 | #TODO: Implement some way of finding the autosieze of this... I used a couple of examples... matlab gave 43 as length we give 64
28 | x = zeros(N)
29 | x[0] = 1
30 | h = lfilter(b,a, x)
31 | return h
32 |
33 |
34 | def stableNmarginal_length(p, tol, delay):
35 | """ % Determine the length for an unstable filter
36 | %minimum height is .00005 original amplitude:"""
37 |
38 | # ind = find(abs(p-1)<1e-5); # does nothing in our example case
39 | # p(ind) = -p(ind); % treat constant as Nyquist # does nothing
40 | # ind = find(abs(abs(p)-1)<1e-5); # does nothing too...
41 | # periods = 5*max(2*pi./abs(angle(p(ind)))); % five periods
42 | # p(ind) = []; % get rid of unit circle poles
43 | # [maxp,maxind] = max(abs(p));
44 | # if isempty(p) % pure oscillator
45 | # N = periods;
46 | # elseif isempty(ind) % no oscillation
47 | # N = mltplcty(p,maxind)*log10(tol)/log10(maxp) + delay;
48 | # else % some of both
49 | # N = max(periods, ...
50 | # mltplcty(p,maxind)*log10(tol)/log10(maxp) ) + delay;
51 | return 1
52 |
53 | # function m = mltplcty( p, ind, tol)
54 | # %MLTPLCTY Multiplicity of a pole
55 | # % MLTPLCTY(P,IND,TOL) finds the multiplicity of P(IND) in the vector P
56 | # % with a tolerance of TOL. TOL defaults to .001.
57 | #
58 | # if nargin<3
59 | # tol = .001;
60 | # end
61 | #
62 | # [mults,indx]=mpoles(p,tol);
63 | #
64 | # m = mults(indx(ind));
65 | # for i=indx(ind)+1:length(mults)
66 | # if mults(i)>m
67 | # m = m + 1;
68 | # else
69 | # break;
70 | # end
71 | # end
72 |
--------------------------------------------------------------------------------
/src/arcov_matlab_vs_python.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 22:26 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 |
9 | Test our python arcov vs the MatlabTM arcov
10 |
11 | MATLAB testing code from:
12 | http://www.music.mcgill.ca/~gary/307/matlab/predict.m
13 | """
14 | from matlabpipe import MatlabPipe
15 | import numpy as np
16 | from arcov import arcov
17 |
18 | OKGREEN = '\033[92m'
19 | FAIL = '\033[91m'
20 | ENDC = '\033[0m'
21 |
22 | if __name__ == '__main__':
23 | matlab = MatlabPipe(matlab_version='2013a')
24 | matlab.open()
25 |
26 | cmd = """% Signal parameters.
27 | fs = 11025;
28 | T = 1/fs;
29 | N = 40000; % signal length
30 | t60 = [1.0 0.8 0.6 0.7 0.7]; % T60 decay constants
31 | tau = -t60/log(0.001); % 1/e decay constants
32 | f = [220 660 1100 4000 6000]; % sinusoid frequencies (Hz)
33 | phi = [pi/4 pi/2 pi 0 0]; % sinusoid phase offsets
34 | p = length(f); % number of resonances
35 | p = 3;
36 |
37 | t = [0:N]*T; % time vector
38 | x = 0; % initialize our input signal
39 | for n = 1:p,
40 | x = x + exp(-t/tau(n)).*sin(2*pi*f(n)*t+phi(n));
41 | end
42 | x = 0.99*x/max(abs(x));
43 |
44 | % Do linear prediction using covariance method.
45 | [a e] = arcov(x, 2*p);"""
46 | out = matlab.eval(cmd)
47 | # Get matlab inputs
48 | matlab_x = matlab.get('x')
49 | matlab_p = matlab.get('p')
50 | # Get matlab output of arcov
51 | matlab_a = matlab.get('a')
52 | matlab_e = matlab.get('e')
53 |
54 |
55 | # Use same inputs on python arcov
56 | [py_a, py_e] = arcov(matlab_x, 2*matlab_p)
57 |
58 | # Check if we get the same result
59 | print "\nMatlab a vs Python a"
60 | if np.allclose(matlab_a, py_a): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
61 | print OKGREEN + "Coincident results!" + ENDC
62 | else:
63 | print FAIL +"Different results..." + ENDC
64 | print matlab_a
65 | print py_a
66 |
67 |
68 | print "\nMatlab e vs Python e"
69 | if np.allclose(matlab_e, py_e): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
70 | print OKGREEN + "Coincident results!" + ENDC
71 | else:
72 | print FAIL +"Different results..." + ENDC
73 | print matlab_e
74 | print py_e
75 |
--------------------------------------------------------------------------------
/src/armcov_matlab_vs_python.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 22:26 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 |
9 | Test our python armcov vs the MatlabTM armcov
10 |
11 | MATLAB testing code from:
12 | http://www.music.mcgill.ca/~gary/307/matlab/predict.m
13 | """
14 | from matlabpipe import MatlabPipe
15 | import numpy as np
16 | from armcov import armcov
17 |
18 | OKGREEN = '\033[92m'
19 | FAIL = '\033[91m'
20 | ENDC = '\033[0m'
21 |
22 | if __name__ == '__main__':
23 | matlab = MatlabPipe(matlab_version='2013a')
24 | matlab.open()
25 |
26 | cmd = """% Signal parameters.
27 | fs = 11025;
28 | T = 1/fs;
29 | N = 40000; % signal length
30 | t60 = [1.0 0.8 0.6 0.7 0.7]; % T60 decay constants
31 | tau = -t60/log(0.001); % 1/e decay constants
32 | f = [220 660 1100 4000 6000]; % sinusoid frequencies (Hz)
33 | phi = [pi/4 pi/2 pi 0 0]; % sinusoid phase offsets
34 | p = length(f); % number of resonances
35 | p = 3;
36 |
37 | t = [0:N]*T; % time vector
38 | x = 0; % initialize our input signal
39 | for n = 1:p,
40 | x = x + exp(-t/tau(n)).*sin(2*pi*f(n)*t+phi(n));
41 | end
42 | x = 0.99*x/max(abs(x));
43 |
44 | % Do linear prediction using covariance method.
45 | [a e] = armcov(x, 2*p);"""
46 | out = matlab.eval(cmd)
47 | # Get matlab inputs
48 | matlab_x = matlab.get('x')
49 | matlab_p = matlab.get('p')
50 | # Get matlab output of armcov
51 | matlab_a = matlab.get('a')
52 | matlab_e = matlab.get('e')
53 |
54 |
55 | # Use same inputs on python armcov
56 | [py_a, py_e] = armcov(matlab_x, 2*matlab_p)
57 |
58 | # Check if we get the same result
59 | print "\nMatlab a vs Python a"
60 | if np.allclose(matlab_a, py_a): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
61 | print OKGREEN + "Coincident results!" + ENDC
62 | else:
63 | print FAIL +"Different results..." + ENDC
64 | print matlab_a
65 | print py_a
66 |
67 |
68 | print "\nMatlab e vs Python e"
69 | if np.allclose(matlab_e, py_e): # see if they are equal with relative tolerance=1e-05 and abs tol=1e-08
70 | print OKGREEN + "Coincident results!" + ENDC
71 | else:
72 | print FAIL +"Different results..." + ENDC
73 | print matlab_e
74 | print py_e
75 |
--------------------------------------------------------------------------------
/src/invfreqs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 23:56 2014
5 |
6 | I'm not really the author, but...
7 | @author: Sammy Pfeiffer
8 | @email: sammypfeiffer@gmail.com
9 |
10 | File found at:
11 | http://projects.scipy.org/scipy/attachment/ticket/393/invfreq.py
12 |
13 | Cleaned up a bit, removed unused imports.
14 | """
15 |
16 |
17 | import numpy
18 | from numpy import atleast_1d, real
19 | from scipy.linalg import solve
20 |
21 |
22 | def invfreqs(g, worN, nB, nA, wf=None, nk=0):
23 | """Compute frequency response of a digital filter.
24 |
25 | Description:
26 |
27 | Computes the numerator (b) and denominator (a) of a digital filter compute
28 | its frequency response, given a frequency response at frequencies given in worN.
29 |
30 | nB nB-1 nk
31 | B(s) (b[0]s + b[1]s + .... + b[nB-1]s + b[nB])s
32 | H(s) = ---- = -----------------------------------------------
33 | nA nA-1
34 | A(s) a[0]s + a[1]s + .... + a[nA-1]s+a[nA]
35 |
36 | with a[0]=1.
37 |
38 | Coefficients are determined by minimizing sum(wf |B-HA|**2).
39 | If opt is not None, minimization of sum(wf |H-B/A|**2) is done in at most
40 | MaxIter iterations until norm of gradient being less than Tol,
41 | with A constrained to be stable.
42 |
43 | Inputs:
44 |
45 | worN -- The frequencies at which h was computed.
46 | h -- The frequency response.
47 |
48 | Outputs: (w,h)
49 |
50 | b, a --- the numerator and denominator of a linear filter.
51 | """
52 | g = atleast_1d(g)
53 | worN = atleast_1d(worN)
54 | if wf==None:
55 | wf = numpy.ones_like(worN)
56 | if len(g)!=len(worN) or len(worN)!=len(wf):
57 | raise ValueError, "The lengths of g, worN and wf must coincide."
58 | if numpy.any(worN<0):
59 | raise ValueError, "worN has negative values."
60 | s = 1j*worN
61 |
62 | # Constraining B(s) with nk trailing zeros
63 | nm = numpy.maximum(nA, nB+nk)
64 | mD = numpy.vander(1j*worN, nm+1)
65 | mH = numpy.mat(numpy.diag(g))
66 | mM = numpy.mat(numpy.hstack(( mH*numpy.mat(mD[:,-nA:]),\
67 | -numpy.mat(mD[:,-nk-nB-1:][:,:nB+1]))))
68 | mW = numpy.mat(numpy.diag(wf))
69 | Y = solve(real(mM.H*mW*mM), -real(mM.H*mW*mH*numpy.mat(mD)[:,-nA-1]))
70 | a = numpy.ones(nA+1)
71 | a[1:] = Y[:nA].flatten()
72 | b = numpy.zeros(nB+nk+1)
73 | b[:nB+1] = Y[nA:].flatten()
74 |
75 | return b,a
--------------------------------------------------------------------------------
/src/arcov.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 20:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file pretends to imitate the behaviour of the MATLAB function arcov
9 |
10 | Using spectrum implementation:
11 | http://thomas-cokelaer.info/software/spectrum/html/user/ref_psd_other.html#spectrum.covar.arcovar
12 | """
13 | import numpy as np
14 | import spectrum
15 |
16 | def arcov(x, p):
17 | """From MATLAB:
18 | % A = ARCOV(X,ORDER) returns the polynomial A corresponding to the AR
19 | % parametric signal model estimate of vector X using the Covariance method.
20 | % ORDER is the model order of the AR system.
21 | %
22 | % [A,E] = ARCOV(...) returns the variance estimate E of the white noise
23 | % input to the AR model.
24 |
25 | Using from spectrum:
26 | def arcovar(x, order):
27 | Simple and fast implementation of the covariance AR estimate
28 |
29 | :param array X: Array of complex data samples
30 | :param int oder: Order of linear prediction model
31 |
32 | :return:
33 | * a - Array of complex forward linear prediction coefficients
34 | * e - error
35 | """
36 | [A, E] = spectrum.covar.arcovar(x,p)
37 | A = np.hstack((1,A)) # MATLAB gives back initial value 1, so we do the same
38 | return A, E
39 |
40 | # Local Variables: a, msgobj, p, msg, x, e
41 | # Function calls: nargchk, arcov, nargin, isempty, error, arparest
42 | #%ARCOV AR parameter estimation via covariance method.
43 | #% A = ARCOV(X,ORDER) returns the polynomial A corresponding to the AR
44 | #% parametric signal model estimate of vector X using the Covariance method.
45 | #% ORDER is the model order of the AR system.
46 | #%
47 | #% [A,E] = ARCOV(...) returns the variance estimate E of the white noise
48 | #% input to the AR model.
49 | #%
50 | #% See also PCOV, ARMCOV, ARBURG, ARYULE, LPC, PRONY.
51 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
52 | #% Prentice-Hall, 1988, Chapter 7
53 | #% P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
54 | #% Prentice-Hall, 1997, Chapter 3
55 | #% Author(s): R. Losada and P. Pacheco
56 | #% Copyright 1988-2002 The MathWorks, Inc.
57 | #% $Revision: 1.13.4.3 $ $Date: 2011/05/13 18:06:51 $
58 | #matcompat.error(nargchk(2., 2., nargin, 'struct'))
59 | # [a, e, msg, msgobj] = arparest(x, p, 'covariance')
60 | # if not isempty(msg):
61 | # matcompat.error(msgobj)
62 | #
63 | #
64 | # #% [EOF] - arcov.m
65 | # return [a, e]
--------------------------------------------------------------------------------
/matlab_test_files/stmcb.m:
--------------------------------------------------------------------------------
1 | function [b,a] = stmcb( x, u_in, q, p, niter, a_in )
2 | %STMCB Compute linear model via Steiglitz-McBride iteration
3 | % [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
4 | % B(z)/A(z) with approximate impulse response H, NA poles and
5 | % NB zeros.
6 | %
7 | % [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
8 | %
9 | % [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
10 | % guess at the denominator coefficients. If you don't specify Ai,
11 | % STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
12 | %
13 | % [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
14 | % A of the system which, given X as input, has Y as output. N and Ai
15 | % are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
16 | % Y and X must be the same length.
17 | %
18 | % % Example:
19 | % % Approximate the impulse response of a Butterworth filter with a
20 | % % system of lower order.
21 | %
22 | % [b,a] = butter(6,0.2); % Butterworth filter design
23 | % h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
24 | % freqz(b,a,128) % Frequency response
25 | % [bb,aa] = stmcb(h,4,4);
26 | % figure; freqz(bb,aa,128)
27 | %
28 | % See also PRONY, LEVINSON, LPC, ARYULE.
29 |
30 | % Author(s): Jim McClellan, 2-89
31 | % T. Krauss, 4-22-93, new help and options
32 | % Copyright 1988-2004 The MathWorks, Inc.
33 | % $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
34 |
35 | error(nargchk(3,6,nargin,'struct'))
36 |
37 | if length(u_in) == 1,
38 | if nargin == 3,
39 | niter = 5; p = q; q = u_in;
40 | a_in = prony(x,0,p);
41 | elseif nargin == 4,
42 | niter = p; p = q; q = u_in;
43 | a_in = prony(x,0,p);
44 | elseif nargin == 5,
45 | a_in = niter; niter = p; p = q; q = u_in;
46 | end
47 | u_in = zeros(size(x));
48 | u_in(1) = 1; % make a unit impulse whose length is same as x
49 | else
50 | if length(u_in)~=length(x),
51 | error(message('signal:stmcb:InvalidDimensions'))
52 | end
53 | if nargin < 6
54 | [b,a_in] = prony(x,0,p);
55 | end
56 | if nargin < 5
57 | niter = 5;
58 | end
59 | end
60 |
61 | a = a_in;
62 | N = length(x);
63 | for i=1:niter
64 | u = filter( 1, a, x );
65 | v = filter( 1, a, u_in );
66 | C1 = convmtx(u(:),p+1);
67 | C2 = convmtx(v(:),q+1);
68 | T = [ -C1(1:N,:) C2(1:N,:) ];
69 | c = T(:,2:p+q+2)\(-T(:,1)); % move 1st column to RHS and do least-squares
70 | a = [1; c(1:p)]; % denominator coefficients
71 | b = c(p+1:p+q+1); % numerator coefficients
72 | end
73 | a=a.';
74 | b=b.';
75 |
76 |
--------------------------------------------------------------------------------
/src/by_hand_code/kalman.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """ Computes the discrete Kalman filter """
3 | from __future__ import division, print_function
4 |
5 | __author__ = 'Richard Lindsley'
6 | import numpy as np
7 |
8 | class Kalman():
9 | def __init__(self, A, C, Qw, Qv, x00, P00):
10 | """ Initializes the discrete Kalman filter
11 |
12 | A: A(n-1) in x(n) = A(n-1)x(n-1) + w(n). A matrix, generally.
13 | C: C(n) in y(n) = C(n)x(n) + v(n). A matrix, generally.
14 | Qw: Autocorrelation matrix of w(n)
15 | Qv: Autocorrelation matrix of v(n)
16 | x00: Initial condition for x_hat(0|0)
17 | P00: Initial condition for P(0|0)
18 |
19 | Note that these values are stored as NumPy matrices to simplify the
20 | code below (due to multiple matrix multiplies needed)
21 |
22 | """
23 | self._A = np.matrix(A)
24 | self._C = np.matrix(C)
25 | self._Qw = np.matrix(Qw)
26 | self._Qv = np.matrix(Qv)
27 | self._x00 = np.matrix(x00)
28 | self._P00 = P00
29 |
30 | self._n = 1 # time index
31 | self._x_n1_n1 = self._x00 # x_hat(n-1|n-1), initialized to x_hat(0|0)
32 | self._P_n1_n1 = self._P00 # P(n-1|n-1), initialized to P(0|0)
33 |
34 | # Computed later
35 | self._x_n_n1 = None # x_hat(n|n-1)
36 | self._x_n_n = None # x_hat(n|n)
37 | self._P_n_n1 = None # P(n|n-1)
38 | self._P_n_n = None # P(n|n)
39 | self._K = None # K(n), the Kalman gain
40 |
41 | def predict(self):
42 | """ Predict x(n|n-1) """
43 | self._x_n_n1 = self._A * self._x_n1_n1
44 | self._P_n_n1 = self._A * self._P_n1_n1 * self._A.H + self._Qw
45 | self._K = self._P_n_n1 * self._C.H * (self._C * self._P_n_n1 *
46 | self._C.H + self._Qv).getI()
47 | return self._x_n_n1
48 |
49 | def update(self, y):
50 | """ Update x(n|n) with y(n) """
51 | self._x_n_n = self._x_n_n1 + self._K * (y - self._C * self._x_n_n1)
52 | i = np.eye(self._P_n_n1.shape[0])
53 | self._P_n_n = (i - self._K * self._C) * self._P_n_n1
54 | return self._x_n_n
55 |
56 | def timestep(self):
57 | """ Increment n and set variables accordingly """
58 | self._n += 1
59 | self._x_n1_n1 = self._x_n_n
60 | self._P_n1_n1 = self._P_n_n
61 |
62 | def print_status(self):
63 | #print('n={} P(n|n-1)={:0.4} K(n)={:0.4} P(n|n)={:0.4}'.format(self._n,
64 | print('----------------')
65 | print(' n={}'.format(self._n))
66 | print(' x(n|n)=\n{}'.format(self._x_n_n))
67 | print(' P(n|n-1)=\n{}'.format(self._P_n_n1))
68 | print(' K(n)=\n{}'.format(self._K))
69 | print(' P(n|n)=\n{}'.format(self._P_n_n))
70 |
--------------------------------------------------------------------------------
/src/by_hand_code/convmtx.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """ This file is a Python translation of the MATLAB file convm.m
3 |
4 | Python version by RDL 10 Jan 2012
5 | Copyright notice from convm.m:
6 | copyright 1996, by M.H. Hayes. For use with the book
7 | "Statistical Digital Signal Processing and Modeling"
8 | (John Wiley & Sons, 1996).
9 | """
10 |
11 | import numpy as np
12 |
13 | def convmtx(v, n):
14 | """Generates a convolution matrix
15 |
16 | Usage: X = convm(v,n)
17 | Given a vector v of length N, an N+n-1 by n convolution matrix is
18 | generated of the following form:
19 | | v(0) 0 0 ... 0 |
20 | | v(1) v(0) 0 ... 0 |
21 | | v(2) v(1) v(0) ... 0 |
22 | X = | . . . . |
23 | | . . . . |
24 | | . . . . |
25 | | v(N) v(N-1) v(N-2) ... v(N-n+1) |
26 | | 0 v(N) v(N-1) ... v(N-n+2) |
27 | | . . . . |
28 | | . . . . |
29 | | 0 0 0 ... v(N) |
30 | And then it's trasposed to fit the MATLAB return value.
31 | That is, v is assumed to be causal, and zero-valued after N.
32 |
33 | """
34 | N = len(v) + 2*n - 2
35 | xpad = np.concatenate([np.zeros(n-1), v[:], np.zeros(n-1)])
36 | X = np.zeros((len(v)+n-1, n))
37 | # Construct X column by column
38 | for i in xrange(n):
39 | X[:,i] = xpad[n-i-1:N-i]
40 |
41 | return X.transpose()
42 |
43 | def main():
44 | """Just a test"""
45 | h = [1,2,3,2,1]
46 | X = convmtx(h,7)
47 | print(X)
48 |
49 | ## MATLAB OUTPUT:
50 | # >> h = [1 2 3 2 1];
51 | # >> convmtx(h,7)
52 | #
53 | # ans =
54 | #
55 | # 1 2 3 2 1 0 0 0 0 0 0
56 | # 0 1 2 3 2 1 0 0 0 0 0
57 | # 0 0 1 2 3 2 1 0 0 0 0
58 | # 0 0 0 1 2 3 2 1 0 0 0
59 | # 0 0 0 0 1 2 3 2 1 0 0
60 | # 0 0 0 0 0 1 2 3 2 1 0
61 | # 0 0 0 0 0 0 1 2 3 2 1
62 | ## PYTHON OUTPUT:
63 | # array([[ 1., 2., 3., 2., 1., 0., 0., 0., 0., 0., 0.],
64 | # [ 0., 1., 2., 3., 2., 1., 0., 0., 0., 0., 0.],
65 | # [ 0., 0., 1., 2., 3., 2., 1., 0., 0., 0., 0.],
66 | # [ 0., 0., 0., 1., 2., 3., 2., 1., 0., 0., 0.],
67 | # [ 0., 0., 0., 0., 1., 2., 3., 2., 1., 0., 0.],
68 |
69 |
70 |
71 | if __name__ == '__main__':
72 | main()
73 |
74 |
--------------------------------------------------------------------------------
/src/armcov.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 20:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file pretends to imitate the behaviour of the MATLAB function armcov
9 |
10 | Using spectrum implementation:
11 | http://thomas-cokelaer.info/software/spectrum/html/user/ref_psd_other.html
12 | search for modcovar (can't direct link it)
13 | """
14 | import numpy as np
15 | import spectrum
16 |
17 | def armcov(x, p):
18 | """From MATLAB:
19 | % A = ARMCOV(X,ORDER) returns the polynomial A corresponding to the AR
20 | % parametric signal model estimate of vector X using the Modified Covariance
21 | % method. ORDER is the model order of the AR system.
22 | %
23 | % [A,E] = ARMCOV(...) returns the variance estimate E of the white noise
24 | % input to the AR model.
25 |
26 | Using from spectrum modcovar and modcovar_marple:
27 | Check http://thomas-cokelaer.info/software/spectrum/html/user/ref_psd_other.html#spectrum.modcovar.modcovar
28 | """
29 | [E, A] = spectrum.modcovar(x, int(p)) # We compute this one because gives back same number of elements in E
30 | number_of_elements = len(E)
31 | [E, A, ISTAT] = spectrum.modcovar_marple(x, int(p)) # works slower but is more accurate with the error than modcovar
32 | E = E[:number_of_elements]
33 | E = np.hstack((1, E))
34 |
35 | return E, A
36 |
37 | ### ORIGINAL IMPLEMENTATION
38 | # Local Variables: a, msgobj, p, msg, x, e
39 | # Function calls: nargchk, nargin, isempty, error, arparest, armcov
40 | #%ARMCOV AR parameter estimation via modified covariance method.
41 | #% A = ARMCOV(X,ORDER) returns the polynomial A corresponding to the AR
42 | #% parametric signal model estimate of vector X using the Modified Covariance
43 | #% method. ORDER is the model order of the AR system.
44 | #%
45 | #% [A,E] = ARMCOV(...) returns the variance estimate E of the white noise
46 | #% input to the AR model.
47 | #%
48 | #% See also PMCOV, ARCOV, ARBURG, ARYULE, LPC, PRONY.
49 | #% References:
50 | #% [1] S. Lawrence Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATIONS,
51 | #% Prentice-Hall, 1987, Chapter 8
52 | #% [2] Steven M. Kay, MODERN SPECTRAL ESTIMATION THEORY & APPLICATION,
53 | #% Prentice-Hall, 1988, Chapter 7
54 | #% Author(s): R. Losada and P. Pacheco
55 | #% Copyright 1988-2002 The MathWorks, Inc.
56 | #% $Revision: 1.13.4.3 $ $Date: 2011/05/13 18:06:53 $
57 | # matcompat.error(nargchk(2., 2., nargin, 'struct'))
58 | # [a, e, msg, msgobj] = arparest(x, p, 'modified')
59 | # if not isempty(msg):
60 | # matcompat.error(msgobj)
61 | #
62 | #
63 | # #% [EOF] - armcov.m
64 | # return [a, e]
--------------------------------------------------------------------------------
/matlab_test_files/prony_test.m:
--------------------------------------------------------------------------------
1 | function [b,a] = prony_test(h, nb ,na)
2 | %PRONY Prony's method for time-domain IIR filter design.
3 | % [B,A] = PRONY(H, NB, NA) finds a filter with numerator order
4 | % NB, denominator order NA, and having the impulse response in
5 | % vector H. The IIR filter coefficients are returned in
6 | % length NB+1 and NA+1 row vectors B and A, ordered in
7 | % descending powers of Z. H may be real or complex.
8 | %
9 | % If the largest order specified is greater than the length of H,
10 | % H is padded with zeros.
11 | %
12 | % % Example:
13 | % % Fit an IIR model to an impulse response of a lowpass filter.
14 | %
15 | % [b,a] = butter(4,0.2);
16 | % impulseResp = impz(b,a); % obtain impulse response
17 | % denOrder=4; numOrder=4; % system function of order 4
18 | % [Num,Den]=prony(impulseResp,numOrder,denOrder);
19 | % subplot(211); % impulse response and input
20 | % stem(impz(Num,Den,length(impulseResp)));
21 | % title('Impulse Response with Prony Design');
22 | % subplot(212);
23 | % stem(impulseResp); title('Input Impulse Response');
24 | %
25 | % See also STMCB, LPC, BUTTER, CHEBY1, CHEBY2, ELLIP, INVFREQZ.
26 |
27 | % Author(s): L. Shure, 5-17-88
28 | % L. Shure, 12-17-90, revised
29 | % Copyright 1988-2012 The MathWorks, Inc.
30 | % $Revision: 1.7.4.1.2.1 $ $Date: 2013/01/02 17:47:48 $
31 |
32 | % References:
33 | % [1] T.W. Parks and C.S. Burrus, Digital Filter Design,
34 | % John Wiley and Sons, 1987, p226.
35 |
36 | K = length(h) - 1;
37 | M = nb; N = na;
38 | display('K M N')
39 | K
40 | M
41 | N
42 | if K <= max(M,N) % zero-pad input if necessary
43 | K = max(M,N)+1;
44 | h(K+1) = 0;
45 | end
46 | c = h(1);
47 | if c==0 % avoid divide by zero
48 | c=1;
49 | end
50 | display('this is the second part of toeplitz')
51 | [1 zeros(1,K)]
52 | H = toeplitz(h/c,[1 zeros(1,K)]);
53 | display('toeplitz is')
54 | H
55 | % K+1 by N+1
56 | if (K > N)
57 | % display('H before doing this thing')
58 | % H
59 | H(:,(N+2):(K+1)) = []; % 43*43 matrix in my example and we are getting rid here of the columns...
60 | % K=43 M=4 N=4; H(all_rows, 4+2:43+1)
61 | % display('H after doing this [] thing')
62 | % H
63 | % error('exiting')
64 | end
65 | % Partition H matrix
66 | H1 = H(1:(M+1),:); % M+1 by N+1
67 | display('H1 is')
68 | H1
69 |
70 | h1 = H((M+2):(K+1),1); % K-M by 1
71 | % display('h1 is')
72 | % h1
73 |
74 | H2 = H((M+2):(K+1),2:(N+1)); % K-M by N
75 | % display('H2 is')
76 | % H2
77 | size(H2)
78 | display('h1 is')
79 | h1
80 | size(h1)
81 | display('sol -H2\h1')
82 | sol = -H2\h1
83 | % display('other way') % same result
84 | % mldivide(-H2,h1)
85 | a = [1; -H2\h1].';
86 | b = c*a*H1.';
87 | display('c*a')
88 | c*a
89 | display('c*a*H1')
90 | c*a*H1.'
--------------------------------------------------------------------------------
/src/trashbin/system_example.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Nov 17 12:30:46 2013
5 |
6 | @author: Sammy Pfeiffer
7 | """
8 | from numpy import allclose # Grab all of the NumPy functions
9 | import numpy as np
10 | from matplotlib.pyplot import plot, show # Grab MATLAB plotting functions
11 | from control.matlab import tf, c2d, step # MATLAB-like functions
12 | #from scipy.signal import cont2discrete as c2d
13 | #from scipy.signal import step
14 | from stmcb import stmcb
15 |
16 |
17 | # MATLAB:
18 | # syst_fake=tf([1],[1 2 3]) # from matlab to python, commas must be used to separate elements
19 | # >> syst_fake
20 | # syst_fake =
21 | #
22 | # 1
23 | # -------------
24 | # s^2 + 2 s + 3
25 | #
26 | # Continuous-time transfer function.
27 |
28 | syst_fake = tf([1],[1, 2, 3])
29 | print syst_fake
30 | # Python:
31 | # 1
32 | # -------------
33 | # s^2 + 2 s + 3
34 |
35 |
36 | # MATLAB:
37 | # zero order hold by default
38 | # syst_fake_dis=c2d(syst_fake,0.01)
39 | # syst_fake_dis =
40 | #
41 | # 4.967e-05 z + 4.934e-05
42 | # -----------------------
43 | # z^2 - 1.98 z + 0.9802
44 | #
45 | # Sample time: 0.01 seconds
46 | # Discrete-time transfer function.
47 |
48 | #Test if we generated a system with the same behaviour:
49 | # MATLAB:
50 | # [output, t] = step(syst_fake)
51 | # plot(t, output)
52 | # Python
53 | # output, t = step([syst_fake.num[0][0][0], syst_fake.den[0][0]])
54 | # plot(output, t) # MATLAB wants the inverse order to plot
55 | # show()
56 |
57 |
58 | syst_fake_dis = c2d(syst_fake, 0.01, method='zoh')
59 | print syst_fake_dis
60 | # OLD scipy.signal.cont2discrete way!
61 | #syst_fake_dis = c2d([syst_fake.num[0][0][0], syst_fake.den[0][0]], 0.01)
62 | #print_c2d_matlablike(syst_fake_dis)
63 |
64 | # Python:
65 | # zero order hold by default
66 | # 4.96670866519e-05 z 4.93370716897e-05
67 | # -----------------------
68 | # z^2 1.0 z^2 -1.97990166083 z 0.980198673307
69 | #
70 | # Sample time: 0.01 seconds
71 | # Discrete-time transfer function.
72 |
73 | # MATLAB:
74 | # [output,t]=step(syst_fake_dis)
75 | ### OLD scipy.signal.step way!
76 | ###output, t = step(syst_fake_dis[0][0], syst_fake_dis[1])# ,T=200) # MATLAB calculates the T size automatically based on black magic different than python one, see [MATLAB]/toolbox/shared/controllib/engine/@DynamicSystem/step.m:
77 | output, t = step(syst_fake_dis)
78 | # MATLAB:
79 | # plot(output)
80 | plot(output[0])
81 | show()
82 |
83 | # out_len = len(output)
84 | out_len = len(output[0])
85 | print "out_len is:"
86 | print out_len
87 | print "output is:"
88 | print output[0]
89 | # input=1:650;
90 | # input(:)=1;
91 | input_ = np.ones(out_len)
92 | # [num,den]=stmcb(output,input,0,2)
93 | [num,den]=stmcb(output[0],input_,0,2)
94 | # sys_model=tf(num,den,0.01)
95 | # step(sys_model)
96 | # hold on
97 | # step(syst_fake)
--------------------------------------------------------------------------------
/src/by_hand_code/system_example.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Nov 17 12:30:46 2013
5 |
6 | @author: Sammy Pfeiffer
7 | """
8 | from numpy import allclose # Grab all of the NumPy functions
9 | import numpy as np
10 | from matplotlib.pyplot import plot, show # Grab MATLAB plotting functions
11 | from control.matlab import tf, c2d, step # MATLAB-like functions
12 | #from scipy.signal import cont2discrete as c2d
13 | #from scipy.signal import step
14 | from stmbc import stmcb
15 |
16 |
17 | # MATLAB:
18 | # syst_fake=tf([1],[1 2 3]) # from matlab to python, commas must be used to separate elements
19 | # >> syst_fake
20 | # syst_fake =
21 | #
22 | # 1
23 | # -------------
24 | # s^2 + 2 s + 3
25 | #
26 | # Continuous-time transfer function.
27 |
28 | syst_fake = tf([1],[1, 2, 3])
29 | print syst_fake
30 | # Python:
31 | # 1
32 | # -------------
33 | # s^2 + 2 s + 3
34 |
35 |
36 | # MATLAB:
37 | # zero order hold by default
38 | # syst_fake_dis=c2d(syst_fake,0.01)
39 | # syst_fake_dis =
40 | #
41 | # 4.967e-05 z + 4.934e-05
42 | # -----------------------
43 | # z^2 - 1.98 z + 0.9802
44 | #
45 | # Sample time: 0.01 seconds
46 | # Discrete-time transfer function.
47 |
48 | #Test if we generated a system with the same behaviour:
49 | # MATLAB:
50 | # [output, t] = step(syst_fake)
51 | # plot(t, output)
52 | # Python
53 | # output, t = step([syst_fake.num[0][0][0], syst_fake.den[0][0]])
54 | # plot(output, t) # MATLAB wants the inverse order to plot
55 | # show()
56 |
57 |
58 | syst_fake_dis = c2d(syst_fake, 0.01, method='zoh')
59 | print syst_fake_dis
60 | # OLD scipy.signal.cont2discrete way!
61 | #syst_fake_dis = c2d([syst_fake.num[0][0][0], syst_fake.den[0][0]], 0.01)
62 | #print_c2d_matlablike(syst_fake_dis)
63 |
64 | # Python:
65 | # zero order hold by default
66 | # 4.96670866519e-05 z 4.93370716897e-05
67 | # -----------------------
68 | # z^2 1.0 z^2 -1.97990166083 z 0.980198673307
69 | #
70 | # Sample time: 0.01 seconds
71 | # Discrete-time transfer function.
72 |
73 | # MATLAB:
74 | # [output,t]=step(syst_fake_dis)
75 | ### OLD scipy.signal.step way!
76 | ###output, t = step(syst_fake_dis[0][0], syst_fake_dis[1])# ,T=200) # MATLAB calculates the T size automatically based on black magic different than python one, see [MATLAB]/toolbox/shared/controllib/engine/@DynamicSystem/step.m:
77 | output, t = step(syst_fake_dis)
78 | # MATLAB:
79 | # plot(output)
80 | plot(output[0])
81 | show()
82 |
83 | # out_len = len(output)
84 | out_len = len(output[0])
85 | print "out_len is:"
86 | print out_len
87 | print "output is:"
88 | print output[0]
89 | # input=1:650;
90 | # input(:)=1;
91 | input_ = np.ones(out_len)
92 | # [num,den]=stmcb(output,input,0,2)
93 | [num,den]=stmcb(output[0],input_,0,2)
94 | # sys_model=tf(num,den,0.01)
95 | # step(sys_model)
96 | # hold on
97 | # step(syst_fake)
--------------------------------------------------------------------------------
/matlab_test_files/prony_to_py.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def prony(h, nb, na):
13 |
14 | # Local Variables: a, c, b, h1, h, nb, H1, M, N, H2, H, na, H2_minus, K
15 | # Function calls: max, length, prony, zeros, toeplitz
16 | #%PRONY Prony's method for time-domain IIR filter design.
17 | #% [B,A] = PRONY(H, NB, NA) finds a filter with numerator order
18 | #% NB, denominator order NA, and having the impulse response in
19 | #% vector H. The IIR filter coefficients are returned in
20 | #% length NB+1 and NA+1 row vectors B and A, ordered in
21 | #% descending powers of Z. H may be real or complex.
22 | #%
23 | #% If the largest order specified is greater than the length of H,
24 | #% H is padded with zeros.
25 | #%
26 | #% % Example:
27 | #% % Fit an IIR model to an impulse response of a lowpass filter.
28 | #%
29 | #% [b,a] = butter(4,0.2);
30 | #% impulseResp = impz(b,a); % obtain impulse response
31 | #% denOrder=4; numOrder=4; % system function of order 4
32 | #% [Num,Den]=prony(impulseResp,numOrder,denOrder);
33 | #% subplot(211); % impulse response and input
34 | #% stem(impz(Num,Den,length(impulseResp)));
35 | #% title('Impulse Response with Prony Design');
36 | #% subplot(212);
37 | #% stem(impulseResp); title('Input Impulse Response');
38 | #%
39 | #% See also STMCB, LPC, BUTTER, CHEBY1, CHEBY2, ELLIP, INVFREQZ.
40 | #% Author(s): L. Shure, 47-88
41 | #% L. Shure, 117-90, revised
42 | #% Copyright 1988-2012 The MathWorks, Inc.
43 | #% $Revision: 1.7.4.1.2.1 $ $Date: 2013/01/02 17:47:48 $
44 | #% References:
45 | #% [1] T.W. Parks and C.S. Burrus, Digital Filter Design,
46 | #% John Wiley and Sons, 1987, p226.
47 | K = length(h)-1.
48 | M = nb
49 | N = na
50 | if K<=matcompat.max(M, N):
51 | #% zero-pad input if necessary
52 | K = matcompat.max(M, N)+1.
53 | h[int((K+1.))-1] = 0.
54 |
55 | c = h[0]
56 | if c == 0.:
57 | #% avoid divide by zero
58 | c = 1.
59 |
60 | H = toeplitz(matdiv(h, c), np.array(np.hstack((1., np.zeros(1., K)))))
61 | #% K+1 by N+1
62 | if K > N:
63 | H[:,int(N+2.)-1:K+1.] = np.array([])
64 |
65 |
66 | #% Partition H matrix
67 | H1 = H[0:M+1.,:]
68 | #% M+1 by N+1
69 | h1 = H[int(M+2.)-1:K+1.,0]
70 | #% K-M by 1
71 | H2 = H[int(M+2.)-1:K+1.,1:N+1.]
72 | #% K-M by N
73 | H2_minus = -H2
74 | a = np.array(np.vstack((np.hstack((1.)), np.hstack((linalg.solve(H2_minus, h1)))))).T
75 | b = np.dot(np.dot(c, a), H1.T)
76 | return [b, a]
--------------------------------------------------------------------------------
/matlab_test_files/aryule_test.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def aryule(x, p):
13 |
14 | # Local Variables: a, e, k, nx, p, R, x, mx
15 | # Function calls: aryule, nargchk, min, issparse, nargin, length, isempty, error, levinson, message, xcorr, round, size
16 | #%ARYULE AR parameter estimation via Yule-Walker method.
17 | #% A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR
18 | #% parametric signal model estimate of vector X using the Yule-Walker
19 | #% (autocorrelation) method. ORDER is the model order of the AR system.
20 | #% This method solves the Yule-Walker equations by means of the Levinson-
21 | #% Durbin recursion.
22 | #%
23 | #% [A,E] = ARYULE(...) returns the final prediction error E (the variance
24 | #% estimate of the white noise input to the AR model).
25 | #%
26 | #% [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients.
27 | #%
28 | #% % Example:
29 | #% % Estimate model order using decay of reflection coefficients.
30 | #%
31 | #% rng default;
32 | #% y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1));
33 | #%
34 | #% % Create AR(2) process
35 | #% [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10);
36 | #%
37 | #% % Fit AR(10) model
38 | #% stem(reflect_coeffs); axis([-0.05 10.5 -1 1]);
39 | #% title('Reflection Coefficients by Lag'); xlabel('Lag');
40 | #% ylabel('Reflection Coefficent');
41 | #%
42 | #% See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY.
43 | #% Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
44 | #% Macmillan, 1988, Chapter 5
45 | #% M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING,
46 | #% John Wiley & Sons, 1996, Chapter 8
47 | #% Author(s): R. Losada
48 | #% Copyright 1988-2004 The MathWorks, Inc.
49 | #% $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $
50 | matcompat.error(nargchk(2., 2., nargin, 'struct'))
51 | #% Check the input data type. Single precision is not supported.
52 | #%try
53 | #% chkinputdatatype(x,p);
54 | #%catch ME
55 | #% throwAsCaller(ME);
56 | #%end
57 | [mx, nx] = matcompat.size(x)
58 | if isempty(x) or length(x) 1.:
59 | matcompat.error(message('signal:aryule:InvalidDimensions'))
60 | elif isempty(p) or not p == np.round(p):
61 | matcompat.error(message('signal:aryule:MustBeInteger'))
62 |
63 |
64 | if issparse(x):
65 | matcompat.error(message('signal:aryule:Sparse'))
66 |
67 |
68 | R = plt.xcorr(x, p, 'biased')
69 | [a, e, k] = levinson(R[int(p+1.)-1:], p)
70 | return [a, e, k]
--------------------------------------------------------------------------------
/matlab_test_files/stmcb_to_py.m:
--------------------------------------------------------------------------------
1 | function [b,a] = stmcb( x, u_in, q, p, niter, a_in )
2 | %STMCB Compute linear model via Steiglitz-McBride iteration
3 | % [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
4 | % B(z)/A(z) with approximate impulse response H, NA poles and
5 | % NB zeros.
6 | %
7 | % [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
8 | %
9 | % [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
10 | % guess at the denominator coefficients. If you don't specify Ai,
11 | % STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
12 | %
13 | % [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
14 | % A of the system which, given X as input, has Y as output. N and Ai
15 | % are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
16 | % Y and X must be the same length.
17 | %
18 | % % Example:
19 | % % Approximate the impulse response of a Butterworth filter with a
20 | % % system of lower order.
21 | %
22 | % [b,a] = butter(6,0.2); % Butterworth filter design
23 | % h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
24 | % freqz(b,a,128) % Frequency response
25 | % [bb,aa] = stmcb(h,4,4);
26 | % figure; freqz(bb,aa,128)
27 | %
28 | % See also PRONY, LEVINSON, LPC, ARYULE.
29 |
30 | % Author(s): Jim McClellan, 2-89
31 | % T. Krauss, 4-22-93, new help and options
32 | % Copyright 1988-2004 The MathWorks, Inc.
33 | % $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
34 |
35 | error(nargchk(3,6,nargin,'struct'))
36 |
37 | if length(u_in) == 1,
38 | if nargin == 3,
39 | niter = 5; p = q; q = u_in;
40 | a_in = prony(x,0,p);
41 | elseif nargin == 4,
42 | niter = p; p = q; q = u_in;
43 | a_in = prony(x,0,p);
44 | elseif nargin == 5,
45 | a_in = niter; niter = p; p = q; q = u_in;
46 | end
47 | u_in = zeros(size(x));
48 | u_in(1) = 1; % make a unit impulse whose length is same as x
49 | else
50 | if length(u_in)~=length(x),
51 | error(message('signal:stmcb:InvalidDimensions'))
52 | end
53 | if nargin < 6
54 | [b,a_in] = prony(x,0,p);
55 | end
56 | if nargin < 5
57 | niter = 5;
58 | end
59 | end
60 |
61 | a = a_in;
62 | N = length(x);
63 | for i=1:niter
64 | u = filter( 1, a, x );
65 | v = filter( 1, a, u_in );
66 | C1 = convmtx(u(:),p+1);
67 | C2 = convmtx(v(:),q+1);
68 | C1_minus = -C1;
69 | T_sub1 = C1_minus(1:N,:);
70 | T_sub2 = C2(1:N,:);
71 | T = [T_sub1 T_sub2];
72 | %T = [ C1_minus(1:N,:) C2(1:N,:) ];
73 | T_minus = -T;
74 | T_left = T(:,2:p+q+2);
75 | T_right = (T_minus(:,1));
76 | c = T_left \ T_right;
77 | % c = T(:,2:p+q+2)\(T_minus(:,1)); % move 1st column to RHS and do least-squares
78 | a = [1; c(1:p)]; % denominator coefficients
79 | b = c(p+1:p+q+1); % numerator coefficients
80 | end
81 | a=a.';
82 | b=b.';
83 |
84 |
--------------------------------------------------------------------------------
/matlab_test_files/arparest.m:
--------------------------------------------------------------------------------
1 | function [a,e,msg,msgobj] = arparest( x, p, method)
2 | %ARPAREST AR parameter estimation via a specified method.
3 | % A = ARPAREST(X,ORDER,METHOD) returns the polynomial A corresponding to
4 | % the AR parametric signal model estimate of vector X using the specified
5 | % METHOD. ORDER is the model order of the AR system.
6 | %
7 | % Supported methods are: 'covariance' and 'modified' although all of the
8 | % methods of CORRMTX will work. In particular if 'autocorrelation' is
9 | % used, the results should be the same as those of ARYULE (but slower).
10 | %
11 | % [A,E] = ARPAREST(...) returns the variance estimate E of the white noise
12 | % input to the AR model.
13 |
14 | % Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
15 | % Prentice-Hall, 1988, Chapter 7
16 | % S. Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATION,
17 | % Prentice-Hall, 1987, Chapter 8.
18 | % P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
19 | % Prentice-Hall, 1997, Chapter 3
20 |
21 | % Author(s): R. Losada and P. Pacheco
22 | % Copyright 1988-2004 The MathWorks, Inc.
23 | % $Revision: 1.5.4.3 $ $Date: 2011/05/13 18:13:56 $
24 |
25 | error(nargchk(3,3,nargin,'struct'))
26 | [mx,nx] = size(x);
27 |
28 | % Initialize in case we return early
29 | a = []; e = [];
30 |
31 | % Assign msg in case there are no errors
32 | msg ='';
33 | msgobj = [];
34 |
35 | % Set up necessary but not sufficient conditions for the correlation
36 | % matrix to be nonsingular. From (Marple)
37 | switch method,
38 | case 'covariance',
39 | minlength_x = 2*p;
40 | case 'modified',
41 | minlength_x = 3*p/2;
42 | otherwise
43 | msgobj = message('signal:arparest:UnknMethod');
44 | msg = getString(msgobj);
45 | return
46 | end
47 |
48 | % Do some data sanity testing
49 | if isempty(x) || length(x) < minlength_x || min(mx,nx) > 1,
50 | if strcmp(method, 'modified')
51 | msgobj = message('signal:arparest:TooSmallForModel','X','3/2');
52 | msg = getString(msgobj);
53 | else
54 | msgobj = message('signal:arparest:TooSmallForModel','X','2');
55 | msg = getString(msgobj);
56 | end
57 | return
58 | end
59 | if issparse(x),
60 | msgobj = message('signal:arparest:InputSignalCannotBeSparse');
61 | msg = getString(msgobj);
62 | return
63 | end
64 | if isempty(p) || p ~= round(p),
65 | msgobj = message('signal:arparest:ModelOrderMustBeInteger');
66 | msg = getString(msgobj);
67 | return
68 | end
69 |
70 | x = x(:);
71 |
72 | % Generate the appropriate data matrix
73 | XM = corrmtx(x,p,method);
74 | Xc = XM(:,2:end);
75 | X1 = XM(:,1);
76 |
77 | % Coefficients estimated via the covariance method
78 | a = [1; -Xc\X1];
79 |
80 | % Estimate the input white noise variance
81 | Cz = X1'*Xc;
82 | e = X1'*X1 + Cz*a(2:end);
83 |
84 | % Ignore the possible imaginary part due to numerical errors and force
85 | % the variance estimate of the white noise to be positive
86 | e = abs(real(e));
87 |
88 | a = a(:).'; % By convention all polynomials are row vectors
89 |
90 | % [EOF] arparest.m
91 |
--------------------------------------------------------------------------------
/matlab_test_files/stmcb_test.m:
--------------------------------------------------------------------------------
1 | function [b,a] = stmcb_test( x, u_in, q, p, niter, a_in )
2 | %STMCB Compute linear model via Steiglitz-McBride iteration
3 | % [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
4 | % B(z)/A(z) with approximate impulse response H, NA poles and
5 | % NB zeros.
6 | %
7 | % [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
8 | %
9 | % [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
10 | % guess at the denominator coefficients. If you don't specify Ai,
11 | % STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
12 | %
13 | % [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
14 | % A of the system which, given X as input, has Y as output. N and Ai
15 | % are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
16 | % Y and X must be the same length.
17 | %
18 | % % Example:
19 | % % Approximate the impulse response of a Butterworth filter with a
20 | % % system of lower order.
21 | %
22 | % [b,a] = butter(6,0.2); % Butterworth filter design
23 | % h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
24 | % freqz(b,a,128) % Frequency response
25 | % [bb,aa] = stmcb(h,4,4);
26 | % figure; freqz(bb,aa,128)
27 | %
28 | % See also PRONY, LEVINSON, LPC, ARYULE.
29 |
30 | % Author(s): Jim McClellan, 2-89
31 | % T. Krauss, 4-22-93, new help and options
32 | % Copyright 1988-2004 The MathWorks, Inc.
33 | % $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
34 |
35 | error(nargchk(3,6,nargin,'struct'))
36 |
37 | if length(u_in) == 1,
38 | if nargin == 3,
39 | niter = 5; p = q; q = u_in;
40 | a_in = prony(x,0,p);
41 | elseif nargin == 4,
42 | niter = p; p = q; q = u_in;
43 | a_in = prony(x,0,p);
44 | elseif nargin == 5,
45 | a_in = niter; niter = p; p = q; q = u_in;
46 | end
47 | u_in = zeros(size(x));
48 | u_in(1) = 1; % make a unit impulse whose length is same as x
49 | else
50 | if length(u_in)~=length(x),
51 | error(message('signal:stmcb:InvalidDimensions'))
52 | end
53 | if nargin < 6
54 | [b,a_in] = prony(x,0,p);
55 | disp('p is:')
56 | disp(p)
57 | disp('b is:')
58 | disp(b)
59 | disp('a_in is:')
60 | disp(a_in)
61 | end
62 | if nargin < 5
63 | niter = 5;
64 | end
65 | end
66 |
67 | a = a_in;
68 | N = length(x);
69 | for i=1:niter
70 | u = filter( 1, a, x );
71 | %u
72 | v = filter( 1, a, u_in );
73 | %v
74 | C1 = convmtx_test(u(:),p+1);
75 | C2 = convmtx_test(v(:),q+1);
76 | %T_left = -C1(1:N,:)
77 | %size(T_left)
78 | %T_right = C2(1:N,:)
79 | %size(T_right)
80 | T = [ -C1(1:N,:) C2(1:N,:) ];
81 | %T
82 | %size(T)
83 | %error('stop here')
84 | c = T(:,2:p+q+2)\(-T(:,1)); % move 1st column to RHS and do least-squares
85 | c
86 | size(c)
87 | a = [1; c(1:p)]; % denominator coefficients
88 | a
89 | size(a)
90 | b = c(p+1:p+q+1); % numerator coefficients
91 | end
92 | a=a.';
93 | b=b.';
94 |
95 |
--------------------------------------------------------------------------------
/src/by_hand_code/prony_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 5 17:11:46 2014
5 |
6 | @author: Sammy Pfeiffer
7 | This file is a test for using prony python implementation versus MATLAB one.
8 | """
9 |
10 | import numpy as np
11 | from prony import prony
12 | from prony_matlab import prony_matlab
13 | from scipy.signal import butter, impulse
14 | from impz import impz
15 |
16 | # % % Example:
17 | # % % Fit an IIR model to an impulse response of a lowpass filter.
18 | # %
19 | # % [b,a] = butter(4,0.2);
20 | b, a = butter(4, 0.2)
21 | # MATLAB output
22 | # Python output
23 |
24 | # b = 0.0048 0.0193 0.0289 0.0193 0.0048
25 | #[ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
26 |
27 | # a = 1.0000 -2.3695 2.3140 -1.0547 0.1874
28 | #[ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
29 | print b
30 | print a
31 |
32 | # % impulseResp = impz(b,a); % obtain impulse response
33 | # 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028 0.233457187867600 0.193512552162805 0.123765243571016 0.0496036031380585 -0.00850905187491667 -0.0406738350178057 -0.0475631979469677 -0.0368517338223919 -0.0185628385243508 -0.00125221912683403 0.0100331628527336 0.0139990059845164 0.0121118272327115 0.00712186446378598 0.00173298095479121 -0.00222279239538353 -0.00403535730812247 -0.00392509206552861 -0.00263181398008669 -0.000992945935699223 0.000353673136269240 0.00109549708726230 0.00122332129708734 0.000922772684652072 0.000444882357824948 3.79019631817530e-06 -0.000276480597968442 -0.000367601488225979 -0.000310628048735716 -0.000177716344133915 -3.82012617315314e-05 6.19874979750476e-05 0.000106051505667546 0.000100862919097785 6.61282460408185e-05 2.35297812645709e-05 -1.07611182300523e-05 -2.91027199865281e-05
34 | impulseResp = impz(b,a)
35 | print impulseResp
36 | # I used a couple of examples... matlab gave 43 as length we give 64
37 | # python [ 0.00482434 0.03072872 0.09059468 0.16794482 0.22464127]
38 | # matlab 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028
39 |
40 | # % denOrder=4; numOrder=4; % system function of order 4
41 | denOrder = 4
42 | numOrder = 4
43 |
44 | # % [Num,Den]=prony(impulseResp,numOrder,denOrder);
45 | #[Num,Den]=prony(impulseResp,numOrder,denOrder)
46 | [Num,Den]=prony_matlab(impulseResp,numOrder,denOrder)
47 | # MATLAB
48 | # Num =0.0048 0.0193 0.0289 0.0193 0.0048
49 | # Den =1.0000 -2.3695 2.3140 -1.0547 0.1874
50 | # Python
51 | # [ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
52 | # [ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
53 |
54 | print Num
55 | print Den
56 |
57 | # % subplot(211); % impulse response and input
58 | # % stem(impz(Num,Den,length(impulseResp)));
59 | # % title('Impulse Response with Prony Design');
60 | # % subplot(212);
61 | # % stem(impulseResp); title('Input Impulse Response');
62 |
63 |
64 |
--------------------------------------------------------------------------------
/matlab_test_files/arparest_test.m:
--------------------------------------------------------------------------------
1 | function [a,e,msg,msgobj] = arparest( x, p, method)
2 | %ARPAREST AR parameter estimation via a specified method.
3 | % A = ARPAREST(X,ORDER,METHOD) returns the polynomial A corresponding to
4 | % the AR parametric signal model estimate of vector X using the specified
5 | % METHOD. ORDER is the model order of the AR system.
6 | %
7 | % Supported methods are: 'covariance' and 'modified' although all of the
8 | % methods of CORRMTX will work. In particular if 'autocorrelation' is
9 | % used, the results should be the same as those of ARYULE (but slower).
10 | %
11 | % [A,E] = ARPAREST(...) returns the variance estimate E of the white noise
12 | % input to the AR model.
13 |
14 | % Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
15 | % Prentice-Hall, 1988, Chapter 7
16 | % S. Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATION,
17 | % Prentice-Hall, 1987, Chapter 8.
18 | % P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
19 | % Prentice-Hall, 1997, Chapter 3
20 |
21 | % Author(s): R. Losada and P. Pacheco
22 | % Copyright 1988-2004 The MathWorks, Inc.
23 | % $Revision: 1.5.4.3 $ $Date: 2011/05/13 18:13:56 $
24 |
25 | error(nargchk(3,3,nargin,'struct'))
26 | [mx,nx] = size(x);
27 |
28 | % Initialize in case we return early
29 | a = []; e = [];
30 |
31 | % Assign msg in case there are no errors
32 | msg ='';
33 | msgobj = [];
34 |
35 | % Set up necessary but not sufficient conditions for the correlation
36 | % matrix to be nonsingular. From (Marple)
37 | switch method,
38 | case 'covariance',
39 | minlength_x = 2*p;
40 | case 'modified',
41 | minlength_x = 3*p/2;
42 | otherwise
43 | msgobj = message('signal:arparest:UnknMethod');
44 | msg = getString(msgobj);
45 | return
46 | end
47 |
48 | % Do some data sanity testing
49 | if isempty(x) || length(x) < minlength_x || min(mx,nx) > 1,
50 | if strcmp(method, 'modified')
51 | msgobj = message('signal:arparest:TooSmallForModel','X','3/2');
52 | msg = getString(msgobj);
53 | else
54 | msgobj = message('signal:arparest:TooSmallForModel','X','2');
55 | msg = getString(msgobj);
56 | end
57 | return
58 | end
59 | if issparse(x),
60 | msgobj = message('signal:arparest:InputSignalCannotBeSparse');
61 | msg = getString(msgobj);
62 | return
63 | end
64 | if isempty(p) || p ~= round(p),
65 | msgobj = message('signal:arparest:ModelOrderMustBeInteger');
66 | msg = getString(msgobj);
67 | return
68 | end
69 |
70 | x = x(:);
71 |
72 | % Generate the appropriate data matrix
73 | XM = corrmtx(x,p,method);
74 | Xc = XM(:,2:end);
75 | X1 = XM(:,1);
76 |
77 | % Coefficients estimated via the covariance method
78 | a_left = [1]
79 | Xc_minus = -Xc
80 | a_right = Xc_minus\X1
81 | a = [a_left; a_right]
82 | %a = [1; -Xc\X1];
83 |
84 | % Estimate the input white noise variance
85 | Cz = X1'*Xc;
86 | e = X1'*X1 + Cz*a(2:end);
87 |
88 | % Ignore the possible imaginary part due to numerical errors and force
89 | % the variance estimate of the white noise to be positive
90 | e = abs(real(e));
91 |
92 | a = a(:).'; % By convention all polynomials are row vectors
93 |
94 | % [EOF] arparest.m
95 |
--------------------------------------------------------------------------------
/matlab_test_files/arburg.m:
--------------------------------------------------------------------------------
1 | function varargout = arburg( x, p)
2 | %ARBURG AR parameter estimation via Burg method.
3 | % A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
4 | % parametric signal model estimate of vector X using Burg's method.
5 | % ORDER is the model order of the AR system.
6 | %
7 | % [A,E] = ARBURG(...) returns the final prediction error E (the variance
8 | % estimate of the white noise input to the AR model).
9 | %
10 | % [A,E,K] = ARBURG(...) returns the vector K of reflection
11 | % coefficients (parcor coefficients).
12 | %
13 | % % Example:
14 | % % Estimate input noise variance for AR(4) model.
15 | %
16 | % A=[1 -2.7607 3.8106 -2.6535 0.9238];
17 | % % Generate noise standard deviations
18 | % % Seed random number generator for reproducible results
19 | % rng default;
20 | % noise_stdz=rand(50,1)+0.5;
21 | % for j=1:50
22 | % y=filter(1,A,noise_stdz(j)*randn(1024,1));
23 | % [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
24 | % end
25 | % %Compare actual vs. estimated variances
26 | % plot(noise_stdz.^2,NoiseVariance,'k*');
27 | % xlabel('Input Noise Variance');
28 | % ylabel('Estimated Noise Variance');
29 | %
30 | % See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
31 |
32 | % Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
33 | % Prentice-Hall, 1988, Chapter 7
34 | % S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
35 | % Macmillan, 1988, Chapter 5
36 |
37 | % Author(s): D. Orofino and R. Losada
38 | % Copyright 1988-2009 The MathWorks, Inc.
39 | % $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
40 |
41 | error(nargchk(2,2,nargin,'struct'))
42 |
43 | % Check the input data type. Single precision is not supported.
44 | try
45 | chkinputdatatype(x,p);
46 | catch ME
47 | throwAsCaller(ME);
48 | end
49 |
50 | validateattributes(x,{'numeric'},{'nonempty','finite','vector'},'arburg','X');
51 | validateattributes(p,{'numeric'},{'positive','integer','scalar'},'arburg','ORDER');
52 | if issparse(x),
53 | error(message('signal:arburg:Sparse'))
54 | end
55 | if numel(x) < p+1
56 | error(message('signal:arburg:InvalidDimension', p + 1));
57 | end
58 |
59 | x = x(:);
60 | N = length(x);
61 |
62 | % Initialization
63 | ef = x;
64 | eb = x;
65 | a = 1;
66 |
67 | % Initial error
68 | E = x'*x./N;
69 |
70 | % Preallocate 'k' for speed.
71 | k = zeros(1, p);
72 |
73 | for m=1:p
74 | % Calculate the next order reflection (parcor) coefficient
75 | efp = ef(2:end);
76 | ebp = eb(1:end-1);
77 | num = -2.*ebp'*efp;
78 | den = efp'*efp+ebp'*ebp;
79 |
80 | k(m) = num ./ den;
81 |
82 | % Update the forward and backward prediction errors
83 | ef = efp + k(m)*ebp;
84 | eb = ebp + k(m)'*efp;
85 |
86 | % Update the AR coeff.
87 | a=[a;0] + k(m)*[0;conj(flipud(a))];
88 |
89 | % Update the prediction error
90 | E(m+1) = (1 - k(m)'*k(m))*E(m);
91 | end
92 |
93 | a = a(:).'; % By convention all polynomials are row vectors
94 | varargout{1} = a;
95 | if nargout >= 2
96 | varargout{2} = E(end);
97 | end
98 | if nargout >= 3
99 | varargout{3} = k(:);
100 | end
101 |
--------------------------------------------------------------------------------
/matlab_test_files/arburg_test.m:
--------------------------------------------------------------------------------
1 | function varargout = arburg( x, p)
2 | %ARBURG AR parameter estimation via Burg method.
3 | % A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
4 | % parametric signal model estimate of vector X using Burg's method.
5 | % ORDER is the model order of the AR system.
6 | %
7 | % [A,E] = ARBURG(...) returns the final prediction error E (the variance
8 | % estimate of the white noise input to the AR model).
9 | %
10 | % [A,E,K] = ARBURG(...) returns the vector K of reflection
11 | % coefficients (parcor coefficients).
12 | %
13 | % % Example:
14 | % % Estimate input noise variance for AR(4) model.
15 | %
16 | % A=[1 -2.7607 3.8106 -2.6535 0.9238];
17 | % % Generate noise standard deviations
18 | % % Seed random number generator for reproducible results
19 | % rng default;
20 | % noise_stdz=rand(50,1)+0.5;
21 | % for j=1:50
22 | % y=filter(1,A,noise_stdz(j)*randn(1024,1));
23 | % [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
24 | % end
25 | % %Compare actual vs. estimated variances
26 | % plot(noise_stdz.^2,NoiseVariance,'k*');
27 | % xlabel('Input Noise Variance');
28 | % ylabel('Estimated Noise Variance');
29 | %
30 | % See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
31 |
32 | % Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
33 | % Prentice-Hall, 1988, Chapter 7
34 | % S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
35 | % Macmillan, 1988, Chapter 5
36 |
37 | % Author(s): D. Orofino and R. Losada
38 | % Copyright 1988-2009 The MathWorks, Inc.
39 | % $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
40 |
41 | % error(nargchk(2,2,nargin,'struct'))
42 | %
43 | % % Check the input data type. Single precision is not supported.
44 | % try
45 | % chkinputdatatype(x,p);
46 | % catch ME
47 | % throwAsCaller(ME);
48 | % end
49 | %
50 | % validateattributes(x,{'numeric'},{'nonempty','finite','vector'},'arburg','X');
51 | % validateattributes(p,{'numeric'},{'positive','integer','scalar'},'arburg','ORDER');
52 | % if issparse(x),
53 | % error(message('signal:arburg:Sparse'))
54 | % end
55 | % if numel(x) < p+1
56 | % error(message('signal:arburg:InvalidDimension', p + 1));
57 | % end
58 |
59 | x = x(:);
60 | N = length(x);
61 |
62 | % Initialization
63 | ef = x;
64 | eb = x;
65 | a = 1;
66 |
67 | % Initial error
68 | E = x'*x./N;
69 |
70 | % Preallocate 'k' for speed.
71 | k = zeros(1, p);
72 |
73 | for m=1:p
74 | % Calculate the next order reflection (parcor) coefficient
75 | efp = ef(2:end);
76 | ebp = eb(1:end-1);
77 | num = -2.*ebp'*efp;
78 | den = efp'*efp+ebp'*ebp;
79 |
80 | k(m) = num ./ den;
81 |
82 | % Update the forward and backward prediction errors
83 | ef = efp + k(m)*ebp;
84 | eb = ebp + k(m)'*efp;
85 |
86 | % Update the AR coeff.
87 | a=[a;0] + k(m)*[0;conj(flipud(a))];
88 |
89 | % Update the prediction error
90 | E(m+1) = (1 - k(m)'*k(m))*E(m);
91 | end
92 |
93 | a = a(:).'; % By convention all polynomials are row vectors
94 | varargout{1} = a;
95 | if nargout >= 2
96 | varargout{2} = E(end);
97 | end
98 | if nargout >= 3
99 | varargout{3} = k(:);
100 | end
101 |
--------------------------------------------------------------------------------
/matlab_test_files/arburg_test2.m:
--------------------------------------------------------------------------------
1 | function varargout = arburg( x, p)
2 | %ARBURG AR parameter estimation via Burg method.
3 | % A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
4 | % parametric signal model estimate of vector X using Burg's method.
5 | % ORDER is the model order of the AR system.
6 | %
7 | % [A,E] = ARBURG(...) returns the final prediction error E (the variance
8 | % estimate of the white noise input to the AR model).
9 | %
10 | % [A,E,K] = ARBURG(...) returns the vector K of reflection
11 | % coefficients (parcor coefficients).
12 | %
13 | % % Example:
14 | % % Estimate input noise variance for AR(4) model.
15 | %
16 | % A=[1 -2.7607 3.8106 -2.6535 0.9238];
17 | % % Generate noise standard deviations
18 | % % Seed random number generator for reproducible results
19 | % rng default;
20 | % noise_stdz=rand(50,1)+0.5;
21 | % for j=1:50
22 | % y=filter(1,A,noise_stdz(j)*randn(1024,1));
23 | % [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
24 | % end
25 | % %Compare actual vs. estimated variances
26 | % plot(noise_stdz.^2,NoiseVariance,'k*');
27 | % xlabel('Input Noise Variance');
28 | % ylabel('Estimated Noise Variance');
29 | %
30 | % See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
31 |
32 | % Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
33 | % Prentice-Hall, 1988, Chapter 7
34 | % S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
35 | % Macmillan, 1988, Chapter 5
36 |
37 | % Author(s): D. Orofino and R. Losada
38 | % Copyright 1988-2009 The MathWorks, Inc.
39 | % $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
40 |
41 | % error(nargchk(2,2,nargin,'struct'))
42 | %
43 | % % Check the input data type. Single precision is not supported.
44 | % try
45 | % chkinputdatatype(x,p);
46 | % catch ME
47 | % throwAsCaller(ME);
48 | % end
49 | %
50 | % validateattributes(x,{'numeric'},{'nonempty','finite','vector'},'arburg','X');
51 | % validateattributes(p,{'numeric'},{'positive','integer','scalar'},'arburg','ORDER');
52 | % if issparse(x),
53 | % error(message('signal:arburg:Sparse'))
54 | % end
55 | % if numel(x) < p+1
56 | % error(message('signal:arburg:InvalidDimension', p + 1));
57 | % end
58 |
59 | x = x(:);
60 | N = length(x);
61 |
62 | % Initialization
63 | ef = x;
64 | eb = x;
65 | a = 1;
66 |
67 | % Initial error
68 | E = x'*x./N;
69 |
70 | % Preallocate 'k' for speed.
71 | k = zeros(1, p);
72 |
73 | % for m=1:p
74 | % Calculate the next order reflection (parcor) coefficient
75 | efp = ef(2:end);
76 | ebp = eb(1:end-1);
77 | num = -2.*ebp'*efp;
78 | den = efp'*efp+ebp'*ebp;
79 |
80 | k(m) = num ./ den;
81 |
82 | % Update the forward and backward prediction errors
83 | ef = efp + k(m)*ebp;
84 | eb = ebp + k(m)'*efp;
85 |
86 | % Update the AR coeff.
87 | a=[a;0] + k(m)*[0;conj(flipud(a))];
88 |
89 | % Update the prediction error
90 | E(m+1) = (1 - k(m)'*k(m))*E(m);
91 | % end
92 |
93 | % a = a(:).'; % By convention all polynomials are row vectors
94 | % varargout{1} = a;
95 | % if nargout >= 2
96 | % varargout{2} = E(end);
97 | % end
98 | % if nargout >= 3
99 | % varargout{3} = k(:);
100 | % end
101 |
--------------------------------------------------------------------------------
/src/by_hand_code/prony.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # vim: set fileencoding=utf-8
3 | """ This file is a Python translation of the MATLAB file prony.m
4 |
5 | Python version by RDL 12 Jan 2012
6 | Copyright notice from prony.m:
7 | copyright 1996, by M.H. Hayes. For use with the book
8 | "Statistical Digital Signal Processing and Modeling"
9 | (John Wiley & Sons, 1996).
10 | """
11 |
12 | from __future__ import print_function,division
13 | import sys
14 | import numpy as np
15 |
16 | from convm import convm
17 |
18 | def prony(x, p, q):
19 | """Model a signal using Prony's method
20 |
21 | Usage: [b,a,err] = prony(x,p,q)
22 |
23 | The input sequence x is modeled as the unit sample response of
24 | a filter having a system function of the form
25 | H(z) = B(z)/A(z)
26 | The polynomials B(z) and A(z) are formed from the vectors
27 | b=[b(0), b(1), ... b(q)]
28 | a=[1 , a(1), ... a(p)]
29 | The input q defines the number of zeros in the model
30 | and p defines the number of poles. The modeling error is
31 | returned in err.
32 |
33 | This comes from Hayes, p. 149, 153, etc
34 |
35 | """
36 | x = x[:]
37 | N = len(x)
38 | if p+q >= len(x):
39 | print('ERROR: model order too large')
40 | print ("p q len(x) " + str(p) + " " + str(q) + " " + str(len(x)))
41 | sys.exit(1)
42 |
43 | # This formulation uses eq. 4.50, p. 153
44 | # Set up the convolution matrices
45 | X = convm(x, p+1)
46 | Xq = X[q:N+p-1, 0:p]
47 | xq1 = -X[q+1:N+p,0]
48 |
49 | # Solve for denominator coefficients
50 | if p>0:
51 | a = np.linalg.lstsq(Xq, xq1)[0]
52 | a = np.insert(a, 0, 1) # a(0) is 1
53 | else:
54 | # all-zero model
55 | a = np.array(1)
56 |
57 | # Solve for the model error
58 | err = np.dot(x[q+1:N].conj().T,X[q+1:N, 0:p+1])
59 | err = np.dot(err, a)
60 |
61 | # Solve for numerator coefficients
62 | if q>0:
63 | # (This is the same as for Pad?)
64 | b = np.dot(X[0:q+1,0:p+1], a)
65 | else:
66 | # all-pole model
67 | # b(0) is x(0), but a better solution is to match energy
68 | b = np.sqrt(err)
69 |
70 | return (b,a)
71 |
72 | #function [a,b,err] = prony(x,p,q)
73 | #x = x(:);
74 | #N = length(x);
75 | #if p+q>=length(x), error('Model order too large'), end
76 | #X = convm(x,p+1);
77 | #Xq = X(q+1:N+p-1,1:p);
78 | #a = [1;-Xq\X(q+2:N+p,1)];
79 | #b = X(1:q+1,1:p+1)*a;
80 | #err = x(q+2:N)'*X(q+2:N,1:p+1)*a;
81 |
82 | def main():
83 | """Test driver"""
84 | # From pp. 149-150
85 | x = np.ones(21)
86 | p = q = 1
87 | print('x: {}\np: {}\nq: {}'.format(x,p,q))
88 | b,a,err = prony(x, p, q)
89 | print('a: {}\nb: {}\nerr: {}'.format(a,b,err))
90 |
91 | # From pp. 152-153
92 | # Note that these results don't match the book, but they do match the
93 | # MATLAB version. So I'm either setting things up wrong or this is an
94 | # errata in the book.
95 | p = q = 5
96 | nd = 5
97 | n = np.arange(11)
98 | i = np.sinc((n-nd)/2)/2
99 | b,a,err = prony(i, p, q)
100 | print('a: {}\nb: {}\nerr: {}'.format(a,b,err))
101 |
102 | if __name__ == '__main__':
103 | main()
--------------------------------------------------------------------------------
/matlab_test_files/arburg_test.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def arburg(x, p):
13 |
14 | # Local Variables: a, E, efp, k, ef, m, varargout, N, p, num, ebp, den, x, eb
15 | # Function calls: arburg, flipud, nargout, length, zeros, conj
16 | #%ARBURG AR parameter estimation via Burg method.
17 | #% A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
18 | #% parametric signal model estimate of vector X using Burg's method.
19 | #% ORDER is the model order of the AR system.
20 | #%
21 | #% [A,E] = ARBURG(...) returns the final prediction error E (the variance
22 | #% estimate of the white noise input to the AR model).
23 | #%
24 | #% [A,E,K] = ARBURG(...) returns the vector K of reflection
25 | #% coefficients (parcor coefficients).
26 | #%
27 | #% % Example:
28 | #% % Estimate input noise variance for AR(4) model.
29 | #%
30 | #% A=[1 -2.7607 3.8106 -2.6535 0.9238];
31 | #% % Generate noise standard deviations
32 | #% % Seed random number generator for reproducible results
33 | #% rng default;
34 | #% noise_stdz=rand(50,1)+0.5;
35 | #% for j=1:50
36 | #% y=filter(1,A,noise_stdz(j)*randn(1024,1));
37 | #% [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
38 | #% end
39 | #% %Compare actual vs. estimated variances
40 | #% plot(noise_stdz.^2,NoiseVariance,'k*');
41 | #% xlabel('Input Noise Variance');
42 | #% ylabel('Estimated Noise Variance');
43 | #%
44 | #% See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
45 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
46 | #% Prentice-Hall, 1988, Chapter 7
47 | #% S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
48 | #% Macmillan, 1988, Chapter 5
49 | #% Author(s): D. Orofino and R. Losada
50 | #% Copyright 1988-2009 The MathWorks, Inc.
51 | #% $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
52 | #% error(nargchk(2,2,nargin,'struct'))
53 | #%
54 | #% % Check the input data type. Single precision is not supported.
55 | #% try
56 | #% chkinputdatatype(x,p);
57 | #% catch ME
58 | #% throwAsCaller(ME);
59 | #% end
60 | #%
61 | #% validateattributes(x,{'numeric'},{'nonempty','finite','vector'},'arburg','X');
62 | #% validateattributes(p,{'numeric'},{'positive','integer','scalar'},'arburg','ORDER');
63 | #% if issparse(x),
64 | #% error(message('signal:arburg:Sparse'))
65 | #% end
66 | #% if numel(x) < p+1
67 | #% error(message('signal:arburg:InvalidDimension', p + 1));
68 | #% end
69 | x = x.flatten(1)
70 | N = length(x)
71 | #% Initialization
72 | ef = x
73 | eb = x
74 | a = 1.
75 | #% Initial error
76 | E = np.dot(x.conj().T, x)/N
77 | #% Preallocate 'k' for speed.
78 | k = np.zeros(1., p)
79 | for m in np.arange(1., (p)+1):
80 | #% Calculate the next order reflection (parcor) coefficient
81 |
82 | a = a.flatten(0)
83 | #% By convention all polynomials are row vectors
84 | varargout.cell[0] = a
85 | if nargout >= 2.:
86 | varargout.cell[1] = E[int(0)-1]
87 |
88 |
89 | if nargout >= 3.:
90 | varargout.cell[2] = k.flatten(1)
91 |
92 |
93 | return [varargout]
--------------------------------------------------------------------------------
/matlab_test_files/arburg.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def arburg(x, p):
13 |
14 | # Local Variables: a, E, efp, k, ef, m, varargout, N, p, num, ebp, den, x, eb
15 | # Function calls: arburg, validateattributes, nargchk, flipud, nargout, issparse, nargin, length, zeros, numel, error, message, conj
16 | #%ARBURG AR parameter estimation via Burg method.
17 | #% A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
18 | #% parametric signal model estimate of vector X using Burg's method.
19 | #% ORDER is the model order of the AR system.
20 | #%
21 | #% [A,E] = ARBURG(...) returns the final prediction error E (the variance
22 | #% estimate of the white noise input to the AR model).
23 | #%
24 | #% [A,E,K] = ARBURG(...) returns the vector K of reflection
25 | #% coefficients (parcor coefficients).
26 | #%
27 | #% % Example:
28 | #% % Estimate input noise variance for AR(4) model.
29 | #%
30 | #% A=[1 -2.7607 3.8106 -2.6535 0.9238];
31 | #% % Generate noise standard deviations
32 | #% % Seed random number generator for reproducible results
33 | #% rng default;
34 | #% noise_stdz=rand(50,1)+0.5;
35 | #% for j=1:50
36 | #% y=filter(1,A,noise_stdz(j)*randn(1024,1));
37 | #% [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
38 | #% end
39 | #% %Compare actual vs. estimated variances
40 | #% plot(noise_stdz.^2,NoiseVariance,'k*');
41 | #% xlabel('Input Noise Variance');
42 | #% ylabel('Estimated Noise Variance');
43 | #%
44 | #% See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
45 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
46 | #% Prentice-Hall, 1988, Chapter 7
47 | #% S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
48 | #% Macmillan, 1988, Chapter 5
49 | #% Author(s): D. Orofino and R. Losada
50 | #% Copyright 1988-2009 The MathWorks, Inc.
51 | #% $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
52 | matcompat.error(nargchk(2., 2., nargin, 'struct'))
53 | #% Check the input data type. Single precision is not supported.
54 | #%try
55 | #% chkinputdatatype(x,p);
56 | #%catch ME
57 | #% throwAsCaller(ME);
58 | #%end
59 | validateattributes(x, cellarray(np.hstack(('numeric'))), cellarray(np.hstack(('nonempty', 'finite', 'vector'))), 'arburg', 'X')
60 | validateattributes(p, cellarray(np.hstack(('numeric'))), cellarray(np.hstack(('positive', 'integer', 'scalar'))), 'arburg', 'ORDER')
61 | if issparse(x):
62 | matcompat.error(message('signal:arburg:Sparse'))
63 |
64 |
65 | if numel(x)
= 2.:
86 | varargout.cell[1] = E[int(0)-1]
87 |
88 |
89 | if nargout >= 3.:
90 | varargout.cell[2] = k.flatten(1)
91 |
92 |
93 | return [varargout]
--------------------------------------------------------------------------------
/src/by_hand_code/prony_matlab.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 6 20:54:46 2014
5 |
6 | @author: Sammy Pfeiffer
7 | This file pretends to imitate the behaviour of the MATLAB function prony
8 | """
9 |
10 | from scipy.linalg import toeplitz
11 | import numpy as np
12 |
13 | # function [b,a] = prony(h, nb ,na)
14 | def prony_matlab(h, nb, na):
15 | # %PRONY Prony's method for time-domain IIR filter design.
16 | # % [B,A] = PRONY(H, NB, NA) finds a filter with numerator order
17 | # % NB, denominator order NA, and having the impulse response in
18 | # % vector H. The IIR filter coefficients are returned in
19 | # % length NB+1 and NA+1 row vectors B and A, ordered in
20 | # % descending powers of Z. H may be real or complex.
21 | # %
22 | # % If the largest order specified is greater than the length of H,
23 | # % H is padded with zeros.
24 | # %
25 | # % % Example:
26 | # % % Fit an IIR model to an impulse response of a lowpass filter.
27 | # %
28 | # % [b,a] = butter(4,0.2);
29 | # % impulseResp = impz(b,a); % obtain impulse response
30 | # % denOrder=4; numOrder=4; % system function of order 4
31 | # % [Num,Den]=prony(impulseResp,numOrder,denOrder);
32 | # % subplot(211); % impulse response and input
33 | # % stem(impz(Num,Den,length(impulseResp)));
34 | # % title('Impulse Response with Prony Design');
35 | # % subplot(212);
36 | # % stem(impulseResp); title('Input Impulse Response');
37 | # %
38 | # % See also STMCB, LPC, BUTTER, CHEBY1, CHEBY2, ELLIP, INVFREQZ.
39 | #
40 | # % Author(s): L. Shure, 5-17-88
41 | # % L. Shure, 12-17-90, revised
42 | # % Copyright 1988-2012 The MathWorks, Inc.
43 | # % $Revision: 1.7.4.1.2.1 $ $Date: 2013/01/02 17:47:48 $
44 | #
45 | # % References:
46 | # % [1] T.W. Parks and C.S. Burrus, Digital Filter Design,
47 | # % John Wiley and Sons, 1987, p226.
48 | #
49 | # K = length(h) - 1;
50 | # M = nb; N = na;
51 | K = len(h) - 1
52 | M = nb
53 | N = na
54 | # if K <= max(M,N) % zero-pad input if necessary
55 | # K = max(M,N)+1;
56 | # h(K+1) = 0;
57 | # end
58 | if K <= max(M,N):
59 | K = max(M,N) + 1
60 | h[K+1] = 0 # probable problem with indices!
61 | # c = h(1);
62 | c = h[0] # probable problem with indices!
63 | # if c==0 % avoid divide by zero
64 | # c=1;
65 | # end
66 | if c == 0:
67 | c = 1
68 | # H = toeplitz(h/c,[1 zeros(1,K)]);
69 | second_part_toeplitz = np.zeros(K+1)
70 | second_part_toeplitz[0] = 1
71 | H = toeplitz(h/c, second_part_toeplitz) # probable problem with indices!
72 | print "H is (toeplitz...)"
73 | print H
74 | # The size of H is different... cause it comes from before different in h
75 | # % K+1 by N+1
76 | # if (K > N)
77 | # H(:,(N+2):(K+1)) = [];
78 | # end
79 | if K > N:
80 | H = H[:,0:N+1] # Here we are just getting rid of all the columns after N+1
81 |
82 | # % Partition H matrix
83 | # H1 = H(1:(M+1),:); % M+1 by N+1
84 | H1 = H[0:M+1,:]
85 | # h1 = H((M+2):(K+1),1); % K-M by 1
86 | h1 = H[M+1:K+1,0]
87 | # H2 = H((M+2):(K+1),2:(N+1)); % K-M by N
88 | H2 = H[M:K,0:N]
89 | # a = [1; -H2\h1].';
90 | #\
91 | # Matrix left division
92 | # x = A\B is the solution to the equation Ax = B. Matrices A and B must have the same number of rows.
93 | #H2 and h1 won't make ever a square (I think) matrix so I will just solve with least squares
94 | a_right = np.linalg.lstsq(-H2,h1)[0]
95 | a_left = np.array([1])
96 | a = np.append(a_left, a_right)
97 |
98 | # b = c*a*H1.';
99 | b = c*(H1.dot(a))
100 |
101 | return [b, a]
--------------------------------------------------------------------------------
/src/prony.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 6 20:54:46 2014
5 | Redone on Jan 22 12:00:00 2014
6 |
7 | @author: Sammy Pfeiffer
8 | @email: sammypfeiffer@gmail.com
9 | This file pretends to imitate the behavior of the MATLAB function prony
10 | """
11 | import numpy as np
12 | from scipy.linalg import toeplitz
13 |
14 |
15 | def prony(h, nb, na):
16 | """From MATLAB:
17 | %PRONY Prony's method for time-domain IIR filter design.
18 | % [B,A] = PRONY(H, NB, NA) finds a filter with numerator order
19 | % NB, denominator order NA, and having the impulse response in
20 | % vector H. The IIR filter coefficients are returned in
21 | % length NB+1 and NA+1 row vectors B and A, ordered in
22 | % descending powers of Z. H may be real or complex.
23 | %
24 | % If the largest order specified is greater than the length of H,
25 | % H is padded with zeros.
26 | """
27 |
28 | # Local Variables: a, c, b, h1, h, nb, H1, M, N, H2, H, na, H2_minus, K
29 | # Function calls: max, length, prony, zeros, toeplitz
30 | #%PRONY Prony's method for time-domain IIR filter design.
31 | #% [B,A] = PRONY(H, NB, NA) finds a filter with numerator order
32 | #% NB, denominator order NA, and having the impulse response in
33 | #% vector H. The IIR filter coefficients are returned in
34 | #% length NB+1 and NA+1 row vectors B and A, ordered in
35 | #% descending powers of Z. H may be real or complex.
36 | #%
37 | #% If the largest order specified is greater than the length of H,
38 | #% H is padded with zeros.
39 | #%
40 | #% % Example:
41 | #% % Fit an IIR model to an impulse response of a lowpass filter.
42 | #%
43 | #% [b,a] = butter(4,0.2);
44 | #% impulseResp = impz(b,a); % obtain impulse response
45 | #% denOrder=4; numOrder=4; % system function of order 4
46 | #% [Num,Den]=prony(impulseResp,numOrder,denOrder);
47 | #% subplot(211); % impulse response and input
48 | #% stem(impz(Num,Den,length(impulseResp)));
49 | #% title('Impulse Response with Prony Design');
50 | #% subplot(212);
51 | #% stem(impulseResp); title('Input Impulse Response');
52 | #%
53 | #% See also STMCB, LPC, BUTTER, CHEBY1, CHEBY2, ELLIP, INVFREQZ.
54 | #% Author(s): L. Shure, 47-88
55 | #% L. Shure, 117-90, revised
56 | #% Copyright 1988-2012 The MathWorks, Inc.
57 | #% $Revision: 1.7.4.1.2.1 $ $Date: 2013/01/02 17:47:48 $
58 | #% References:
59 | #% [1] T.W. Parks and C.S. Burrus, Digital Filter Design,
60 | #% John Wiley and Sons, 1987, p226.
61 | K = len(h)-1
62 | M = nb
63 | N = na
64 | if K<=max(M, N):
65 | #% zero-pad input if necessary
66 | K = max(M, N)+1
67 | h[K+1] = 0
68 |
69 | c = h[0]
70 | if c == 0:
71 | #% avoid divide by zero
72 | c = 1
73 |
74 | # second_part_toeplitz = np.zeros(K+1)
75 | # second_part_toeplitz[0] = 1
76 | H = toeplitz(h / c, np.array(np.hstack((1, np.zeros(K)))))
77 | #% K+1 by N+1
78 | if K > N:
79 | #H[:,int(N+2)-1:K+1] = np.array([])
80 | H = H[:,0:N+1] # Here we are just getting rid of all the columns after N+1
81 |
82 |
83 | #% Partition H matrix
84 | H1 = H[0:M+1,:]
85 | #% M+1 by N+1
86 | h1 = H[M+1:K+1,0]
87 | #% K-M by 1
88 | H2 = H[M:K,0:N]
89 | #% K-M by N
90 | H2_minus = -H2
91 | a_right = np.linalg.lstsq(-H2,h1)[0]
92 | a_left = np.array([1])
93 | a = np.append(a_left, a_right)
94 | #a = np.array(np.vstack((np.hstack((1)), np.hstack((solve(H2_minus, h1)))))).T
95 | b = np.dot(np.dot(c, a), H1.T)
96 | return [b, a]
--------------------------------------------------------------------------------
/matlab_test_files/arburg_test2.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def arburg(x, p):
13 |
14 | # Local Variables: a, E, efp, k, ef, varargout, N, p, num, ebp, den, x, eb
15 | # Function calls: arburg, flipud, m, length, zeros, conj
16 | #%ARBURG AR parameter estimation via Burg method.
17 | #% A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
18 | #% parametric signal model estimate of vector X using Burg's method.
19 | #% ORDER is the model order of the AR system.
20 | #%
21 | #% [A,E] = ARBURG(...) returns the final prediction error E (the variance
22 | #% estimate of the white noise input to the AR model).
23 | #%
24 | #% [A,E,K] = ARBURG(...) returns the vector K of reflection
25 | #% coefficients (parcor coefficients).
26 | #%
27 | #% % Example:
28 | #% % Estimate input noise variance for AR(4) model.
29 | #%
30 | #% A=[1 -2.7607 3.8106 -2.6535 0.9238];
31 | #% % Generate noise standard deviations
32 | #% % Seed random number generator for reproducible results
33 | #% rng default;
34 | #% noise_stdz=rand(50,1)+0.5;
35 | #% for j=1:50
36 | #% y=filter(1,A,noise_stdz(j)*randn(1024,1));
37 | #% [ar_coeffs,NoiseVariance(j)]=arburg(y,4);
38 | #% end
39 | #% %Compare actual vs. estimated variances
40 | #% plot(noise_stdz.^2,NoiseVariance,'k*');
41 | #% xlabel('Input Noise Variance');
42 | #% ylabel('Estimated Noise Variance');
43 | #%
44 | #% See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY.
45 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
46 | #% Prentice-Hall, 1988, Chapter 7
47 | #% S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
48 | #% Macmillan, 1988, Chapter 5
49 | #% Author(s): D. Orofino and R. Losada
50 | #% Copyright 1988-2009 The MathWorks, Inc.
51 | #% $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $
52 | #% error(nargchk(2,2,nargin,'struct'))
53 | #%
54 | #% % Check the input data type. Single precision is not supported.
55 | #% try
56 | #% chkinputdatatype(x,p);
57 | #% catch ME
58 | #% throwAsCaller(ME);
59 | #% end
60 | #%
61 | #% validateattributes(x,{'numeric'},{'nonempty','finite','vector'},'arburg','X');
62 | #% validateattributes(p,{'numeric'},{'positive','integer','scalar'},'arburg','ORDER');
63 | #% if issparse(x),
64 | #% error(message('signal:arburg:Sparse'))
65 | #% end
66 | #% if numel(x) < p+1
67 | #% error(message('signal:arburg:InvalidDimension', p + 1));
68 | #% end
69 | x = x.flatten(1)
70 | N = length(x)
71 | #% Initialization
72 | ef = x
73 | eb = x
74 | a = 1.
75 | #% Initial error
76 | E = np.dot(x.conj().T, x)/N
77 | #% Preallocate 'k' for speed.
78 | k = np.zeros(1., p)
79 | #% for m=1:p
80 | #% Calculate the next order reflection (parcor) coefficient
81 | efp = ef[1:]
82 | ebp = eb[0:0-1.]
83 | num = np.dot(np.dot(-2., ebp.conj().T), efp)
84 | den = np.dot(efp.conj().T, efp)+np.dot(ebp.conj().T, ebp)
85 | k[int(m)-1] = num/den
86 | #% Update the forward and backward prediction errors
87 | ef = efp+np.dot(k[int(m)-1], ebp)
88 | eb = ebp+np.dot(k[int(m)-1].conj().T, efp)
89 | #% Update the AR coeff.
90 | a = np.array(np.vstack((np.hstack((a)), np.hstack((0.)))))+np.dot(k[int(m)-1], np.array(np.vstack((np.hstack((0.)), np.hstack((np.conj(np.flipud(a))))))))
91 | #% Update the prediction error
92 | E[int((m+1.))-1] = np.dot(1.-np.dot(k[int(m)-1].conj().T, k[int(m)-1]), E[int(m)-1])
93 | #% end
94 | #% a = a(:).'; % By convention all polynomials are row vectors
95 | #% varargout{1} = a;
96 | #% if nargout >= 2
97 | #% varargout{2} = E(end);
98 | #% end
99 | #% if nargout >= 3
100 | #% varargout{3} = k(:);
101 | #% end
102 | return [varargout]
--------------------------------------------------------------------------------
/matlab_test_files/stmcb_to_py.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def stmcb(x, u_in, q, p, niter, a_in):
13 |
14 | # Local Variables: T_sub2, T_sub1, T_minus, C2, C1, a_in, N, u_in, T, a, niter, c, b, i, q, p, u, v, x, T_left, T_right, C1_minus
15 | # Function calls: convmtx, filter, prony, nargchk, stmcb, nargin, length, zeros, error, message, size
16 | #%STMCB Compute linear model via Steiglitz-McBride iteration
17 | #% [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
18 | #% B(z)/A(z) with approximate impulse response H, NA poles and
19 | #% NB zeros.
20 | #%
21 | #% [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
22 | #%
23 | #% [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
24 | #% guess at the denominator coefficients. If you don't specify Ai,
25 | #% STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
26 | #%
27 | #% [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
28 | #% A of the system which, given X as input, has Y as output. N and Ai
29 | #% are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
30 | #% Y and X must be the same length.
31 | #%
32 | #% % Example:
33 | #% % Approximate the impulse response of a Butterworth filter with a
34 | #% % system of lower order.
35 | #%
36 | #% [b,a] = butter(6,0.2); % Butterworth filter design
37 | #% h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
38 | #% freqz(b,a,128) % Frequency response
39 | #% [bb,aa] = stmcb(h,4,4);
40 | #% figure; freqz(bb,aa,128)
41 | #%
42 | #% See also PRONY, LEVINSON, LPC, ARYULE.
43 | #% Author(s): Jim McClellan, 2-89
44 | #% T. Krauss, 4-22-93, new help and options
45 | #% Copyright 1988-2004 The MathWorks, Inc.
46 | #% $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
47 | matcompat.error(nargchk(3., 6., nargin, 'struct'))
48 | if length(u_in) == 1.:
49 | if nargin == 3.:
50 | niter = 5.
51 | p = q
52 | q = u_in
53 | a_in = prony(x, 0., p)
54 | elif nargin == 4.:
55 | niter = p
56 | p = q
57 | q = u_in
58 | a_in = prony(x, 0., p)
59 |
60 | elif nargin == 5.:
61 | a_in = niter
62 | niter = p
63 | p = q
64 | q = u_in
65 |
66 |
67 | u_in = np.zeros(matcompat.size(x))
68 | u_in[0] = 1.
69 | #% make a unit impulse whose length is same as x
70 | else:
71 | if length(u_in) != length(x):
72 | matcompat.error(message('signal:stmcb:InvalidDimensions'))
73 |
74 |
75 | if nargin<6.:
76 | [b, a_in] = prony(x, 0., p)
77 |
78 |
79 | if nargin<5.:
80 | niter = 5.
81 |
82 |
83 |
84 |
85 | a = a_in
86 | N = length(x)
87 | for i in np.arange(1., (niter)+1):
88 | u = filter(1., a, x)
89 | v = filter(1., a, u_in)
90 | C1 = convmtx(u.flatten(1), (p+1.))
91 | C2 = convmtx(v.flatten(1), (q+1.))
92 | C1_minus = -C1
93 | T_sub1 = C1_minus[0:N,:]
94 | T_sub2 = C2[0:N,:]
95 | T = np.array(np.hstack((T_sub1, T_sub2)))
96 | #%T = [ C1_minus(1:N,:) C2(1:N,:) ];
97 | T_minus = -T
98 | T_left = T[:,1:p+q+2.]
99 | T_right = T_minus[:,0]
100 | c = linalg.solve(T_left, T_right)
101 | #% c = T(:,2:p+q+2)\(T_minus(:,1)); % move 1st column to RHS and do least-squares
102 | a = np.array(np.vstack((np.hstack((1.)), np.hstack((c[0:p])))))
103 | #% denominator coefficients
104 | b = c[int(p+1.)-1:p+q+1.]
105 | #% numerator coefficients
106 |
107 | a = a.T
108 | b = b.T
109 | return [b, a]
--------------------------------------------------------------------------------
/src/arparest.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | from scipy.sparse import issparse
5 | import matcompat
6 | from matcompat import *
7 |
8 | # if available import pylab (from matlibplot)
9 | try:
10 | import matplotlib.pylab as plt
11 | except ImportError:
12 | pass
13 |
14 | def arparest(x, p, method):
15 |
16 | # Local Variables: a, msgobj, XM, Xc, a_left, a_right, minlength_x, mx, nx, p, x, msg, e, Xc_minus, X1, method, Cz
17 | # Function calls: real, corrmtx, nargchk, getString, min, strcmp, issparse, nargin, length, abs, isempty, error, arparest, message, round, size
18 | #%ARPAREST AR parameter estimation via a specified method.
19 | #% A = ARPAREST(X,ORDER,METHOD) returns the polynomial A corresponding to
20 | #% the AR parametric signal model estimate of vector X using the specified
21 | #% METHOD. ORDER is the model order of the AR system.
22 | #%
23 | #% Supported methods are: 'covariance' and 'modified' although all of the
24 | #% methods of CORRMTX will work. In particular if 'autocorrelation' is
25 | #% used, the results should be the same as those of ARYULE (but slower).
26 | #%
27 | #% [A,E] = ARPAREST(...) returns the variance estimate E of the white noise
28 | #% input to the AR model.
29 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
30 | #% Prentice-Hall, 1988, Chapter 7
31 | #% S. Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATION,
32 | #% Prentice-Hall, 1987, Chapter 8.
33 | #% P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
34 | #% Prentice-Hall, 1997, Chapter 3
35 | #% Author(s): R. Losada and P. Pacheco
36 | #% Copyright 1988-2004 The MathWorks, Inc.
37 | #% $Revision: 1.5.4.3 $ $Date: 2011/05/13 18:13:56 $
38 | #matcompat.error(nargchk(3., 3., nargin, 'struct'))
39 | #[mx, nx] = matcompat.size(x)
40 | [mx, nx] = x.shape
41 | #% Initialize in case we return early
42 | a = np.array([])
43 | e = np.array([])
44 | #% Assign msg in case there are no errors
45 | msg = ''
46 | msgobj = np.array([])
47 | #% Set up necessary but not sufficient conditions for the correlation
48 | #% matrix to be nonsingular. From (Marple)
49 | _switch_val=method
50 | if False: # switch
51 | pass
52 | elif _switch_val == 'covariance':
53 | minlength_x = 2.*p
54 | elif _switch_val == 'modified':
55 | minlength_x = 3.*p/2.
56 | else:
57 | msgobj = 'signal:arparest:UnknMethod'
58 | msg = msgobj
59 | return []
60 |
61 | #% Do some data sanity testing
62 | if x==None or len(x) 1.:
63 | if method == 'modified':
64 | msgobj = 'signal:arparest:TooSmallForModel', 'X', '3/2'
65 | msg = msgobj
66 | else:
67 | msgobj = 'signal:arparest:TooSmallForModel', 'X', '2'
68 | msg = msgobj
69 |
70 |
71 | return []
72 |
73 |
74 | if issparse(x):
75 | msgobj = 'signal:arparest:InputSignalCannotBeSparse'
76 | msg = msgobj
77 | return []
78 |
79 |
80 | if p==None or p != np.round(p):
81 | msgobj = 'signal:arparest:ModelOrderMustBeInteger'
82 | msg = msgobj
83 | return []
84 |
85 |
86 | x = x.flatten(1)
87 | #% Generate the appropriate data matrix
88 | XM = corrmtx(x, p, method)
89 | Xc = XM[:,1:]
90 | X1 = XM[:,0]
91 | #% Coefficients estimated via the covariance method
92 | a_left = np.array(np.hstack((1.)))
93 | Xc_minus = -Xc
94 | a_right = linalg.solve(Xc_minus, X1)
95 | a = np.array(np.vstack((np.hstack((a_left)), np.hstack((a_right)))))
96 | #%a = [1; -Xc\X1];
97 | #% Estimate the input white noise variance
98 | Cz = np.dot(X1.conj().T, Xc)
99 | e = np.dot(X1.conj().T, X1)+np.dot(Cz, a[1:])
100 | #% Ignore the possible imaginary part due to numerical errors and force
101 | #% the variance estimate of the white noise to be positive
102 | e = np.abs(np.real(e))
103 | a = a.flatten(0)
104 | #% By convention all polynomials are row vectors
105 | #% [EOF] arparest.m
106 | return [a, e, msg, msgobj]
--------------------------------------------------------------------------------
/src/by_hand_code/prony_testing.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 5 17:11:46 2014
5 |
6 | @author: Sammy Pfeiffer
7 | This file is a test for using prony python implementation versus MATLAB one.
8 | """
9 |
10 | import numpy as np
11 | from prony import prony
12 | from prony_matlab import prony_matlab
13 | from scipy.signal import butter, impulse
14 | from impz import impz
15 |
16 | # % % Example:
17 | # % % Fit an IIR model to an impulse response of a lowpass filter.
18 | # %
19 | # % [b,a] = butter(4,0.2);
20 | b, a = butter(4, 0.2)
21 | # MATLAB output
22 | # Python output
23 |
24 | # b = 0.0048 0.0193 0.0289 0.0193 0.0048
25 | #[ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
26 |
27 | # a = 1.0000 -2.3695 2.3140 -1.0547 0.1874
28 | #[ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
29 | print b
30 | print a
31 |
32 | # % impulseResp = impz(b,a); % obtain impulse response
33 | # 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028 0.233457187867600 0.193512552162805 0.123765243571016 0.0496036031380585 -0.00850905187491667 -0.0406738350178057 -0.0475631979469677 -0.0368517338223919 -0.0185628385243508 -0.00125221912683403 0.0100331628527336 0.0139990059845164 0.0121118272327115 0.00712186446378598 0.00173298095479121 -0.00222279239538353 -0.00403535730812247 -0.00392509206552861 -0.00263181398008669 -0.000992945935699223 0.000353673136269240 0.00109549708726230 0.00122332129708734 0.000922772684652072 0.000444882357824948 3.79019631817530e-06 -0.000276480597968442 -0.000367601488225979 -0.000310628048735716 -0.000177716344133915 -3.82012617315314e-05 6.19874979750476e-05 0.000106051505667546 0.000100862919097785 6.61282460408185e-05 2.35297812645709e-05 -1.07611182300523e-05 -2.91027199865281e-05
34 | impulseResp = impz(b,a)
35 | print impulseResp
36 | # I used a couple of examples... matlab gave 43 as length we give 64
37 | # python [ 0.00482434 0.03072872 0.09059468 0.16794482 0.22464127]
38 | # matlab 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028
39 |
40 | # AS I CAN'T GET TO GENERATE THE SAME SIZE FOR THIS EXAMPLE (ITS JUST A EXAMPLE)
41 | # IM HARDCODING THE IMPULSE RESP WITH THE MATLAB OUTPUT
42 | impulseResp = np.array([0.00482434335771622, 0.0307287177680857, 0.0905946819548826, 0.167944821844737,
43 | 0.224641271344028, 0.233457187867600, 0.193512552162805, 0.123765243571016,
44 | 0.0496036031380585, -0.00850905187491667, -0.0406738350178057, -0.0475631979469677,
45 | -0.0368517338223919, -0.0185628385243508, -0.00125221912683403, 0.0100331628527336,
46 | 0.0139990059845164, 0.0121118272327115, 0.00712186446378598, 0.00173298095479121,
47 | -0.00222279239538353, -0.00403535730812247, -0.00392509206552861, -0.00263181398008669,
48 | -0.000992945935699223, 0.000353673136269240, 0.00109549708726230, 0.00122332129708734,
49 | 0.000922772684652072, 0.000444882357824948, 3.79019631817530e-06, -0.000276480597968442,
50 | -0.000367601488225979, -0.000310628048735716, -0.000177716344133915, -3.82012617315314e-05,
51 | 6.19874979750476e-05, 0.000106051505667546, 0.000100862919097785, 6.61282460408185e-05,
52 | 2.35297812645709e-05, -1.07611182300523e-05, -2.91027199865281e-05])
53 |
54 |
55 | # % denOrder=4; numOrder=4; % system function of order 4
56 | denOrder = 4
57 | numOrder = 4
58 |
59 | # % [Num,Den]=prony(impulseResp,numOrder,denOrder);
60 | #[Num,Den]=prony(impulseResp,numOrder,denOrder)
61 | [Num,Den]=prony_matlab(impulseResp,numOrder,denOrder)
62 | # MATLAB
63 | # Num =0.0048 0.0193 0.0289 0.0193 0.0048
64 | # Den =1.0000 -2.3695 2.3140 -1.0547 0.1874
65 | # Python
66 | # [ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
67 | # [ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
68 | print "Num:"
69 | print Num
70 | print "Den:"
71 | print Den
72 |
73 | # % subplot(211); % impulse response and input
74 | # % stem(impz(Num,Den,length(impulseResp)));
75 | # % title('Impulse Response with Prony Design');
76 | # % subplot(212);
77 | # % stem(impulseResp); title('Input Impulse Response');
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/trashbin/prony_testing.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Jan 5 17:11:46 2014
5 |
6 | @author: Sammy Pfeiffer
7 | This file is a test for using prony python implementation versus MATLAB one.
8 | """
9 |
10 | import numpy as np
11 | from prony import prony
12 | #from prony_matlab import prony_matlab
13 | from scipy.signal import butter, impulse
14 | #from impz import impz
15 |
16 | # % % Example:
17 | # % % Fit an IIR model to an impulse response of a lowpass filter.
18 | # %
19 | # % [b,a] = butter(4,0.2);
20 | b, a = butter(4, 0.2)
21 | # MATLAB output
22 | # Python output
23 |
24 | # b = 0.0048 0.0193 0.0289 0.0193 0.0048
25 | #[ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
26 |
27 | # a = 1.0000 -2.3695 2.3140 -1.0547 0.1874
28 | #[ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
29 | print b
30 | print a
31 |
32 | # % impulseResp = impz(b,a); % obtain impulse response
33 | # 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028 0.233457187867600 0.193512552162805 0.123765243571016 0.0496036031380585 -0.00850905187491667 -0.0406738350178057 -0.0475631979469677 -0.0368517338223919 -0.0185628385243508 -0.00125221912683403 0.0100331628527336 0.0139990059845164 0.0121118272327115 0.00712186446378598 0.00173298095479121 -0.00222279239538353 -0.00403535730812247 -0.00392509206552861 -0.00263181398008669 -0.000992945935699223 0.000353673136269240 0.00109549708726230 0.00122332129708734 0.000922772684652072 0.000444882357824948 3.79019631817530e-06 -0.000276480597968442 -0.000367601488225979 -0.000310628048735716 -0.000177716344133915 -3.82012617315314e-05 6.19874979750476e-05 0.000106051505667546 0.000100862919097785 6.61282460408185e-05 2.35297812645709e-05 -1.07611182300523e-05 -2.91027199865281e-05
34 | #impulseResp = impz(b,a)
35 | #print impulseResp
36 | # I used a couple of examples... matlab gave 43 as length we give 64
37 | # python [ 0.00482434 0.03072872 0.09059468 0.16794482 0.22464127]
38 | # matlab 0.00482434335771622 0.0307287177680857 0.0905946819548826 0.167944821844737 0.224641271344028
39 |
40 | # AS I CAN'T GET TO GENERATE THE SAME SIZE FOR THIS EXAMPLE (ITS JUST A EXAMPLE)
41 | # IM HARDCODING THE IMPULSE RESP WITH THE MATLAB OUTPUT
42 | impulseResp = np.array([0.00482434335771622, 0.0307287177680857, 0.0905946819548826, 0.167944821844737,
43 | 0.224641271344028, 0.233457187867600, 0.193512552162805, 0.123765243571016,
44 | 0.0496036031380585, -0.00850905187491667, -0.0406738350178057, -0.0475631979469677,
45 | -0.0368517338223919, -0.0185628385243508, -0.00125221912683403, 0.0100331628527336,
46 | 0.0139990059845164, 0.0121118272327115, 0.00712186446378598, 0.00173298095479121,
47 | -0.00222279239538353, -0.00403535730812247, -0.00392509206552861, -0.00263181398008669,
48 | -0.000992945935699223, 0.000353673136269240, 0.00109549708726230, 0.00122332129708734,
49 | 0.000922772684652072, 0.000444882357824948, 3.79019631817530e-06, -0.000276480597968442,
50 | -0.000367601488225979, -0.000310628048735716, -0.000177716344133915, -3.82012617315314e-05,
51 | 6.19874979750476e-05, 0.000106051505667546, 0.000100862919097785, 6.61282460408185e-05,
52 | 2.35297812645709e-05, -1.07611182300523e-05, -2.91027199865281e-05])
53 |
54 |
55 | # % denOrder=4; numOrder=4; % system function of order 4
56 | denOrder = 4
57 | numOrder = 4
58 |
59 | # % [Num,Den]=prony(impulseResp,numOrder,denOrder);
60 | [Num,Den]=prony(impulseResp,numOrder,denOrder)
61 | #[Num,Den]=prony_matlab(impulseResp,numOrder,denOrder)
62 | # MATLAB
63 | # Num =0.0048 0.0193 0.0289 0.0193 0.0048
64 | # Den =1.0000 -2.3695 2.3140 -1.0547 0.1874
65 | # Python
66 | # [ 0.00482434 0.01929737 0.02894606 0.01929737 0.00482434]
67 | # [ 1. -2.36951301 2.31398841 -1.05466541 0.18737949]
68 | print "Num:"
69 | print Num
70 | print "Den:"
71 | print Den
72 |
73 | # % subplot(211); % impulse response and input
74 | # % stem(impz(Num,Den,length(impulseResp)));
75 | # % title('Impulse Response with Prony Design');
76 | # % subplot(212);
77 | # % stem(impulseResp); title('Input Impulse Response');
78 |
79 |
80 |
--------------------------------------------------------------------------------
/matlab_test_files/arparest_test.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import scipy
4 | import matcompat
5 |
6 | # if available import pylab (from matlibplot)
7 | try:
8 | import matplotlib.pylab as plt
9 | except ImportError:
10 | pass
11 |
12 | def arparest(x, p, method):
13 |
14 | # Local Variables: a, msgobj, XM, Xc, a_left, a_right, minlength_x, mx, nx, p, x, msg, e, Xc_minus, X1, method, Cz
15 | # Function calls: real, corrmtx, nargchk, getString, min, strcmp, issparse, nargin, length, abs, isempty, error, arparest, message, round, size
16 | #%ARPAREST AR parameter estimation via a specified method.
17 | #% A = ARPAREST(X,ORDER,METHOD) returns the polynomial A corresponding to
18 | #% the AR parametric signal model estimate of vector X using the specified
19 | #% METHOD. ORDER is the model order of the AR system.
20 | #%
21 | #% Supported methods are: 'covariance' and 'modified' although all of the
22 | #% methods of CORRMTX will work. In particular if 'autocorrelation' is
23 | #% used, the results should be the same as those of ARYULE (but slower).
24 | #%
25 | #% [A,E] = ARPAREST(...) returns the variance estimate E of the white noise
26 | #% input to the AR model.
27 | #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION,
28 | #% Prentice-Hall, 1988, Chapter 7
29 | #% S. Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATION,
30 | #% Prentice-Hall, 1987, Chapter 8.
31 | #% P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS,
32 | #% Prentice-Hall, 1997, Chapter 3
33 | #% Author(s): R. Losada and P. Pacheco
34 | #% Copyright 1988-2004 The MathWorks, Inc.
35 | #% $Revision: 1.5.4.3 $ $Date: 2011/05/13 18:13:56 $
36 | matcompat.error(nargchk(3., 3., nargin, 'struct'))
37 | [mx, nx] = matcompat.size(x)
38 | #% Initialize in case we return early
39 | a = np.array([])
40 | e = np.array([])
41 | #% Assign msg in case there are no errors
42 | msg = \'
43 | msgobj = np.array([])
44 | #% Set up necessary but not sufficient conditions for the correlation
45 | #% matrix to be nonsingular. From (Marple)
46 | _switch_val=method
47 | if False: # switch
48 | pass
49 | elif _switch_val == 'covariance':
50 | minlength_x = 2.*p
51 | elif _switch_val == 'modified':
52 | minlength_x = 3.*p/2.
53 | else:
54 | msgobj = message('signal:arparest:UnknMethod')
55 | msg = getString(msgobj)
56 | return []
57 |
58 | #% Do some data sanity testing
59 | if isempty(x) or length(x) 1.:
60 | if strcmp(method, 'modified'):
61 | msgobj = message('signal:arparest:TooSmallForModel', 'X', '3/2')
62 | msg = getString(msgobj)
63 | else:
64 | msgobj = message('signal:arparest:TooSmallForModel', 'X', '2')
65 | msg = getString(msgobj)
66 |
67 |
68 | return []
69 |
70 |
71 | if issparse(x):
72 | msgobj = message('signal:arparest:InputSignalCannotBeSparse')
73 | msg = getString(msgobj)
74 | return []
75 |
76 |
77 | if isempty(p) or p != np.round(p):
78 | msgobj = message('signal:arparest:ModelOrderMustBeInteger')
79 | msg = getString(msgobj)
80 | return []
81 |
82 |
83 | x = x.flatten(1)
84 | #% Generate the appropriate data matrix
85 | XM = corrmtx(x, p, method)
86 | Xc = XM[:,1:]
87 | X1 = XM[:,0]
88 | #% Coefficients estimated via the covariance method
89 | a_left = np.array(np.hstack((1.)))
90 | Xc_minus = -Xc
91 | a_right = linalg.solve(Xc_minus, X1)
92 | a = np.array(np.vstack((np.hstack((a_left)), np.hstack((a_right)))))
93 | #%a = [1; -Xc\X1];
94 | #% Estimate the input white noise variance
95 | Cz = np.dot(X1.conj().T, Xc)
96 | e = np.dot(X1.conj().T, X1)+np.dot(Cz, a[1:])
97 | #% Ignore the possible imaginary part due to numerical errors and force
98 | #% the variance estimate of the white noise to be positive
99 | e = np.abs(np.real(e))
100 | a = a.flatten(0)
101 | #% By convention all polynomials are row vectors
102 | #% [EOF] arparest.m
103 | return [a, e, msg, msgobj]
--------------------------------------------------------------------------------
/src/by_hand_code/lms.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """ LMS adaptive filters """
3 | from __future__ import print_function, division
4 | __author__ = 'Richard Lindsley'
5 |
6 | import sys
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 | import convm
10 |
11 | def lms(x, d, p, mu, w0=None):
12 | """ Finds the LMS adaptive filter w based on the inputs
13 |
14 | Adapted from the Hayes MATLAB code.
15 |
16 | Inputs:
17 | x: input data to the filter, Nx1 vector
18 | d: desired output signal, Nx1 vector
19 | p: filter order
20 | mu: step size, scalar or Nx1 vector
21 | w0: initial guess (optional)
22 |
23 | Outputs:
24 | w: filter coefficient matrix: w[n,p] where
25 | n is the time index and
26 | p is the filter tap index
27 | e: error sequence e(n): Nx1 vector
28 |
29 | """
30 | # Initialize
31 | N = len(x)
32 | X = convm.convm(x, p)
33 | if not w0:
34 | w0 = np.zeros(p)
35 | # Promote mu to be a vector if it's not already
36 | if not isinstance(mu, np.ndarray):
37 | mu = np.ones(N) * mu
38 | w = np.zeros((N,p))
39 | e = np.zeros(N)
40 | w[0,:] = w0
41 |
42 | # Run the filter
43 | for n in xrange(N-1):
44 | y = np.dot(w[n,:], X[n,:])
45 | e[n] = d[n] - y
46 | w[n+1,:] = w[n,:] + mu[n] * e[n] * X[n,:].conj()
47 |
48 | return w, e
49 |
50 | def nlms(x, d, p, beta, w0=None, verbose=False):
51 | """ Finds the NLMS adaptive filter w based on the inputs
52 |
53 | Adapted from the Hayes MATLAB code.
54 |
55 | Inputs:
56 | x: input data to the filter, Nx1 vector
57 | d: desired output signal, Nx1 vector
58 | p: filter order
59 | beta: normalized step size (0 < beta < 2)
60 | w0: initial guess (optional)
61 | verbose: verbosity flag
62 |
63 | Outputs:
64 | w: filter coefficient matrix: w[n,p] where
65 | n is the time index and
66 | p is the filter tap index
67 | e: error sequence e(n): Nx1 vector
68 |
69 | """
70 | # Initialize
71 | N = len(x)
72 | eps = 1e-4 # epsilon for denominator
73 | X = convm.convm(x, p)
74 | if not w0:
75 | w0 = np.zeros(p)
76 | w = np.zeros((N,p))
77 | e = np.zeros(N)
78 | w[0,:] = w0
79 | if verbose:
80 | print(' ')
81 |
82 | # Run the filter
83 | for n in xrange(N-1):
84 | if verbose and n % 10000 == 0:
85 | print(' {}/{}\r'.format(n,N-1), end='')
86 | sys.stdout.flush()
87 | y = np.dot(w[n,:], X[n,:])
88 | e[n] = d[n] - y
89 | norm = eps + np.dot(X[n,:], X[n,:].T.conj())
90 | w[n+1,:] = w[n,:] + beta / norm * e[n] * X[n,:].conj()
91 |
92 | if verbose:
93 | print(' ')
94 | return w, e
95 |
96 | def plot_traj(w, w_true, fname=None):
97 | """ Plot the trajectory of the filter coefficients
98 |
99 | Inputs:
100 | w: matrix of filter weights versus time
101 | w_true: vector of true filter weights
102 | fname: what filename to export the figure to. If None, then doesn't
103 | export
104 |
105 | """
106 | plt.figure()
107 | n = np.arange(w.shape[0])
108 | n_ones = np.ones(w.shape[0])
109 | plt.hold(True)
110 | # NOTE: This construction places a limit of 4 on the filter order
111 | plt_colors = ['b', 'r', 'g', 'k']
112 | for p in xrange(w.shape[1]):
113 | plt.plot(n, w[:,p], '{}-'.format(plt_colors[p]), label='w({})'.format(p))
114 | plt.plot(n, w_true[p] * n_ones, '{}--'.format(plt_colors[p]))
115 | plt.xlabel('Iteration')
116 | plt.ylabel('Coefficients')
117 | plt.legend()
118 | if fname:
119 | plt.savefig(fname)
120 | plt.close()
121 |
122 | def plot_error(e, fname=None):
123 | """ Plot the squared error versus time
124 |
125 | Inputs:
126 | e: vector of the error versus time
127 | fname: what filename to export the figure to. If None, then doesn't
128 | export
129 |
130 | """
131 | plt.figure()
132 | n = np.arange(len(e))
133 | e2 = np.power(e, 2)
134 | plt.plot(n, e2)
135 | #plt.semilogy(n, e2)
136 | plt.xlabel('Iteration')
137 | plt.ylabel('Squared error')
138 | if fname:
139 | plt.savefig(fname)
140 | plt.close()
141 |
--------------------------------------------------------------------------------
/src/aryule.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 20:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file pretends to imitate the behaviour of the MATLAB function aryule
9 |
10 | Using spectrum implementation:
11 | http://thomas-cokelaer.info/software/spectrum/html/user/ref_param.html#spectrum.yulewalker.aryule
12 |
13 | """
14 | import numpy as np
15 | import spectrum
16 |
17 | def aryule(x, p):
18 | """From MATLAB:
19 | % A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR
20 | % parametric signal model estimate of vector X using the Yule-Walker
21 | % (autocorrelation) method. ORDER is the model order of the AR system.
22 | % This method solves the Yule-Walker equations by means of the Levinson-
23 | % Durbin recursion.
24 | %
25 | % [A,E] = ARYULE(...) returns the final prediction error E (the variance
26 | % estimate of the white noise input to the AR model).
27 | %
28 | % [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients.
29 |
30 | Using spectrum aryule:
31 | def aryule(X, order, norm='biased', allow_singularity=True):
32 | Compute AR coefficients using Yule-Walker method
33 |
34 | :param X: Array of complex data values, X(1) to X(N)
35 | :param int order: Order of autoregressive process to be fitted (integer)
36 | :param str norm: Use a biased or unbiased correlation.
37 | :param bool allow_singularity:
38 |
39 | :return:
40 | * AR coefficients (complex)
41 | * variance of white noise (Real)
42 | * reflection coefficients for use in lattice filter
43 | """
44 | [A, E, K] = spectrum.aryule(x, p)
45 | A = np.hstack((1, A)) # MATLAB adds the first "1.0"
46 | return A, E, K
47 |
48 | # Local Variables: a, e, k, nx, p, R, x, mx
49 | # Function calls: aryule, nargchk, min, issparse, nargin, length, isempty, error, levinson, message, xcorr, round, size
50 | #%ARYULE AR parameter estimation via Yule-Walker method.
51 | #% A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR
52 | #% parametric signal model estimate of vector X using the Yule-Walker
53 | #% (autocorrelation) method. ORDER is the model order of the AR system.
54 | #% This method solves the Yule-Walker equations by means of the Levinson-
55 | #% Durbin recursion.
56 | #%
57 | #% [A,E] = ARYULE(...) returns the final prediction error E (the variance
58 | #% estimate of the white noise input to the AR model).
59 | #%
60 | #% [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients.
61 | #%
62 | #% % Example:
63 | #% % Estimate model order using decay of reflection coefficients.
64 | #%
65 | #% rng default;
66 | #% y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1));
67 | #%
68 | #% % Create AR(2) process
69 | #% [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10);
70 | #%
71 | #% % Fit AR(10) model
72 | #% stem(reflect_coeffs); axis([-0.05 10.5 -1 1]);
73 | #% title('Reflection Coefficients by Lag'); xlabel('Lag');
74 | #% ylabel('Reflection Coefficent');
75 | #%
76 | #% See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY.
77 | #% Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed.
78 | #% Macmillan, 1988, Chapter 5
79 | #% M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING,
80 | #% John Wiley & Sons, 1996, Chapter 8
81 | #% Author(s): R. Losada
82 | #% Copyright 1988-2004 The MathWorks, Inc.
83 | #% $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $
84 | # matcompat.error(nargchk(2., 2., nargin, 'struct'))
85 | # #% Check the input data type. Single precision is not supported.
86 | # #%try
87 | # #% chkinputdatatype(x,p);
88 | # #%catch ME
89 | # #% throwAsCaller(ME);
90 | # #%end
91 | # [mx, nx] = matcompat.size(x)
92 | # if isempty(x) or length(x) 1.:
93 | # matcompat.error(message('signal:aryule:InvalidDimensions'))
94 | # elif isempty(p) or not p == np.round(p):
95 | # matcompat.error(message('signal:aryule:MustBeInteger'))
96 | #
97 | #
98 | # if issparse(x):
99 | # matcompat.error(message('signal:aryule:Sparse'))
100 | #
101 | #
102 | # R = plt.xcorr(x, p, 'biased')
103 | # [a, e, k] = levinson(R[int(p+1.)-1:], p)
104 | # return [a, e, k]
--------------------------------------------------------------------------------
/src/by_hand_code/stmbc.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Sun Nov 17 12:30:46 2013
5 |
6 | @author: Sammy Pfeiffer
7 | This file pretends to imitate the behaviour of the MATLAB function with the same name.
8 | """
9 |
10 | from prony_matlab import prony_matlab
11 | from convmtx import convmtx
12 | from scipy.signal import lfilter
13 | import numpy as np
14 |
15 | def stmcb(x, u_in=None, q=None, p=None, niter=5, a_in=None):
16 | """
17 | %STMCB Compute linear model via Steiglitz-McBride iteration
18 | [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
19 | B(z)/A(z) with approximate impulse response H, NA poles and
20 | NB zeros.
21 |
22 | [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
23 |
24 | [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
25 | guess at the denominator coefficients. If you don't specify Ai,
26 | STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
27 |
28 | [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
29 | A of the system which, given X as input, has Y as output. N and Ai
30 | are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
31 | Y and X must be the same length.
32 |
33 | % Example:
34 | % Approximate the impulse response of a Butterworth filter with a
35 | % system of lower order.
36 |
37 | [b,a] = butter(6,0.2); % Butterworth filter design
38 | h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
39 | freqz(b,a,128) % Frequency response
40 | [bb,aa] = stmcb(h,4,4);
41 | figure; freqz(bb,aa,128)
42 |
43 | See also PRONY, LEVINSON, LPC, ARYULE.
44 |
45 | Author(s): Jim McClellan, 2-89
46 | T. Krauss, 4-22-93, new help and options
47 | Copyright 1988-2004 The MathWorks, Inc.
48 | $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
49 | """
50 |
51 | #error(nargchk(3,6,nargin,'struct'))
52 |
53 | #TODO: fit the full definition of the function
54 | # if length(u_in) == 1,
55 | # if nargin == 3,
56 | # niter = 5; p = q; q = u_in;
57 | # a_in = prony(x,0,p);
58 | # elseif nargin == 4,
59 | # niter = p; p = q; q = u_in;
60 | # a_in = prony(x,0,p);
61 | # elseif nargin == 5,
62 | # a_in = niter; niter = p; p = q; q = u_in;
63 | # end
64 | # u_in = zeros(size(x));
65 | # u_in(1) = 1; % make a unit impulse whose length is same as x
66 | # else
67 | # if length(u_in)~=length(x),
68 | # error(message('signal:stmcb:InvalidDimensions'))
69 | # end
70 | if len(u_in) != len(x):
71 | print "stmbc:"
72 | print "Invalid dimensions on u_in and x, must be of the same size: " + str(len(u_in)) + "!=" + str(len(x))
73 | exit(0)
74 | # if nargin < 6
75 | # [b,a_in] = prony(x,0,p);
76 | # end
77 | if a_in == None:
78 | [b, a_in] = prony_matlab(x, 0, p)
79 | print "p is:"
80 | print p
81 | print "b is: "
82 | print b
83 | print "a_in is:"
84 | print a_in
85 | # if nargin < 5
86 | # niter = 5;
87 | # end
88 | # nargin already initialized as 5 on function definition, check not necessary
89 | # end
90 |
91 |
92 |
93 | # a = a_in;
94 | # N = length(x);
95 | a = a_in
96 | N = len(x)
97 | # for i=1:niter
98 | for i in range(niter):
99 | # u = filter( 1, a, x );
100 | print "a is: " + str(a)
101 | ## MATLAB
102 | # a =
103 | # 1.0000
104 | # -1.9803
105 | # 0.9806
106 | # python a is: 1
107 |
108 | #print "x is: " + str(x)
109 | u = lfilter(1, a, x)
110 | print u
111 | exit(0)
112 | # v = filter( 1, a, u_in );
113 | v = lfilter(1, a, u_in)
114 | # C1 = convmtx(u(:),p+1);
115 | C1 = convmtx(u,p+1)
116 | # C2 = convmtx(v(:),q+1);
117 | C2 = convmtx(v,q+1)
118 | # T = [ -C1(1:N,:) C2(1:N,:) ];
119 | T = np.array([-C1[0:N,:],
120 | C2[0:N,:]])
121 | # c = T(:,2:p+q+2)\(-T(:,1)); % move 1st column to RHS and do least-squares
122 | # Si la matriz no es cuadrada: numpy.linalg.lstsq
123 | # Si la matriz es cuadrada: numpy.linalg.solve
124 | if T.shape[0] != T.shape[1]:
125 | c = np.linalg.lstsq(a, b)
126 |
127 | # a = [1; c(1:p)]; % denominator coefficients
128 | # b = c(p+1:p+q+1); % numerator coefficients
129 | # end
130 | # a=a.';
131 | # b=b.';
132 | a = b = 0
133 | return b, a
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | parametric_modeling
2 | ===================
3 |
4 | Parametric modelling functions that can be found in MATLAB... now in Python!
5 | (AR, ARMA, frequency response modeling)
6 | The idea is to have all the functions listed at: http://www.mathworks.es/es/help/signal/parametric-modeling.html
7 |
8 | Note about license: All the code I wrote is BSD as stated in the LICENSE file. Any commented/inspired by MATLAB code is of their own property. Given this was a project for university I won't dig further into this issue. If you want to re-use this code, you should research under what conditions you can based on that.
9 |
10 | Right now we have:
11 |
12 | * **arburg** Autoregressive (AR) all-pole model parameters estimated using Burg method
13 | * Working thanks to spectrum arburg (http://thomas-cokelaer.info/software/spectrum/html/user/ref_param.html#spectrum.burg.arburg)
14 |
15 | * **arcov** Estimate AR model parameters using covariance method
16 | * Working thanks to spectrum arcovar (http://thomas-cokelaer.info/software/spectrum/html/user/ref_psd_other.html#spectrum.covar.arcovar)
17 |
18 | * **armcov** Estimate AR model parameters using modified covariance method
19 | * Working thanks to spectrum modcovar (http://thomas-cokelaer.info/software/spectrum/html/user/ref_psd_other.html#spectrum.modcovar.modcovar)
20 |
21 | * **aryule** Estimate autoregressive (AR) all-pole model using Yule-Walker method
22 | * Working thanks to spectrum aryule (http://thomas-cokelaer.info/software/spectrum/html/user/ref_param.html#spectrum.yulewalker.aryule)
23 |
24 | * **invfreqs** Identify continuous-time filter parameters from frequency response data
25 | * Working thanks to a file found at http://projects.scipy.org/scipy/attachment/ticket/393/invfreq.py
26 |
27 | * **invfreqz** Identify discrete-time filter parameters from frequency response data
28 | * Not working :( whenever polystab function in spectrum is implemented this file can be finalized easily (it's nearly done!) Note that I found a maybe working implementation here: https://github.com/yurochka/dsptools/blob/master/dsptools/invfreqz.py
29 |
30 | * **prony** Prony method for filter design
31 | * Working thanks to... me!
32 |
33 | * **stmcb** Compute linear model using Steiglitz-McBride iteration
34 | * Working thanks to... me!
35 |
36 | Also I needed to implement:
37 |
38 | * **convmtx** Convolution matrix
39 | * Working thanks to... me!
40 |
41 |
42 | ===================
43 |
44 | Developed using **Python 2.7, Eclipse + PyDev, MATLAB R2013a 64 bits**
45 |
46 | * Using **numpy 1.6.1** (from ubuntu debs, using Ubuntu 12.04 64 bit)
47 | ```
48 | sudo apt-get install numpy
49 | ```
50 |
51 | * Using **scipy 0.13.1** (upgraded it from Ubuntu debs as I needed newer functions and some bugfixes)
52 | ```
53 | sudo pip install scipy
54 | ```
55 |
56 | * Using **spectrum 0.5.6** https://pypi.python.org/pypi/spectrum
57 | ```
58 | sudo pip install spectrum
59 | ```
60 |
61 |
62 | I wanted to use/integrate in: **python_control**, using a checkout of the most updated branch, can be found at:
63 | https://github.com/awesomebytes/python-control-code
64 |
65 | But I don't have time for now.
66 |
67 |
68 | * For testing purposes using **matlabpipe** from **python-mlabwrap**
69 |
70 | This great library lets you **execute MATLAB code from Python** (easily! check the tests xxxxx_matlab_vs_python.py).
71 |
72 | https://github.com/awesomebytes/python-mlabwrap
73 |
74 | This is a fork from the work of Filipe Fernandes which he forked from http://code.google.com/p/danapeerlab/
75 | ```
76 | git clone https://github.com/awesomebytes/python-mlabwrap
77 | cd python-mlwrap
78 | sudo python setup.py install
79 | ```
80 |
81 | Thanks to this tool I can test the behaviour of my functions versus the MATLAB functions
82 | and also give the same input data without needing to implement lots of other functions.
83 |
84 | * Also another incredible tool is **libermate** http://libermate.sourceforge.net/
85 |
86 | **A MATLAB to Python code translator** which doesn't do all the job but helps
87 |
88 | I've rehosted it now in Github https://github.com/awesomebytes/libermate to give it more visibility and
89 | add it's README to it and my advice on how to use it if you ever want to translate a MATLAB script to Python.
90 |
91 | Guide on How to translate a MATLAB file to Python
92 | ====================
93 |
94 | Note: I haven't tried it, but you may want to try: https://github.com/victorlei/smop for the automatic MATLAB->Python translation
95 |
96 | 1) Use libermate for making a quick automatic translation
97 |
98 | python libermate.py ~/my_path_to/my_matlab_script.m
99 |
100 | If you have problems check my file: https://github.com/awesomebytes/libermate/blob/master/notes_on_using_libermate.txt
101 |
102 | 2) Correct other errors (many mentioned in notes_on_using_libermate.txt), use http://wiki.scipy.org/NumPy_for_Matlab_Users for helping yourself
103 |
104 | 3) Check little pieces of code executing in MATLAB the same line using https://github.com/awesomebytes/python-mlabwrap Use any of my test files as an example on how to execute code and recover variables (structs and cells have some problems).
105 |
106 | 4) Keep a iPython open to check little doubts (numpy arrays don't behave the same as MATLAB matrices)
107 |
108 | 5) Use some IDE on Python to ease your life looking at how to use functions and correcting coding errors, I recomend Eclipse + PyDev
109 |
110 | Eclipse (Standard 4.3.1 as of writing) http://www.eclipse.org/downloads/
111 |
112 | PyDev plugin (Instructions on how to install) http://pydev.org/manual_101_install.html
113 |
114 | You may need to update Java, here you have a nice tutorial on that: http://www.webupd8.org/2012/01/install-oracle-java-jdk-7-in-ubuntu-via.html
115 |
116 |
--------------------------------------------------------------------------------
/src/stmcb.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 20:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file imitates the behaviour of stmcb of MatlabTM
9 |
10 | """
11 | import numpy as np
12 | from scipy.linalg import solve, lstsq
13 | from scipy.signal import lfilter
14 | from convmtx import convmtx
15 | from prony import prony
16 |
17 |
18 | # def printInfo(name, thing_to_print):
19 | # print name + " is: ", thing_to_print
20 | # print name + " shape is:", thing_to_print.shape
21 |
22 | #def stmcb(x, u_in=None, q=None, p=None, niter=5, a_in=None): # Old definition
23 | #function [b,a] = stmcb_test( x, u_in, q, p, niter, a_in ) # matlab definition
24 | def stmcb(*args):
25 | """From MATLAB:
26 | %STMCB Compute linear model via Steiglitz-McBride iteration
27 | % [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
28 | % B(z)/A(z) with approximate impulse response H, NA poles and
29 | % NB zeros.
30 | %
31 | % [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
32 | %
33 | % [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
34 | % guess at the denominator coefficients. If you don't specify Ai,
35 | % STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
36 | %
37 | % [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
38 | % A of the system which, given X as input, has Y as output. N and Ai
39 | % are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
40 | % Y and X must be the same length.
41 | """
42 |
43 | # Local Variables: T_sub2, T_sub1, T_minus, C2, C1, a_in, N, u_in, T, a, niter, c, b, i, q, p, u, v, x, T_left, T_right, C1_minus
44 | # Function calls: convmtx, filter, prony, nargchk, stmcb, nargin, length, zeros, error, message, size
45 | #%STMCB Compute linear model via Steiglitz-McBride iteration
46 | #% [B,A] = stmcb(H,NB,NA) finds the coefficients of the system
47 | #% B(z)/A(z) with approximate impulse response H, NA poles and
48 | #% NB zeros.
49 | #%
50 | #% [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5.
51 | #%
52 | #% [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial
53 | #% guess at the denominator coefficients. If you don't specify Ai,
54 | #% STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions.
55 | #%
56 | #% [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and
57 | #% A of the system which, given X as input, has Y as output. N and Ai
58 | #% are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA).
59 | #% Y and X must be the same length.
60 | #%
61 | #% % Example:
62 | #% % Approximate the impulse response of a Butterworth filter with a
63 | #% % system of lower order.
64 | #%
65 | #% [b,a] = butter(6,0.2); % Butterworth filter design
66 | #% h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter
67 | #% freqz(b,a,128) % Frequency response
68 | #% [bb,aa] = stmcb(h,4,4);
69 | #% figure; freqz(bb,aa,128)
70 | #%
71 | #% See also PRONY, LEVINSON, LPC, ARYULE.
72 | #% Author(s): Jim McClellan, 2-89
73 | #% T. Krauss, 4-22-93, new help and options
74 | #% Copyright 1988-2004 The MathWorks, Inc.
75 | #% $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $
76 | #matcompat.error(nargchk(3, 6, nargin, 'struct'))
77 | x = args[0]
78 | # Default assignments
79 | u_in = args[1]
80 | q = args[2]
81 | if len(args) >= 4:
82 | p = args[3]
83 | if type(u_in) == type(1):
84 | if len(args) == 3:
85 | niter = 5
86 | p = args[2]
87 | q = args[1]
88 | [a_in, tmp] = prony(x, 0, p) # In Python there is no way to just get one of the two items returned
89 |
90 | elif len(args) == 4:
91 | niter = args[3]
92 | p = args[2]
93 | q = u_in
94 | [a_in, tmp] = prony(x, 0, p)
95 |
96 | elif len(args) == 5:
97 | a_in = args[4]
98 | niter = args[3]
99 | p = args[2]
100 | q = u_in
101 |
102 | u_in = np.zeros(len(x))
103 | u_in[0] = 1.
104 | #% make a unit impulse whose length is same as x
105 | else:
106 | if len(u_in) != len(x):
107 | print "stmcb:"
108 | print "Invalid dimensions on u_in and x, must be of the same size: " + str(len(u_in)) + "!=" + str(len(x))
109 | exit(0)
110 |
111 | if len(args) < 6:
112 | [b, a_in] = prony(x, 0, args[3])
113 |
114 | if len(args) < 5:
115 | niter = 5
116 |
117 |
118 | a = a_in
119 | N = len(x)
120 | for i in range(niter):
121 | u = lfilter([1], a, x)
122 | v = lfilter([1], a, u_in)
123 | C1 = convmtx(u, (p+1))
124 | C2 = convmtx(v, (q+1))
125 | T_left = -C1[0:N,:]
126 | T_right = C2[0:N,:]
127 | T = np.hstack((T_left, T_right))
128 | #%T = [ C1_minus(1:N,:) C2(1:N,:) ];
129 | T_minus = -T
130 | T_left = T[:,1:p+q+2]
131 | T_right = T_minus[:,0]
132 | # If not squared matrix: numpy.linalg.lstsq
133 | # If squared matrix: numpy.linalg.solve
134 | if T.shape[0] != T.shape[1]:
135 | [c, residuals, rank, singular_values] = lstsq(T_left, T_right) # lstsq in python returns more stuff
136 | else:
137 | c = solve(T_left, T_right)
138 | #% c = T(:,2:p+q+2)\(T_minus(:,1)); % move 1st column to RHS and do least-squares
139 | a_left = np.array([1])
140 | a_right = c[:p]
141 | a = np.hstack((a_left, a_right))
142 | #% denominator coefficients
143 | b = c[p:p+q+1]
144 | #% numerator coefficients
145 | a = a.T
146 | b = b.T
147 | return [b, a]
--------------------------------------------------------------------------------
/src/convmtx.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 21:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file pretends to imitate the behavior of the MATLAB function convmtx
9 |
10 | """
11 |
12 | import numpy as np
13 | from scipy.linalg import toeplitz
14 |
15 | def convmtx(v, n):
16 | """From MATLAB:
17 | %CONVMTX Convolution matrix.
18 | % CONVMTX(C,N) returns the convolution matrix for vector C.
19 | % If C is a column vector and X is a column vector of length N,
20 | % then CONVMTX(C,N)*X is the same as CONV(C,X).
21 | % If R is a row vector and X is a row vector of length N,
22 | % then X*CONVMTX(R,N) is the same as CONV(R,X).
23 | """
24 | # Local Variables: cidx, c, x_left, ridx, m, n, x_right, mv, t, v, x, r, nv
25 | # Function calls: convmtx, length, ones, zeros, size, toeplitz
26 | #%CONVMTX Convolution matrix.
27 | #% CONVMTX(C,N) returns the convolution matrix for vector C.
28 | #% If C is a column vector and X is a column vector of length N,
29 | #% then CONVMTX(C,N)*X is the same as CONV(C,X).
30 | #% If R is a row vector and X is a row vector of length N,
31 | #% then X*CONVMTX(R,N) is the same as CONV(R,X).
32 | #%
33 | #% % Example:
34 | #% % Generate a simple convolution matrix.
35 | #%
36 | #% h = [1 2 3 2 1];
37 | #% convmtx(h,7) % Convolution matrix
38 | #%
39 | #% See also CONV.
40 | #% Author(s): L. Shure, 47-88
41 | #% T. Krauss, 3-30-93, removed dependence on toeplitz
42 | #% Copyright 1988-2004 The MathWorks, Inc.
43 | #% $Revision: 1.6.4.3 $ $Date: 2012/10/29 19:30:54 $
44 | try:
45 | [nv, mv] = v.shape # if its vertical, shape will return 2 values, rows and cols
46 | except ValueError: # if its horizontal only len value will be available
47 | mv = len(v)
48 | nv = 1
49 | v = v.flatten(1)
50 |
51 | #c = np.vstack((v, np.zeros(n-1)))
52 | c = np.hstack((v, np.zeros((n-1))))
53 | r = np.zeros(n)
54 | m = len(c)
55 | x_left = r[n:0:-1] # reverse order from n to 2 in original code
56 | x_right = c.flatten(1)
57 | x = np.hstack((x_left, x_right))
58 | #%x = [r(n:-1:2) ; c(:)]; % build vector of user data
59 | cidx = np.arange(0., (m-1.)+1).conj().T
60 | ridx = np.arange(n, (1.)+(-1.), -1.)
61 |
62 | t = np.zeros([len(cidx),len(ridx)])
63 | counter_cidx = 0
64 | for c_val in cidx:
65 | counter_ridx = 0
66 | for r_val in ridx:
67 | t[counter_cidx, counter_ridx] = c_val + r_val
68 | counter_ridx += 1
69 | counter_cidx += 1
70 | #t = cidx[:,int(np.ones(n))-1] + ridx[int(np.ones(m))-1,:] # that double loop should do this...
71 | #% Toeplitz subscripts
72 |
73 | t[:] = x[t.astype(int)-1]
74 | #% actual data
75 | #% end of toeplitz code
76 |
77 | if mv> h = [1 2 3 2 1];
145 | # >> convmtx(h,7)
146 | #
147 | # ans =
148 | #
149 | # 1 2 3 2 1 0 0 0 0 0 0
150 | # 0 1 2 3 2 1 0 0 0 0 0
151 | # 0 0 1 2 3 2 1 0 0 0 0
152 | # 0 0 0 1 2 3 2 1 0 0 0
153 | # 0 0 0 0 1 2 3 2 1 0 0
154 | # 0 0 0 0 0 1 2 3 2 1 0
155 | # 0 0 0 0 0 0 1 2 3 2 1
156 | ## PYTHON OUTPUT:
157 | # array([[ 1., 2., 3., 2., 1., 0., 0., 0., 0., 0., 0.],
158 | # [ 0., 1., 2., 3., 2., 1., 0., 0., 0., 0., 0.],
159 | # [ 0., 0., 1., 2., 3., 2., 1., 0., 0., 0., 0.],
160 | # [ 0., 0., 0., 1., 2., 3., 2., 1., 0., 0., 0.],
161 | # [ 0., 0., 0., 0., 1., 2., 3., 2., 1., 0., 0.],
162 |
163 |
164 |
165 | if __name__ == '__main__':
166 | main()
167 |
168 |
--------------------------------------------------------------------------------
/src/arburg.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Created on Jan 22 20:38 2014
5 |
6 | @author: Sammy Pfeiffer
7 | @email: sammypfeiffer@gmail.com
8 | This file pretends to imitate the behaviour of the MATLAB function arburg
9 |
10 | This function can't be tested as the main MATLAB functions isn't even working,
11 | gives:
12 |
13 | Undefined function 'chkinputdatatype' for input arguments of type 'double'.
14 |
15 | But there is still a python version from which we can get it's functionality
16 | http://thomas-cokelaer.info/software/spectrum/html/user/ref_param.html#spectrum.burg.arburg
17 |
18 | """
19 |
20 | import spectrum
21 | import numpy as np
22 |
23 | #def arburg(x, p): # original def
24 | def arburg(*args):
25 | """From MATLAB:
26 |
27 | %ARBURG AR parameter estimation via Burg method.
28 | % A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR
29 | % parametric signal model estimate of vector X using Burg's method.
30 | % ORDER is the model order of the AR system.
31 | %
32 | % [A,E] = ARBURG(...) returns the final prediction error E (the variance
33 | % estimate of the white noise input to the AR model).
34 | %
35 | % [A,E,K] = ARBURG(...) returns the vector K of reflection
36 | % coefficients (parcor coefficients).
37 |
38 | Using spectrum arburg:
39 | def arburg(X, order, criteria=None):
40 | Estimate the complex autoregressive parameters by the Burg algorithm.
41 |
42 | .. math:: x(n) = \sqrt{(v}) e(n) + \sum_{k=1}^{P+1} a(k) x(n-k)
43 |
44 | :param x: Array of complex data samples (length N)
45 | :param order: Order of autoregressive process (0= 2:
160 | # varargout.append( E[int(0)-1])
161 | #
162 | #
163 | # if len(args) >= 3:
164 | # varargout.append( k.flatten(1))
165 | #
166 | #
167 | # return [varargout]
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/matlab_test_files/invfreqz.m:
--------------------------------------------------------------------------------
1 | function [b,a]=invfreqz(g,w,varargin)
2 | %INVFREQZ Discrete filter least squares fit to frequency response data.
3 | % [B,A] = INVFREQZ(H,W,NB,NA) gives real numerator and denominator
4 | % coefficients B and A of orders NB and NA respectively, where
5 | % H is the desired complex frequency response of the system at frequency
6 | % points W, and W contains the normalized frequency values within the
7 | % interval [0, Pi] (W is in units of radians/sample).
8 | %
9 | % INVFREQZ yields a filter with real coefficients. This means that it is
10 | % sufficient to specify positive frequencies only; the filter fits the data
11 | % conj(H) at -W, ensuring the proper frequency domain symmetry for a real
12 | % filter.
13 | %
14 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt) allows the fit-errors to be weighted
15 | % versus frequency. LENGTH(Wt)=LENGTH(W)=LENGTH(H).
16 | % Determined by minimization of sum |B-H*A|^2*Wt over the freqs in W.
17 | %
18 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER) does another type of fit:
19 | % Sum |B/A-H|^2*Wt is minimized with respect to the coefficients in B and
20 | % A by numerical search in at most ITER iterations. The A-polynomial is
21 | % then constrained to be stable. [B,A]=INVFREQZ(H,W,NB,NA,Wt,ITER,TOL)
22 | % stops the iterations when the norm of the gradient is less than TOL.
23 | % The default value of TOL is 0.01. The default value of Wt is all ones.
24 | % This default value is also obtained by Wt=[].
25 | %
26 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER,TOL,'trace') provides a textual
27 | % progress report of the iteration.
28 | %
29 | % [B,A] = INVFREQZ(H,W,'complex',NB,NA,...) creates a complex filter. In
30 | % this case, no symmetry is enforced and W contains normalized frequency
31 | % values within the interval [-Pi, Pi].
32 | %
33 | % % Example:
34 | % % Convert a simple transfer function to frequency response data and
35 | % % then back to the original filter coefficients. If the system is
36 | % % unstable, use invfreqs's iterative algorithm to find a stable
37 | % % approximation to the system.
38 | %
39 | % b = [1 2 3 2 3]; % Numerator coefficients
40 | % a = [1 2 3 2 1 4]; % Denominator coefficients
41 | % [h,w] = freqz(b,a,64);
42 | % [bb,aa] = invfreqz(h,w,4,5) % aa has poles in the right half-plane.
43 | % [z,p,k] = tf2zp(bb,aa); % Get Zero-Pole form
44 | % fprintf('Stable Approximation to the system:')
45 | % [bbb,aaa] = invfreqz(h,w,4,5,[],30) % Stable approximation to system
46 | % subplot(2,1,1); zplane(bb,aa); title('PZ plot - Unstable system')
47 | % subplot(2,1,2); zplane(bbb,aaa); title('PZ plot of stable system')
48 | %
49 | % See also FREQZ, FREQS, INVFREQS.
50 |
51 | % Author(s): J.O. Smith and J.N. Little, 4-23-86
52 | % J.N. Little, 4-27-88, revised
53 | % Lennart Ljung, 9-21-92, rewritten
54 | % T. Krauss, 10-19-92, trace mode made optional
55 | % Copyright 1988-2004 The MathWorks, Inc.
56 | % $Revision: 1.8.4.8 $ $Date: 2012/10/29 19:31:23 $
57 |
58 | % calling sequence is
59 | %function [b,a]=invfreqz(g,w,nb,na,wf,maxiter,tol,pf)
60 | % OR
61 | %function [b,a]=invfreqz(g,w,'complex',nb,na,wf,maxiter,tol,pf)
62 | error(nargchk(4,9,nargin,'struct'))
63 | if ischar(varargin{1})
64 | realStr = lower(varargin{1});
65 | varargin(1) = [];
66 | else
67 | realStr = 'real';
68 | end
69 | gaussFlag = length(varargin)>3; % run Gauss-Newton algorithm or not?
70 | if length(varargin)<6
71 | varargin{6} = []; % pad varargin with []'s
72 | end
73 | [nb,na,wf,maxiter,tol,pf] = deal(varargin{:});
74 |
75 | switch realStr
76 | case 'real'
77 | realFlag = 1;
78 | case 'complex'
79 | realFlag = 0;
80 | otherwise
81 | warning(message('signal:invfreqz:InvalidParam', realStr));
82 | realFlag = 0;
83 | end
84 |
85 | nk=0;T=1; % The code is prepared for arbitrary sampling interval T and for
86 | % constraining the numerator to begin with nk zeros.
87 |
88 | nb=nb+nk+1;
89 | if isempty(pf)
90 | verb=0;
91 | elseif (strcmp(pf,'trace')),
92 | verb=1;
93 | else
94 | error(message('signal:invfreqz:NotSupported', pf));
95 | end
96 | if isempty(wf),wf=ones(length(w),1);end
97 | wf=sqrt(wf);
98 |
99 | if length(g)~=length(w),error(message('signal:invfreqz:InvalidDimensions', 'H', 'W')),end
100 | if length(wf)~=length(w),error(message('signal:invfreqz:InvalidDimensions', 'Wt', 'W')),end
101 | if any( (w>pi) | (w<0) ) && realFlag
102 | warning(message('signal:invfreqz:InvalidRegion', 'W', 'INVFREQZ', '''complex'''))
103 | end
104 | [rw,cw]=size(w); if rw>cw, w=w'; end
105 | [rg,cg]=size(g); if cg>rg, g=g.'; end
106 | [rwf,cwf]=size(wf); if cwf>rwf, wf=wf'; end
107 |
108 | nm=max(na,nb+nk-1);
109 | OM=exp(-1i*(0:nm)'*w*T);
110 |
111 | %
112 | % Estimation in the least squares case:
113 | %
114 | Dva=(OM(2:na+1,:).').*(g*ones(1,na));
115 | Dvb=-(OM(nk+1:nk+nb,:).');
116 | D=[Dva Dvb].*(wf*ones(1,na+nb));
117 | if realFlag
118 | R=real(D'*D);
119 | Vd=real(D'*(-g.*wf));
120 | else
121 | R=D'*D;
122 | Vd=D'*(-g.*wf);
123 | end
124 | th=R\Vd;
125 | a=[1 th(1:na).'];b=[zeros(1,nk) th(na+1:na+nb).'];
126 |
127 | if ~gaussFlag,return,end
128 |
129 | % Now for the iterative minimization
130 | if isempty(maxiter), maxiter = 30; end
131 |
132 | if isempty(tol)
133 | tol = 0.01;
134 | end
135 | indb=1:length(b);indg=1:length(a);
136 | a=polystab(a); % Stabilizing the denominator
137 |
138 | % The initial estimate:
139 |
140 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
141 | e=(GC-g).*wf;
142 | Vcap=e'*e; t=[a(2:na+1) b(nk+1:nk+nb)].';
143 | if (verb),
144 | %messages similar to invfreqs
145 | clc, disp([' ' getString(message('signal:invfreqs:INITIALESTIMATE'))]);
146 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(Vcap)])
147 | disp(getString(message('signal:invfreqs:Parvector')));
148 | disp(t)
149 | end;
150 |
151 | %
152 | % ** the minimization loop **
153 | %
154 | gndir=2*tol+1;l=0;st=0;
155 | while all([norm(gndir)>tol l Vcap ll<20])
180 |
181 | t1=t-k*gndir; if ll==19,t1=t;end
182 | a=polystab([1 t1(1:na).']);
183 | t1(1:na)=a(2:na+1).'; %Stabilizing denominator
184 | b=[zeros(1,nk) t1(na+1:na+nb).'];
185 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
186 | V1=((GC-g).*wf)'*((GC-g).*wf); t1=[a(2:na+1) b(nk+1:nk+nb)].';
187 | if (verb),
188 | home, disp(int2str(ll))
189 | end;
190 | k=k/2;
191 | ll=ll+1; if ll==20, st=1;end
192 | if ll==10,gndir=Vd/norm(R)*length(R);k=1;end
193 | end
194 |
195 | if (verb),
196 | home
197 | disp([' ' getString(message('signal:invfreqs:ITERATION')) ' ' int2str(l)])
198 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(V1) ' ' getString(message('signal:invfreqs:PreviousFit')) ' ' num2str(Vcap)])
199 | disp(getString(message('signal:invfreqs:CurrentParPrevparGNdir')));
200 | disp([t1 t gndir])
201 | disp([getString(message('signal:invfreqs:NormOfGNvector')) ' ' num2str(norm(gndir))])
202 | if st==1,
203 | disp(getString(message('signal:invfreqs:NoImprovement'))),
204 | disp(getString(message('signal:invfreqs:IterationsThereforeTerminated'))),
205 | end
206 | end
207 | t=t1; Vcap=V1;
208 | end
209 |
--------------------------------------------------------------------------------
/matlab_test_files/invfreqz_test.m:
--------------------------------------------------------------------------------
1 | function [b,a]=invfreqz(g,w,varargin)
2 | %INVFREQZ Discrete filter least squares fit to frequency response data.
3 | % [B,A] = INVFREQZ(H,W,NB,NA) gives real numerator and denominator
4 | % coefficients B and A of orders NB and NA respectively, where
5 | % H is the desired complex frequency response of the system at frequency
6 | % points W, and W contains the normalized frequency values within the
7 | % interval [0, Pi] (W is in units of radians/sample).
8 | %
9 | % INVFREQZ yields a filter with real coefficients. This means that it is
10 | % sufficient to specify positive frequencies only; the filter fits the data
11 | % conj(H) at -W, ensuring the proper frequency domain symmetry for a real
12 | % filter.
13 | %
14 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt) allows the fit-errors to be weighted
15 | % versus frequency. LENGTH(Wt)=LENGTH(W)=LENGTH(H).
16 | % Determined by minimization of sum |B-H*A|^2*Wt over the freqs in W.
17 | %
18 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER) does another type of fit:
19 | % Sum |B/A-H|^2*Wt is minimized with respect to the coefficients in B and
20 | % A by numerical search in at most ITER iterations. The A-polynomial is
21 | % then constrained to be stable. [B,A]=INVFREQZ(H,W,NB,NA,Wt,ITER,TOL)
22 | % stops the iterations when the norm of the gradient is less than TOL.
23 | % The default value of TOL is 0.01. The default value of Wt is all ones.
24 | % This default value is also obtained by Wt=[].
25 | %
26 | % [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER,TOL,'trace') provides a textual
27 | % progress report of the iteration.
28 | %
29 | % [B,A] = INVFREQZ(H,W,'complex',NB,NA,...) creates a complex filter. In
30 | % this case, no symmetry is enforced and W contains normalized frequency
31 | % values within the interval [-Pi, Pi].
32 | %
33 | % % Example:
34 | % % Convert a simple transfer function to frequency response data and
35 | % % then back to the original filter coefficients. If the system is
36 | % % unstable, use invfreqs's iterative algorithm to find a stable
37 | % % approximation to the system.
38 | %
39 | % b = [1 2 3 2 3]; % Numerator coefficients
40 | % a = [1 2 3 2 1 4]; % Denominator coefficients
41 | % [h,w] = freqz(b,a,64);
42 | % [bb,aa] = invfreqz(h,w,4,5) % aa has poles in the right half-plane.
43 | % [z,p,k] = tf2zp(bb,aa); % Get Zero-Pole form
44 | % fprintf('Stable Approximation to the system:')
45 | % [bbb,aaa] = invfreqz(h,w,4,5,[],30) % Stable approximation to system
46 | % subplot(2,1,1); zplane(bb,aa); title('PZ plot - Unstable system')
47 | % subplot(2,1,2); zplane(bbb,aaa); title('PZ plot of stable system')
48 | %
49 | % See also FREQZ, FREQS, INVFREQS.
50 |
51 | % Author(s): J.O. Smith and J.N. Little, 4-23-86
52 | % J.N. Little, 4-27-88, revised
53 | % Lennart Ljung, 9-21-92, rewritten
54 | % T. Krauss, 10-19-92, trace mode made optional
55 | % Copyright 1988-2004 The MathWorks, Inc.
56 | % $Revision: 1.8.4.8 $ $Date: 2012/10/29 19:31:23 $
57 |
58 | % calling sequence is
59 | %function [b,a]=invfreqz(g,w,nb,na,wf,maxiter,tol,pf)
60 | % OR
61 | %function [b,a]=invfreqz(g,w,'complex',nb,na,wf,maxiter,tol,pf)
62 | error(nargchk(4,9,nargin,'struct'))
63 | if ischar(varargin{1})
64 | realStr = lower(varargin{1});
65 | varargin(1) = [];
66 | else
67 | realStr = 'real';
68 | end
69 | gaussFlag = length(varargin)>3; % run Gauss-Newton algorithm or not?
70 | if length(varargin)<6
71 | varargin{6} = []; % pad varargin with []'s
72 | end
73 | [nb,na,wf,maxiter,tol,pf] = deal(varargin{:});
74 |
75 | switch realStr
76 | case 'real'
77 | realFlag = 1;
78 | case 'complex'
79 | realFlag = 0;
80 | otherwise
81 | warning(message('signal:invfreqz:InvalidParam', realStr));
82 | realFlag = 0;
83 | end
84 |
85 | nk=0;T=1; % The code is prepared for arbitrary sampling interval T and for
86 | % constraining the numerator to begin with nk zeros.
87 |
88 | nb=nb+nk+1;
89 | if isempty(pf)
90 | verb=0;
91 | elseif (strcmp(pf,'trace')),
92 | verb=1;
93 | else
94 | error(message('signal:invfreqz:NotSupported', pf));
95 | end
96 | if isempty(wf),wf=ones(length(w),1);end
97 | wf=sqrt(wf);
98 |
99 | if length(g)~=length(w),error(message('signal:invfreqz:InvalidDimensions', 'H', 'W')),end
100 | if length(wf)~=length(w),error(message('signal:invfreqz:InvalidDimensions', 'Wt', 'W')),end
101 | % if any( (w>pi) | (w<0) ) && realFlag
102 | % warning(message('signal:invfreqz:InvalidRegion', 'W', 'INVFREQZ', '''complex'''))
103 | % end
104 | [rw,cw]=size(w); if rw>cw, w=w'; end
105 | [rg,cg]=size(g); if cg>rg, g=g.'; end
106 | [rwf,cwf]=size(wf); if cwf>rwf, wf=wf'; end
107 |
108 | nm=max(na,nb+nk-1);
109 | OM=exp(-1i*(0:nm)'*w*T);
110 |
111 | %
112 | % Estimation in the least squares case:
113 | %
114 | Dva=(OM(2:na+1,:).').*(g*ones(1,na));
115 | Dvb=-(OM(nk+1:nk+nb,:).');
116 | D=[Dva Dvb].*(wf*ones(1,na+nb));
117 | if realFlag
118 | R=real(D'*D);
119 | Vd=real(D'*(-g.*wf));
120 | else
121 | R=D'*D;
122 | Vd=D'*(-g.*wf);
123 | end
124 | th=R\Vd;
125 | a=[1 th(1:na).'];b=[zeros(1,nk) th(na+1:na+nb).'];
126 |
127 | if ~gaussFlag,return,end
128 |
129 | % Now for the iterative minimization
130 | if isempty(maxiter), maxiter = 30; end
131 |
132 | if isempty(tol)
133 | tol = 0.01;
134 | end
135 | indb=1:length(b);indg=1:length(a);
136 | a=polystab(a); % Stabilizing the denominator
137 |
138 | % The initial estimate:
139 |
140 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
141 | e=(GC-g).*wf;
142 | Vcap=e'*e; t=[a(2:na+1) b(nk+1:nk+nb)].';
143 | if (verb),
144 | %messages similar to invfreqs
145 | clc, disp([' ' getString(message('signal:invfreqs:INITIALESTIMATE'))]);
146 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(Vcap)])
147 | disp(getString(message('signal:invfreqs:Parvector')));
148 | disp(t)
149 | end;
150 |
151 | %
152 | % ** the minimization loop **
153 | %
154 | gndir=2*tol+1;l=0;st=0;
155 | while all([norm(gndir)>tol l Vcap ll<20])
180 |
181 | t1=t-k*gndir; if ll==19,t1=t;end
182 | a=polystab([1 t1(1:na).']);
183 | t1(1:na)=a(2:na+1).'; %Stabilizing denominator
184 | b=[zeros(1,nk) t1(na+1:na+nb).'];
185 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
186 | V1=((GC-g).*wf)'*((GC-g).*wf); t1=[a(2:na+1) b(nk+1:nk+nb)].';
187 | if (verb),
188 | home, disp(int2str(ll))
189 | end;
190 | k=k/2;
191 | ll=ll+1; if ll==20, st=1;end
192 | if ll==10,gndir=Vd/norm(R)*length(R);k=1;end
193 | end
194 |
195 | if (verb),
196 | home
197 | disp([' ' getString(message('signal:invfreqs:ITERATION')) ' ' int2str(l)])
198 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(V1) ' ' getString(message('signal:invfreqs:PreviousFit')) ' ' num2str(Vcap)])
199 | disp(getString(message('signal:invfreqs:CurrentParPrevparGNdir')));
200 | disp([t1 t gndir])
201 | disp([getString(message('signal:invfreqs:NormOfGNvector')) ' ' num2str(norm(gndir))])
202 | if st==1,
203 | disp(getString(message('signal:invfreqs:NoImprovement'))),
204 | disp(getString(message('signal:invfreqs:IterationsThereforeTerminated'))),
205 | end
206 | end
207 | t=t1; Vcap=V1;
208 | end
209 |
--------------------------------------------------------------------------------
/matlab_test_files/invfreqs.m:
--------------------------------------------------------------------------------
1 | function [b,a]=invfreqs(g,w,varargin)
2 | %INVFREQS Analog filter least squares fit to frequency response data.
3 | % [B,A] = INVFREQS(H,W,nb,na) gives real numerator and denominator
4 | % coefficients B and A of orders nb and na respectively, where
5 | % H is the desired complex frequency response of the system at frequency
6 | % points W, and W contains the frequency values in radians/s.
7 | % INVFREQS yields a filter with real coefficients. This means that it is
8 | % sufficient to specify positive frequencies only; the filter fits the data
9 | % conj(H) at -W, ensuring the proper frequency domain symmetry for a real
10 | % filter.
11 | %
12 | % [B,A]=INVFREQS(H,W,nb,na,Wt) allows the fit-errors to the weighted
13 | % versus frequency. LENGTH(Wt)=LENGTH(W)=LENGTH(H).
14 | % Determined by minimization of sum |B-H*A|^2*Wt over the freqs in W.
15 | %
16 | % [B,A] = INVFREQS(H,W,nb,na,Wt,ITER) does another type of fit:
17 | % Sum |B/A-H|^2*Wt is minimized with respect to the coefficients in B and
18 | % A by numerical search in at most ITER iterations. The A-polynomial is
19 | % then constrained to be stable. [B,A]=INVFREQS(H,W,nb,na,Wt,ITER,TOL)
20 | % stops the iterations when the norm of the gradient is less than TOL.
21 | % The default value of TOL is 0.01. The default value of Wt is all ones.
22 | % This default value is also obtained by Wt=[].
23 | %
24 | % [B,A]=INVFREQS(H,W,nb,na,Wt,ITER,TOL,'trace') provides a textual
25 | % progress report of the iteration.
26 | %
27 | % [B,A] = INVFREQS(H,W,'complex',NB,NA,...) creates a complex filter. In
28 | % this case, no symmetry is enforced.
29 | %
30 | % % Example:
31 | % % Convert a simple transfer function to frequency response data and
32 | % % then back to the original filter coefficients. If the system is
33 | % % unstable, use invfreqs's iterative algorithm to find a stable
34 | % % approximation to the system.
35 | %
36 | % b = [1 2 3 2 3]; % Numerator coefficients
37 | % a = [1 2 3 2 1 4]; % Denominator coefficients
38 | % [h,w] = freqs(b,a,64);
39 | % [bb,aa] = invfreqs(h,w,4,5) % aa has poles in the right half-plane.
40 | % fprintf('Stable Approximation to the system:')
41 | % [bbb,aaa] = invfreqs(h,w,4,5,[],30) % stable approximation to system
42 | %
43 | % See also FREQZ, FREQS, INVFREQZ.
44 |
45 | % Author(s): J.O. Smith and J.N. Little, 4-23-86
46 | % J.N. Little, 4-27-88, revised
47 | % Lennart Ljung, 9-21-92, rewritten
48 | % T. Krauss, 10-22-92, trace mode made optional
49 | % Copyright 1988-2011 The MathWorks, Inc.
50 | %
51 |
52 | % calling sequence is
53 | %function [b,a]=invfreqs(g,w,nb,na,wf,maxiter,tol,pf)
54 | % OR
55 | %function [b,a]=invfreqs(g,w,'complex',nb,na,wf,maxiter,tol,pf)
56 | error(nargchk(4,9,nargin,'struct'))
57 | if ischar(varargin{1})
58 | realStr = lower(varargin{1});
59 | varargin(1) = [];
60 | else
61 | realStr = 'real';
62 | end
63 | gaussFlag = length(varargin)>3; % run Gauss-Newton algorithm or not?
64 | if length(varargin)<6
65 | varargin{6} = []; % pad varargin with []'s
66 | end
67 | [nb,na,wf,maxiter,tol,pf] = deal(varargin{:});
68 |
69 | switch realStr
70 | case 'real'
71 | realFlag = 1;
72 | case 'complex'
73 | realFlag = 0;
74 | otherwise
75 | warning(message('signal:invfreqs:InvalidParam', realStr));
76 | realFlag = 0;
77 | end
78 |
79 | nk=0; % The code is prepared for constraining the numerator to
80 | % begin with nk zeros.
81 |
82 | nb=nb+nk+1;
83 | if isempty(pf)
84 | verb=0;
85 | elseif (strcmp(pf,'trace')),
86 | verb=1;
87 | else
88 | error(message('signal:invfreqs:NotSupported', pf));
89 | end
90 | if isempty(wf),wf=ones(length(w),1);end
91 | wf=sqrt(wf);
92 |
93 | if length(g)~=length(w)
94 | error(message('signal:invfreqs:UnmatchedLengths', 'H', 'W'))
95 | end
96 |
97 | if length(wf)~=length(w)
98 | error(message('signal:invfreqs:UnmatchedLengths', 'Wt', 'W'))
99 | end
100 |
101 | if any( w(:)<0 ) && realFlag
102 | warning(message('signal:invfreqs:InvalidWParam', 'W', 'INVFREQS', 'complex'))
103 | end
104 |
105 | [rw,cw]=size(w); if rw>cw, w=w'; end
106 | [rg,cg]=size(g); if cg>rg, g=g.'; end
107 | [rwf,cwf]=size(wf); if cwf>rwf, wf=wf'; end
108 |
109 | nm=max(na+1,nb+nk);
110 | indb=nb:-1:1; indg=na+1:-1:1; inda=na:-1:1;
111 |
112 | OM=ones(1,length(w));
113 | for kom=1:nm-1
114 | OM=[OM;(1i*w).^kom];
115 | end
116 |
117 | %
118 | % Estimation in the least squares case:
119 | %
120 | Dva=(OM(inda,:).').*(g*ones(1,na));
121 | Dvb=-(OM(indb,:).');
122 | D=[Dva Dvb].*(wf*ones(1,na+nb));
123 | R=D'*D;
124 | Vd=D'*((-g.*OM(na+1,:).').*wf);
125 | if realFlag
126 | R=real(R);
127 | Vd=real(Vd);
128 | end
129 | th=R\Vd;
130 | a=[1 th(1:na).'];b=[zeros(1,nk) th(na+1:na+nb).'];
131 |
132 | if ~gaussFlag,return,end
133 |
134 | % Now for the iterative minimization
135 |
136 | if isempty(maxiter), maxiter = 30; end
137 | if isempty(tol)
138 | tol=0.01;
139 | end
140 | % Stabilizing the denominator:
141 | a=apolystab(a,realFlag);
142 |
143 | % The initial estimate:
144 |
145 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
146 | e=(GC-g).*wf;
147 | Vcap=e'*e; t=[a(2:na+1) b(nk+1:nk+nb)].';
148 | if (verb),
149 | % invfreqz using same messages
150 | clc, disp([' ' getString(message('signal:invfreqs:INITIALESTIMATE'))]);
151 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(Vcap)])
152 | disp(getString(message('signal:invfreqs:Parvector')));
153 | disp(t)
154 | end
155 |
156 | %
157 | % ** the minimization loop **
158 | %
159 | gndir=2*tol+1;l=0;st=0;
160 | while all([norm(gndir)>tol l Vcap ll<20]),
184 |
185 | t1=t-k*gndir; if ll==19,t1=t;end
186 | a=[1 t1(1:na).'];
187 | b=[zeros(1,nk) t1(na+1:na+nb).'];
188 | a=apolystab(a,realFlag); % Stabilizing the denominator
189 | t1(1:na)=a(2:na+1).';
190 | GC=((b*OM(indb,:))./(a*OM(indg,:))).';
191 | V1=((GC-g).*wf)'*((GC-g).*wf);
192 | if (verb),
193 | home, disp(int2str(ll))
194 | end;
195 | k=k/2;
196 | ll=ll+1; if ll==10, gndir=Vd/norm(R)*length(R);k=1;end
197 | if ll==20,st=1;end
198 | end
199 | if (verb),
200 | home
201 | disp([' ' getString(message('signal:invfreqs:ITERATION')) ' ' int2str(l)])
202 | disp([getString(message('signal:invfreqs:CurrentFit')) ' ' num2str(V1) ' ' getString(message('signal:invfreqs:PreviousFit')) ' ' num2str(Vcap)])
203 | disp(getString(message('signal:invfreqs:CurrentParPrevparGNdir')));
204 | disp([t1 t gndir])
205 | disp([getString(message('signal:invfreqs:NormOfGNvector')) ' ' num2str(norm(gndir))])
206 | if st==1,
207 | disp(getString(message('signal:invfreqs:NoImprovement'))),
208 | disp(getString(message('signal:invfreqs:IterationsThereforeTerminated'))),
209 | end
210 | end
211 | t=t1; Vcap=V1;
212 | end
213 |
214 | function a = apolystab(a,realFlag)
215 | %APOLYSTAB Stabilize filter, analog
216 | % inputs: a - denominator polynomial
217 | % realFlag - 1 for real, 0 for complex
218 | % returns stabilized denoninator polynomial
219 | if length(a)>0
220 | v=roots(a);
221 | vind=find(real(v)>0);
222 | v(vind)=-v(vind);
223 | a=poly(v);
224 | if realFlag
225 | a=real(a);
226 | end
227 | end
228 |
--------------------------------------------------------------------------------