|
![](/i/fill.gif) |
So,
Andrew prodded me a bit with the whole "You know, you could use a linear
filter rather than an fft" bit. It got me thinking about IIR (infinite
impulse response) filters.
I made some offhand remark about IIR filters being exceedingly difficult
to design.
So. I first read a primer on how IIR works. OK, seems simple enough.
Multiply some of the input stream by a few coefficients and multiply
some of the output stream by a few coefficients add it all together, and
you get a filter.
Good. Remarkably simple and very easy to calculate. But how does one
design the coefficients? Poles and Zeros and something called the z
transform, the discrete cousin of the Laplace transform. Laplace
transform.... ooh, isn't that complicated?
I was surprised when I realized just how simple it really is.
Essentially a Fourier transform, but adding exponential curves to the
mix. So you have increasing and decaying waveforms. So, after reading
about that and gaining an understanding on that, I turned to the Z
transform. Which is a bit different. Foremost, it's discrete, of course,
but also uses polar coordinates rather than rectangular.
Now, my understanding of how poles and zeros relate to the way a filter
will respond is this:
The poles and zeros in the s domain are arranged along the imaginary
axis, and their position on this axis determines the frequency they will
affect. The higher the imaginary portion, the higher the frequency, the
real portion affects the exponential attack or decay. Obviously, the
magnitude of the effect is related to their distance from the axis.
Poles cannot be on the positive side of this axis. (The exponent
increases on the positive side, therefore any filter built on that would
be unstable and oscillate)
Now, that's all fine and great for doing nice manipulations to equations
and designing analog filters, but it doesn't quite fit into the discrete
world. Enter the z domain.
The z domain has similar properties to the s domain, only polar. So the
magnitude relates to how the exponent will attack or decay, and the
phase relates to the frequency. The polar orientation of the z domain
actually makes sense when you think about it. There is only a finite
number of frequencies available, and like the DFT, they will reflect at
the halfway point. This is also why poles and zeros are symmetrical
about the Real axis.
So, the polar coordinates will need to be translated to rectangular
before they can be plugged into an equation as complex numbers.
What's the frequency response? In the s domain, it's the slice of the
complex plane along the imaginary axis. In the z domain, it's the
cylinder of the complex plane defined by the unit circle, and only
really the top half of that.
So once you have the coordinates, they need to be plugged into something
to get the coefficients for the filter. That's where the z transform
comes in. Which for each unit of the summation does this:
X[z] = x[0]*z^0 + x[1]*z^-1 + ... + x[n]*z^-n
So then,
The equation for an IIR filter:
y[n] = a0*x[n] + a1*x[n-1] + ... + b1*y[n-1] + ...
becomes, through the Z transform:
H[z] = (a0 + a1*z^-1 + a2*z^-2 + a3*z^-3 ...)/(- b1*z^-1 - b2*z^-2 +
-b3*z^-3 ...)
While I understand what the Z transform does, I'm not quite sure exactly
what steps were taken to arrive at the form presented above.
But with that, it becomes rather easy to translate the locations of
poles and zeros to the coefficients:
for(n = 0; n < n_poles; n++)
{
z[n] = z[n-1]
for(i = n-1; i > 0; i--)
{
z[i] = -p[n]*z[i] + z[i-1]
}
z[0] = -p[n]*z[0]
}
The code may be a bit buggy.... I grabbed that from my notes from the
other day.
(Keeping in mind, of course, complex numbers are used in the code above)
Going the other way, however is a different story....
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |