def arcov(x, p): # Local Variables: a, msgobj, p, msg, x, e # Function calls: nargchk, arcov, nargin, isempty, error, arparest #%ARCOV AR parameter estimation via covariance method. #% A = ARCOV(X,ORDER) returns the polynomial A corresponding to the AR #% parametric signal model estimate of vector X using the Covariance method. #% ORDER is the model order of the AR system. #% #% [A,E] = ARCOV(...) returns the variance estimate E of the white noise #% input to the AR model. #% #% See also PCOV, ARMCOV, ARBURG, ARYULE, LPC, PRONY. #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION, #% Prentice-Hall, 1988, Chapter 7 #% P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS, #% Prentice-Hall, 1997, Chapter 3 #% Author(s): R. Losada and P. Pacheco #% Copyright 1988-2002 The MathWorks, Inc. #% $Revision: 1.13.4.3 $ $Date: 2011/05/13 18:06:51 $ matcompat.error(nargchk(2., 2., nargin, 'struct')) [a, e, msg, msgobj] = arparest(x, p, 'covariance') if not isempty(msg): matcompat.error(msgobj) #% [EOF] - arcov.m return [a, e]
def armcov(x, p): # Local Variables: a, msgobj, p, msg, x, e # Function calls: nargchk, nargin, isempty, error, arparest, armcov #%ARMCOV AR parameter estimation via modified covariance method. #% A = ARMCOV(X,ORDER) returns the polynomial A corresponding to the AR #% parametric signal model estimate of vector X using the Modified Covariance #% method. ORDER is the model order of the AR system. #% #% [A,E] = ARMCOV(...) returns the variance estimate E of the white noise #% input to the AR model. #% #% See also PMCOV, ARCOV, ARBURG, ARYULE, LPC, PRONY. #% References: #% [1] S. Lawrence Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATIONS, #% Prentice-Hall, 1987, Chapter 8 #% [2] Steven M. Kay, MODERN SPECTRAL ESTIMATION THEORY & APPLICATION, #% Prentice-Hall, 1988, Chapter 7 #% Author(s): R. Losada and P. Pacheco #% Copyright 1988-2002 The MathWorks, Inc. #% $Revision: 1.13.4.3 $ $Date: 2011/05/13 18:06:53 $ matcompat.error(nargchk(2., 2., nargin, 'struct')) [a, e, msg, msgobj] = arparest(x, p, 'modified') if not isempty(msg): matcompat.error(msgobj) #% [EOF] - armcov.m return [a, e]
def kntbrkdegmult(breaks, degree, mult): # Local Variables: knots, breaks, mult, degree # Function calls: false, do_kntbrkdegmult, kntbrkdegmult, nargin, num2cell, numel, error, cellfun, iscell if iscell(breaks): if nargin == 2.: mult = 1. if numel(breaks) != numel(degree) or numel(breaks) != numel(mult): matcompat.error('kntbrkdegmult: degree and multiplicity must have the same length as the number of knot vectors') degree = num2cell(degree) if not iscell(mult): mult = num2cell(mult) knots = cellfun(do_kntbrkdegmult, breaks, degree, mult, 'uniformoutput', false) else: if nargin == 2.: mult = 1. knots = do_kntbrkdegmult(breaks, degree, mult) return [knots]
def NormalizeRows(a, type): # Local Variables: a, b, type, normF, normFUsed # Function calls: sum, bsxfun, sqrt, nargin, abs, error, NormalizeRows #% Normalizes the rows of a using specified normalisation type. Makes sure #% there is no division by zero: b will not contain any NaN entries. #% #% a: data with row vectors #% type: String: #% 'L1' (default) Sums to 1 #% 'L2' Unit Length #% 'Sqrt->L1' Square root followed by L1 #% 'L1->Sqrt' L1 followed by Square root. Becomes unit length #% 'Sqrt->L2' Square root followed by L2. Square rooting #% while keeping the sign #% 'None' No normalization #% #% b: normalized data with row vecors. #% normF: Normalization factor per row (when valid) #% #% Jasper Uijlings, 2011 #% Default: L1 if nargin == 1.: type = 'L1' _switch_val = type if False: # switch pass elif _switch_val == 'L1': normF = np.sum(a, 2.) #% Get sums normFUsed = normF normFUsed[int((normFUsed == 0.)) - 1] = 1. #% Prevent division by zero b = bsxfun(rdivide, a, normFUsed) #% Normalise elif _switch_val == 'L2': normF = np.sqrt(np.sum((a * a), 2.)) #% Get length normFUsed = normF normFUsed[int((normFUsed == 0.)) - 1] = 1. #% Prevent division by zero b = bsxfun(rdivide, a, normFUsed) elif _switch_val == 'Sqrt->L1': b = NormalizeRows(np.sqrt(a), 'L1') normF = np.array([]) elif _switch_val == 'L1->Sqrt': #% This is the same as ROOTSIFT b = np.sqrt(NormalizeRows(np.abs(a), 'L1')) normF = np.array([]) elif _switch_val == 'Sqrt->L2': b = NormalizeRows(np.sqrt(a), 'L2') normF = np.array([]) elif _switch_val == 'None': b = a normF = np.array([]) else: matcompat.error('Wrong normalization type given') return [b, normF]
def kntbrkdegreg(breaks, degree, reg): # Local Variables: knots, breaks, reg, degree # Function calls: false, do_kntbrkdegreg, nargin, num2cell, numel, error, cellfun, iscell, kntbrkdegreg if iscell(breaks): if nargin == 2.: reg = degree-1. if numel(breaks) != numel(degree) or numel(breaks) != numel(reg): matcompat.error('kntbrkdegreg: degree and regularity must have the same length as the number of knot vectors') degree = num2cell(degree) if not iscell(reg): reg = num2cell(reg) knots = cellfun(do_kntbrkdegreg, breaks, degree, reg, 'uniformoutput', false) else: if nargin == 2.: reg = degree-1. knots = do_kntbrkdegreg(breaks, degree, reg) return [knots]
def do_kntbrkdegreg(breaks, degree, reg): # Local Variables: knots, mults, breaks, reg, degree # Function calls: do_kntbrkdegreg, kntbrkdegmult, warning, numel, error, any if numel(breaks)<2.: matcompat.error('kntbrkdegreg: the knots sequence should contain at least two points') if numel(reg) == 1.: elif numel(reg) == numel(breaks): mults = degree-reg
def aryule(x, p): # Local Variables: a, e, k, nx, p, R, x, mx # Function calls: aryule, nargchk, min, issparse, nargin, length, isempty, error, levinson, message, xcorr, round, size #%ARYULE AR parameter estimation via Yule-Walker method. #% A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR #% parametric signal model estimate of vector X using the Yule-Walker #% (autocorrelation) method. ORDER is the model order of the AR system. #% This method solves the Yule-Walker equations by means of the Levinson- #% Durbin recursion. #% #% [A,E] = ARYULE(...) returns the final prediction error E (the variance #% estimate of the white noise input to the AR model). #% #% [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients. #% #% % Example: #% % Estimate model order using decay of reflection coefficients. #% #% rng default; #% y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1)); #% #% % Create AR(2) process #% [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10); #% #% % Fit AR(10) model #% stem(reflect_coeffs); axis([-0.05 10.5 -1 1]); #% title('Reflection Coefficients by Lag'); xlabel('Lag'); #% ylabel('Reflection Coefficent'); #% #% See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY. #% Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed. #% Macmillan, 1988, Chapter 5 #% M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING, #% John Wiley & Sons, 1996, Chapter 8 #% Author(s): R. Losada #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $ matcompat.error(nargchk(2., 2., nargin, 'struct')) #% Check the input data type. Single precision is not supported. #%try #% chkinputdatatype(x,p); #%catch ME #% throwAsCaller(ME); #%end [mx, nx] = matcompat.size(x) if isempty(x) or length(x)<p or matcompat.max(mx, nx) > 1.: matcompat.error(message('signal:aryule:InvalidDimensions')) elif isempty(p) or not p == np.round(p): matcompat.error(message('signal:aryule:MustBeInteger')) if issparse(x): matcompat.error(message('signal:aryule:Sparse')) R = plt.xcorr(x, p, 'biased') [a, e, k] = levinson(R[int(p+1.)-1:], p) return [a, e, k]
def aryule(x, p): # Local Variables: a, e, k, nx, p, R, x, mx # Function calls: aryule, nargchk, min, issparse, nargin, length, isempty, error, levinson, message, xcorr, round, size #%ARYULE AR parameter estimation via Yule-Walker method. #% A = ARYULE(X,ORDER) returns the polynomial A corresponding to the AR #% parametric signal model estimate of vector X using the Yule-Walker #% (autocorrelation) method. ORDER is the model order of the AR system. #% This method solves the Yule-Walker equations by means of the Levinson- #% Durbin recursion. #% #% [A,E] = ARYULE(...) returns the final prediction error E (the variance #% estimate of the white noise input to the AR model). #% #% [A,E,K] = ARYULE(...) returns the vector K of reflection coefficients. #% #% % Example: #% % Estimate model order using decay of reflection coefficients. #% #% rng default; #% y=filter(1,[1 -0.75 0.5],0.2*randn(1024,1)); #% #% % Create AR(2) process #% [ar_coeffs,NoiseVariance,reflect_coeffs]=aryule(y,10); #% #% % Fit AR(10) model #% stem(reflect_coeffs); axis([-0.05 10.5 -1 1]); #% title('Reflection Coefficients by Lag'); xlabel('Lag'); #% ylabel('Reflection Coefficent'); #% #% See also PYULEAR, ARMCOV, ARBURG, ARCOV, LPC, PRONY. #% Ref: S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed. #% Macmillan, 1988, Chapter 5 #% M. Hayes, STATISTICAL DIGITAL SIGNAL PROCESSING AND MODELING, #% John Wiley & Sons, 1996, Chapter 8 #% Author(s): R. Losada #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.12.4.6 $ $Date: 2012/10/29 19:30:38 $ matcompat.error(nargchk(2., 2., nargin, 'struct')) #% Check the input data type. Single precision is not supported. #%try #% chkinputdatatype(x,p); #%catch ME #% throwAsCaller(ME); #%end [mx, nx] = matcompat.size(x) if isempty(x) or length(x) < p or matcompat.max(mx, nx) > 1.: matcompat.error(message('signal:aryule:InvalidDimensions')) elif isempty(p) or not p == np.round(p): matcompat.error(message('signal:aryule:MustBeInteger')) if issparse(x): matcompat.error(message('signal:aryule:Sparse')) R = plt.xcorr(x, p, 'biased') [a, e, k] = levinson(R[int(p + 1.) - 1:], p) return [a, e, k]
def asserteq(varargin): # Local Variables: varargin, i # Function calls: length, error, asserteq, isequal #% asserteq(in1, in2, ...) #% Assert all arguments are equal (via "isequal") #% If nargin is 1 then do nothing #% Sam Hallman, 2013 if length(varargin) >= 2.: for i in np.arange(2., (length(varargin))+1): if not isequal(varargin.cell[0], varargin.cell[int(i)-1]): matcompat.error('inputs %d,%d not equal', 1., i) return
def binangles360(angles, nBins): # Local Variables: a, nBins, b, edges, angles, delta, orient # Function calls: binangles360, any, error #% Assume angles lie in [0,360] if np.any(np.logical_or(angles < 0., angles > 360.)): matcompat.error('angles should be in the range [0,360]') #% #% change from [0,360] to [-270,90] #% angles[int((angles > 90.)) - 1] = angles[int((angles > 90.)) - 1] - 360. delta = 360. / nBins a = -270. + delta / 2. b = +90. - delta / 2. edges = np.arange(a, (b) + (delta), delta) orient = nBins - orient + 1. orient[int((orient == nBins + 1.)) - 1] = 1. return [orient]
def clustMasks(opts): # Local Variables: gtWidth, E, zz, i, k, j, xx, yy, S, t, w, theta, dist, nDists, nOrients, K, opts # Function calls: all, cosd, sum, rem, nargout, single, meshgrid, zeros, linspace, error, sind, clustMasks, gradientMag, size gtWidth = opts.gtWidth nDists = opts.nDists nOrients = opts.nOrients if plt.rem(gtWidth, 2.) != 0.: matcompat.error('gtWidth should be even') #% define gtWidth x gtWidth grid [xx, yy] = matcompat.meshgrid(np.arange(-gtWidth/2.+1., (gtWidth/2.)+1)) #% define the distances and orientations k = gtWidth/1.0. dist = np.linspace(k, (-k), nDists) theta = np.arange(0., (180.-.01)+(180./nOrients), 180./nOrients) #% render seg masks for each cluster K = np.dot(nDists, nOrients) S = np.zeros(gtWidth, gtWidth, K) for i in np.arange(1., (nOrients)+1): t = theta[int(i)-1] w = np.array(np.vstack((np.hstack((cosd(t))), np.hstack((sind(t)))))) zz = np.dot(w[0], xx)+np.dot(w[1], yy) for j in np.arange(1., (nDists)+1): k = np.dot(i-1., nDists)+j S[:,:,int(k)-1] = zz > dist[int(j)-1] #% check for bugs #% demonstrate how to convert segs S to edges E if nargout > 1.: E = np.zeros(matcompat.size(S)) for k in np.arange(1., (K)+1): E[:,:,int(k)-1] = gradientMag(np.single(S[:,:,int(k)-1])) > .01 return [S, E]
def mirrorhistc(x, e): # Local Variables: b, lastBin, nn, bn, n, bp, np, x, e # Function calls: all, mirrorhistc, max, min, histc, length, abs, error, diff, ndims, any, size #% [N,B] = mirrorhistc( X, E ) #% #% Suppose E = [a b]. Then the binning #% used is (-b,-a] (-a,a) [a,b). #% #% Suppose E = [a b c]. Then the binning #% used is (-c,-b] (-b,-a] (-a,a) [a,b) [b,c). #% #% ...and so on. if np.any((e <= 0.)) or not np.all((np.diff(e) > 0.)): matcompat.error('invalid bin edges') if np.abs(matcompat.max(x)) >= e[int(0) - 1]: matcompat.error('data is out of bounds') if matcompat.ndim(x) > 2. or matcompat.max(matcompat.size(x)) > 1.: matcompat.error('data should be a vector') x = x.flatten(0).conj() e = e.flatten(0).conj() e = np.array(np.hstack((0., e))) lastBin = length(e) - 1. [nn, bn] = histc((-x[int((x < 0.)) - 1]), e) bn = lastBin - bn + 1. nn = nn[int(0 - 1.) - 1:1.:-1.] [np, bp] = histc(x[int((x >= 0.)) - 1], e) bp = bp + lastBin - 1. np = np[0:0 - 1.] b = 0. * x b[int((x < 0.)) - 1] = bn b[int((x >= 0.)) - 1] = bp n = np.array(np.hstack((nn[0:0 - 1.], nn[int(0) - 1] + np[0], np[1:]))) return [n, b]
def aveknt(varargin): # Local Variables: ndim, nrb, onedim, idim, varargin, knt_aux, knt, pts, order # Function calls: false, nargin, reshape, sum, isfield, cell, aveknt, zeros, numel, error, iscell, repmat, true #% AVEKNT: compute the knot averages (Greville points) of a knot vector #% #% Calling Sequence: #% #% pts = aveknt (knt, p) #% pts = aveknt (nrb) #% #% INPUT: #% #% knt - knot sequence #% p - spline order (degree + 1) #% nrb - NURBS structure (see nrbmak) #% #% OUTPUT: #% #% pts - average knots. If the input is a NURBS, it gives a cell-array, #% with the average knots in each direction #% #% See also: #% #% Copyright (C) 2016 Rafael Vazquez #% #% This program is free software: you can redistribute it and/or modify #% it under the terms of the GNU General Public License as published by #% the Free Software Foundation, either version 3 of the License, or #% (at your option) any later version. #% This program is distributed in the hope that it will be useful, #% but WITHOUT ANY WARRANTY; without even the implied warranty of #% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #% GNU General Public License for more details. #% #% You should have received a copy of the GNU General Public License #% along with this program. If not, see <http://www.gnu.org/licenses/>. if nargin == 1.: if isfield(varargin.cell[0], 'form'): nrb = varargin.cell[0] knt = nrb.knots order = nrb.order else: matcompat.error( 'The input should be a NURBS structure, or a knot vector and the order. See the help for details' ) elif nargin == 2.: knt = varargin.cell[0] order = varargin.cell[1] else: matcompat.error( 'The input should be a NURBS structure, or a knot vector and the order. See the help for details' ) onedim = false if not iscell(knt): knt = cellarray(np.hstack((knt))) onedim = true ndim = numel(knt) pts = cell(ndim, 1.) for idim in np.arange(1., (ndim) + 1): if numel(knt.cell[int(idim) - 1]) < order[int(idim) - 1] + 1.: matcompat.error( 'The knot vector must contain at least p+2 knots, with p the degree' ) knt_aux = matcompat.repmat(knt.cell[int(idim) - 1, 1:0 - 1.](), 1., (order[int(idim) - 1] - 1.)) knt_aux = np.array( np.vstack((np.hstack((knt_aux.flatten(1))), np.hstack((np.zeros((order[int(idim) - 1] - 1.), 1.)))))) knt_aux = np.reshape(knt_aux, np.array([]), (order[int(idim) - 1] - 1.)) pts.cell[int(idim) - 1] = matdiv(np.sum(knt_aux.T, 1.), order[int(idim) - 1] - 1.) pts.cell[int(idim) - 1] = pts.cell[int(idim) - 1, 0:0 - order[int(idim) - 1] + 1.]() if onedim: pts = pts.cell[0] #%!test #%! knt = [0 0 0 0.5 1 1 1]; #%! pts = aveknt (knt, 3); #%! assert (pts - [0 1/4 3/4 1] < 1e-14) #%! #%!test #%! knt = {[0 0 0 0.5 1 1 1] [0 0 0 0 1/3 2/3 1 1 1 1]}; #%! pts = aveknt (knt, [3 4]); #%! assert (pts{1} - [0 1/4 3/4 1] < 1e-14); #%! assert (pts{2} - [0 1/9 1/3 2/3 8/9 1] < 1e-14); #%! #%!test #%! nrb = nrb4surf([0 0], [1 0], [0 1], [1 1]); #%! nrb = nrbkntins (nrbdegelev (nrb, [1 2]), {[1/2] [1/3 2/3]}); #%! pts = aveknt (nrb); #%! assert (pts{1} - [0 1/4 3/4 1] < 1e-14); #%! assert (pts{2} - [0 1/9 1/3 2/3 8/9 1] < 1e-14); return [pts]
def kntrefine(knots, n_sub, degree, regularity): # Local Variables: knots, old_mult, degree, insk, nz, varargout, regularity, aux_knots, n_sub, idim, new_knots, ik, min_mult, zeta, z, rknots, mult, deg # Function calls: repmat, max, sum, kntrefine, nargout, ones, linspace, numel, error, iscell, unique, vec if iscell(knots): if numel(n_sub) != numel(degree) or numel(n_sub) != numel(regularity) or numel(n_sub) != numel(knots): matcompat.error('kntrefine: n_sub, degree and regularity must have the same length as the number of knot vectors') aux_knots = knots else: if numel(n_sub) != numel(degree) or numel(n_sub) != numel(regularity) or numel(n_sub) != 1.: matcompat.error('kntrefine: n_sub, degree and regularity must have the same length as the number of knot vectors') aux_knots = cellarray(np.hstack((knots))) if nargout == 3.: for idim in np.arange(1., (numel(n_sub))+1): if degree[int(idim)-1]+1. != np.sum((aux_knots.cell[int(idim)-1] == aux_knots.cell[int(idim)-1,0]())): matcompat.error('kntrefine: new_knots is only computed when the degree is maintained') for idim in np.arange(1., (numel(n_sub))+1): min_mult = degree[int(idim)-1]-regularity[int(idim)-1] z = np.unique(aux_knots.cell[int(idim)-1]) nz = numel(z) deg = np.sum((aux_knots.cell[int(idim)-1] == z[0]))-1. rknots.cell[int(idim)-1] = z[int(np.ones(1., (degree[int(idim)-1]+1.)))-1] new_knots.cell[int(idim)-1] = np.array([]) for ik in np.arange(2., (nz)+1): insk = np.linspace(z[int((ik-1.))-1], z[int(ik)-1], (n_sub[int(idim)-1]+2.)) insk = vec(matcompat.repmat(insk[1:0-1.], min_mult, 1.)).conj().T old_mult = np.sum((aux_knots.cell[int(idim)-1] == z[int(ik)-1])) mult = matcompat.max(min_mult, (degree[int(idim)-1]-deg+old_mult)) rknots.cell[int(idim)-1] = np.array(np.hstack((rknots.cell[int(idim)-1], insk, z[int(np.dot(ik, np.ones(1., mult)))-1]))) new_knots.cell[int(idim)-1] = np.array(np.hstack((new_knots.cell[int(idim)-1], insk, z[int(np.dot(ik, np.ones(1., (mult-old_mult))))-1]))) zeta.cell[int(idim)-1] = np.unique(rknots.cell[int(idim)-1]) if not iscell(knots): rknots = rknots.cell[0] zeta = zeta.cell[0] new_knots = new_knots.cell[0] varargout.cell[0] = rknots varargout.cell[1] = zeta varargout.cell[2] = new_knots else: for idim in np.arange(1., (numel(n_sub))+1): min_mult = degree[int(idim)-1]-regularity[int(idim)-1] z = np.unique(aux_knots.cell[int(idim)-1]) nz = numel(z) deg = np.sum((aux_knots.cell[int(idim)-1] == z[0]))-1. rknots.cell[int(idim)-1] = z[int(np.ones(1., (degree[int(idim)-1]+1.)))-1] for ik in np.arange(2., (nz)+1): insk = np.linspace(z[int((ik-1.))-1], z[int(ik)-1], (n_sub[int(idim)-1]+2.)) insk = vec(matcompat.repmat(insk[1:0-1.], min_mult, 1.)).conj().T old_mult = np.sum((aux_knots.cell[int(idim)-1] == z[int(ik)-1])) mult = matcompat.max(min_mult, (degree[int(idim)-1]-deg+old_mult)) rknots.cell[int(idim)-1] = np.array(np.hstack((rknots.cell[int(idim)-1], insk, z[int(np.dot(ik, np.ones(1., mult)))-1]))) zeta.cell[int(idim)-1] = np.unique(rknots.cell[int(idim)-1]) if not iscell(knots): rknots = rknots.cell[0] zeta = zeta.cell[0] varargout.cell[0] = rknots if nargout == 2.: varargout.cell[1] = zeta return [varargout]
def findspan(n, p, u, U): # Local Variables: j, n, p, s, u, U # Function calls: min, max, find, zeros, numel, error, findspan, size #% FINDSPAN Find the span of a B-Spline knot vector at a parametric point #% #% Calling Sequence: #% #% s = findspan(n,p,u,U) #% #% INPUT: #% #% n - number of control points - 1 #% p - spline degree #% u - parametric point #% U - knot sequence #% #% OUTPUT: #% #% s - knot span index #% #% Modification of Algorithm A2.1 from 'The NURBS BOOK' pg68 #% #% Copyright (C) 2010 Rafael Vazquez #% #% This program is free software: you can redistribute it and/or modify #% it under the terms of the GNU General Public License as published by #% the Free Software Foundation, either version 3 of the License, or #% (at your option) any later version. #% This program is distributed in the hope that it will be useful, #% but WITHOUT ANY WARRANTY; without even the implied warranty of #% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #% GNU General Public License for more details. #% #% You should have received a copy of the GNU General Public License #% along with this program. If not, see <http://www.gnu.org/licenses/>. if matcompat.max(u.flatten(1)) > U[int(0) - 1] or matcompat.max( u.flatten(1)) < U[0]: matcompat.error('Some value is outside the knot span') s = np.zeros(matcompat.size(u)) for j in np.arange(1., (numel(u)) + 1): if u[int(j) - 1] == U[int((n + 2.)) - 1]: s[int(j) - 1] = n continue s[int(j) - 1] = nonzero((u[int(j) - 1] >= U), 1., 'last') - 1. #%!test #%! n = 3; #%! U = [0 0 0 1/2 1 1 1]; #%! p = 2; #%! u = linspace(0, 1, 10); #%! s = findspan (n, p, u, U); #%! assert (s, [2*ones(1, 5) 3*ones(1, 5)]); #%!test #%! p = 2; m = 7; n = m - p - 1; #%! U = [zeros(1,p) linspace(0,1,m+1-2*p) ones(1,p)]; #%! u = [ 0 0.11880 0.55118 0.93141 0.40068 0.35492 0.44392 0.88360 0.35414 0.92186 0.83085 1]; #%! s = [2 2 3 4 3 3 3 4 3 4 4 4]; #%! assert (findspan (n, p, u, U), s, 1e-10); return [s]
def stmcb(x, u_in, q, p, niter, a_in): # 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 # Function calls: convmtx, filter, prony, nargchk, stmcb, nargin, length, zeros, error, message, size #%STMCB Compute linear model via Steiglitz-McBride iteration #% [B,A] = stmcb(H,NB,NA) finds the coefficients of the system #% B(z)/A(z) with approximate impulse response H, NA poles and #% NB zeros. #% #% [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5. #% #% [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial #% guess at the denominator coefficients. If you don't specify Ai, #% STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions. #% #% [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and #% A of the system which, given X as input, has Y as output. N and Ai #% are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA). #% Y and X must be the same length. #% #% % Example: #% % Approximate the impulse response of a Butterworth filter with a #% % system of lower order. #% #% [b,a] = butter(6,0.2); % Butterworth filter design #% h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter #% freqz(b,a,128) % Frequency response #% [bb,aa] = stmcb(h,4,4); #% figure; freqz(bb,aa,128) #% #% See also PRONY, LEVINSON, LPC, ARYULE. #% Author(s): Jim McClellan, 2-89 #% T. Krauss, 4-22-93, new help and options #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $ matcompat.error(nargchk(3., 6., nargin, 'struct')) if length(u_in) == 1.: if nargin == 3.: niter = 5. p = q q = u_in a_in = prony(x, 0., p) elif nargin == 4.: niter = p p = q q = u_in a_in = prony(x, 0., p) elif nargin == 5.: a_in = niter niter = p p = q q = u_in u_in = np.zeros(matcompat.size(x)) u_in[0] = 1. #% make a unit impulse whose length is same as x else: if length(u_in) != length(x): matcompat.error(message('signal:stmcb:InvalidDimensions')) if nargin < 6.: [b, a_in] = prony(x, 0., p) if nargin < 5.: niter = 5. a = a_in N = length(x) for i in np.arange(1., (niter) + 1): u = filter(1., a, x) v = filter(1., a, u_in) C1 = convmtx(u.flatten(1), (p + 1.)) C2 = convmtx(v.flatten(1), (q + 1.)) C1_minus = -C1 T_sub1 = C1_minus[0:N, :] T_sub2 = C2[0:N, :] T = np.array(np.hstack((T_sub1, T_sub2))) #%T = [ C1_minus(1:N,:) C2(1:N,:) ]; T_minus = -T T_left = T[:, 1:p + q + 2.] T_right = T_minus[:, 0] c = linalg.solve(T_left, T_right) #% c = T(:,2:p+q+2)\(T_minus(:,1)); % move 1st column to RHS and do least-squares a = np.array(np.vstack((np.hstack((1.)), np.hstack((c[0:p]))))) #% denominator coefficients b = c[int(p + 1.) - 1:p + q + 1.] #% numerator coefficients a = a.T b = b.T return [b, a]
def arburg(x, p): # Local Variables: a, E, efp, k, ef, m, varargout, N, p, num, ebp, den, x, eb # Function calls: arburg, validateattributes, nargchk, flipud, nargout, issparse, nargin, length, zeros, numel, error, message, conj #%ARBURG AR parameter estimation via Burg method. #% A = ARBURG(X,ORDER) returns the polynomial A corresponding to the AR #% parametric signal model estimate of vector X using Burg's method. #% ORDER is the model order of the AR system. #% #% [A,E] = ARBURG(...) returns the final prediction error E (the variance #% estimate of the white noise input to the AR model). #% #% [A,E,K] = ARBURG(...) returns the vector K of reflection #% coefficients (parcor coefficients). #% #% % Example: #% % Estimate input noise variance for AR(4) model. #% #% A=[1 -2.7607 3.8106 -2.6535 0.9238]; #% % Generate noise standard deviations #% % Seed random number generator for reproducible results #% rng default; #% noise_stdz=rand(50,1)+0.5; #% for j=1:50 #% y=filter(1,A,noise_stdz(j)*randn(1024,1)); #% [ar_coeffs,NoiseVariance(j)]=arburg(y,4); #% end #% %Compare actual vs. estimated variances #% plot(noise_stdz.^2,NoiseVariance,'k*'); #% xlabel('Input Noise Variance'); #% ylabel('Estimated Noise Variance'); #% #% See also PBURG, ARMCOV, ARCOV, ARYULE, LPC, PRONY. #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION, #% Prentice-Hall, 1988, Chapter 7 #% S. Orfanidis, OPTIMUM SIGNAL PROCESSING, 2nd Ed. #% Macmillan, 1988, Chapter 5 #% Author(s): D. Orofino and R. Losada #% Copyright 1988-2009 The MathWorks, Inc. #% $Revision: 1.12.4.7 $ $Date: 2012/10/29 19:30:37 $ matcompat.error(nargchk(2., 2., nargin, 'struct')) #% Check the input data type. Single precision is not supported. #%try #% chkinputdatatype(x,p); #%catch ME #% throwAsCaller(ME); #%end validateattributes(x, cellarray(np.hstack(('numeric'))), cellarray(np.hstack(('nonempty', 'finite', 'vector'))), 'arburg', 'X') validateattributes(p, cellarray(np.hstack(('numeric'))), cellarray(np.hstack(('positive', 'integer', 'scalar'))), 'arburg', 'ORDER') if issparse(x): matcompat.error(message('signal:arburg:Sparse')) if numel(x)<p+1.: matcompat.error(message('signal:arburg:InvalidDimension', (p+1.))) x = x.flatten(1) N = length(x) #% Initialization ef = x eb = x a = 1. #% Initial error E = np.dot(x.conj().T, x)/N #% Preallocate 'k' for speed. k = np.zeros(1., p) for m in np.arange(1., (p)+1): #% Calculate the next order reflection (parcor) coefficient a = a.flatten(0) #% By convention all polynomials are row vectors varargout.cell[0] = a if nargout >= 2.: varargout.cell[1] = E[int(0)-1] if nargout >= 3.: varargout.cell[2] = k.flatten(1) return [varargout]
def bspinterpcrv(Q, p, method): # Local Variables: A, ii, crv, d, n, Q, p, u, pnts, jj, x, y, span, z, knts, method # Function calls: basisfun, nrbmak, cumsum, sum, error, sqrt, nargin, ones, isempty, linspace, zeros, diff, size, bspinterpcrv, findspan, strcmpi #% #% BSPINTERPCRV: B-Spline interpolation of a 3d curve. #% #% Calling Sequence: #% #% crv = bspinterpcrv (Q, p); #% crv = bspinterpcrv (Q, p, method); #% [crv, u] = bspinterpcrv (Q, p); #% [crv, u] = bspinterpcrv (Q, p, method); #% #% INPUT: #% #% Q - points to be interpolated in the form [x_coord; y_coord; z_coord]. #% p - degree of the interpolating curve. #% method - parametrization method. The available choices are: #% 'equally_spaced' #% 'chord_length' #% 'centripetal' (Default) #% #% OUTPUT: #% #% crv - the B-Spline curve. #% u - the parametric points corresponding to the interpolation ones. #% #% See The NURBS book pag. 364 for more information. #% #% #% Copyright (C) 2015 Jacopo Corno #% #% This program is free software: you can redistribute it and/or modify #% it under the terms of the GNU General Public License as published by #% the Free Software Foundation, either version 3 of the License, or #% (at your option) any later version. #% This program is distributed in the hope that it will be useful, #% but WITHOUT ANY WARRANTY; without even the implied warranty of #% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #% GNU General Public License for more details. #% #% You should have received a copy of the GNU General Public License #% along with this program. If not, see <http://www.gnu.org/licenses/>. #% if nargin<3. or isempty(method): method = 'centripetal' n = matcompat.size(Q, 2.) if strcmpi(method, 'equally_spaced'): u = np.linspace(0., 1., n) elif strcmpi(method, 'chord_length'): d = np.sum(np.sqrt(np.sum((np.diff(Q.conj().T).conj().T**2.), 1.))) u = np.zeros(1., n) u[1:n] = matdiv(np.cumsum(np.sqrt(np.sum((np.diff(Q, np.array([]), 2.)**2.), 1.))), d) #% for ii = 2:n-1 #% u(ii) = u(ii-1) + norm (Q(:,ii) - Q(:,ii-1)) / d; #% end u[int(0)-1] = 1. elif strcmpi(method, 'centripetal'): d = np.sum(np.sqrt(np.sqrt(np.sum((np.diff(Q.conj().T).conj().T**2.), 1.)))) u = np.zeros(1., n) u[1:n] = matdiv(np.cumsum(np.sqrt(np.sqrt(np.sum((np.diff(Q, np.array([]), 2.)**2.), 1.)))), d) #% for ii = 2:n-1 #% u(ii) = u(ii-1) + sqrt (norm (Q(:,ii) - Q(:,ii-1))) / d; #% end u[int(0)-1] = 1. else: matcompat.error('BSPINTERPCRV: unrecognized parametrization method.') knts = np.zeros(1., (n+p+1.)) for jj in np.arange(2., (n-p)+1): knts[int((jj+p))-1] = np.dot(1./p, np.sum(u[int(jj)-1:jj+p-1.])) knts[int(0-p)-1:] = np.ones(1., (p+1.)) A = np.zeros(n, n) A[0,0] = 1. A[int(n)-1,int(n)-1] = 1. for ii in np.arange(2., (n-1.)+1): span = findspan(n, p, u[int(ii)-1], knts) A[int(ii)-1,int(span-p+1.)-1:span+1.] = basisfun(span, u[int(ii)-1], p, knts) x = linalg.solve(A, Q[0,:].conj().T) y = linalg.solve(A, Q[1,:].conj().T) z = linalg.solve(A, Q[2,:].conj().T) pnts = np.array(np.vstack((np.hstack((x.conj().T)), np.hstack((y.conj().T)), np.hstack((z.conj().T)), np.hstack((np.ones(matcompat.size(x.conj().T))))))) crv = nrbmak(pnts, knts) #%!demo #%! Q = [1 0 -1 -1 -2 -3; #%! 0 1 0 -1 -1 0; #%! 0 0 0 0 0 0]; #%! p = 2; #%! crv = bspinterpcrv (Q, p); #%! #%! plot (Q(1,:), Q(2,:), 'xk'); #%! hold on; grid on; #%! nrbkntplot (crv); return [crv, u]
def stmcb(x, u_in, q, p, niter, a_in): # 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 # Function calls: convmtx, filter, prony, nargchk, stmcb, nargin, length, zeros, error, message, size #%STMCB Compute linear model via Steiglitz-McBride iteration #% [B,A] = stmcb(H,NB,NA) finds the coefficients of the system #% B(z)/A(z) with approximate impulse response H, NA poles and #% NB zeros. #% #% [B,A] = stmcb(H,NB,NA,N) uses N iterations. N defaults to 5. #% #% [B,A] = stmcb(H,NB,NA,N,Ai) uses the vector Ai as the initial #% guess at the denominator coefficients. If you don't specify Ai, #% STMCB uses [B,Ai] = PRONY(H,0,NA) as the initial conditions. #% #% [B,A] = STMCB(Y,X,NB,NA,N,Ai) finds the system coefficients B and #% A of the system which, given X as input, has Y as output. N and Ai #% are again optional with default values of N = 5, [B,Ai] = PRONY(Y,0,NA). #% Y and X must be the same length. #% #% % Example: #% % Approximate the impulse response of a Butterworth filter with a #% % system of lower order. #% #% [b,a] = butter(6,0.2); % Butterworth filter design #% h = filter(b,a,[1 zeros(1,100)]); % Filter data using above filter #% freqz(b,a,128) % Frequency response #% [bb,aa] = stmcb(h,4,4); #% figure; freqz(bb,aa,128) #% #% See also PRONY, LEVINSON, LPC, ARYULE. #% Author(s): Jim McClellan, 2-89 #% T. Krauss, 4-22-93, new help and options #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.8.4.6 $ $Date: 2012/10/29 19:32:10 $ matcompat.error(nargchk(3., 6., nargin, 'struct')) if length(u_in) == 1.: if nargin == 3.: niter = 5. p = q q = u_in a_in = prony(x, 0., p) elif nargin == 4.: niter = p p = q q = u_in a_in = prony(x, 0., p) elif nargin == 5.: a_in = niter niter = p p = q q = u_in u_in = np.zeros(matcompat.size(x)) u_in[0] = 1. #% make a unit impulse whose length is same as x else: if length(u_in) != length(x): matcompat.error(message('signal:stmcb:InvalidDimensions')) if nargin<6.: [b, a_in] = prony(x, 0., p) if nargin<5.: niter = 5. a = a_in N = length(x) for i in np.arange(1., (niter)+1): u = filter(1., a, x) v = filter(1., a, u_in) C1 = convmtx(u.flatten(1), (p+1.)) C2 = convmtx(v.flatten(1), (q+1.)) C1_minus = -C1 T_sub1 = C1_minus[0:N,:] T_sub2 = C2[0:N,:] T = np.array(np.hstack((T_sub1, T_sub2))) #%T = [ C1_minus(1:N,:) C2(1:N,:) ]; T_minus = -T T_left = T[:,1:p+q+2.] T_right = T_minus[:,0] c = linalg.solve(T_left, T_right) #% c = T(:,2:p+q+2)\(T_minus(:,1)); % move 1st column to RHS and do least-squares a = np.array(np.vstack((np.hstack((1.)), np.hstack((c[0:p]))))) #% denominator coefficients b = c[int(p+1.)-1:p+q+1.] #% numerator coefficients a = a.T b = b.T return [b, a]
def arparest(x, p, method): # Local Variables: a, msgobj, XM, Xc, a_left, a_right, minlength_x, mx, nx, p, x, msg, e, Xc_minus, X1, method, Cz # Function calls: real, corrmtx, nargchk, getString, min, strcmp, issparse, nargin, length, abs, isempty, error, arparest, message, round, size #%ARPAREST AR parameter estimation via a specified method. #% A = ARPAREST(X,ORDER,METHOD) returns the polynomial A corresponding to #% the AR parametric signal model estimate of vector X using the specified #% METHOD. ORDER is the model order of the AR system. #% #% Supported methods are: 'covariance' and 'modified' although all of the #% methods of CORRMTX will work. In particular if 'autocorrelation' is #% used, the results should be the same as those of ARYULE (but slower). #% #% [A,E] = ARPAREST(...) returns the variance estimate E of the white noise #% input to the AR model. #% Ref: S. Kay, MODERN SPECTRAL ESTIMATION, #% Prentice-Hall, 1988, Chapter 7 #% S. Marple, DIGITAL SPECTRAL ANALYSIS WITH APPLICATION, #% Prentice-Hall, 1987, Chapter 8. #% P. Stoica and R. Moses, INTRODUCTION TO SPECTRAL ANALYSIS, #% Prentice-Hall, 1997, Chapter 3 #% Author(s): R. Losada and P. Pacheco #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.5.4.3 $ $Date: 2011/05/13 18:13:56 $ matcompat.error(nargchk(3., 3., nargin, 'struct')) [mx, nx] = matcompat.size(x) #% Initialize in case we return early a = np.array([]) e = np.array([]) #% Assign msg in case there are no errors msg = \' msgobj = np.array([]) #% Set up necessary but not sufficient conditions for the correlation #% matrix to be nonsingular. From (Marple) _switch_val=method if False: # switch pass elif _switch_val == 'covariance': minlength_x = 2.*p elif _switch_val == 'modified': minlength_x = 3.*p/2. else: msgobj = message('signal:arparest:UnknMethod') msg = getString(msgobj) return [] #% Do some data sanity testing if isempty(x) or length(x)<minlength_x or matcompat.max(mx, nx) > 1.: if strcmp(method, 'modified'): msgobj = message('signal:arparest:TooSmallForModel', 'X', '3/2') msg = getString(msgobj) else: msgobj = message('signal:arparest:TooSmallForModel', 'X', '2') msg = getString(msgobj) return [] if issparse(x): msgobj = message('signal:arparest:InputSignalCannotBeSparse') msg = getString(msgobj) return [] if isempty(p) or p != np.round(p): msgobj = message('signal:arparest:ModelOrderMustBeInteger') msg = getString(msgobj) return [] x = x.flatten(1) #% Generate the appropriate data matrix XM = corrmtx(x, p, method) Xc = XM[:,1:] X1 = XM[:,0] #% Coefficients estimated via the covariance method a_left = np.array(np.hstack((1.))) Xc_minus = -Xc a_right = linalg.solve(Xc_minus, X1) a = np.array(np.vstack((np.hstack((a_left)), np.hstack((a_right))))) #%a = [1; -Xc\X1]; #% Estimate the input white noise variance Cz = np.dot(X1.conj().T, Xc) e = np.dot(X1.conj().T, X1)+np.dot(Cz, a[1:]) #% Ignore the possible imaginary part due to numerical errors and force #% the variance estimate of the white noise to be positive e = np.abs(np.real(e)) a = a.flatten(0) #% By convention all polynomials are row vectors #% [EOF] arparest.m return [a, e, msg, msgobj]
# Local Variables: knots, mults, breaks, reg, degree # Function calls: do_kntbrkdegreg, kntbrkdegmult, warning, numel, error, any if numel(breaks)<2.: matcompat.error('kntbrkdegreg: the knots sequence should contain at least two points') if numel(reg) == 1.: elif numel(reg) == numel(breaks): mults = degree-reg elif numel(reg) == numel(breaks)-2.: mults = np.array(np.hstack((-1., degree-reg, -1.))) else: matcompat.error('kntbrkdegreg: the length of mult should be equal to one or the number of knots') if np.any((reg<-1.)): matcompat.warning('kntbrkdegreg: for some knots the regularity is lower than -1') elif np.any((reg > degree-1.)): matcompat.error('kntbrkdegreg: the regularity should be lower than the degree') knots = kntbrkdegmult(breaks, degree, mults) #%!test #%! breaks = [0 1 2 3 4]; #%! degree = 3; #%! knots = kntbrkdegreg (breaks, degree); #%! assert (knots, [0 0 0 0 1 2 3 4 4 4 4]) #%!test
def InterpolateCrossCorrelation(FirstSignal, SecondSignal, Delays, SamplingPeriod, MaxDelay): # Local Variables: SecondPolynomialCoefficients, FirstPolynomialCoefficients, MaxDelay, SecondSignal, MaxLag, PCCC, Delays, Curvature, SamplingPeriod, CrossCorrelation, FirstSignal, Derivative, dd # Function calls: disp, PolynomialCoefficientsCrossCorrelation, numel, PolynomialInterpolationCoefficients, ceil, nargin, zeros, InterpolateCrossCorrelation, error, size #%InterpolatieCrossCorrelation interpolates the cross-correlation function #%of two discrete signals #% #% USAGE: [CrossCorrelation Derivative Curvature] = #% InterpolateCrossCorrelation(FirstSignal,SecondSignal,Delays,SamplingPeriod) #% #% PARAMETERS: #% FirstSignal ~ values of the first signal #% SecondSignal ~ values of the second signal #% Delays ~ delays in which we want to evaluate the cross-correlation function #% SamplingPeriod ~ sampling period of the signals #% #% RETURN VALUE: #% CrossCorrelation ~ values of the cross-correlation function at delays #% Derivatives ~ values of its derivative at delays #% Curvature ~ values of its second derivative at delays #% #% DESCRIPTION: #% This function interpolates the cross-correlation function at times Delays #% of the signals FirstSignal and SecondSignal (sampled at SamplingPeriod). #% It does that assuming some polynomial interpolation at each time interval. #% #% This function will then compute: #% 1) The sequence of coefficients of each polynomial interpolation. #% 2) The cross-correlation of these sequences of coefficients. #% 3) The interpolation of the cross-correlation function at each of the Delays. #% #% REFERENCES: #% X. Alameda-Pineda and R. Horaud. Geometrically-constrained time delay #% estimation-based sound source localisation (gTDESSL). Research Report #% RR-7988, INRIA, June 2012. #% #% see also PolynomialInterpolationCoefficients, PolynomialCoefficientsCrossCorrelation and performCCInterpolation #% Copyright 2012, Xavier Alameda-Pineda #% INRIA Grenoble Rhone-Alpes #% E-mail: [email protected] #% #% This is part of the gtde program. #% #% gtde is free software: you can redistribute it and/or modify #% it under the terms of the GNU General Public License as published by #% the Free Software Foundation, either version 3 of the License, or #% (at your option) any later version. #% #% This program is distributed in the hope that it will be useful, #% but WITHOUT ANY WARRANTY; without even the implied warranty of #% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #% GNU General Public License for more details. #% #% You should have received a copy of the GNU General Public License #% along with this program. If not, see <http://www.gnu.org/licenses/>. #%%% Input check if nargin<4.: matcompat.error('Usage: [CrossCorrelation Derivative] = Interpolation(FirstSignal,SecondSignal,Delays,SamplingPeriod[,MaxDelay]') #%%% Compute the interpolation polynomial coefficients of the signals [FirstPolynomialCoefficients] = PolynomialInterpolationCoefficients(FirstSignal, SamplingPeriod) [SecondPolynomialCoefficients] = PolynomialInterpolationCoefficients(SecondSignal, SamplingPeriod) #%%% Compute the cross-correlation of the coefficients if nargin<5.: [PCCC] = PolynomialCoefficientsCrossCorrelation(FirstPolynomialCoefficients, SecondPolynomialCoefficients) else: MaxLag = np.ceil(matdiv(MaxDelay, SamplingPeriod)) [PCCC] = PolynomialCoefficientsCrossCorrelation(FirstPolynomialCoefficients, SecondPolynomialCoefficients, MaxLag) #%%% Interpolate the cross-correlation at "Delays" CrossCorrelation = np.zeros(matcompat.size(Delays)) Derivative = np.zeros(matcompat.size(Delays)) Curvature = np.zeros(matcompat.size(Delays)) for dd in np.arange(1., (numel(Delays))+1): if dd == 2651.: np.disp('stop') Delays[int(dd)-1] return [CrossCorrelation, Derivative, Curvature]
def invfreqz(g, w, varargin): # Local Variables: realFlag, cg, realStr, D31, gndir, t1, cw, rw, nm, na, nb, Vcap, V1, rg, pf, tol, maxiter, varargin, cwf, wf, ll, D, rwf, D32, Dva, Dvb, gaussFlag, verb, GC, T, e, th, nk, a, OM, b, Vd, g, k, l, st, indg, R, t, w, indb, D3 # Function calls: disp, polystab, deal, ischar, int2str, all, warning, home, message, size, getString, sqrt, clc, zeros, invfreqz, norm, real, nargchk, max, nargin, ones, isempty, lower, length, num2str, exp, error, strcmp #%INVFREQZ Discrete filter least squares fit to frequency response data. #% [B,A] = INVFREQZ(H,W,NB,NA) gives real numerator and denominator #% coefficients B and A of orders NB and NA respectively, where #% H is the desired complex frequency response of the system at frequency #% points W, and W contains the normalized frequency values within the #% interval [0, Pi] (W is in units of radians/sample). #% #% INVFREQZ yields a filter with real coefficients. This means that it is #% sufficient to specify positive frequencies only; the filter fits the data #% conj(H) at -W, ensuring the proper frequency domain symmetry for a real #% filter. #% #% [B,A] = INVFREQZ(H,W,NB,NA,Wt) allows the fit-errors to be weighted #% versus frequency. LENGTH(Wt)=LENGTH(W)=LENGTH(H). #% Determined by minimization of sum |B-H*A|^2*Wt over the freqs in W. #% #% [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER) does another type of fit: #% Sum |B/A-H|^2*Wt is minimized with respect to the coefficients in B and #% A by numerical search in at most ITER iterations. The A-polynomial is #% then constrained to be stable. [B,A]=INVFREQZ(H,W,NB,NA,Wt,ITER,TOL) #% stops the iterations when the norm of the gradient is less than TOL. #% The default value of TOL is 0.01. The default value of Wt is all ones. #% This default value is also obtained by Wt=[]. #% #% [B,A] = INVFREQZ(H,W,NB,NA,Wt,ITER,TOL,'trace') provides a textual #% progress report of the iteration. #% #% [B,A] = INVFREQZ(H,W,'complex',NB,NA,...) creates a complex filter. In #% this case, no symmetry is enforced and W contains normalized frequency #% values within the interval [-Pi, Pi]. #% #% % Example: #% % Convert a simple transfer function to frequency response data and #% % then back to the original filter coefficients. If the system is #% % unstable, use invfreqs's iterative algorithm to find a stable #% % approximation to the system. #% #% b = [1 2 3 2 3]; % Numerator coefficients #% a = [1 2 3 2 1 4]; % Denominator coefficients #% [h,w] = freqz(b,a,64); #% [bb,aa] = invfreqz(h,w,4,5) % aa has poles in the right half-plane. #% [z,p,k] = tf2zp(bb,aa); % Get Zero-Pole form #% fprintf('Stable Approximation to the system:') #% [bbb,aaa] = invfreqz(h,w,4,5,[],30) % Stable approximation to system #% subplot(2,1,1); zplane(bb,aa); title('PZ plot - Unstable system') #% subplot(2,1,2); zplane(bbb,aaa); title('PZ plot of stable system') #% #% See also FREQZ, FREQS, INVFREQS. #% Author(s): J.O. Smith and J.N. Little, 4-23-86 #% J.N. Little, 4-27-88, revised #% Lennart Ljung, 9-21-92, rewritten #% T. Krauss, 99-92, trace mode made optional #% Copyright 1988-2004 The MathWorks, Inc. #% $Revision: 1.8.4.8 $ $Date: 2012/10/29 19:31:23 $ #% calling sequence is #%function [b,a]=invfreqz(g,w,nb,na,wf,maxiter,tol,pf) #% OR #%function [b,a]=invfreqz(g,w,'complex',nb,na,wf,maxiter,tol,pf) matcompat.error(nargchk(4., 9., nargin, 'struct')) if ischar(varargin.cell[0]): realStr = lower(varargin.cell[0]) varargin[0] = np.array([]) else: realStr = 'real' gaussFlag = length(varargin) > 3. #% run Gauss-Newton algorithm or not? if length(varargin)<6.: varargin.cell[5] = np.array([]) #% pad varargin with []'s [nb, na, wf, maxiter, tol, pf] = deal(varargin.cell[:]) _switch_val=realStr if False: # switch pass elif _switch_val == 'real': realFlag = 1. elif _switch_val == 'complex': realFlag = 0. else: matcompat.warning(message('signal:invfreqz:InvalidParam', realStr)) realFlag = 0. nk = 0. T = 1. #% The code is prepared for arbitrary sampling interval T and for #% constraining the numerator to begin with nk zeros. nb = nb+nk+1. if isempty(pf): verb = 0. elif strcmp(pf, 'trace'): verb = 1. else: matcompat.error(message('signal:invfreqz:NotSupported', pf)) if isempty(wf): wf = np.ones(length(w), 1.) wf = np.sqrt(wf) if length(g) != length(w): matcompat.error(message('signal:invfreqz:InvalidDimensions', 'H', 'W')) if length(wf) != length(w): matcompat.error(message('signal:invfreqz:InvalidDimensions', 'Wt', 'W')) #% if any( (w>pi) | (w<0) ) && realFlag #% warning(message('signal:invfreqz:InvalidRegion', 'W', 'INVFREQZ', '''complex''')) #% end [rw, cw] = matcompat.size(w) if rw > cw: w = w.conj().T [rg, cg] = matcompat.size(g) if cg > rg: g = g.T [rwf, cwf] = matcompat.size(wf) if cwf > rwf: wf = wf.conj().T nm = matcompat.max(na, (nb+nk-1.)) OM = np.exp(np.dot(np.dot(np.dot(-1i., np.arange(0., (nm)+1).conj().T), w), T)) #% #% Estimation in the least squares case: #% Dva = OM[1:na+1.,:].T*np.dot(g, np.ones(1., na)) Dvb = -OM[int(nk+1.)-1:nk+nb,:].T D = np.array(np.hstack((Dva, Dvb)))*np.dot(wf, np.ones(1., (na+nb))) if realFlag: R = np.real(np.dot(D.conj().T, D)) Vd = np.real(np.dot(D.conj().T, -g*wf)) else: R = np.dot(D.conj().T, D) Vd = np.dot(D.conj().T, -g*wf) th = linalg.solve(R, Vd) a = np.array(np.hstack((1., th[0:na].T))) b = np.array(np.hstack((np.zeros(1., nk), th[int(na+1.)-1:na+nb].T))) if not gaussFlag: return [] #% Now for the iterative minimization if isempty(maxiter): maxiter = 30. if isempty(tol): tol = 0.01 indb = np.arange(1., (length(b))+1) indg = np.arange(1., (length(a))+1) a = polystab(a) #% Stabilizing the denominator #% The initial estimate: GC = (np.dot(b, OM[int(indb)-1,:])/np.dot(a, OM[int(indg)-1,:])).T e = (GC-g)*wf Vcap = np.dot(e.conj().T, e) t = np.array(np.hstack((a[1:na+1.], b[int(nk+1.)-1:nk+nb]))).T if verb: #%messages similar to invfreqs clc np.disp(np.array(np.hstack((' ', getString(message('signal:invfreqs:INITIALESTIMATE')))))) np.disp(np.array(np.hstack((getString(message('signal:invfreqs:CurrentFit')), num2str(Vcap))))) np.disp(getString(message('signal:invfreqs:Parvector'))) np.disp(t) #% #% ** the minimization loop ** #% gndir = 2.*tol+1. l = 0. st = 0. while np.all(np.array(np.hstack((linalg.norm(gndir) > tol, l<maxiter, st != 1.)))): l = l+1. #% * compute gradient * D31 = OM[1:na+1.,:].T*np.dot(-GC/np.dot(a, OM[0:na+1.,:]).T, np.ones(1., na)) D32 = OM[int(nk+1.)-1:nk+nb,:].T/np.dot(np.dot(a, OM[0:na+1.,:]).T, np.ones(1., nb)) D3 = np.array(np.hstack((D31, D32)))*np.dot(wf, np.ones(1., (na+nb))) #% * compute Gauss-Newton search direction * e = (GC-g)*wf if realFlag: R = np.real(np.dot(D3.conj().T, D3)) Vd = np.real(np.dot(D3.conj().T, e)) else: R = np.dot(D3.conj().T, D3) Vd = np.dot(D3.conj().T, e) gndir = linalg.solve(R, Vd) #% * search along the gndir-direction * ll = 0. k = 1. V1 = Vcap+1. while np.all(np.array(np.hstack((V1, ll<20.)))): t1 = t-np.dot(k, gndir) if ll == 19.: t1 = t a = polystab(np.array(np.hstack((1., t1[0:na].T)))) t1[0:na] = a[1:na+1.].T #%Stabilizing denominator b = np.array(np.hstack((np.zeros(1., nk), t1[int(na+1.)-1:na+nb].T))) GC = (np.dot(b, OM[int(indb)-1,:])/np.dot(a, OM[int(indg)-1,:])).T V1 = np.dot(((GC-g)*wf).conj().T, (GC-g)*wf) t1 = np.array(np.hstack((a[1:na+1.], b[int(nk+1.)-1:nk+nb]))).T if verb: home np.disp(int2str(ll)) k = k/2. ll = ll+1. if ll == 20.: st = 1. if ll == 10.: gndir = np.dot(matdiv(Vd, linalg.norm(R)), length(R)) k = 1. if verb: home np.disp(np.array(np.hstack((' ', getString(message('signal:invfreqs:ITERATION')), int2str(l))))) np.disp(np.array(np.hstack((getString(message('signal:invfreqs:CurrentFit')), num2str(V1), getString(message('signal:invfreqs:PreviousFit')), num2str(Vcap))))) np.disp(getString(message('signal:invfreqs:CurrentParPrevparGNdir'))) np.disp(np.array(np.hstack((t1, t, gndir)))) np.disp(np.array(np.hstack((getString(message('signal:invfreqs:NormOfGNvector')), num2str(linalg.norm(gndir)))))) if st == 1.: np.disp(getString(message('signal:invfreqs:NoImprovement'))) np.disp(getString(message('signal:invfreqs:IterationsThereforeTerminated'))) t = t1 Vcap = V1 return [b, a]