www.gusucode.com > signal 工具箱matlab源码程序 > signal/impzlength.m

    function N = impzlength(b,varargin)
%IMPZLENGTH Impulse response length of digital filter
%   L = IMPZLENGTH(B,A) returns the length, L, of the impulse response of
%   the filter:
%
%               jw               -jw              -jmw
%        jw  B(e)    b(1) + b(2)e + .... + b(m+1)e
%     H(e) = ---- = ------------------------------------
%               jw               -jw              -jnw
%            A(e)    a(1) + a(2)e + .... + a(n+1)e
%
%   given numerator and denominator coefficients in vectors B and A.
%
%   L = IMPZLENGTH(SOS) returns the approximate length, L, of the impulse
%   response of the filter specified using a second order sections matrix
%   SOS. SOS is a Kx6 matrix, where the number of sections, K, must be
%   greater than or equal to 2. Each row of SOS corresponds to the
%   coefficients of a second order filter. From the transfer function
%   displayed above, the ith row of the SOS matrix corresponds to [bi(1)
%   bi(2) bi(3) ai(1) ai(2) ai(3)].
%
%   L = IMPZLENGTH(D) returns the approximate length, L, of the impulse
%   response of the digital filter, D. You design a digital filter, D, by
%   calling the <a href="matlab:help designfilt">designfilt</a> function.
%
%   L = IMPZLENGTH(...,TOL) specifies a tolerance for greater or less
%   accuracy.  By default, TOL = 5e-5.
%
%   % Example 1:
%   %   Design a lowpass FIR filter with normalized cut-off frequency at
%   %   0.3 and determine the length of its impulse response.
%
%   b=fircls1(54,0.3,0.02,0.008);
%   impzlength(b)                       % length of impulse response
%
%   % Example 2:
%   %   Design a 5th order lowpass elliptic IIR filter and determine the
%   %   length of its impulse response.
%
%   [b,a] = ellip(5,0.5,20,0.4);
%   impzlength(b,a)                     % length of impulse response
%
%   % Example 3:
%   %   Design a Butterworth highpass IIR filter, represent its coefficients
%   %   using second order sections, and determine the length of its
%   %   impulse response.
%
%   [z,p,k] = butter(6,0.7,'high');
%   SOS = zp2sos(z,p,k);
%   impzlength(SOS)                     % length of impulse response
%
%   % Example 4:
%   %   Use the designfilt function to design a highpass IIR digital filter 
%   %   with order 8, passband frequency of 75 KHz, and a passband ripple 
%   %   of 0.2 dB. Sample rate is 200 KHz. Determine the length of its
%   %   impulse response.
%  
%   D = designfilt('highpassiir', 'FilterOrder', 8, ...
%            'PassbandFrequency', 75e3, 'PassbandRipple', 0.2,...
%            'SampleRate', 200e3);
%
%   impzlength(D)
%
%   See also IMPZ.

%   Copyright 1988-2013 The MathWorks, Inc.

narginchk(1,3)

isTF = true; % True if dealing with a transfer function

if all(size(b)>[1 1])
    % Input is a matrix, check if it is a valid SOS matrix
    if size(b,2) ~= 6
        error(message('signal:signalanalysisbase:invalidinputsosmatrix'));
    end
    isTF = false; % SOS instead of transfer function
    
    if nargin > 1
        tol = varargin{1};
    else
        tol = .00005;
    end
    % Checks if SOS is a valid numeric data input
    signal.internal.sigcheckfloattype(b,'','impzlength','SOS');
    % Cast to enforce precision rules
    tol = signal.internal.sigcasttofloat(tol,'double','impzlength',...
      'tol','allownumeric');
end

if isTF
    if nargin == 1
        a = 1;
    else
        a = varargin{1};
    end
    
    % Checks if B and A are valid numeric data inputs
    signal.internal.sigcheckfloattype(b,'','impzlength','B');
    signal.internal.sigcheckfloattype(a,'','impzlength','A');

    if nargin < 3
        tol = .00005;
    else
        tol = varargin{2};
    end
    % Cast to enforce precision rules
    tol = signal.internal.sigcasttofloat(tol,'double','impzlength',...
      'tol','allownumeric');
    
    % Determine if filter is FIR
    if signalpolyutils('isfir',b,a),
        N = length(b);
    else
        indx= find(b, 1);
        if isempty(indx),
            delay = 0;
        else
            delay=indx-1;
        end
        p = roots(a);
        if any(abs(p)>1.0001),
            N = unstable_length(p);
        else
            N = stableNmarginal_length(p,tol,delay);
        end
        % Cast to enforce precision rules
        N = double(N);
        N = max(length(a)+length(b)-1,N);
        
        % Always return an integer length
        N = floor(N);
    end
else
    N = lclsosimpzlength(b,tol);
    % Cast to enforce precision rules
    N = double(N);
end
%-------------------------------------------------------------------------
function N = unstable_length(p)
% Determine the length for an unstable filter
ind = abs(p)>1;
N = 6/log10(max(abs(p(ind))));% 1000000 times original amplitude


%-------------------------------------------------------------------------
function N = stableNmarginal_length(p,tol,delay)
% Determine the length for an unstable filter

%minimum height is .00005 original amplitude:
ind = find(abs(p-1)<1e-5);
p(ind) = -p(ind);    % treat constant as Nyquist
ind = find(abs(abs(p)-1)<1e-5);
periods = 5*max(2*pi./abs(angle(p(ind)))); % five periods
p(ind) = [];   % get rid of unit circle poles
[maxp,maxind] = max(abs(p));
if isempty(p)   % pure oscillator
    N = periods;
elseif isempty(ind)   % no oscillation
    N = mltplcty(p,maxind)*log10(tol)/log10(maxp) + delay;
else    % some of both
    N = max(periods, ...
        mltplcty(p,maxind)*log10(tol)/log10(maxp) ) + delay;
end

%-------------------------------------------------------------------------
function m = mltplcty( p, ind, tol)
%MLTPLCTY  Multiplicity of a pole
%   MLTPLCTY(P,IND,TOL) finds the multiplicity of P(IND) in the vector P
%   with a tolerance of TOL.  TOL defaults to .001.

if nargin<3
    tol = .001;
end

[mults,indx]=mpoles(p,tol);

m = mults(indx(ind));
for i=indx(ind)+1:length(mults)
    if mults(i)>m
        m = m + 1;
    else
        break;
    end
end

%--------------------------------------------------------------------------
function len = lclsosimpzlength(sos,tol)

% Initialize length
firlen=1;
iirlen=1;

% Convert the filter to a transfer function.
for k=1:size(sos,1)
    
    % Get the transfer function coefficients
    b=sos(k,1:3);
    a=sos(k,4:6);
    
    if signalpolyutils('isfir',b,a),
        % Add the length of each FIR section
        firlen = firlen + length(b) - 1;
    else
        % Keep the maximum length of all IIR sections
        iirlen = max(iirlen, impzlength(b,a,tol));
    end
end

% Use the longest of FIR or IIR
len=max(firlen,iirlen);