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
# 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 plot and the impz is a function for impulse and step response].
Python3
# 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( '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() |
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 Elliptic Bandpass digital filter.
Python3
# 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) |
Step 6: Design digital Elliptical bandpass filter.
Python3
# 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) |
Step 7: Plot magnitude and phase response.
Python3
# Depicting visualizations # Call mfreqz to plot the magnitude and phase response mfreqz(z, p, Fs) |
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) |
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 # 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( '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 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 visualizations # 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) |
Output: