[SciPy-Dev] scipy.signal.normalize problems?
Ralf Gommers
ralf.gommers at googlemail.com
Tue May 29 16:08:27 EDT 2012
On Mon, May 21, 2012 at 9:11 PM, Josh Lawrence <josh.k.lawrence at gmail.com>wrote:
> If I change the allclose lines to have
>
> allclose(0, outb[:,0], atol=1e-14)
>
> it works. I think that is what the original goal was, anyways. From the
> documentation of allclose, what I have written above result in ensuring
>
> np.abs(0 - outb[:,0]) > atol + rtol * np.abs(outb[:,0])
>
> with rtol defaulting to 1e-5. I'm still not sure about how things have
> been written for the 'b' argument of normalize being rank-2, so I can't
> guarantee that my fix makes things work for that. Should I file a bug
> report/submit a patch/send a git pull request, etc?
>
Sounds like you understood the issue and have a fix that does what you
expect (matches Matlab), so a pull request would be nice.
For the rank-2 thing, you can just note it on the PR if you can't figure it
out.
Ralf
> Cheers,
>
> Josh Lawrence
>
> On May 21, 2012, at 2:45 PM, Josh Lawrence wrote:
>
> > Hey all,
> >
> > I've been having some problems designing a Chebyshev filter and I think
> I have narrowed down the hang-up to scipy.signal.normalize. I think what's
> going on in my case is that line 286 of filter_design.py (the first
> allclose call in the normalize function) is producing a false positive.
> Here's the function definition:
> >
> > def normalize(b, a):
> > """Normalize polynomial representation of a transfer function.
> >
> > If values of b are too close to 0, they are removed. In that case, a
> > BadCoefficients warning is emitted.
> > """
> > b, a = map(atleast_1d, (b, a))
> > if len(a.shape) != 1:
> > raise ValueError("Denominator polynomial must be rank-1 array.")
> > if len(b.shape) > 2:
> > raise ValueError("Numerator polynomial must be rank-1 or"
> > " rank-2 array.")
> > if len(b.shape) == 1:
> > b = asarray([b], b.dtype.char)
> > while a[0] == 0.0 and len(a) > 1:
> > a = a[1:]
> > outb = b * (1.0) / a[0]
> > outa = a * (1.0) / a[0]
> > if allclose(outb[:, 0], 0, rtol=1e-14): <------------------ Line 286
> > 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:]
> > if outb.shape[0] == 1:
> > outb = outb[0]
> > return outb, outa
> >
> > I marked line 286. If I reproduce all the steps carried out by
> scipy.signal.iirdesign, I end up with a (b, a) pair which results of
> scipy.signal.lp2lp and looks like this:
> >
> > In [106]: b_lp2
> > Out[106]: array([ 1.55431359e-06+0.j])
> >
> > In [107]: a_lp2
> > Out[107]:
> > array([ 1.00000000e+00 +0.00000000e+00j,
> > 3.46306104e-01 -2.01282794e-16j,
> > 2.42572185e-01 -6.08207573e-17j,
> > 5.92946943e-02 +0.00000000e+00j,
> > 1.82069156e-02 +5.55318531e-18j,
> > 2.89328123e-03 +0.00000000e+00j,
> > 4.36566281e-04 -2.95766719e-19j,
> > 3.50842810e-05 -3.19180568e-20j, 1.64641246e-06
> -1.00966301e-21j])
> >
> > scipy.signal.iirdesign takes b_lp2, a_lp2 (my local variable names to
> keep track of what's going on) and runs them through scipy.signal.bilinear
> (in filter_design.py bilinear is called on line 624 within iirfilter.
> iirdesign calls iirfilter which calls bilinear). Inside bilinear, normalize
> is called on line 445. I've made my own class with bilinear copied and
> pasted from filter_design.py to test things. In bilinear, the input to
> normalize is given by
> >
> > b = [ 1.55431359e-06 1.24345087e-05 4.35207804e-05 8.70415608e-05
> > 1.08801951e-04 8.70415608e-05 4.35207804e-05 1.24345087e-05
> > 1.55431359e-06]
> > a = [ 72269.02590913 -562426.61430468 1918276.19173089
> -3745112.83646825
> > 4577612.13937628 -3586970.61385926 1759651.18184723 -494097.93515708
> > 60799.46134722]
> >
> > In normalize, right before the allclose() call, outb is defined by
> >
> > outb = [[ 2.15073272e-11 1.72058618e-10 6.02205162e-10
> 1.20441032e-09
> > 1.50551290e-09 1.20441032e-09 6.02205162e-10 1.72058618e-10
> > 2.15073272e-11]]
> >
> > From what I read of the function normalize, it should only evaluate true
> if all of the coefficients in outb are smaller than 1e-14. However, that's
> not what is going on. I have access to MATLAB and if I go through the same
> design criteria to design a chebyshev filter, I get the following:
> >
> > b =
> >
> > 1.0e-08 *
> >
> > Columns 1 through 5
> >
> > 0.002150733144728 0.017205865157826 0.060220528052392
> 0.120441056104784 0.150551320130980
> >
> > Columns 6 through 9
> >
> > 0.120441056104784 0.060220528052392 0.017205865157826
> 0.002150733144728
> >
> > which matches up rather well for several significant figures.
> >
> > I apologize if this is not clearly explained, but I'm not sure what to
> do. I tried messing around with the arguments to allclose (switching it to
> be allclose(0, outb[:,0], ...), or changing the keyword from rtol to atol).
> I am also not sure why normalize is setup to run on rank-2 arrays. I looked
> through filter_design.py and none of the functions contained in it send a
> rank-2 array to normalize from what I can tell. Any thoughts?
> >
> > Cheers,
> >
> > Josh Lawrence
>
> _______________________________________________
> SciPy-Dev mailing list
> SciPy-Dev at scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scipy-dev/attachments/20120529/31767607/attachment.html>
More information about the SciPy-Dev
mailing list