Example #1
0
    def denormalize_one_pole(self, pole):
        # cambio de variable: s -> q*(s/wo+wo/s) = q*(s^2+wo^2)/(s*wo)

        # 1/(s-p) -> (wo*s)/(q*s^2 - p*s*wo + q*wo^2)

        # entonces por cada polo REAL tengo:

        if pole.imag == 0:
            [denorm_zeroes, denorm_poles, gain_factor] = \
                signal.tf2zpk([self.denormalized_template.w0, 0], [self.q, -pole * self.denormalized_template.w0,
                                                                   self.q * self.denormalized_template.w0**2])

        # 1/( (s-p)*(s-conj(p)) ) ->
        # ((-wo^2)*s^2)/((-q^2)*s^4 + q*wo*(conj(p) + p) *s^3 + (- 2*q^2*wo^2 - p*conj(p)*wo^2)*s^2 + (p*q*wo^3 + q*wo^3*conj(p))*s - q^2*wo^4)
        # ((-wo^2)*s^2)/(a*s^4 + b *s^3 + c *s^2 + d *s + e)

        # entonces por cada polo IMAGINARIO tengo:

        else:
            a = -self.q**2
            b = self.q * self.denormalized_template.w0 * 2 * np.real(pole)
            c = -(2 * self.q**2 +
                  abs(pole)**2) * self.denormalized_template.w0**2
            d = 2 * np.real(pole) * self.q * self.denormalized_template.w0**3
            e = -self.q**2 * self.denormalized_template.w0**4

            [denorm_zeroes, denorm_poles, gain_factor
             ] = signal.tf2zpk([-self.denormalized_template.w0**2, 0, 0],
                               [a, b, c, d, e])

        return [list(denorm_poles), list(denorm_zeroes), gain_factor]
Example #2
0
 def plot_zp(self):
     zd, pd, kd = signal.tf2zpk(self.b_num_dig, self.a_den_dig)
     za, pa, ka = signal.tf2zpk(self.b_num, self.a_den)
     Pza, Ppa, Pka = signal.tf2zpk(self.Pb_num, self.Pa_den)
     plt.figure(figsize=(5760 / 300, 3240 / 300), dpi=300)
     plt.subplot(131)
     plt.xlabel('Imaginary')
     plt.ylabel('Real')
     plt.grid(True)
     plt.xlim(-1.2, 1.2)
     plt.ylim(-1, 1)
     plt.plot(np.real(zd), np.imag(zd), 'or')
     plt.plot(np.real(pd), np.imag(pd), 'xr')
     x = np.linspace(-2, 2, 400)
     y = np.linspace(-2, 2, 400)
     x, y = np.meshgrid(x, y)
     z = x * x + y * y
     plt.contour(x, y, z, [1])
     plt.subplot(132)
     plt.xlabel('Imaginary')
     plt.ylabel('Real')
     plt.grid(True)
     plt.plot(np.real(za), np.imag(za), 'ob')
     plt.plot(np.real(pa), np.imag(pa), 'xb')
     plt.subplot(133)
     plt.xlabel('Imaginary')
     plt.ylabel('Real')
     plt.grid(True)
     plt.plot(np.real(Pza), np.imag(Pza), 'og')
     plt.plot(np.real(Ppa), np.imag(Ppa), 'xg')
     plt.savefig(str(self.low_f_Hz) + '-' + str(self.high_f_Hz) + 'zp.png')
     plt.close()
Example #3
0
def test_real_summation_partition():
    # F = 1 / (z + 0.5)
    F = Fz, Fp, Fk = tf2zpk([1.], [1., 0.5])
    L, R = rf.real_summation_partition(F)
    assert isreal(L) and isreal(R)
    Sz, Sp, Sk = rf.add(L, R)
    assert_almost_equal(np.sort(Fz), np.sort(Sz))
    assert_almost_equal(np.sort(Fp), np.sort(Sp))
    assert_almost_equal(Fk, Sk)

    # F = (z^2 - 2) / (z^3 + 2 * z^2 + 2 * z + 1)
    F = Fz, Fp, Fk = tf2zpk([1, 0, -2], [1, 2, 2, 1])
    L, R = rf.real_summation_partition(F)
    assert isreal(L) and isreal(R)
    Sz, Sp, Sk = rf.add(L, R)
    assert_almost_equal(np.sort(Fz), np.sort(Sz))
    assert_almost_equal(np.sort(Fp), np.sort(Sp))
    assert_almost_equal(Fk, Sk)

    # F = (z^4 + 1) / (z^4 + 2 * z^3 + 2 * z^2 + 1)
    F = Fz, Fp, Fk = tf2zpk([1, 0, 0, 0, 1], [1, 2, 2, 0, 1])
    L, R = rf.real_summation_partition(F)
    assert isreal(L) and isreal(R)
    Sz, Sp, Sk = rf.add(L, R)
    assert_almost_equal(np.sort(np.around(Fz, decimals=15)),
                        np.sort(np.around(Sz, decimals=15)))
    assert_almost_equal(np.sort(np.around(Fp, decimals=15)),
                        np.sort(np.around(Sp, decimals=15)))
    assert_almost_equal(Fk, Sk)
Example #4
0
def convert_forward_euler(pa, Tsampling=0.01):
    # if isintance(pa, TransferFunction):
    if isinstance(pa, lti):

        #reviso primero el valor final
        s = Symbol('s')
        pa_sympy = lti_to_sympy(pa)
        final_value_analog = pa_sympy.subs(s, 0).evalf()
        # print (' Final value: ' + str(final_value_analog))

        #convierto backward euler
        num_d, den_d, td = cont2discrete((pa.num, pa.den),
                                         Tsampling,
                                         method='euler')

        zd, pd, kd = tf2zpk(num_d, den_d)
        #agrego zeros infinitos
        while (np.shape(zd) < np.shape(pd)):
            zd = np.append(zd, [-1])

        #normalizo los zeros
        planta_d = ZerosPolesGain(zd, pd, kd)
        planta_d = planta_d.to_tf()
        zd, pd, kd = tf2zpk(planta_d.num, planta_d.den)

        #convierto a sympy para evaluar el valor final y ajustarlo
        planta_d_sympy = lti_to_sympy(planta_d)
        z = Symbol('z')
        planta_d_sympy = planta_d_sympy.subs(s, z)
        final_value_d = planta_d_sympy.subs(z, 1).evalf()

        #ahora ajusto la ganancia para que me coincidan los dos valores finales
        kd = kd * final_value / final_value_d
        # print ('Ceros digital: ' + str(zd))
        # print ('Polos digital: ' + str(pd))
        # print ('K digital: ' + str(kd))

        #normalizo por ultima vez planta_d, ya agregue los zeros
        #y ajuste la ganancia con los valores finales
        planta_d = ZerosPolesGain(zd, pd, kd)
        planta_d = planta_d.to_tf()
        # print ('planta_d ' + str(planta_d))

        #muestro el valor final
        planta_d_sympy = lti_to_sympy(planta_d)
        z = Symbol('z')
        planta_d_sympy = planta_d_sympy.subs(s, z)
        final_value_d = planta_d_sympy.subs(z, 1).evalf()
        # print ('planta_d final value: ' + str(final_value_d))

        #reconvierto planta_d a dlti
        planta_d = dlti(planta_d.num, planta_d.den, dt=td)
        return planta_d

    else:
        raise ValueError('planta_analog is not instance of TransferFunction!')
Example #5
0
def test_multiply():
    # F = (z + 1) / (z^3 - 3 * z^2 + 10 * z + 1)
    F = tf2zpk([1, 1], [1, -3, 10, 1])
    # G = 1 / (z^2 - z + 3)
    G = tf2zpk([1], [1, -1, 3])
    # H = F * G = \
    #                     (z + 1) /
    # (z^5 - 4 * z^4 + 16 * z^3 - 18 * z^2 + 29 * z + 3)
    Hz, Hp, Hk = tf2zpk([1, 1], [1, -4, 16, -18, 29, 3])
    Mz, Mp, Mk = rf.multiply(*F, *G)
    assert_almost_equal(np.sort(Hz), np.sort(Mz))
    assert_almost_equal(np.sort(Hp), np.sort(Mp))
    assert_almost_equal(Hk, Mk)
Example #6
0
def test_add():
    # F = (z + 1) / (z^3 - 3 * z^2 + 10 * z + 1)
    F = tf2zpk([1, 1], [1, -3, 10, 1])
    # G = 1 / (z^2 - z + 3)
    G = tf2zpk([1], [1, -1, 3])
    # H = F + G = \
    #        (2 * z^3 - 3 * z^2 + 12 * z + 4) /
    # (z^5 - 4 * z^4 + 16 * z^3 - 18 * z^2 + 29 * z + 3)
    Hz, Hp, Hk = tf2zpk([2, -3, 12, 4], [1, -4, 16, -18, 29, 3])
    Sz, Sp, Sk = rf.add(*F, *G)
    assert_almost_equal(np.sort(Hz), np.sort(Sz))
    assert_almost_equal(np.sort(Hp), np.sort(Sp))
    assert_almost_equal(Hk, Sk)
Example #7
0
def test_product():
    # F = (z + 1) / (z^3 - 3 * z^2 + 10 * z + 1)
    F = tf2zpk([1, 1], [1, -3, 10, 1])
    # G = 1 / (z^2 - z + 3)
    G = tf2zpk([1], [1, -1, 3])
    # H = (-5 * z^2 + 10) / 2
    H = tf2zpk([-5, 0, 10], [2])
    # J = F * G * H = \
    #         (-5 * z^3 - 5 * z^2 + 10 z + 10) /
    # (2 * z^5 - 8 * z^4 + 32 * z^3 - 36 * z^2 + 58 * z + 6)
    Jz, Jp, Jk = tf2zpk([-5, -5, 10, 10], [2, -8, 32, -36, 58, 6])
    Mz, Mp, Mk = rf.product([F, G, H])
    assert_almost_equal(np.sort(Jz), np.sort(Mz))
    assert_almost_equal(np.sort(Jp), np.sort(Mp))
    assert_almost_equal(Jk, Mk)
Example #8
0
def mirroredNTF(ntf):
    """Creates a symmetric noise transfer function from a prototype.

    This function takes a prototype single band NTF for a LP modulator
    and returns a symmetric NTF with signal bands at the bottom and at
    the top of the available frequency ranges.

    Note that the way in which the mirroring happens make the resulting
    NTF peak at about the squared value as the peak of the original
    prototype. Hence the prototype should be designed with an H_inf value
    that is the square root of the desired one.

    Parameters
    ----------
    ntf : tuple
        input noise tranfer function in zpk form

    Returns
    -------
    ntf2 : tuple
        output noise transfer function in zpk form
    """
    zpk_mode = True
    if len(ntf) != 3:
        zpk_mode = False
        ntf = tf2zpk(*ntf)
    # Take the opposite of poles and zeros to get an HP filter
    ntf_flipped = (-ntf[0], -ntf[1], ntf[2])
    # Take the product of the two
    ntf_mirrored = (np.hstack((ntf[0], ntf_flipped[0])),
                    np.hstack((ntf[1], ntf_flipped[1])), 1)
    if not zpk_mode:
        ntf_mirrored = zpk2tf(*ntf_mirrored)
    return ntf_mirrored
Example #9
0
def mirroredNTF(ntf):
    """Creates a symmetric noise transfer function from a prototype.

    This function takes a prototype single band NTF for a LP modulator
    and returns a symmetric NTF with signal bands at the bottom and at
    the top of the available frequency ranges.

    Note that the way in which the mirroring happens make the resulting
    NTF peak at about the squared value as the peak of the original
    prototype. Hence the prototype should be designed with an H_inf value
    that is the square root of the desired one.

    Parameters
    ----------
    ntf : tuple
        input noise tranfer function in zpk form

    Returns
    -------
    ntf2 : tuple
        output noise transfer function in zpk form
    """
    zpk_mode = True
    if len(ntf) != 3:
        zpk_mode = False
        ntf = tf2zpk(*ntf)
    # Take the opposite of poles and zeros to get an HP filter
    ntf_flipped = (-ntf[0], -ntf[1], ntf[2])
    # Take the product of the two
    ntf_mirrored = (np.hstack((ntf[0], ntf_flipped[0])),
                    np.hstack((ntf[1], ntf_flipped[1])), 1)
    if not zpk_mode:
        ntf_mirrored = zpk2tf(*ntf_mirrored)
    return ntf_mirrored
def _transform(b, a, Wn, analog, output):
    """
    Shift prototype filter to desired frequency, convert to digital with
    pre-warping, and return in various formats.
    """
    Wn = np.asarray(Wn)
    if not analog:
        if np.any(Wn < 0) or np.any(Wn > 1):
            raise ValueError("Digital filter critical frequencies "
                             "must be 0 <= Wn <= 1")
        fs = 2.0
        warped = 2 * fs * tan(pi * Wn / fs)
    else:
        warped = Wn

    # Shift frequency
    b, a = lp2lp(b, a, wo=warped)

    # Find discrete equivalent if necessary
    if not analog:
        b, a = bilinear(b, a, fs=fs)

    # Transform to proper out type (pole-zero, state-space, numer-denom)
    if output in ('zpk', 'zp'):
        return tf2zpk(b, a)
    elif output in ('ba', 'tf'):
        return b, a
    elif output in ('ss', 'abcd'):
        return tf2ss(b, a)
    elif output in ('sos'):
        raise NotImplementedError('second-order sections not yet implemented')
    else:
        raise ValueError('Unknown output type {0}'.format(output))
Example #11
0
 def check_minphase(self, ):
     zeros, poles, _ = signal.tf2zpk(self.b, self.a)
     print(zeros)
     print(poles)
     for kai in np.concatenate([zeros, poles]):
         if not np.abs(kai) < 1.0:
             print('This is not min phase')
Example #12
0
def stabilityPlot(transferFunction):
    pyplot.figure(figsize=(6, 3))
    maxIteration = 1024
    nK2 = 256
    data = []
    for idx, k2 in enumerate(np.linspace(0.1, 1, nK2)):
        k1 = 65536
        delta = k1 / 2
        jdx = 0
        while jdx < maxIteration:
            b, a = transferFunction(k1, k2)
            _, pole, gain = signal.tf2zpk(b, a)
            if np.max(np.abs(pole * gain)) >= 1:
                k1 -= delta
            else:
                k1 += delta
            jdx += 1
            delta *= 0.5
        data.append((k1, k2))
        print(idx, k1, k2)
    k1, k2 = zip(*data)
    pyplot.scatter(k2, k1, s=4, zorder=2)
    k1Array, k2Array = zip(*data)
    # with open("k1_k2.json", "w") as fi:
    #     json.dump({"k1": k1Array, "k2": k2Array}, fi, indent=2)
    pyplot.title("k1-k2 Plot")
    pyplot.ylabel("k1")
    pyplot.xlabel("k2")
    pyplot.grid(zorder=1)
    pyplot.tight_layout()
    pyplot.show()
Example #13
0
def _check_coefficients(b, a):
    """Check for filter stability"""
    z, p, k = signal.tf2zpk(b, a)
    if np.any(np.abs(p) > 1.0):
        raise RuntimeError('Filter poles outside unit circle, filter will be '
                           'unstable. Consider using different filter '
                           'coefficients.')
def filterResponse2zeros(vandermondeMatrixSuperSet):
    """
    This function takes in a Vandermonde matrix and generates the zeros of each column of the matrix.
    This function can be used to generate the zeros of a vandermonde matrix upfront and then store them
    inputs:
        1. vandermondeMatrixSuperSet: Matrix of sinusoids stacked as columns

    outputs:
        1. zerosFilterResponseSuperSet: Zeros of each column of filterResponseSuperSet stacked again as columns.
        Note: # rows of zerosFilterResponseSuperSet = # of rows of filterResponseSuperSet -1 (Since the number of zeros is 1 less than the filter tap length)
        This function uses the inbuilt scipy.signal.tf2zpk
    """

    filterResponseSuperSet = np.conj(
        vandermondeMatrixSuperSet
    )  ## This has to have a conjugation effect to enhance the true tone
    numResponses = filterResponseSuperSet.shape[1]
    numZeros = filterResponseSuperSet.shape[0] - 1
    zerosFilterResponseSuperSet = np.zeros((numZeros, numResponses),
                                           dtype=np.complex64)
    for ele in np.arange(numResponses):
        zerosFilterResponseSuperSet[:, ele], _, _ = sig.tf2zpk(
            filterResponseSuperSet[:, ele], 1)

    return zerosFilterResponseSuperSet
Example #15
0
def ss_to_zpk(A, B, C):
    """Convert a state-space system to sets of Zero-Pole-Gain objects.

    Parameters
    ----------
    A: (n,n) array_like
        State-space dynamics matrix
    B: (n,m) array_like
        Input matrix.
    C: (n,m) array_like
        Output matrix
    """
    zpks = []
    for im in range(B.shape[1]):
        zpks.append([])
        for ip in range(C.shape[0]):
            try:
                num, den = signal.ss2tf(
                    A, B[:, im].reshape((-1, 1)),
                    C[ip, :].reshape((1, -1)), np.zeros((1, 1)))
                nu2 = num

                # strip leading (close to zeros) from num
                while np.allclose(nu2[:, 0], 0, 1e-14) and \
                        nu2.shape[-1] > 1:
                    nu2 = nu2[:, 1:]

                # to zpk
                z, p, k = signal.tf2zpk(nu2, den)
                zpks[-1].append(ZPK(z, p, k))
            except ValueError:
                raise RuntimeWarning("cannot analyse state-space")
    return zpks
