Figure 8.6 gives a listing of a matlab function stabilitycheck for testing the stability of a digital filter using the Durbin step-down recursion. Figure 8.7 lists a main program for testing stabilitycheck against the more prosaic method of factoring the transfer-function denominator and measuring the pole radii. The Durbin recursion is far faster than the method based on root-finding.
function [stable] = stabilitycheck(A); N = length(A)-1; % Order of A(z) stable = 1; % stable unless shown otherwise A = A(:); % make sure it's a column vector for i=N:-1:1 rci=A(i+1); if abs(rci) >= 1 stable=0; return; end A = (A(1:i) - rci * A(i+1:-1:2))/(1-rci^2); % disp(sprintf('A[%d]=',i)); A(1:i)' end |
% TSC - test function stabilitycheck, comparing against
% pole radius computation
N = 200; % polynomial order
M = 20; % number of random polynomials to generate
disp('Random polynomial test');
nunstp = 0; % count of unstable A polynomials
sctime = 0; % total time in stabilitycheck()
rftime = 0; % total time computing pole radii
for pol=1:M
A = [1; rand(N,1)]'; % random polynomial
tic;
stable = stabilitycheck(A);
et=toc; % Typ. 0.02 sec Octave/Linux, 2.8GHz Pentium
sctime = sctime + et;
% Now do it the old fashioned way
tic;
poles = roots(A); % system poles
pr = abs(poles); % pole radii
unst = (pr >= 1); % bit vector
nunst = sum(unst);% number of unstable poles
et=toc; % Typ. 2.9 sec Octave/Linux, 2.8GHz Pentium
rftime = rftime + et;
if stable, nunstp = nunstp + 1; end
if (stable & nunst>0) | (~stable & nunst==0)
error('*** stabilitycheck() and poles DISAGREE ***');
end
end
disp(sprintf(...
['Out of %d random polynomials of order %d,',...
' %d were unstable'], M,N,nunstp));
|
When run in Octave over Linux 2.4 on a 2.8 GHz Pentium PC, the Durbin recursion is approximately 140 times faster than brute-force root-finding, as measured by the program listed in Fig.8.7.