# [Scipy-tickets] [SciPy] #1315: FIR filter created by firwin() does not have linear phase

SciPy Trac scipy-tickets@scipy....
Sat Nov 13 11:57:33 CST 2010

```#1315: FIR filter created by firwin() does not have linear phase
---------------------------------------+------------------------------------
Reporter:  warren.weckesser           |       Owner:  somebody
Type:  defect                     |      Status:  new
Priority:  normal                     |   Milestone:  0.9.0
Component:  scipy.signal               |     Version:  0.8.0
Keywords:  firwin, FIR, linear phase  |
---------------------------------------+------------------------------------

Old description:

> For even numbers of taps for which half the number of taps is odd, firwin
> gives coefficients for a FIR filter that does not have linear phase.  The
> following script:
> {{{
> import numpy as np
> from scipy.signal import firwin, freqz
> from pylab import plot, show, figure, clf, title
>
> # The following demonstrates that an even number of taps results
> # in a coefficients that are not symmetric.
> for n in range(8,12):
>     taps = firwin(n, 0.5)
>     print "number of taps: ", taps.size
>     m = n/2
>     print "Symmetric: ", np.allclose(taps[:n/2],taps[n:m:-1])
>     print "taps:"
>     print taps
>     print
>
> # Compute the phase response for n=10
> n = 10
> taps = firwin(n, 0.5)
> w, h = freqz(taps, worN=8000)
>
> phase = np.unwrap(np.arctan2(h.imag, h.real))
> dphase = np.diff(phase)/np.diff(w)
>
> figure(1)
> clf()
> plot(w[:-1]/np.pi, dphase)
> title("Derivative of the phase\n(should be constant)")
>
> show()
> }}}
> generates the following output:
> {{{
> number of taps:  8
> Symmetric:  False
> taps:
> [ -1.55107885e-18  -2.26639855e-02   1.04697822e-17   2.73977083e-01
>    4.97373806e-01   2.73977083e-01   1.04697822e-17  -2.26639855e-02]
>
> number of taps:  9
> Symmetric:  True
> taps:
> [ -1.55107885e-18  -2.26639855e-02   1.04697822e-17   2.73977083e-01
>    4.97373806e-01   2.73977083e-01   1.04697822e-17  -2.26639855e-02
>   -1.55107885e-18]
>
> number of taps:  10
> Symmetric:  False
> taps:
> [  5.08605417e-03  -3.26714830e-18  -4.21562032e-02   1.32776235e-17
>    2.89952076e-01   4.99322201e-01   2.89952076e-01   1.32776235e-17
>   -4.21562032e-02  -3.26714830e-18]
>
> number of taps:  11
> Symmetric:  True
> taps:
> [  5.06031712e-03  -3.25061549e-18  -4.19428794e-02   1.32104345e-17
>    2.88484826e-01   4.96795472e-01   2.88484826e-01   1.32104345e-17
>   -4.19428794e-02  -3.25061549e-18   5.06031712e-03]
> }}}
> A fix will be included in the patch being discussed in Ticket #902; see
> that ticket for more details.
>
> The current ticket ensures that we have a record of the bug in Trac.
>
> Technically, firwin() doesn't *say* the filter will have linear phase,
> but the result is surprising enough that I consider it a bug.

New description:

For even numbers of taps for which half the number of taps is odd, firwin
gives coefficients for a FIR filter that does not have linear phase.  The
following script:
{{{
import numpy as np
from scipy.signal import firwin, freqz
from pylab import plot, show, figure, clf, title

# The following demonstrates that an even number of taps results
# in a coefficients that are not symmetric.
for n in range(8,12):
taps = firwin(n, 0.5)
print "number of taps: ", taps.size
m = n/2
print "Symmetric: ", np.allclose(taps[:m],taps[n:-m-1:-1])
print "taps:"
print taps
print

# Compute the phase response for n=10
n = 10
taps = firwin(n, 0.5)
w, h = freqz(taps, worN=8000)

phase = np.unwrap(np.arctan2(h.imag, h.real))
dphase = np.diff(phase)/np.diff(w)

figure(1)
clf()
plot(w[:-1]/np.pi, dphase)
title("Derivative of the phase\n(should be constant)")

show()
}}}
generates the following output:
{{{
number of taps:  8
Symmetric:  False
taps:
[ -1.55107885e-18  -2.26639855e-02   1.04697822e-17   2.73977083e-01
4.97373806e-01   2.73977083e-01   1.04697822e-17  -2.26639855e-02]

number of taps:  9
Symmetric:  True
taps:
[ -1.55107885e-18  -2.26639855e-02   1.04697822e-17   2.73977083e-01
4.97373806e-01   2.73977083e-01   1.04697822e-17  -2.26639855e-02
-1.55107885e-18]

number of taps:  10
Symmetric:  False
taps:
[  5.08605417e-03  -3.26714830e-18  -4.21562032e-02   1.32776235e-17
2.89952076e-01   4.99322201e-01   2.89952076e-01   1.32776235e-17
-4.21562032e-02  -3.26714830e-18]

number of taps:  11
Symmetric:  True
taps:
[  5.06031712e-03  -3.25061549e-18  -4.19428794e-02   1.32104345e-17
2.88484826e-01   4.96795472e-01   2.88484826e-01   1.32104345e-17
-4.19428794e-02  -3.25061549e-18   5.06031712e-03]
}}}
A fix will be included in the patch being discussed in Ticket #902; see
that ticket for more details.

The current ticket ensures that we have a record of the bug in Trac.

Technically, firwin() doesn't *say* the filter will have linear phase, but
the result is surprising enough that I consider it a bug.

--

Comment(by warren.weckesser):

Fix script.

--
Ticket URL: <http://projects.scipy.org/scipy/ticket/1315#comment:1>
SciPy <http://www.scipy.org>
SciPy is open-source software for mathematics, science, and engineering.
```