def lab6_ex4():
    # set parameters of system    
    fs = 2000 #sampling frequency (Hz)
    fn = fs/2.0 #nyqvist frequency
    wp = array([200/fn,400/fn]) #band-pass in normalized corner frequencies
    ws = array([1/fn,100/fn,500/fn,5000/fn]) #band-stop in normalized corner frequencies
    gstop = 40 #minimum attenuation in stopband
    gpass = 1 #maximum loss in passband
    
    # create remez filter, frequency response, and plot
    b,a = iirdesign(wp,ws,gpass,gstop,analog=0)
    w,h = freqz(b,a)
    plot(w/pi, 20*log10(abs(h)),'b-')
    title('IIR of given frequency response')
    xlabel('normalized frequency (1 = fn)')
    ylabel('magnitude (dB scale)')
    grid()
    show()

    print("\nBoth designs achieve the desired response at the desired attenuation, but the IIR design's response attenuates and gains more quickly than the 46th-order remez FIR design.")

    z,p,k = tf2zpk(b,a)
    zplane(z,p)
    title('zplane of IIR of given frequency response')
    show()

    print('\nZ-plane analysis shows that the IIR design uses an 8th degree polynomial, while the remez FIR uses a 46th order polynomial (and thus far more components) to achieve the same desired response. This is because the IIR filter is able to use both zeros and poles (i.e. feedback) to achieve the desired frequency response at the desired attenuation and loss, whereas the remez FIR must use only zeros (no feedback).')
Example #17
0
    def test_sine(self):
        rate = 2000
        t = np.linspace(0, 1.0, rate + 1)
        # A signal with low frequency and a high frequency.
        xlow = np.sin(5 * 2 * np.pi * t)
        xhigh = np.sin(250 * 2 * np.pi * t)
        x = xlow + xhigh

        b, a = butter(8, 0.125)
        z, p, k = tf2zpk(b, a)
        # r is the magnitude of the largest pole.
        r = np.abs(p).max()
        eps = 1e-5
        # n estimates the number of steps for the
        # transient to decay by a factor of eps.
        n = int(np.ceil(np.log(eps) / np.log(r)))

        # High order lowpass filter...
        y = filtfilt(b, a, x, padlen=n)
        # Result should be just xlow.
        err = np.abs(y - xlow).max()
        assert_(err < 1e-4)

        # A 2D case.
        x2d = np.vstack([xlow, xlow + xhigh])
        y2d = filtfilt(b, a, x2d, padlen=n, axis=1)
        assert_equal(y2d.shape, x2d.shape)
        err = np.abs(y2d - xlow).max()
        assert_(err < 1e-4)

        # Use the previous result to check the use of the axis keyword.
        # (Regression test for ticket #1620)
        y2dt = filtfilt(b, a, x2d.T, padlen=n, axis=0)
        assert_equal(y2d, y2dt.T)
def lab6_ex3():
    # set parameters of system
    fs = 2000 #sampling frequency (Hz)
    fn = fs/2 #nyqvist frequency
    fc = array([0,100,200,400,500,1000]) #corner frequencies
    fb = array([0,1.0,0]) #desired band gains for each pair of corner frequencies
    deg = 46 #degree of polynomial
    nt = deg + 1 #number of taps = degree + 1
    a = array([1.0,0]) #(no feedback (FIR), poles at origin reduced to 1 for simplification)    
    
    # create remez filter, frequency response, and plot
    b = remez(nt,fc,fb,Hz=fs)
    w,h = freqz(b,a)
    plot(w/pi*fn, 20*log10(abs(h)),'b-')
    title('FIR of given frequency response using remez algo')
    xlabel('frequency')
    ylabel('magnitude (dB scale)')
    grid()
    show()

    print('\nFilter requires 47 taps for stop-band attenuation of at least -40 dB')
    
    z,p,k = tf2zpk(b,a)
    zplane(z,p)
    title('zplane of remez-FIR of given frequency response (47 taps)')
    show()
Example #19
0
def pzmap(filters):
    try:
        iter(filters)
    except TypeError:
        filters = [filters]
    fig, ax = plt.subplots()
    ax.ticklabel_format(useOffset=False)
    ax.set_ylabel('rad/sec')
    ax.set_xlabel('rad/sec')
    ax.grid(True)
    title = 'pzmap'
    fig.suptitle(title)
    fig.canvas.set_window_title(title)
    r = 1.5
    for filt in filters:
        z, p, k = sig.tf2zpk(filt.num, filt.den)
        poles = ax.plot(p.real, p.imag, 'x', markersize=9, alpha=0.5)
        rx = 1.5 * np.amax(np.concatenate((abs(z), abs(p))))
        r = rx if rx > r else r
        ax.plot(z.real,
                z.imag,
                'o',
                color='none',
                markersize=9,
                alpha=0.5,
                markeredgecolor=poles[0].get_color())
    ax.axis('scaled')
    ax.axis([-r, r, -r, r])
Example #20
0
def save_fil(fil_dict, arg, out_format, sender, DEBUG = False):
    """
    Convert between poles / zeros / gain, filter coefficients (polynomes)
    and second-order sections and store all available formats in the passed
    dictionary 'fil_dict'.
    """
    if DEBUG: print("saveFil: arg = ",arg)
    if out_format == 'zpk': # arg = [z,p,k]
        (b, a) = sig.zpk2tf(arg[0], arg[1], arg[2])
        zpk = arg
    elif out_format == 'ba': # arg = [b,a]
        if np.ndim(arg) == 1:
#            print(len(arg))
            b = np.asarray(arg)
            a = np.zeros(len(arg))
            a[0] = 1
        else:
            b = arg[0]
            a = arg[1]
#        print("saveFil: b, a = ",b , a)
        zpk = sig.tf2zpk(b, a)#[np.roots(arg), [1, np.zeros(len(arg)-1)],1]
    else:
        raise ValueError("Unknown output format {0:s}".format(out_format))
    fil_dict['ba'] = [b, a]
    fil_dict['zpk'] = [zpk[0], zpk[1], zpk[2]]#zpk
    fil_dict['sos'] = None
    fil_dict['creator'] = (out_format, sender)
Example #21
0
def zplane(b, a):
    z, p, k = signal.tf2zpk(b, a)

    # plt.figure()
    plt.title("Pole-zero placement of EQ Filters")
    plt.plot(z.real, z.imag, 'ko', fillstyle='none', ms=10)
    plt.plot(p.real, p.imag, 'kx', fillstyle='none', ms=10)

    unit_circle = patches.Circle(
        (0, 0),
        radius=1,
        fill=False,
        color='black',
        ls='solid',
        alpha=0.9)
    plt.gca().add_patch(unit_circle)
    plt.axvline(0, color='0.7')
    plt.axhline(0, color='0.7')
    plt.grid()
    plt.ylim([-1, 1])
    plt.xlim([-1, 1])
    plt.gca().set_aspect('equal', adjustable='box')

    plt.ylabel('Imaginary')
    plt.xlabel('Real')
def filter_char(b, a, show=True):
    # Pole-zero characteristics
    zero, pole, __ = sp.tf2zpk(b, a)
    if (pole.shape < zero.shape):
        pole = np.concatenate(
            (pole, np.zeros(zero.shape[0] - pole.shape[0], dtype=complex)))
    zp = [zero, pole]
    # Magnitude and Phase Characteristics
    w1, H = sp.freqz(b, a, 1024, whole=True)
    # Time domain sequence (= Coefficients for given filter since it is FIR)
    h = ifft(H)
    ii = np.where(abs(h) > 1e-4)
    h = np.real(
        h[ii])  # remove noisy imaginary components- h is a real FIR filter
    # Group Delay of Filter
    w2, gd = sp.group_delay((b, a), whole=True)
    if show == True:
        plt.figure("Pole-Zero Plot")
        plt.polar(np.angle(zp[0]), np.abs(zp[0]), 'bo')
        plt.polar(np.angle(zp[1]), np.abs(zp[1]), 'gx')
        plt.polar(np.linspace(0, 2 * pi, 360), np.ones(360), 'k-')
        plt.title("Pole-Zero Plot")
        plt.figure("Mag-Phase Characteristics")
        plt.subplot(211)
        plt.plot(w1, abs(H))
        plt.title("Mag-Phase Characteristics of FIR filter")
        plt.subplot(212)
        plt.plot(w1, np.unwrap(np.angle(H)))
        plt.figure("h[n]")
        plt.plot(h, "ro")
        plt.title("Time Domain: FIR Filter")
        plt.figure("Group Delay of Filter")
        plt.plot(w2, gd)
        plt.title("Group Delay of Filter")
    return zp, H, h, gd
