0
$\begingroup$

I'm always confused that scipy has

According to the documentation they all compute the frequency response. Surprisingly, the convention for the b coefficients are exactly opposite (as pointed out in this answer as well), and they use a different default of sample points. Other than that, my interpretation of the documentation is that scipy.signal.freqz should be yield the same as scipy.signal.dlti.freqresp. However I can't get the same results trying it out on a small example:

import scipy
import matplotlib.pyplot as plt

filter_coef = [0.2, 0.8]
w1, h1 = scipy.signal.freqz(filter_coef)

dlti = scipy.signal.dlti(filter_coef[::-1], [1]) # accounting for flipped convention
w2, h2 = dlti.freqresp(n=len(w1))

fig, axes = plt.subplots(2, 1)
axes[0].plot(w1, np.abs(h1), label="freqz")
axes[0].plot(w2, np.abs(h2), label="dlti.freqresp")
axes[1].plot(w1, np.angle(h1), label="freqz")
axes[1].plot(w2, np.angle(h2), label="dlti.freqresp")
plt.legend()
plt.show()

Produces:

enter image description here

It looks like they match in terms of magnitude, but for some reason the phase is flipped.

Any ideas what is the difference here? And more generally, when should I use which version of freqz/freqresp?

$\endgroup$
1
  • $\begingroup$ don't forget freqs $\endgroup$
    – endolith
    Jun 11 '20 at 17:30
1
$\begingroup$

The equation of the filter is given as

$$H(z) = 0.2 + 0.8z^{-1}$$

This can be equivalently described with positive powers of z as:

$$H(z) = \frac{0.2z+0.8}{z}$$

The two equations above are mathematically equivalent. The function freqz specifies that the numerator and denominator polynomials are to be entered in decreasing (negative) powers of z, while freqresp specifies that they are to be entered in positive powers of z. So the OP should use the first form for freqz and the second form for freqresp. In contrast the OP has flipped the order which is the not the same filter.

In general, in order for the filter to be causal, if expressed in positive powers of z it is implied that it also must be divided by poles at the origin, in this case multiplied by $z^{-1}$.

Doing the following will result in the same answer as the result with freqz:

dlti = scipy.signal.dlti(filter_coef, [1,0]) # accounting for positive power convention

Flipping the coefficients, as the OP has done, is the "reverse filter". The reverse filter has the same magnitude response but has zeros at the reciprocal locations on the z-plane, given by $H(z^{-1})$, giving the result that the OP achieved.

$\endgroup$
7
  • $\begingroup$ Since I'm new to signal processing, I'll have to ponder over that for a while. So in terms of differences of the functions is it correct to conclude that freqz assumes causality whereas freqresp doesn't? How do you arrive in general for any given causal b / a at the equivalent terms for freqresp? $\endgroup$
    – bluenote10
    Jun 11 '20 at 13:18
  • $\begingroup$ You need to put the same equation in both. You have fundamentally changed the equation by flipping it, while if you follow what I did the equality still holds. So there format of the exponent is different, but you can't change the equation itself. Simply 5x+1 is NOT equal to 1x+5! But (5 + 1/x)x is the same equation $\endgroup$ Jun 11 '20 at 13:21
  • $\begingroup$ So neither assumes causality, they are just specifying the input format. They will give you the result for the equation to that specification. $\endgroup$ Jun 11 '20 at 13:23
  • $\begingroup$ But to see why 0.2z+0.8 by itself is non-causal: $z^{-1}$ is (the z transform of) a unit delay. Something with a transfer function of $5z^{-1}$ for example multiplies the input by 5 and shifts it one sample, such that the output represents a previous input in the past, multiplied by 5. In comparison $5z$ would be a system whose output represents then next sample in the future, multiplied by 5. That is non-causal and something we can't implement. So you asked freqresp to give you the response for a non-causal filter, which it did. This isn't the filter $0.2 + 0.8z^{-1}$, you changed it! $\endgroup$ Jun 11 '20 at 13:27
  • $\begingroup$ Note that I did not flip the coefficients with the intention to reverse the filter, but simply because the documentation of freqz says coefficients are in increasing order, whereas for freqresp they are in decreasing order. My goal simply is: Given any freqz(b, a) call, find the equivalent via dlti.freqresp. $\endgroup$
    – bluenote10
    Jun 11 '20 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.