Skip to content
Related Articles

Related Articles

Design IIR Bandpass Elliptic Filter using Scipy- Python
  • Last Updated : 24 Jan, 2021

IIR stands for Infinite Impulse Response, It is one of the striking characteristics of many linear-time invariant systems that are characterized from having an impulse response h(t)/h(n) that does not reach 0 at any stage but instead persists indefinitely.

What is IIR Bandpass Elliptic Filter ?

Elliptical Filter is a special type of Filter that is used in digital signal processing when there is a need for a fast transition from pass to stop band. 

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 response of the filter.

Step-by-step Approach:

Step 1: Importing all the necessary libraries.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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



Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Function to depict magnitude 
# and phase plot
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('Magnitute 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()

chevron_right


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

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


Step 4: Compute the cut-off frequency

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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)

chevron_right


Step 5: Compute order of the Elliptic Bandpass digital filter.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right




Step 6: Design digital Elliptical bandpass filter.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Design digital elliptic bandpass filter 
# using signal.ellip function
z, p = signal.ellip(N, Ap, As, wc, 'bandpass')
  
  
# Print numerator and denomerator 
# coefficients of the filter
print('Numerator Coefficients:', z)
print('Denominator Coefficients:', p)

chevron_right


Step 7: Plot magnitude and phase response.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Below is the complete implementation of the above stepwise approach:

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Import required library
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt
  
  
# Function to depict magnitude 
# and phase plot
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('Magnitute 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 elliptic filter 
# using signal.ellipord
N, wc = signal.ellipord(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 elliptic bandpass filter 
# using signal.ellip() function
z, p = signal.ellip(N, Ap, As, wc, 'bandpass')
  
  
# Print numerator and denomerator coefficients of the filter
print('Numerator Coefficients:', z)
print('Denominator Coefficients:', p)
  
  
# Depicting visulalizations
  
# 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)

chevron_right


Output:


Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :