A low-pass FIR filter lets low frequencies pass and blocks high frequencies. It helps clean signals by removing noise or unwanted fast changes.
Low-pass FIR filter design in Signal Processing
from scipy.signal import firwin # firwin(numtaps, cutoff, window='hamming', pass_zero=True) # numtaps: number of filter taps (length) # cutoff: cutoff frequency (0 to 1, where 1 is Nyquist frequency) # window: type of window to shape filter # pass_zero=True means low-pass filter
The cutoff frequency is given as a fraction of the Nyquist frequency (half the sampling rate).
The number of taps controls filter sharpness and length; more taps mean better filtering but more delay.
from scipy.signal import firwin # Create a low-pass FIR filter with 31 taps and cutoff at 0.3 (30% of Nyquist) filter_coefs = firwin(31, 0.3)
filter_coefs = firwin(51, 0.2, window='blackman')
filter_coefs = firwin(21, 0.4, pass_zero=True)
This program creates a low-pass FIR filter with a cutoff at 100 Hz for a 1000 Hz sampling rate. It filters a signal made of a slow 5 Hz wave and a fast 300 Hz wave. The plots show the original signal, the filtered signal (where the 300 Hz part is removed), and the filter's frequency response.
import numpy as np import matplotlib.pyplot as plt from scipy.signal import firwin, lfilter, freqz # Sampling frequency fs = 1000 # 1000 Hz # Design low-pass FIR filter numtaps = 51 cutoff = 100 # 100 Hz cutoff frequency # Normalize cutoff frequency to Nyquist frequency (fs/2) normalized_cutoff = cutoff / (fs / 2) # Get filter coefficients fir_coeff = firwin(numtaps, normalized_cutoff) # Create a sample signal: 5 Hz + 300 Hz sine waves t = np.linspace(0, 1.0, fs, endpoint=False) signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 300 * t) # Apply the filter to the signal filtered_signal = lfilter(fir_coeff, 1.0, signal) # Frequency response of the filter w, h = freqz(fir_coeff, worN=8000) # Plot results plt.figure(figsize=(12, 8)) plt.subplot(3, 1, 1) plt.plot(t, signal) plt.title('Original Signal (5 Hz + 300 Hz)') plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.subplot(3, 1, 2) plt.plot(t, filtered_signal) plt.title('Filtered Signal (Low-pass FIR)') plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.subplot(3, 1, 3) plt.plot(w * fs / (2 * np.pi), 20 * np.log10(abs(h))) plt.title('Frequency Response of the Filter') plt.xlabel('Frequency [Hz]') plt.ylabel('Gain [dB]') plt.ylim(-100, 10) plt.grid(True) plt.tight_layout() plt.show()
More taps mean better filtering but slower processing and more delay.
Choosing the right window affects the filter's sharpness and ripple.
Always normalize cutoff frequency by Nyquist frequency (half the sampling rate).
Low-pass FIR filters keep slow changes and remove fast changes in signals.
Use firwin to design filters by specifying taps and cutoff frequency.
Test filters by applying them to signals and checking frequency response.
Practice
Solution
Step 1: Understand filter types
Low-pass filters are designed to pass signals with frequencies below a cutoff frequency and attenuate frequencies above it.Step 2: Identify the filter purpose
Since the filter blocks high frequencies and allows low frequencies, it matches the description in To allow low frequencies and block high frequencies.Final Answer:
To allow low frequencies and block high frequencies -> Option CQuick Check:
Low-pass filter = allows low frequencies [OK]
- Confusing low-pass with high-pass filters
- Thinking it amplifies all frequencies
- Mixing filter purpose with signal conversion
scipy.signal.firwin with cutoff frequency 0.3 and filter length 51?Solution
Step 1: Recall firwin parameters
Thefirwinfunction usesnumtapsfor length andcutofffrequency. Thepass_zeroparameter set toTruedesigns a low-pass filter.Step 2: Match correct syntax
firwin(51, 0.3, pass_zero=True) usesfirwin(51, 0.3, pass_zero=True), which is the correct way to specify a low-pass FIR filter with length 51 and cutoff 0.3.Final Answer:
firwin(51, 0.3, pass_zero=True) -> Option AQuick Check:
pass_zero=True means low-pass [OK]
- Using pass_zero='bandpass' instead of True
- Setting pass_zero=False which makes high-pass
- Incorrect parameter names like cutoff= instead of positional
coeffs?
from scipy.signal import firwin coeffs = firwin(numtaps=31, cutoff=0.25, pass_zero=True)
Solution
Step 1: Understand numtaps parameter
Thenumtapsparameter infirwinspecifies the number of filter coefficients (taps) to generate.Step 2: Check given numtaps value
Here,numtaps=31means the filter will have 31 coefficients.Final Answer:
31 -> Option BQuick Check:
numtaps = length of coeffs = 31 [OK]
- Confusing cutoff frequency with length
- Off-by-one errors in counting taps
- Assuming length is cutoff * numtaps
from scipy.signal import firwin coeffs = firwin(50, cutoff=0.4, pass_zero=False) print(len(coeffs))
Solution
Step 1: Check pass_zero parameter meaning
Settingpass_zero=Falseinfirwindesigns a high-pass filter, not a low-pass filter.Step 2: Identify mismatch with question intent
The code intends to design a low-pass filter but usespass_zero=False, which is incorrect for low-pass.Final Answer:
pass_zero=False creates a high-pass filter, not low-pass -> Option AQuick Check:
pass_zero=False means high-pass, not low-pass [OK]
- Assuming pass_zero=False is low-pass
- Thinking cutoff frequency range is invalid
- Believing window parameter is mandatory
firwin call correctly sets the cutoff parameter?Solution
Step 1: Understand cutoff frequency scaling
When specifyingfs(sample rate), the cutoff frequency must be given in Hz, not normalized frequency.Step 2: Calculate normalized cutoff frequency
Normalized cutoff = cutoff frequency / (fs / 2) = 1000 / (8000 / 2) = 1000 / 4000 = 0.25. But sincefs=8000is given, cutoff should be in Hz, so cutoff=1000 is valid.Step 3: Check options
firwin(51, cutoff=1000, fs=8000, pass_zero=True) uses cutoff=1000 with fs=8000, which is correct. firwin(51, cutoff=0.125, fs=8000, pass_zero=True) uses cutoff=0.125 with fs=8000, which is incorrect because cutoff should be in Hz if fs is specified. firwin(51, cutoff=0.125, pass_zero=True) uses cutoff=0.125 without fs, which means normalized frequency. firwin(51, cutoff=1000, pass_zero=True) uses cutoff=1000 without fs, which is invalid.Step 4: Correct interpretation
Actually, whenfsis specified, cutoff is in Hz. So cutoff=1000 with fs=8000 is correct (firwin(51, cutoff=1000, fs=8000, pass_zero=True)). firwin(51, cutoff=0.125, fs=8000, pass_zero=True) cutoff=0.125 Hz is too low. So firwin(51, cutoff=1000, fs=8000, pass_zero=True) is correct.Final Answer:
firwin(51, cutoff=1000, fs=8000, pass_zero=True) -> Option DQuick Check:
With fs, cutoff is in Hz [OK]
- Using normalized cutoff with fs parameter
- Omitting fs when cutoff is in Hz
- Confusing normalized and absolute frequency units
Ready to prove it?
Pass the test and this pattern moves unknown
