Mercurial > hg > octave-nkf
view scripts/signal/filter.m @ 2121:bc6ecd8f1175
[project @ 1996-05-12 06:45:55 by jwe]
author | jwe |
---|---|
date | Sun, 12 May 1996 06:45:55 +0000 |
parents | bdec2591f844 |
children |
line wrap: on
line source
function [y, w] = filter(b,a,x,w) # Filter a vector. # y = filter(b,a,x) returns the solution to the following linear, # time-invariant difference equation: # # N M # sum a(k+1) y(n-k) = sum b(k+1) x(n-k) for 1<=n<=length(x) # k=0 k=0 # # where N=length(a)-1 and M=length(b)-1. An equivalent form of this # equation is: # # N M # y(n) = - sum c(k+1) y(n-k) + sum d(k+1) x(n-k) for 1<=n<=length(x) # k=1 k=0 # # where c = a/a(1) and d = b/a(1). # # In terms of the z-transform, y is the result of passing the discrete- # time signal x through a system characterized by the following rational # system function: # # M # sum d(k+1) z^(-k) # k=0 # H(z) = ---------------------- # N # 1 + sum c(k+1) z^(-k) # k=1 # # [y, sf] = filter(b,a,x,si) sets the initial state of the system, si, # and returns the final state, sf. The state vector is a column vector # whose length is equal to the length of the longest coefficient vector # minus one. If si is not set, the initial state vector is set to all # zeros. # # The particular algorithm employed is known as a transposed Direct # Form II implementation. # # SEE ALSO: poly, roots, conv, deconv, residue, polyval, polyderiv, polyinteg # Written by Tony Richardson <amr@mpl.ucsd.edu> June 1994. # Bug fix by FL (Friedrich.Leisch@ci.tuwien.ac.at) on Oct 12, 1994 if(nargin < 3 || nargin > 4) error("usage: [y, sf] = filter(b,a,x[,si])"); endif if(is_matrix(a) || is_matrix(b) || is_matrix(x)) error("Argument must be a vector."); endif N = length(a); M = length(b); L = length(x); MN = max([N, M]); lw = MN - 1; # It's convenient to pad the coefficient vectors to the same length. b = postpad(b,MN); # Ensure that all vectors have the assumed dimension. if(columns(a) > 1) a = reshape(a,N,1); endif if(columns(b) > 1) b = reshape(b,MN,1); endif if(nargin == 3) # Set initial state to zero. w = zeros(lw,1); else if(is_matrix(w) || length(w) != lw) error("state vector has the wrong dimensions."); endif if(columns(w) > 1) w = reshape(w,lw,1); endif endif # Allocate space for result. y = zeros(1,L); norm = a(1); if (norm == 0.) error("First element in second argument must be non-zero."); endif if (norm != 1.) b = b/norm; endif # Distinguish between IIR and FIR cases. The IIR code can easily be made # to work for both cases, but the FIR code is slightly faster when it can # be used. if (N > 1) # IIR filter. a = postpad(a,MN); if (norm != 1.) a = a/norm; endif for index = 1:L y(index) = w(1) + b(1)*x(index); # Update state vector if(lw > 1) w(1:(lw-1)) = w(2:lw) - a(2:lw)*y(index) + b(2:lw)*x(index); w(lw) = b(MN)*x(index) - a(MN) * y(index); else w(1) = b(MN)*x(index) - a(MN) * y(index); endif endfor else # FIR filter. if(lw > 0) for index = 1:L y(index) = w(1) + b(1)*x(index); if ( lw > 1) # Update state vector w(1:lw-1) = w(2:lw) + b(2:lw)*x(index); w(lw) = b(MN)*x(index); else w(1) = b(2)*x(index); endif endfor else # Handle special case where there is no delay separately. y = b(1)*x; endif endif endfunction