[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