Example #23
0
def test_summation_decomposition():
    # F = 1 / (z + 0.5)
    F = Fz, Fp, Fk = tf2zpk([1.], [1., 0.5])
    terms = rf.summation_decomposition(*F, nterms=2)
    S = Sz, Sp, Sk = rf.summation(terms)
    assert_almost_equal(np.sort(Sz), np.sort(Fz))
    assert_almost_equal(np.sort(Sp), np.sort(Fp))
    assert_almost_equal(Sk, Fk)

    # F = (z^2 - 2) / (z^4 + 2 * z^3 + 2 * z^2 + 1)
    F = Fz, Fp, Fk = tf2zpk([1, 0, -2], [1, 2, 2, 1])
    terms = rf.summation_decomposition(*F, nterms=2)
    S = Sz, Sp, Sk = rf.summation(terms)
    assert_almost_equal(np.sort(Sz), np.sort(Fz))
    assert_almost_equal(np.sort(Sp), np.sort(Fp))
    assert_almost_equal(Sk, Fk)
Example #24
0
def _transform(b, a, Wn, analog, output):
    """
    Shift prototype filter to desired frequency, convert to digital with
    pre-warping, and return in various formats.
    """
    Wn = np.asarray(Wn)
    if not analog:
        if np.any(Wn < 0) or np.any(Wn > 1):
            raise ValueError("Digital filter critical frequencies "
                             "must be 0 <= Wn <= 1")
        fs = 2.0
        warped = 2 * fs * tan(pi * Wn / fs)
    else:
        warped = Wn

    # Shift frequency
    b, a = lp2lp(b, a, wo=warped)

    # Find discrete equivalent if necessary
    if not analog:
        b, a = bilinear(b, a, fs=fs)

    # Transform to proper out type (pole-zero, state-space, numer-denom)
    if output in ('zpk', 'zp'):
        return tf2zpk(b, a)
    elif output in ('ba', 'tf'):
        return b, a
    elif output in ('ss', 'abcd'):
        return tf2ss(b, a)
    elif output in ('sos'):
        raise NotImplementedError('second-order sections not yet implemented')
    else:
        raise ValueError('Unknown output type {0}'.format(output))
Example #25
0
def test_summation():
    # F = (z + 1) / (z^3 - 3 * z^2 + 10 * z + 1)
    F = tf2zpk([1, 1], [1, -3, 10, 1])
    # G = 1 / (z^2 - z + 3)
    G = tf2zpk([1], [1, -1, 3])
    # H = (-z^2 + 1) / 1
    H = tf2zpk([-1, 0, 1], [1])
    # J = F + G + H = \
    # (-z^7 + 4 * z^6 - 15 * z^5 + 14 * z^4 - 13 * z^3 - 21 * z^2 + 29 * z + 3) /
    #         (z^5 - 4 * z^4 + 16 * z^3 - 18 * z^2 + 29 * z + 3)
    Jz, Jp, Jk = tf2zpk([-1, 4, -15, 14, -11, -24, 41, 7],
                        [1, -4, 16, -18, 29, 3])
    Sz, Sp, Sk = rf.summation([F, G, H])
    assert_almost_equal(np.sort(Jz), np.sort(Sz))
    assert_almost_equal(np.sort(Jp), np.sort(Sp))
    assert_almost_equal(Jk, Sk)
Example #26
0
    def test_sine(self):
        rate = 2000
        t = np.linspace(0, 1.0, rate + 1)
        # A signal with low frequency and a high frequency.
        xlow = np.sin(5 * 2 * np.pi * t)
        xhigh = np.sin(250 * 2 * np.pi * t)
        x = xlow + xhigh

        b, a = butter(8, 0.125)
        z, p, k = tf2zpk(b, a)
        # r is the magnitude of the largest pole.
        r = np.abs(p).max()
        eps = 1e-5
        # n estimates the number of steps for the
        # transient to decay by a factor of eps.
        n = int(np.ceil(np.log(eps) / np.log(r)))

        # High order lowpass filter...
        y = filtfilt(b, a, x, padlen=n)
        # Result should be just xlow.
        err = np.abs(y - xlow).max()
        assert_(err < 1e-4)

        # A 2D case.
        x2d = np.vstack([xlow, xlow + xhigh])
        y2d = filtfilt(b, a, x2d, padlen=n, axis=1)
        assert_equal(y2d.shape, x2d.shape)
        err = np.abs(y2d - xlow).max()
        assert_(err < 1e-4)

        # Use the previous result to check the use of the axis keyword.
        # (Regression test for ticket #1620)
        y2dt = filtfilt(b, a, x2d.T, padlen=n, axis=0)
        assert_equal(y2d, y2dt.T)
def lab6_ex2():

    # set parameters of system
    fn = 1.0
    nt = 50 #number of taps
    freq = array([0,0.1,0.2,0.5,1.0]) #frequency sampling points
    gain = array([1.0,1.0,0.01,0.001,0])
    b = firwin2(nt,freq,gain,nyq=fn) #calc FIR coefficients with given frequency response
    a = array([1.0,0]) #(no feedback (FIR), poles at origin reduced to 1 for simplification)  

    # calc frequency response of filter and plot
    w,h = freqz(b,a)
    plot(w/pi, 20*log10(abs(h)),'b-')
    title('FIR of given frequency response')
    xlabel('normalized frequency (1 = fn)')
    ylabel('magnitude (dB scale)')
    grid()
    show()

    print('\nResponses in dB scale (all frequencies are relative to fn):\nf = 0, gain = 0 dB\nf = 0.1, gain = -1.05 dB\nf = 0.2, gain = -18.25 dB\nf = 0.5, gain = -56.4 dB\nf = 1.0, gain =~ -92 dB (filter tries to approach -inf and goes off the scale around f = 0.999)')
    
    print('\nThe filter has 49 zeros (the same as number of taps - 1)')
    print('The filter should also have 49 poles (all at the origin) so that it is causal. However, in this implementation (firwin2) there are no poles (except those added by the user)')
    
    # calc and show zeros and poles on zplane
    z,p,k = tf2zpk(b,a)
    zplane(z,p)
    title('zplane of FIR of given frequency response (50 taps)')
    show()

    print('\nFrom the zplane diagram, we can see pairs of conjugate pairs of zeros that follow along the unit circle. For each pair of conjugate pairs, one conjugate pair is inside of the unit circle and one is on the outside. As the frequency increases to fn, each pair of zeros generally gets closer and closer to the unit circle, thus attenuating the signal even further, up to a gain of 0 @ f = fn)')
Example #28
0
def print_zpk(num, den):
    z, p, k = sig.tf2zpk(num, den)
    print('Poles:')
    print_pole_or_zero_info(p)
    if z.size:
        print('Zeros:')
        print_pole_or_zero_info(z)
    print('K = {}'.format(k))
Example #29
0
def frequency_response(tf, w_in=[0.01, 100], plot=0):
    w = linspace(w_in[0], w_in[1], 10000)
    wi = w * 1j
    g = 20 * log10(abs(polyval(tf.num[0][0], wi))) - 20 * log10(
        abs(polyval(tf.den[0][0], wi)))
    zero, pole, gain = tf2zpk(tf.num[0][0], tf.den[0][0])

    m = count_nonzero(zero == 0)
    n = count_nonzero(pole == 0)
    zero = zero[zero != 0]
    pole = pole[pole != 0]

    real_zero = zero[imag(zero) == 0]
    real_pole = pole[imag(pole) == 0]
    p_real_zero = 0
    p_real_pole = 0
    for zi in real_zero:
        p_real_zero += rad2deg(arctan2(w, -real(zi)))
    for ip in real_pole:
        p_real_pole += rad2deg(arctan2(w, -real(ip)))

    imag_zero = zero[imag(zero) != 0]
    imag_pole = pole[imag(pole) != 0]
    n_pairs_zero = len(imag_zero) / 2
    n_pairs_pole = len(imag_pole) / 2
    p_imag_zero = 0
    p_imag_pole = 0
    for ii in range(0, int(n_pairs_zero)):
        char_equ = real(polymul([1, -imag_zero[0]], [1, -imag_zero[1]]))
        w_n = sqrt(char_equ[2])
        zeta = char_equ[1] / (2 * w_n)
        p_imag_zero += rad2deg(
            arctan2((2 * zeta * w / w_n), (1 - (w / w_n)**2)))
        imag_zero = delete(imag_zero, [0, 1])

    for jj in range(0, int(n_pairs_pole)):
        char_equ = real(polymul([1, -imag_pole[0]], [1, -imag_pole[1]]))
        w_n = sqrt(char_equ[2])
        zeta = char_equ[1] / (2 * w_n)
        p_imag_pole += rad2deg(
            arctan2((2 * zeta * w / w_n), (1 - (w / w_n)**2)))
        imag_pole = delete(imag_pole, [0, 1])

    p = 90 * m - 90 * n + p_real_zero - p_real_pole + p_imag_zero - p_imag_pole

    if plot:
        plt.figure()
        plt.subplot(2, 1, 1)
        plt.plot(w, g)
        plt.xscale('log')
        plt.grid()
        plt.subplot(2, 1, 2)
        plt.plot(w, p)
        plt.xscale('log')
        plt.grid()
        plt.show()

    return g, p, w
Example #30
0
def test_real_product_decomposition():
    # F = 1 / (z + 0.5)
    F = Fz, Fp, Fk = tf2zpk([1.], [1., 0.5])
    terms = rf.real_product_decomposition(*F, nterms=2)
    assert all(isreal(term) for term in terms)
    Pz, Pp, Pk = rf.product(terms)
    assert_almost_equal(np.sort(Fz), np.sort(Pz))
    assert_almost_equal(np.sort(Fp), np.sort(Pp))
    assert_almost_equal(Fk, Pk)

    # F = (z^2 - 2) / (z^4 + 2 * z^3 - 2 * z^2 + 2 * z + 1)
    F = Fz, Fp, Fk = tf2zpk([1, 0, -2], [1, 2, -2, 2, 1])
    terms = rf.real_product_decomposition(*F, nterms=2)
    assert all(isreal(term) for term in terms)
    Pz, Pp, Pk = rf.product(terms)
    assert_almost_equal(np.sort(Fz), np.sort(Pz))
    assert_almost_equal(np.sort(Fp), np.sort(Pp))
    assert_almost_equal(Fk, Pk)
Example #31
0
def get_APower(file):
    fs, data = read(file)
    data = data.astype("float32")
    b, a = A_weighting(fs)
    z, p, k = tf2zpk(b, a)
    IRLen = getIRLen(p)
    filtData = filtfilt(b, a, data, padlen=IRLen)
    power = (filtData*filtData).sum()
    return power
Example #32
0
def find_zeros_poles(numerator, denominator):
    # calculate zeros, poles and gain
    zeros, poles , gain = signal.tf2zpk(numerator, denominator)

    # rounding to 2 decimal place
    zeros = np.round(zeros, 3)
    poles = np.round(poles, 3)

    return zeros, poles
def lab6_ex1():
    
    # set parameters of system
    fs = 5000 #sampling frequency (Hz)
    fn = fs/2 #nyqvist frequency
    fc1 = 0.1*fn #corner frequency1
    fc2 = 0.2*fn #corner frequency2
    fc3 = array([fc1,fc2]) #corner frequency3 (as an array of two corner frequencies)
    deg = 18 #degree of polynomial
    nt = deg + 1 #number of taps = degree + 1
    a = array([1.0,0]) #(no feedback (FIR), poles at origin reduced to 1 for simplification)
    
    # calc FIR filter coefficients
    
    b1 = firwin(nt,fc1,pass_zero=1,nyq=fn) #low-pass
    b2 = firwin(nt,fc2,pass_zero=0,nyq=fn) #high-pass
    b3 = firwin(nt,fc3,pass_zero=0,nyq=fn) #band-pass
    
    # calc and show freq response
    w,h = freqz(b1,a)   
    plot(w/pi, 20*log10(abs(h)),'b-')
    w,h = freqz(b2,a)
    plot(w/pi, 20*log10(abs(h)),'r-')
    w,h = freqz(b3,a)
    plot(w/pi, 20*log10(abs(h)),'g-')
    legend(('low-pass, fc = 0.1*fn','high-pass, fc = 0.2*fn','band-pass, fc = 0.1*fn, 0.2*fn'), loc=3)
    title('firwin filters')
    xlabel('normalized frequency (1.0 = fn)')
    ylabel('magnitude (dB scale)')
    show()

    # calc and show zeros and poles on zplane
    z,p,k = tf2zpk(b1,a)
    zplane(z,p)
    title('zplane of low-pass, fc = 0.1*fn')
    show()
    z,p,k = tf2zpk(b2,a)
    zplane(z,p)
    title('zplane of high-pass, fc = 0.2*fn')
    show()
    z,p,k = tf2zpk(b3,a)
    zplane(z,p)
    title('zplane of band-pass, fc = 0.1*fn, 0.2*fn')
    show()
Example #34
0
def freqz_plot(line, cell):
    # line, cellをparse
    N, FS = [float(v) for v in line.split()]
    ba = cell.split("\n")
    b = [float(v) for v in ba[0].split(",")]
    a = [float(v) for v in ba[1].split(",")]

    # 時間特性、周波数特性、位相特性、群遅延特性等を計算
    w, h = sg.freqz(b, a, worN=int(N))
    f = w * FS / (2.0 * np.pi)
    z, p, k = sg.tf2zpk(b, a)
    _, gd = sg.group_delay((b, a), w=w)

    # 上記パラメータをプロット
    fig = plt.figure(1, figsize=(8, 12))
    
    ax = fig.add_subplot(321)
    ax.plot(b, "o-")
    ax.plot(a, "x-")
    ax.grid()
    ax.set_xlabel("time [pt]")
    ax.set_ylabel("amplitude")
    
    ax = fig.add_subplot(322)
    ax.semilogx(f, 20.0 * np.log10(np.abs(h)))
    ax.grid()
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("power [dB]")
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-40.0, 10.0])

    ax = fig.add_subplot(323)
    ax.semilogx(f, np.angle(h))
    ax.grid()
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-np.pi, np.pi])
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("phase [rad]")
    
    ax = fig.add_subplot(324)
    ax.semilogx(f, gd)
    ax.grid()
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("group delay [pt]")
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-40.0, 40.0])

    ax = fig.add_subplot(325)
    ax.add_patch(plt.Circle((0.0, 0.0), 1.0, fc="white"))
    ax.plot(np.real(z), np.imag(z), "o", mfc="white")
    ax.plot(np.real(p), np.imag(p), "x", mfc="white")
    ax.grid()
    ax.set_xlim([-1.5, 1.5])
    ax.set_ylim([-1.5, 1.5])

    plt.show()
Example #35
0
    def denormalize_one_pole(self, pole):
        # cambio de variable: s-> s/wp

        # 1/(s-p) -> (wp) /(s - wp*p)
        # entonces por cada polo REAL en poles tengo:
        wp = self.denormalized_template.wp
        if pole.imag == 0:
            [denorm_zeroes, denorm_poles,
             gain_factor] = signal.tf2zpk([wp], [1, -wp * pole])

        # 1/( (s-p)*(s-conj(p))) =  1/(s^2 -2*real(p)*s + abs(p)^2) ->
        # (wp)^2 / (s^2 - 2*real(p)*wp *s + wp^2*abs(p)^2)
        # entonces por cada polo IMAGINARIO tengo:

        else:
            [denorm_zeroes, denorm_poles, gain_factor] = \
                signal.tf2zpk([wp**2], [1, - 2 * np.real(pole)*wp, wp**2 * abs(pole)**2])

        return [list(denorm_poles), list(denorm_zeroes), gain_factor]
Example #36
0
 def set_band_pass(self):
     self.num = [1, 0]
     self.den = [1, 1, 1]
     self.sys = signal.TransferFunction([1, 0], [1, 1, 1])
     self.w, self.mag, self.phase = signal.bode(self.sys)
     self.stepT, self.stepMag = signal.step(self.sys)
     self.impT, self.impMag = signal.impulse(self.sys)
     self.pzg = signal.tf2zpk(self.sys.num, self.sys.den)
     self.GDfreq, self.gd = signal.group_delay((self.num, self.den))
     self.plotMag()
