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)

  1. 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
    train=np.zeros(240)
    for k in range(0,10):
    train[80*k]=1
    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:
    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))
  2. 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
    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]
    Use your code to filter the impulse train. Plot the waveform, magnitude spectrum, phase spectrum, and level spectrum of the result.
  3. 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.
    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]
    Run butterworth1 and butterworthbackward 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.
  4. 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:

  1. Four figures:
    1. Signal, magnitude spectrum, phase spectrum, and level spectrum of an impulse train.
    2. Same as (a), after being lowpass filtered by a one-tap Butterworth with bandwidth of pi/20 radians/sample.
    3. Same as (a), after being lowpass filtered both forward and backward in time.
    4. Same as (a), after being highpass filtered by a one-tap Butterworth with bandwidth of pi/20.
  2. Your code.

Walkthrough

Here's a video walkthrough of lab 10.