0

Consider a bandpass filter with Low Cut 17Hz, High Cut 22 Hz, Fs = 45000 Hz and Order = 6. When I pass a mixture of multiple sinusoidal waves through this filter (with a sine wave of frequency 20 Hz), I noticed that Scipy's Butter Bandpass filter, upon filtering, returned values that were unexpectedly high. I did not get a sinusoidal output, but rather, ended up getting an almost straight line that was scaled up by a factor of 1e305. Since I haven't done a course on DSP, and hail from a CS Background, any help would be greatly appreciated.

Here is my code:

from scipy.signal import butter, filtfilt

def butter_bandpass(lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band')
    return b, a

def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    y = filtfilt(b, a, data)
    return y
Deepak
  • 1
  • 1
  • Designing that filter properly is extremely hard, if at all possible, especially with order 6. You should resample your signal to maybe 60 hz or so, and then design a filter for that. And use a higher order filter if you can afford it. – MBaz Jun 06 '19 at 18:42
  • Thank @MBaz for the quick response. Can you explain why a high sampling rate affects the filter? While the order more or less refers to how much feedback we include, it is still not very clear to me as to how sampling rate affects filtering. Any pointers to useful resources will also be greatly appreciated, since my knowledge is extremely minimal on Signals and DSP. – Deepak Jun 06 '19 at 18:55
  • 1
    The problem is that your bandpass is very narrow compared to Nyquist. See https://dsp.stackexchange.com/q/31066/11256 for a lot of discussion and pointers. – MBaz Jun 06 '19 at 22:05
  • Try using sos = butter(order, [low, high], btype='band', output='sos') and sosfiltfilt instead – endolith Jun 07 '19 at 01:34

1 Answers1

1

Limited numerical precision makes your filter unstable.

In this case you can fix it by implementing the filter in second order sections using the zeros and the poles of the filter.

Hilmar
  • 44,604
  • 1
  • 32
  • 63