咨询scipy.signal.firwin截止频率的定义与验证方法
Understanding & Verifying
scipy.signal.firwin Cutoff Frequency Rules Hey there, let’s break down exactly how scipy.signal.firwin handles cutoff frequencies, and walk through how you can prove these rules with code and plots.
Core Cutoff Frequency Rules for scipy.signal.firwin
- Definition: The
cutoffparameter you pass corresponds to the -6dB (half-amplitude) point of the filter’s magnitude response. This stems from the window method design:firwintargets an ideal rectangular filter, and for high-order filters, the cutoff aligns almost perfectly with the half-amplitude mark. - Position: The specified cutoff is the boundary between the passband and transition band. For a lowpass filter, frequencies below this point stay in the passband (with minimal attenuation set by your chosen window), while frequencies above enter the transition band where attenuation ramps up toward the stopband.
How to Verify These Rules
The best way to confirm this is to design a high-order filter (to make the transition band as narrow as possible) and analyze its magnitude response. Here’s a step-by-step guide:
Step 1: Design the Filter & Calculate Frequency Response
import numpy as np import scipy.signal as signal import matplotlib.pyplot as plt # Set up our parameters sampling_freq = 1000 # Hz nyquist_freq = sampling_freq / 2 specified_cutoff = 200 # Our target cutoff in Hz filter_order = 10000 # High order = extremely narrow transition band # Normalize cutoff to Nyquist frequency (required for firwin) norm_cutoff = specified_cutoff / nyquist_freq # Design the filter with a rectangular window (sharpest transition) filter_coeffs = signal.firwin(filter_order, norm_cutoff, window="rectangular") # Compute the frequency response freq_response, magnitude_response = signal.freqz(filter_coeffs, worN=4096) # Convert frequency values from radians/sample to Hz freq_hz = freq_response * nyquist_freq / np.pi # Convert magnitude to decibels for easier interpretation magnitude_db = 20 * np.log10(np.abs(magnitude_response)) # Find the -3dB and -6dB frequency points idx_3db = np.where(magnitude_db <= -3)[0][0] freq_3db = freq_hz[idx_3db] idx_6db = np.where(magnitude_db <= -6)[0][0] freq_6db = freq_hz[idx_6db] # Print our results print(f"Specified Cutoff: {specified_cutoff} Hz") print(f"-3dB (Half-Power) Frequency: {freq_3db:.2f} Hz") print(f"-6dB (Half-Amplitude) Frequency: {freq_6db:.2f} Hz")
Step 2: Plot the Magnitude Response
Zoom in on the cutoff region to see the alignment clearly:
plt.figure(figsize=(12, 6)) plt.plot(freq_hz, magnitude_db, label="Filter Magnitude Response") # Mark our key reference points plt.axvline(specified_cutoff, color="red", linestyle="--", linewidth=2, label="Specified Cutoff") plt.axhline(-3, color="green", linestyle=":", label="-3dB (Half-Power)") plt.axhline(-6, color="blue", linestyle=":", label="-6dB (Half-Amplitude)") # Zoom in to focus on the cutoff transition plt.xlim([specified_cutoff - 50, specified_cutoff + 50]) plt.ylim([-10, 5]) plt.xlabel("Frequency (Hz)") plt.ylabel("Magnitude (dB)") plt.title("FIR Filter Magnitude Response (High-Order, Rectangular Window)") plt.legend() plt.grid(True) plt.show()
What You’ll Observe
- The
-6dB frequencywill be nearly identical to your specified cutoff (any tiny discrepancy is due to the finite filter order). - The
-3dB frequencywill sit slightly inside the passband (below the specified cutoff for a lowpass filter), confirming the cutoff parameter doesn’t map to the half-power point. - The plot will clearly show the specified cutoff is the exact spot where the filter leaves the flat passband and begins transitioning into the attenuation region.
内容的提问来源于stack exchange,提问作者S.A.
相关产品推荐
相关产品推荐

