python - Frequency Response Scipy.signal -
i'm learning digital signal processing implement filters , using python implement test ideas. started using scipy.signal library find impulse response , frequency response of different filters.
currently working through book "digital signals, processors , noise paul a. lynn (1992)" (and finding amazing resource learning stuff). in book have filter transfer functions shown below:
i divided numerator , denominator in order following equation:
i implemented scipy using:
numeratorzcoefs = [1, -1, 1, -1] denominatorzcoefs = [1, 0.54048, -0.62519, -0.66354, 0.60317, 0.69341] freqresponse = scipy.signal.freqz(numeratorzcoefs, denominatorzcoefs) fig = plt.figure(figsize = [8, 6]) ax = fig.add_subplot(111) ax.plot(freqresponse[0], abs(np.array(freqresponse[1]))) ax.set_xlim(0, 2*np.pi) ax.set_xlabel("$\omega$")
and produce plot shown below:
however in book frequency response shown following:
they same shape ratio of peaks @ ~2.3 , 0.5 different 2 plots, suggest why is?
edit:
to add this, i've implemented function calculate frequency response hand (by calculating distance poles , zeros of function) , similar ratio plot generated scipy.signal, numbers not same, know why might by?
implementation follows:
def h(omega): z1 = np.array([0,0]) # 0 @ 0, 0 z2 = np.array([0,0]) # 0 @ 0, 0 z3 = np.array([0, 1]) # 0 @ z4 = np.array([0, -1]) # 0 @ -i z5 = np.array([1, 0]) # 0 @ 1 z = np.array([z1, z2, z3, z4, z5]) p1 = np.array([-0.8, 0]) p = cmath.rect(0.98, np.pi/4) p2 = np.array([p.real, p.imag]) p = cmath.rect(0.98, -np.pi/4) p3 = np.array([p.real, p.imag]) p = cmath.rect(0.95, 5*np.pi/6) p4 = np.array([p.real, p.imag]) p = cmath.rect(0.95, -5*np.pi/6) p5 = np.array([p.real, p.imag]) p = np.array([p1, p2, p3, p4, p5]) = cmath.rect(1,omega) a_2dvector = np.array([a.real, a.imag]) dz = z-a_2dvector dp = p-a_2dvector dzmag = [] dis in dz: dzmag.append(np.sqrt(dis.dot(dis))) dpmag = [] dis in dp: dpmag.append(np.sqrt(dis.dot(dis))) return(np.product(dzmag)/np.product(dpmag))
i plot frequency response so:
omegalist = np.linspace(0,2*np.pi,5000) hlist = [] omega in omegalist: hlist.append(h(omega)) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(omegalist, hlist) ax.set_xlabel("$\omega$") ax.set_ylabel("$|h(\omega)|$")
and following plot:
the scipy generated frequency response correct. in case, wouldn't trust book's figure appears have been drawn hand.
if want find frequency response "manually", can done defining function returning original z-transform , evaluating on unit circle follows
def h(z): num = z**5 - z**4 + z**3 - z**2 denom = z**5 + 0.54048*z**4 - 0.62519*z**3 - 0.66354*z**2 + 0.60317*z + 0.69341 return num/denom import numpy np import matplotlib.pyplot plt w_range = np.linspace(0, 2*np.pi, 1000) plt.plot(w_range, np.abs(h(np.exp(1j*w_range))))
the result same scipy.
Comments
Post a Comment