Open In App

Design an IIR Bandpass Chebyshev Type-2 Filter using Scipy – Python

Last Updated : 10 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

IR stands for Infinite Impulse Response, It is one of the striking features of many linear-time invariant systems that are distinguished by having an impulse response h(t)/h(n) which does not become zero after some point but instead continues infinitely.

What is IIR Chebyshev Filter?

IIR Chebyshev is a filter that is linear-time invariant filter just like the Butterworth however, it has a steeper roll-off compared to the Butterworth Filter. Chebyshev Filter is further classified as Chebyshev Type-I and Chebyshev Type-II according to the parameters such as pass band ripple and stop ripple.

How is Chebyshev Filter different from Butterworth?

Chebyshev Filter has a steeper roll-off compared to the Butterworth Filter.

What is Chebyshev Type-2 Filter?

Chebyshev Type-2 minimizes the absolute difference between the ideal and actual frequency response over the entire stopband by incorporating an equal ripple in the stopband.

The specifications are as follows:  

  • Pass band frequency: 1400-2100 Hz
  • Stop band frequency: 1050-24500 Hz
  • Pass band ripple: 0.4dB
  • Stop band attenuation: 50 dB
  • Sampling frequency: 7 kHz

We will plot the magnitude, phase, impulse, step response of the filter.

Step-by-step Approach:

Step 1: Importing all the necessary libraries.

Python3




# import required library
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt


Step 2: Defining user-defined functions mfreqz() and impz(). The mfreqz is a function for magnitude and phase plotand the impz is a function for impulse and step response]

Python3




def mfreqz(b, a, Fs):
   
    # Compute frequency response of the filter
    # using signal.freqz function
    wz, hz = signal.freqz(b, a)
 
    # Calculate Magnitude from hz in dB
    Mag = 20*np.log10(abs(hz))
 
    # Calculate phase angle in degree from hz
    Phase = np.unwrap(np.arctan2(np.imag(hz), np.real(hz)))*(180/np.pi)
 
    # Calculate frequency in Hz from wz
    Freq = wz*Fs/(2*np.pi)
 
    # Plot filter magnitude and phase responses using subplot.
    fig = plt.figure(figsize=(10, 6))
 
    # Plot Magnitude response
    sub1 = plt.subplot(2, 1, 1)
    sub1.plot(Freq, Mag, 'r', linewidth=2)
    sub1.axis([1, Fs/2, -100, 5])
    sub1.set_title('Magnitude Response', fontsize=20)
    sub1.set_xlabel('Frequency [Hz]', fontsize=20)
    sub1.set_ylabel('Magnitude [dB]', fontsize=20)
    sub1.grid()
 
    # Plot phase angle
    sub2 = plt.subplot(2, 1, 2)
    sub2.plot(Freq, Phase, 'g', linewidth=2)
    sub2.set_ylabel('Phase (degree)', fontsize=20)
    sub2.set_xlabel(r'Frequency (Hz)', fontsize=20)
    sub2.set_title(r'Phase response', fontsize=20)
    sub2.grid()
 
    plt.subplots_adjust(hspace=0.5)
    fig.tight_layout()
    plt.show()
 
 
# Define impz(b,a) to calculate impulse
# response and step response of a system
# input: b= an array containing numerator
# coefficients,a= an array containing
# denominator coefficients
def impz(b, a):
 
    # Define the impulse sequence of length 60
    impulse = np.repeat(0., 60)
    impulse[0] = 1.
    x = np.arange(0, 60)
 
    # Compute the impulse response
    response = signal.lfilter(b, a, impulse)
 
    # Plot filter impulse and step response:
    fig = plt.figure(figsize=(10, 6))
    plt.subplot(211)
    plt.stem(x, response, 'm', use_line_collection=True)
    plt.ylabel('Amplitude', fontsize=15)
    plt.xlabel(r'n (samples)', fontsize=15)
    plt.title(r'Impulse response', fontsize=15)
 
    plt.subplot(212)
    step = np.cumsum(response)
 
    plt.stem(x, step, 'g', use_line_collection=True)
    plt.ylabel('Amplitude', fontsize=15)
    plt.xlabel(r'n (samples)', fontsize=15)
    plt.title(r'Step response', fontsize=15)
    plt.subplots_adjust(hspace=0.5)
 
    fig.tight_layout()
    plt.show()


Step 3:Define variables with the given specifications of the filter.

Python3




# Given specification
 
# Sampling frequency in Hz
Fs = 7000 
 
# Pass band frequency in Hz
fp = np.array([1400, 2100]) 
 
# Stop band frequency in Hz
fs = np.array([1050, 2450]) 
 
# Pass band ripple in dB
Ap = 0.4
 
# Stop band attenuation in dB
As = 50 


Step 4: Compute the cut-off frequency

Python3




# Compute pass band and stop band edge frequencies
 
# Normalized passband edge
# frequencies w.r.t. Nyquist rate
wp = fp/(Fs/2
 
# Normalized stopband
# edge frequencies
ws = fs/(Fs/2)


Step 5: Compute order of the Chebyshev type-2 digital filter.

Python3




# Compute order of the Chebyshev type-2
# digital filter using signal.cheb2ord
N, wc = signal.cheb2ord(wp, ws, Ap, As)
 
# Print the order of the filter
# and cutoff frequencies
print('Order of the filter=', N)
print('Cut-off frequency=', wc)


Output:

Step 6: Design digital Chebyshev type-2 bandpass filter.

Python3




# Design digital Chebyshev type-2 bandpass
# filter using signal.cheby2 function
z, p = signal.cheby2(N, As, wc, 'bandpass')
 
 
# Print numerator and denomerator
# coefficients of the filter
print('Numerator Coefficients:', z)
print('Denominator Coefficients:', p)


Output:

Step 7: Plot magnitude and phase response.

Python3




# Call mfreqz to plot the
# magnitude and phase response
mfreqz(z, p, Fs)


Output:

Step 8: Plot impulse and step response of the filter.

Python3




# Call impz function to plot impulse
# and step response of the filter
impz(z, p)


Output:

Below is the complete implementation of the above stepwise approach:

Python3




# import required library
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt
 
 
def mfreqz(b, a, Fs):
   
    # Compute frequency response of the
    # filter using signal.freqz function
    wz, hz = signal.freqz(b, a)
 
    # Calculate Magnitude from hz in dB
 
    Mag = 20*np.log10(abs(hz))
 
    # Calculate phase angle in degree from hz
    Phase = np.unwrap(np.arctan2(np.imag(hz), np.real(hz)))*(180/np.pi)
 
    # Calculate frequency in Hz from wz
    Freq = wz*Fs/(2*np.pi)
 
    # Plot filter magnitude and phase responses using subplot.
    fig = plt.figure(figsize=(10, 6))
 
    # Plot Magnitude response
    sub1 = plt.subplot(2, 1, 1)
    sub1.plot(Freq, Mag, 'r', linewidth=2)
    sub1.axis([1, Fs/2, -100, 5])
    sub1.set_title('Magnitude Response', fontsize=20)
    sub1.set_xlabel('Frequency [Hz]', fontsize=20)
    sub1.set_ylabel('Magnitude [dB]', fontsize=20)
    sub1.grid()
 
    # Plot phase angle
    sub2 = plt.subplot(2, 1, 2)
    sub2.plot(Freq, Phase, 'g', linewidth=2)
    sub2.set_ylabel('Phase (degree)', fontsize=20)
    sub2.set_xlabel(r'Frequency (Hz)', fontsize=20)
    sub2.set_title(r'Phase response', fontsize=20)
    sub2.grid()
 
    plt.subplots_adjust(hspace=0.5)
    fig.tight_layout()
    plt.show()
 
# Define impz(b,a) to calculate impulse
# response and step response of a system
# input: b= an array containing numerator
# coefficients,a= an array containing
# denominator coefficients
def impz(b, a):
   
    # Define the impulse sequence of length 60
    impulse = np.repeat(0., 60)
    impulse[0] = 1.
    x = np.arange(0, 60)
 
    # Compute the impulse response
    response = signal.lfilter(b, a, impulse)
 
    # Plot filter impulse and step response:
    fig = plt.figure(figsize=(10, 6))
    plt.subplot(211)
    plt.stem(x, response, 'm', use_line_collection=True)
    plt.ylabel('Amplitude', fontsize=15)
    plt.xlabel(r'n (samples)', fontsize=15)
    plt.title(r'Impulse response', fontsize=15)
 
    plt.subplot(212)
    step = np.cumsum(response) 
     
    # Compute step response of the system
    plt.stem(x, step, 'g', use_line_collection=True)
    plt.ylabel('Amplitude', fontsize=15)
    plt.xlabel(r'n (samples)', fontsize=15)
    plt.title(r'Step response', fontsize=15)
    plt.subplots_adjust(hspace=0.5)
 
    fig.tight_layout()
    plt.show()
 
 
# Given specification
 
# Sampling frequency in Hz
Fs = 7000 
 
# Pass band frequency in Hz
fp = np.array([1400, 2100])
 
# Stop band frequency in Hz
fs = np.array([1050, 2450])
 
# Pass band ripple in dB
Ap = 0.4
 
# Stop band attenuation in dB
As = 50 
 
# Compute pass band and
# stop band edge frequencies
 
# Normalized passband edge frequencies w.r.t. Nyquist rate
wp = fp/(Fs/2)
 
# Normalized stopband edge frequencies
ws = fs/(Fs/2
 
# Compute order of the Chebyshev type-2
# digital filter using signal.cheb2ord
N, wc = signal.cheb2ord(wp, ws, Ap, As)
 
# Print the order of the filter and cutoff frequencies
print('Order of the filter=', N)
print('Cut-off frequency=', wc)
 
# Design digital Chebyshev type-2 bandpass
# filter using signal.cheby2 function
z, p = signal.cheby2(N, As, wc, 'bandpass')
 
 
# Print numerator and denomerator coefficients of the filter
print('Numerator Coefficients:', z)
print('Denominator Coefficients:', p)
 
# Call mfreqz to plot the
# magnitude and phase response
mfreqz(z, p, Fs)
 
# Call impz function to plot impulse
# and step response of the filter
impz(z, p)




Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads