[Scipy-tickets] [SciPy] #1615: filter_design.py removing useful coefficients in normalize()
SciPy Trac
scipy-tickets@scipy....
Sat Mar 3 09:49:54 CST 2012
#1615: filter_design.py removing useful coefficients in normalize()
-------------------------+--------------------------------------------------
Reporter: waywardgeek | Owner: somebody
Type: defect | Status: new
Priority: normal | Milestone: Unscheduled
Component: Other | Version: 0.10.0
Keywords: |
-------------------------+--------------------------------------------------
First, scipy, and the signal package in particular rock! I'm a big fan,
and we're using this code in some analog design wizards wher I work. I've
played with the iirfilter function and the iirdesign functions
extensively, in both analog and digital modes.
Digital mode is more finicky than analog. This is due in part to the
instability that seems to be inherent in the bilinear transform. If
critical frequencies are very far from the Niquist frequency (half the
sample rate), then numerator coefficients can get so small that numerical
errors in calculations dominate. To point this out, a helpful warning is
printed at the end of the "normalize" function in filter_design.py, which
is good. However, normalize then sets these small coefficients to 0. Why
it does this, I do not know, but what I do know is that it makes some
otherwise reasonably effective digital filters completely broken. What I
have been doing for our internal use is comment out the two lines that
modify the numerator, and the improvements are huge. Here's my modified
code:
if allclose(outb[:,0], 0, rtol=1e-14):
warnings.warn("Badly conditioned filter coefficients (numerator):
the "
"results may be meaningless", BadCoefficients)
#while allclose(outb[:,0], 0, rtol=1e-14) and (outb.shape[-1] >
1):
#outb = outb[:,1:]
Note that I just comment out the while loop. For an example of a filter
that needs these lines commented out, try to build a 4th order lowpass
Butterworth digital filter with a 1 KHz corner frequency, and 2 MHz sample
rate. With these two lines left in, I get a huge attenuation of the
output signal:
[http://vinux-project.org/bad.png]
With them commented out, it looks great:
[http://vinux-project.org/good.png]
I am not sure if there is a valid reason to remove terms smaller than
1e-14, but I have managed to convince myself that the results from
iirfilter are always better when we don't. In reality, users can shift
their sample frequency closer to their corner frequencies, and this
problem goes away, but if they do push the envelope, those two lines are a
real killer.
There is one other issue we had with iirdesign, which isn't a bug, but
it's annoying enough that we had to switch to using iirfilter instead.
For a lowpass, the user specifies a pass band, a stop band, and a required
attenuation in the stop band. The lowest order filter meeting the
requirements is automatically chosen, which is cool. However, the filer
implemented does not begin rolling off at the users specified pass band
frequency. Instead it stays flat until it has to start rolling off to
meet the attenuation specified at the stop band frequency. While this
makes sense to a sophisticated user, our users typically think it's a bug.
Thanks for all the good work!
--
Ticket URL: <http://projects.scipy.org/scipy/ticket/1615>
SciPy <http://www.scipy.org>
SciPy is open-source software for mathematics, science, and engineering.
More information about the Scipy-tickets
mailing list