Example #37
0
    def denormalize_one_pole(self, pole):

        # cambio de variable: s -> 1/ ( q*(s/wo+wo/s) ) == s*wo / (q * (s^2 + wo^2) )

        # 1/(s-p) -> (- q*s^2 - q*wo^2)/(p*q*s^2 - s*wo + p*q*wo^2)
        # entonces por cada polo REAL tengo:

        if pole.imag == 0:
            [denorm_zeroes, denorm_poles, gain_factor] = signal.tf2zpk(
                [-self.q, 0, -self.q * self.denormalized_template.w0**2], [
                    pole * self.q, -self.denormalized_template.w0,
                    pole * self.q * self.denormalized_template.w0**2
                ])

        # (q^2*s^4 + 2*q^2*s^2*wo^2 + q^2*wo^4) /
        # ((p*q^2*conj(p))*s^4 + (- q*wo*conj(p) - p*q*wo)*s^3 + (2*p*conj(p)*q^2*wo^2 + wo^2)*s^2 + (- p*q*wo^3 - q*wo^3*conj(p))*s + p*q^2*wo^4*conj(p))

        # que se puede escribir como
        # (a*s^4 + c*s^2 + e) /
        # (f*s^4 + g*s^3 + h *s^2 + i *s + j)
        # entonces por cada polo IMAGINARIO tengo:
        else:

            # numerador
            a = self.q**2
            c = 2 * self.q**2 * self.denormalized_template.w0**2
            e = self.q**2 * self.denormalized_template.w0**4
            # denominador

            f = np.absolute(pole)**2 * self.q**2
            g = -self.q * self.denormalized_template.w0 * 2 * pole.real
            h = (2 * np.absolute(pole)**2 * self.q**2 *
                 self.denormalized_template.w0**2 +
                 self.denormalized_template.w0**2)
            i = -self.denormalized_template.w0**3 * self.q * 2 * pole.real
            j = np.absolute(
                pole)**2 * self.q**2 * self.denormalized_template.w0**4

            [denorm_zeroes, denorm_poles,
             gain_factor] = signal.tf2zpk([a, 0, c, 0, e], [f, g, h, i, j])

        return [list(denorm_poles), list(denorm_zeroes), gain_factor]
Example #38
0
def ex4_1():
    wp = 0.2*np.pi
    ws = 0.3*np.pi
    fs = 4000.0
    T = 1/fs
    Wp = wp/T
    Ws = ws/T
    n, x = signal.buttord(Wp, Ws, 2, 40, analog=True)
    b, a = signal.butter(n, x, analog=True)
    z, p, k = signal.tf2zpk(b, a)
    print z, p, k
Example #39
0
 def plot_cont2(self, b2, c2):
     self.z2, self.p2, self.k2 = signal.tf2zpk(b2, c2)
     plt.plot(numpy.real(self.z2),
              numpy.imag(self.z2),
              'oy',
              label='Zeros of TF3')
     plt.plot(numpy.real(self.p2),
              numpy.imag(self.p2),
              'xk',
              label='Poles of TF3')
     plt.legend(loc=1, numpoints=1)
Example #40
0
 def test_bad_filter(self):
     """Regression test for #651: better handling of badly conditioned
     filter coefficients."""
     warnings.simplefilter("error", BadCoefficients)
     try:
         b, a = bessel(20, 0.1)
         z, p, k = tf2zpk(b, a)
         raise AssertionError("tf2zpk did not warn about bad "\
                              "coefficients")
     except BadCoefficients:
         pass
     finally:
         warnings.simplefilter("always", BadCoefficients)
Example #41
0
def pole_zero(sys, xlim=None, ylim=None, figax=None, rcParams=None):
    if len(sys) == 2:
        z, p, k = signal.tf2zpk(*sys)
    elif len(sys) == 3:
        z, p, k = sys
    elif len(sys) == 4:
        z, p, k = signal.ss2zpk(*sys)
    else:
        ValueError("""\
sys must have 2 (transfer function), 3 (zeros, poles, gain),
or 4 (state space) elements. sys is: {}""".format(sys))

    return _pole_zero(z, p, k, xlim=xlim, ylim=ylim, figax=figax,
                      rcParams=rcParams)
def poleZeroPlot(b,a, phone):
    a[1:len(a)] = -a[1:len(a)];
    b=[b]
    z, p, k = signal.tf2zpk(b, a)
    p = p[p!=0]
    fig = plt.figure()
    plt.plot(np.real(z), np.imag(z), 'xb')
    plt.plot(np.real(p), np.imag(p), 'or')
    plt.ylim((-2.0, 2.0))
    plt.xlim((-2.0,2.0))
    plt.legend(['Zeros', 'Poles'], loc=2)
    plt.title('Pole / Zero Plot for /'+phone+'/ for order '+str(len(p)))
    plt.ylabel('Real')
    plt.xlabel('Imaginary')
    plt.grid()
Example #43
0
    def test_simple(self):
        z_r = np.array([0.5, -0.5])
        p_r = np.array([1.j / np.sqrt(2), -1.j / np.sqrt(2)])
        # Sort the zeros/poles so that we don't fail the test if the order
        # changes
        z_r.sort()
        p_r.sort()
        b = np.poly(z_r)
        a = np.poly(p_r)

        z, p, k = tf2zpk(b, a)
        z.sort()
        p.sort()
        assert_array_almost_equal(z, z_r)
        assert_array_almost_equal(p, p_r)
Example #44
0
def polosyzeros(b, a):
    (zeros,poles,gain) = tf2zpk(b, a)
    angle = np.linspace(-np.pi,np.pi,50)
    cirx = np.sin(angle)
    ciry = np.cos(angle)
    l, = pl.plot(poles.real, poles.imag, 'x')
    pl.plot(zeros.real, zeros.imag, 'o',color=l.get_color())
    pl.plot(cirx,ciry, 'k-')
    pl.grid()
    
    pl.xlim((-2, 2))
    pl.xlabel('Real')
    pl.ylim((-1.5, 1.5))
    pl.ylabel('Imag')
    
    return (zeros,poles,gain)
def PlotFilterCharacteristics(b,a,figname):
    w, h = sig.freqz(b,a)
    z, p, k = sig.tf2zpk(b, a)

    plt.figure(num=figname)
    plt.subplot(211)
    plt.plot(np.real(z), np.imag(z), 'xb')
    plt.plot(np.real(p), np.imag(p), 'or')
    # plot unit circle
    phis=np.arange(0, 2*np.pi, 0.01)
    plt.plot( np.cos(phis), np.sin(phis), c='b')
    plt.grid()
    plt.xlim([-3,3])
    plt.ylim([-1.2, 1.2])
    plt.legend(['Zeros', 'Poles'], loc=2)

    plt.subplot(212)
    plt.plot(np.abs(h))
Example #46
0
def test_evalTF():
	"""Test function for evalTF()
	"""
	from scipy.signal import tf2zpk
	from ._utils import empty
	num, den = np.poly([3, 0.3, 1]), np.poly([2, 0.5, .25])
	H = (num, den)
	tstr1 = empty()
	tstr1.form, tstr1.num, tstr1.den = 'coeff', num, den
	tstr2 = empty()
	tstr2.form = 'zp'
	tstr2.zeros, tstr2.poles, tstr2.k = tf2zpk(num, den)
	z = np.exp(1j*np.linspace(0, 2*np.pi, num=129, endpoint=True))
	h1 = evalTF(tstr1, z)
	h2 = evalTF(tstr2, z)
	h3 = evalTF(H, z)
	assert np.allclose(np.abs(h1), np.abs(h2), atol=1e-8, rtol=1e-5)
	assert np.allclose(h1, h3, atol=1e-8, rtol=1e-5)
Example #47
0
    def test_dstep(self):

        a = np.asarray([[0.9, 0.1], [-0.2, 0.9]])
        b = np.asarray([[0.4, 0.1, -0.1], [0.0, 0.05, 0.0]])
        c = np.asarray([[0.1, 0.3]])
        d = np.asarray([[0.0, -0.1, 0.0]])
        dt = 0.5

        # Because b.shape[1] == 3, dstep should result in a tuple of three
        # result vectors
        yout_step_truth = (np.asarray([0.0, 0.04, 0.052, 0.0404, 0.00956,
                                       -0.036324, -0.093318, -0.15782348,
                                       -0.226628324, -0.2969374948]),
                           np.asarray([-0.1, -0.075, -0.058, -0.04815,
                                       -0.04453, -0.0461895, -0.0521812,
                                       -0.061588875, -0.073549579,
                                       -0.08727047595]),
                           np.asarray([0.0, -0.01, -0.013, -0.0101, -0.00239,
                                       0.009081, 0.0233295, 0.03945587,
                                       0.056657081, 0.0742343737]))

        tout, yout = dstep((a, b, c, d, dt), n=10)

        assert_equal(len(yout), 3)

        for i in range(0, len(yout)):
            assert_equal(yout[i].shape[0], 10)
            assert_array_almost_equal(yout[i].flatten(), yout_step_truth[i])

        # Check that the other two inputs (tf, zpk) will work as well
        tfin = ([1.0], [1.0, 1.0], 0.5)
        yout_tfstep = np.asarray([0.0, 1.0, 0.0])
        tout, yout = dstep(tfin, n=3)
        assert_equal(len(yout), 1)
        assert_array_almost_equal(yout[0].flatten(), yout_tfstep)

        zpkin = tf2zpk(tfin[0], tfin[1]) + (0.5,)
        tout, yout = dstep(zpkin, n=3)
        assert_equal(len(yout), 1)
        assert_array_almost_equal(yout[0].flatten(), yout_tfstep)

        # Raise an error for continuous-time systems
        system = lti([1], [1, 1])
        assert_raises(AttributeError, dstep, system)
Example #48
0
    def test_dimpulse(self):

        a = np.asarray([[0.9, 0.1], [-0.2, 0.9]])
        b = np.asarray([[0.4, 0.1, -0.1], [0.0, 0.05, 0.0]])
        c = np.asarray([[0.1, 0.3]])
        d = np.asarray([[0.0, -0.1, 0.0]])
        dt = 0.5

        # Because b.shape[1] == 3, dimpulse should result in a tuple of three
        # result vectors
        yout_imp_truth = (np.asarray([0.0, 0.04, 0.012, -0.0116, -0.03084,
                                      -0.045884, -0.056994, -0.06450548,
                                      -0.068804844, -0.0703091708]),
                          np.asarray([-0.1, 0.025, 0.017, 0.00985, 0.00362,
                                      -0.0016595, -0.0059917, -0.009407675,
                                      -0.011960704, -0.01372089695]),
                          np.asarray([0.0, -0.01, -0.003, 0.0029, 0.00771,
                                      0.011471, 0.0142485, 0.01612637,
                                      0.017201211, 0.0175772927]))

        tout, yout = dimpulse((a, b, c, d, dt), n=10)

        assert_equal(len(yout), 3)

        for i in range(0, len(yout)):
            assert_equal(yout[i].shape[0], 10)
            assert_array_almost_equal(yout[i].flatten(), yout_imp_truth[i])

        # Check that the other two inputs (tf, zpk) will work as well
        tfin = ([1.0], [1.0, 1.0], 0.5)
        yout_tfimpulse = np.asarray([0.0, 1.0, -1.0])
        tout, yout = dimpulse(tfin, n=3)
        assert_equal(len(yout), 1)
        assert_array_almost_equal(yout[0].flatten(), yout_tfimpulse)

        zpkin = tf2zpk(tfin[0], tfin[1]) + (0.5,)
        tout, yout = dimpulse(zpkin, n=3)
        assert_equal(len(yout), 1)
        assert_array_almost_equal(yout[0].flatten(), yout_tfimpulse)

        # Raise an error for continuous-time systems
        system = lti([1], [1, 1])
        assert_raises(AttributeError, dimpulse, system)
 def setUp(self):
     num = np.poly([3, 0.3, 1])
     den = np.poly([2, 0.5, .25])
     H = (num, den)
     tstr1 = empty()
     (tstr1.form, tstr1.num, tstr1.den) = ('coeff', num, den)
     tstr2 = empty()
     tstr2.form = 'zp'
     (tstr2.zeros, tstr2.poles, tstr2.gain) = tf2zpk(num, den)
     z = np.exp(1j * np.linspace(0, 2*np.pi, num=129, endpoint=True))
     self.h1 = ds.evalTF(tstr1, z)
     self.h2 = ds.evalTF(tstr2, z)
     self.h3 = ds.evalTF(H, z)
     self.h4 = ds.evalTF(lti(tstr2.zeros, tstr2.poles, tstr2.gain), z)
     h5tf = lti(tstr2.zeros, tstr2.poles, tstr2.gain)
     self.h5 = ds.evalTF((h5tf.A, h5tf.B, h5tf.C, h5tf.D), z)
     h6tf = np.vstack((np.hstack((h5tf.A, h5tf.B)),
                       np.hstack((h5tf.C, np.atleast_2d(h5tf.D)))))
     self.h6 = ds.evalTF(h6tf, z)
def _c2dmatched(sysC, Ts):
    # Pole-zero match method of continuous to discrete time conversion
    szeros, spoles, sgain = tf2zpk(sysC.num[0][0], sysC.den[0][0])
    zzeros = [0] * len(szeros)
    zpoles = [0] * len(spoles)
    pregainnum = [0] * len(szeros)
    pregainden = [0] * len(spoles)
    for idx, s in enumerate(szeros):
        sTs = s*Ts
        z = exp(sTs)
        zzeros[idx] = z
        pregainnum[idx] = 1-z
    for idx, s in enumerate(spoles):
        sTs = s*Ts
        z = exp(sTs)
        zpoles[idx] = z
        pregainden[idx] = 1-z
    zgain = np.multiply.reduce(pregainnum)/np.multiply.reduce(pregainden)
    gain = sgain/zgain
    sysDnum, sysDden = zpk2tf(zzeros, zpoles, gain)
    return TransferFunction(sysDnum, sysDden, Ts)
Example #51
0
 def __init__(self, num, den, dt=0.01, maxt=5.0, myvar='s', label='G'):
     """num and den are either scalar constants or lists that are
     passed to scipy.poly1d to create a list of coefficients."""
     #print('in TransferFunction.__init__, dt=%s' % dt)
     if _realizable(num, den):
         num = atleast_1d(num)
         den = atleast_1d(den)
         start_num_ind = nonzero(num)[0][0]
         start_den_ind = nonzero(den)[0][0]
         num_ = num[start_num_ind:]
         den_ = den[start_den_ind:]
         signal.lti.__init__(self, num_, den_)
     else:
         z, p, k = signal.tf2zpk(num, den)
         self.gain = k
     self.num = poly1d(num)
     self.den = poly1d(den)
     self.dt = dt
     self.myvar = myvar
     self.maxt = maxt
     self.label = label
Example #52
0
def trigonometric_filter_zeros(zeros):
    """ function return the zeros of trigonometric polynomial L(w)"""
    v = []
    z = []
    for i in range(zeros):
        v.append(calculate_combinations(zeros - 1, i))

    v = np.array(v, float)

    result = np.zeros(2 * zeros - 1)
    for k in range(zeros):
        result = result + v[k] * sinp(k, zeros - 1)

    den = np.zeros(len(result))
    den[len(den) - 1] = 1

    # convertize the transfer function to pole zero representation
    z1, p, k = tf2zpk(result, den)

    z = np.append(z, unique_real_zeros(z1))
    z = np.append(z, stable_zeros(z1))

    return z
Example #53
0
    def poles_zeros(self):
        """Computing and plotting POLES-ZEROS of the filter"""
        pyplot.figure(figsize=(6, 6))
        (p, z, k) = signal.tf2zpk(self.b, self.a)
        
        if self.ftype == 'butter':
            z = -(z / min(real(z)))
            circle = Circle((0, 0), radius=abs(max(z)), linestyle='dotted', fill=False)
            try:
               p = -(p / min(real(p)))
            except ValueError:
               pass
        else:
            circle = Circle((0, 0), radius=1, linestyle='dotted', fill=False)

        #Plotting Poles-zeros
        #pyplot.scatter(real(p), imag(p), marker='o', s=50)
        pyplot.scatter(real(z), imag(z), marker='x', s=100)

        pyplot.xlabel('Real Part')
        pyplot.ylabel('Imaginary Part')
        pyplot.title('Pole-zeros' + "\n" + str(self.ord) + "th order " + self.btype + " " + self.ftype_plot + " filter")

        #Formatting plot.
        pyplot.gca().add_patch(circle)
        limits = []
        limits.append(max(pyplot.gca().get_xlim()))
        limits.append(max(pyplot.gca().get_ylim()))
        max_limit = max(limits)
        
        if max_limit < 1.2:
            max_limit = 1.2

        pyplot.axis([-max_limit, max_limit, -max_limit, max_limit])
        pyplot.vlines(0, -max_limit, max_limit, color='k', linestyles='dotted')
        pyplot.hlines(0, -max_limit, max_limit, color='k', linestyles='dotted')
Example #54
0
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt

b, a = signal.iirdesign(wp=100, ws=200, gpass=2.0, gstop=40., analog=True)
w, h = signal.freqs(b, a)

plt.title('Analog filter frequency response')
plt.plot(w, 20*np.log10(np.abs(h)))
plt.ylabel('Amplitude Response [dB]')
plt.xlabel('Frequency')
plt.grid()
plt.show()


z, p, k = signal.tf2zpk(b, a)

plt.plot(np.real(z), np.imag(z), 'xb')
plt.plot(np.real(p), np.imag(p), 'or')
plt.legend(['Zeros', 'Poles'], loc=2)

plt.title('Pole / Zero Plot')
plt.ylabel('Real')
plt.xlabel('Imaginary')
plt.grid()
plt.show()
Example #55
0
For BPF when the transformation is applied to 1/(s-root) we get 
Numerator = Bs
Denominator = s^2+omega_0^2-B*c*s
Using this basic result and finding numerator and denominator to get the bandpass transfer function
'''
analog_numer = chebyshev_k.real
analog_denom = 1+0.j
for c in poles:
	if(c.real<= 0):
		analog_numer = np.poly1d([f_B,0],r=0)*analog_numer 
		analog_denom = np.poly1d([1,-f_B*c,omega_z_s],r=0)*analog_denom
print "Analog numerator\n",analog_numer
print "\nAnalog denominator\n",analog_denom

# Converting back to digital domain from transfer function
z,p,k=sg.tf2zpk(analog_numer,analog_denom)

plt.figure(5)
plt.grid(True)
plt.scatter(p.real,p.imag,s=50,c='b',marker='x')
plt.scatter(z.real,z.imag,s=50,c='b',marker='o')
plt.title('Pole Zero plot of Analog Bandpass filter')
plt.ylabel('Imaginary')
plt.xlabel('Real')

'''
For converting the bandpass filter to digital domain using 
s = (1-z^-1)/(1+z^-1)
Numerator = B(z^2-1)
Denominator = (omega_0^2-B+1)z^2+(2*omega_0^2-2)z+(omega_0^2+B+1)
Using this basic result and finding numerator and denominator to get the bandpass transfer function
Example #56
0

print dec_lo
print dec_hi
print recon_lo
print recon_hi


w = pywt.Wavelet("db3")
print w.rec_lo
print w.rec_hi
print w.dec_lo
print w.dec_hi

figure()
z, p, k = tf2zpk(w.rec_lo, [1])
zplane(z, p)
show()
ddddddddd
# print "constrains",np.sum(h1),np.sum(h1**2)


print np.mean((w.rec_lo - h1) ** 2), "estimation error"


show()
ddddddd
asdasd
c = np.convolve(w.dec_lo, np.flipud(w.dec_lo))
print c
Example #57
0
rptpole = figure("Frequency Response")
fft_N = 32768
mag_p = rptpole.add_subplot(2,1,1)
ang_p = rptpole.add_subplot(2,1,2)

rep_array = arange(6) + 0
color_list = ['r', 'k', 'b', 'm', 'g', 'y']

for i in rep_array:
	ply = poly(ones(i + 1) * root_r)
	gfiltpak.gfreqz(b, ply, fft_N, Fs=1e6, color = color_list[i], magfig = mag_p, angfig = ang_p, logx = True, threedb = True, ylimmag = [-10, 0])
	hold(True)
##########################################

# Residues = Partial fraction expansion
z, p, k = si.tf2zpk(b, a)

#figure("Scatter plot")
#scatter(real(p), imag(p), vmin = -0.5, vmax = 0.5)
#scatter(real(z), imag(z), vmin = -0.5, vmax = 0.5)

#figure("Zplane plot")
#gfiltpak.zplane(b, a)

##########################################
# Residues
b = [0.5, 0.5, 0.25]
a = [1, 0.5, 0.5, 0.75]

ylims = [-50, 0]
Example #58
0
#Lowpass filter transfer function
#Find gain for Chebyshev
K_butter=omega_c**N
#print "GAIN:",K_butter
#print "omega_c:",omega_c
numer=K_butter
denom=1+0.j
for c in poles_a:
  if(c.real<= 0):
    numer=np.poly1d([1,0,omega_z_s],r=0)*numer 
    denom=np.poly1d([-c,f_B,-c*omega_z_s],r=0)*denom

#print "analog numerator\n",numer
#print "\nanalog denominator\n",denom
z,p,k=sg.tf2zpk(numer,denom)
#print "Check",z,p,k

plt.figure(5)
plt.grid(True)
plt.scatter(p.real,p.imag,s=50,marker='x')
plt.scatter(z.real,z.imag,s=50,marker='o')
plt.title('Pole Zero plot of Analog Bandstop filter')
plt.ylabel('Imaginary')
plt.xlabel('Real')

#Tedious still basic version
#Need to try convolution
#Numerator= (omega_0^2+1)z^2+2*(omega_0^2-1)z+(omega_0^2+1) 
#Denominator= (-B-c-c*omega_0^2)z^2+(2*c-2*c*omega_0^2)z+(-c*omega_0^2-c+B)
numer=K_butter
def lab6_ex5():
    
    # set parameters of system
    fs = 2000 #sampling frequency (Hz)
    fn = fs/2 #nyqvist frequency
    fc = array([0,200,300,1000]) #corner frequencies (assuming typo in lab, putting pass-band @ 0-200 and stop-band @ 300-1000)
    fb = array([1.0,0]) #desired band gains for each pair of corner frequencies
    deg = 19 #degree of polynomial
    nt = deg + 1 #number of taps = degree + 1
    a = array([1.0,0]) #(no feedback (FIR), poles at origin reduced to 1 for simplification)

    # create remez filter, frequency response, and plot
    b1 = remez(nt,fc,fb,Hz=fs)
    w,h = freqz(b1,a)
    subplot(211)
    plot(w/pi*fn, 20*log10(abs(h)),'b-')
    title('Remez algo FIRs (20 taps)')
    ylabel('magnitude (dB scale)')
    grid()

    # change to high-pass (switch desired band gains)
    fb = array([0,1.0]) #desired band gains for each pair of corner frequencies
    b2 = remez(nt,fc,fb,Hz=fs)
    w,h = freqz(b2,a)
    plot(w/pi*fn, 20*log10(abs(h)),'r-')
    
    # change to band-stop (add pair of corner frequencies: need at least 3 pairs to produce stopband between 200-300Hz)
    fc = array([0,199,200,300,301,1000]) #corner frequencies
    fb = array([1.0,0,1.0]) #desired band gains for each pair of corner frequencies
    b3 = remez(nt,fc,fb,Hz=fs)
    w,h = freqz(b3,a)
    plot(w/pi*fn, 20*log10(abs(h)),'g-')
    legend(("low-pass","high-pass","band-stop"),loc='best')
    
    # redo all 3 filters using firwin2 instead of remez algorithm
    # low-pass
    fc = array([0,200,300,fn-1,fn]) #frequency sampling points
    fb = array([1.0,1.0,0,0,0]) #gains for each sampling point
    b4 = firwin2(nt,fc,fb,nyq=fn) #calc FIR coefficients with given frequency response
    a = array([1.0,0]) #(no feedback (FIR), poles at origin reduced to 1 for simplification)      
    w,h = freqz(b4,a)
    subplot(212)    
    plot(w/pi*fn, 20*log10(abs(h)),'b-')
    title('Firwin2 algo FIRs (20 taps)')
    xlabel('frequency')
    ylabel('magnitude (dB scale)')    
    # high-pass    
    fb = array([0,0,1,1,0])
    b5 = firwin2(nt,fc,fb,nyq=fn)
    w,h = freqz(b5,a)
    plot(w/pi*fn, 20*log10(abs(h)),'r-')
    # band-stop (200-300Hz)        
    fc = array([0,200,300,fn-1,fn])
    fb = array([1.0,0,0,1.0,0])
    b6 = firwin2(nt,fc,fb,nyq=fn)
    w,h = freqz(b6,a)
    plot(w/pi*fn, 20*log10(abs(h)),'g-')
    legend(("low-pass","high-pass","band-stop"),loc='best')
    show()  
        
    z,p,k = tf2zpk(b1,a)
    zplane(z,p)
    title('low-pass remez FIR')
    show()    
    z,p,k = tf2zpk(b4,a)
    zplane(z,p)
    title('low-pass firwin2 FIR')
    show()    

    z,p,k = tf2zpk(b2,a)
    zplane(z,p)
    title('high-pass remez FIR')
    show()        
    z,p,k = tf2zpk(b5,a)
    zplane(z,p)
    title('high-pass firwin2 FIR')
    show()  
    
    z,p,k = tf2zpk(b3,a)
    zplane(z,p)
    title('band-stop remez FIR')
    show()    
    z,p,k = tf2zpk(b6,a)
    zplane(z,p)
    title('band-stop firwin2 FIR')
    show()
    
    print("\nHere we see that a 20-tap FIR system is limited in performance, whether its algorithm is Remez or Firwin2 (window method):")    
    print("\nRemez:\nThe low-pass Remez does attenuate rapidly at 300Hz, but the high-pass's response at higher frequencies oscillates above and below 0dB, meaning it both amplifies and attenuates high frequencies. The band-stop FIR has the same issue at both low and high frequency bands that should be passed.")    
    print("\nFirwin2:\nThe low-pass and high-pass Firwin2 filters attenuate slowly at their corner frequencies, but at least they attenuate. The band-stop filter shows the weakness of this response, however, as it looks to be attenuating just about every frequency available, not just those within the 200-300Hz range")    
    print("\nClearly, these FIRs require much higher numbers of taps (e.g. at least 40-50 taps, as in earlier exercises) to perform adequately in many situations")