The goal of today's lab will be to simulate IIR lowpass and bandpass filters. We will use one-tap Butterworth filters, applied both forward and backward in time.
Instructions | Deliverables | Walkthrough |Detailed Instructions (Recommended Steps in Python)
- Create a 240-sample impulse train, containing impulses
every 80 samples, starting at the first sample (sample
number 0). This could be done using code such as
Plot the time domain signal, magnitude spectrum, phase spectrum, and level spectrum, but this time, plot the Fourier series coefficients. You can calculate the Fourier series coefficients by taking the Fourier transform of just one period, something like this:
train=np.zeros(240)
for k in range(0,10):
train[80*k]=1
def plotstuff(signal,label):
plt.subplot(4,1,1)
plt.plot(signal)
plt.title('{} Time Domain Signal'.format(label))
plt.subplot(4,1,2)
dtft = scipy.fftpack.fft(signal[0:80])
magnitude_response = [ abs(x) for x in dtft[0:41] ]
omega = [ math.pi*k/len(dtft) for k in range(0,41)]
plt.plot(omega,magnitude_response)
plt.title('Magnitude Spectrum of {}'.format(label))
plt.subplot(4,1,3)
phase_response = [ cmath.phase(x) for x in dtft[0:41] ]
plt.plot(omega,phase_response,omega,zero_line)
plt.title('Phase Spectrum of {}'.format(label))
plt.subplot(4,1,4)
level_spectrum = [ 20*math.log10(max(0.001,x)) for x in magnitude_response ]
plt.subplot(4,1,4)
plt.plot(omega,level_spectrum)
plt.title('Level Spectrum of {}'.format(label))
- A one-tap lowpass Butterworth filter has the transfer
function H(z)=(1+a/z)/(1-a/z), where the bandwidth of the
filter is -log(a) (natural logarithm). Choose "a" so that
the bandwidth is roughly pi/20. Write a
function
butterworth1
that implements a one-tap Butterworth, as
Use your code to filter the impulse train. Plot the waveform, magnitude spectrum, phase spectrum, and level spectrum of the result.
def y=butterworth1(x,a):
y = np.zeros(len(x))
y[0] = x[0]
for n in range(1,len(x)):
y[n] = x[n]+a*x[n-1]+a*y[n-1]
-
You might have noticed that the signal has been lowpass
filtered, but that its phase spectrum has been a bit
distorted. Here's a trick that lets us cancel the phase
distortion: we filter the signal again, but backward.
Run
def y=butterworthbackward(x,a):
N = len(x)
y = np.zeros(N)
y[N-1] = x[N-1]
for n in range(N-2,-1,-1):
y[n] = x[n]+a*x[n+1]+a*y[n+1]
butterworth1
andbutterworthbackward
in series (feed the output of one into the input of the other). Plot the resulting signal, magnitude spectrum, phase spectrum, and level spectrum. You should find that the signal has been even more lowpass filtered in its magnitude, but that its phase spectrum is back to being zero phase. - A Butterworth highpass filter is just rotated around
from 0 radians/sample to pi radians/sample. That means we
change from z to -z --- or equivalently, change from "a" to
"-a". Run
butterworth1
on your impulse train again, but this time, change the sign of "a". Plot the signal, magnitude spectrum, phase spectrum, and level spectrum. You should find that the magnitude spectrum looks highpass filtered.
Deliverables (Required)
By 4/18/2017 23:59, upload to compass a zip file named MYNAME_LAB10.ZIP containing the following things:
- Four figures:
- Signal, magnitude spectrum, phase spectrum, and level spectrum of an impulse train.
- Same as (a), after being lowpass filtered by a one-tap Butterworth with bandwidth of pi/20 radians/sample.
- Same as (a), after being lowpass filtered both forward and backward in time.
- Same as (a), after being highpass filtered by a one-tap Butterworth with bandwidth of pi/20.
- Your code.
Walkthrough
Here's a video walkthrough of lab 10.