How to adjust cutoff frequency when using filtfilt? (zero-phase filters with multiple passes)

Jonas (view profile)

on 8 Nov 2018 at 16:00
Latest activity Edited by Jonas

Jonas (view profile)

on 11 Nov 2018 at 13:52
When using filtfilt function the cutoff frequency has to be adjusted due to dual passes (forward and reverse direction). This is not mentioned in filtfilt documentation and there is very little to find about it on the web. I just stumble upon it on this website that reference this paper that reference the book Biomechanics and Motor Control of Human Movement, By David A. Winter (page 69). Actually the website and paper got the implementation incorrect. It's not the frequency but the pameter Wc that's the correction factor should be applied on, as shown by Winter.
Now I have eventually figured out how to correct lowpass butterworth cutoff.
So my question, what about cutoff correction for highpass filter with multiple passes, like filtfilt?
For butterworth lowpass filter the adjustment can be done like this
filter_passes = 2; % 2 filter passes for filtfilt
C = (((2^(1/filter_passes))-1)^(1/4)); % lowpass butter correction factor
Wc = tan(pi*cutoff_frequency/sampling_frequency) / C; % David A. Winter
f_adjusted = atan(Wc)*sampling_frequency/pi; % convert back to Hz for butter input
[B, A] = butter(2, f_adjusted / (sampling_frequency / 2), 'low');
m_filtered = filtfilt(B, A, data);
Now for highpass filter I have tried to use the invers of C, and that seems to do the trick but I have no ide if that is theoretically correct.
Below you see the test result where filter() is used as reference, then filtfilt() done in two ways and last filtfilt with cutoff adjustment. In the plot you see periodogram of filtered random noise.
As you can see if not adjusted the lowpass 150Hz cutoff becomes 134Hz and highpass 150Hz cutoff becomes 168Hz.
See attached graphs and code to create the graphs.