简体   繁体   中英

Impulse response of notch filter

I'm trying to implement a notch filter of form W(z) = N(z)/D(z) for an assignment, where N=a+bz+cz^2 and D=1+Bz+Cz^2. To do this, I apply the first filter as a direct 3 term convolution, and then the second filter as a 3 term inverse convolution.

To test this filter, I then create a discretized delta function and pass it into the function as an input.

The code I use for my filter and my test is as below:

import numpy as np
import matplotlib.pyplot as plt

fs=12
f0=1
M=1.05
epsilon = 0.05

# Define rational filter:
def ratFilter(N, D, x):
    '''
    Apply two filters in succession to x
    :param N: 3-tuple parameters for numerator filter
    :param D: 3-tuple parameters for denominator inverse filter
    :param x:
    :return: y
    '''
    y = np.zeros(np.size(x))
    n = np.zeros(np.size(x)+np.size(D)) #middle value
    # apply first filter:
    for i in range(np.size(n)):
        for k in range(0, i+1):
            try:
                n[i]+=N[k]*x[i-k]
            except:
                pass
    for i in range(np.size(y)):
        y[i]=n[i]/D[0]
        for k in range(1, i+1):
            try:
                y[i]-=D[k]/D[0]*y[i-k]
            except:
                pass
    return y

# Impulse response:
delta = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

N = [0.952, -1.650, 0.952]
D = [1, -1.650, 0.907]

output = ratFilter(N, D, delta)

plt.plot(output)
plt.title("impulse response")
plt.show()

The resulting graph has the following form, and I believe it is incorrect, as other people I know have a sharp upward spike at the start, followed by a linear increase:

Output of impulse response:

在此处输入图片说明

Something else that must be done is to fourier transform the impulse response to obtain the frequency response |W(f)|, but intuitively I'm uncertain about the link between the fourier transform and the z transform, and thus if there is any special procedure as opposed to taking whatever the result of np.fft.fft as applied to the output is.

I'm not sure what makes you think that your classmates' results are correct and yours aren't, but it looks like your implementation yields the same results as a standard implementation from scipy.signal.lfilter with the same inputs.

As far as |W(f)| is concerned, the relationship between the z-transform and np.fft.fft can be obtained from the following observations:

  • The Discrete Time Fourier Transform (DTFT) corresponds to the z-transform evaluated on the unit circle in the complex plane.
  • In the frequency-domain the Discrete Fourier Transform (DFT) corresponds to the uniformly sampled version of the continuous DTFT frequency-spectrum.
  • The Fast Fourier Transform (which is computed by np.fft.fft ) is an efficient algorithm to compute the Discret Fourier Transform.

Thus computing the FFT of your impulse response would give you the frequency spectrum of that sequence at discrete frequency values. The main issue in this case is that due to the recursive nature of your filter, the impulse response has an infinite length. So, you'd need to make sure you consider a sufficiently long portion of the impulse response that the truncation error is negligible.

Hint : as an alternative, you should consider what happens when evaluating the ratio of the FFT of N and of the FFT of D .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM