You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 7, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Feb 7, 2024. It is now read-only.
Zero-phase filtfilt distortion of weighting filter frequency response? #240
In signal.weigh there is the zero-phase option that uses scipy.signal.filtfilt.
To inspect the frequency response of the zero-phase (forwards-backwards operation) filter Hzp, it is necessary to calculate the frequency response of the forwards filter H (using scipy.signal.freqz), and then multiply it by the complex conjugate H*. Doing this shows that the forwards-backwards operation (ie applying the filter two times to the signal) distorts the overall frequency response Hzp, which in many cases will not give the desired response. In this case, zero-phase operation pushes the filter response outside the relevant IEC acceptance limits.
To avoid this distortion it would be necessary to pre-warp the filter frequencies (in a similar way to compensating for bilinear transform distortion), although I'm unaware of any way to determine the appropriate pre-warping analytically for arbitrary filter responses.
That's interesting. For my application I never bothered with validating the high-frequency response because my signal of interest was typically below 4 to 8 kHz.
Unfortunately the filtfilt distortion is not limited to the high frequency range - it affects the entire frequency response, and is a result of applying the filter twice, once forwards, once backwards. This is a separate problem to the issue I raised in relation to the bilinear transform distortion, which affects mainly the high frequencies. To demonstrate both problems, see the figures below. The first one compares the frequency response obtained using a one-way filter (lfilter) with that using a zero-phase forwards-backwards filter (filtfilt), against the IEC 61672-1 acceptance limits, when pre-warping for bilinear transform distortion has not been applied (ie representing the code currently in your library):
This comparison shows that the frequency response using filtfilt is considerably outside the IEC limits (whereas the lfilter response is inside, although the roll-off at higher frequencies is faster than the IEC ideal curve).
The next figure shows exactly the same comparison, but this time with pre-warping to compensate for bilinear transform distortion, but still no compensation for the filtfilt distortion (as I don't currently know how one would achieve this!):
From this second figure you can see that the effect of compensating for the bilinear transform distortion is to slightly improve the higher frequency response roll-off, but there is negligible effect elsewhere in the response.
In either case (ie with or without bilinear distortion pre-warping compensation), the frequency response obtained using filtfilt is way outside the IEC acceptance limits because the zero-phase filter applies the filter twice, which drastically exaggerates the overall response.
@mlotinga
I know it's been a while but I'm looking into this at the moment as well and can't reproduce your figures. Could you share your code to produce the figures?
Great library!
In
signal.weighthere is the zero-phase option that usesscipy.signal.filtfilt.To inspect the frequency response of the zero-phase (forwards-backwards operation) filter Hzp, it is necessary to calculate the frequency response of the forwards filter H (using
scipy.signal.freqz), and then multiply it by the complex conjugate H*. Doing this shows that the forwards-backwards operation (ie applying the filter two times to the signal) distorts the overall frequency response Hzp, which in many cases will not give the desired response. In this case, zero-phase operation pushes the filter response outside the relevant IEC acceptance limits.To avoid this distortion it would be necessary to pre-warp the filter frequencies (in a similar way to compensating for bilinear transform distortion), although I'm unaware of any way to determine the appropriate pre-warping analytically for arbitrary filter responses.