IirFilter
Namespace: RTPROCESSINGLIB · Library: DSP Library
mne.filter.filter_data (method='iir') in MNE-Python.
#include <dsp/iirfilter.h>
class UTILSLIB::IirFilter
Butterworth IIR filter design and application using second-order sections.
All filter types (LP, HP, BP, BS) are supported via the classical analogue-prototype → bilinear-transform design route with pre-warped cutoff frequencies. The resulting biquad cascade is numerically stable for high filter orders.
const QVector<IirBiquad> sos = IirFilter::designButterworth(4, IirFilter::LowPass, 30.0, 0.0, kSFreq);
const RowVectorXd lowPassed = IirFilter::applyZeroPhase(signal, sos); // forward-backward, no phase shift
Static Methods
designButterworth(iOrder, type, dCutoffLow, dCutoffHigh, dSFreq)
Design a Butterworth filter as a cascade of second-order sections.
Parameters:
-
iOrder : int Filter order (≥ 1). For BP/BS the effective order is 2*iOrder.
-
type : FilterType Filter type: LowPass, HighPass, BandPass, or BandStop.
-
dCutoffLow : double Lower cutoff frequency in Hz. Used for LP, HP, BP, BS.
-
dCutoffHigh : double Upper cutoff frequency in Hz. Used for BP and BS only.
-
dSFreq : double Sampling frequency in Hz.
Returns:
- QVector< IirBiquad > — QVector of
IirBiquadsections (multiply their transfer functions to get H(z)).
applySos(vecData, sos)
Apply a biquad cascade to one data row (causal, single-pass).
Parameters:
-
vecData : const Eigen::RowVectorXd & Input row vector.
-
sos : const QVector< IirBiquad > & Second-order sections from
designButterworth().
Returns:
- Eigen::RowVectorXd — Filtered row vector (same length as vecData).
applyZeroPhase(vecData, sos)
Apply a biquad cascade with zero-phase (forward + backward pass) to one row.
The effective order is doubled and there is no phase distortion.
Parameters:
-
vecData : const Eigen::RowVectorXd & Input row vector.
-
sos : const QVector< IirBiquad > & Second-order sections from
designButterworth().
Returns:
- Eigen::RowVectorXd — Zero-phase filtered row vector (same length as vecData).
applyZeroPhaseMatrix(matData, sos)
Apply zero-phase filtering to every row of a matrix (each row = one channel).
Parameters:
-
matData : const Eigen::MatrixXd & Input matrix (n_channels x n_samples).
-
sos : const QVector< IirBiquad > & Second-order sections from
designButterworth().
Returns:
- Eigen::MatrixXd — Filtered matrix (n_channels x n_samples).
Example
- Full source:
src/examples/ex_dsp_spectral/main.cpp - Build target:
ex_dsp_spectral(runs under CTest)
Used in examples
ex_dsp_spectral
Spectral and filtering tools of the dsp library on signals with known content.
const QVector<IirBiquad> sos = IirFilter::designButterworth(4, IirFilter::LowPass, 30.0, 0.0, kSFreq);
const RowVectorXd lowPassed = IirFilter::applyZeroPhase(signal, sos); // forward-backward, no phase shift
// scipy.signal.butter(4, 30, 'low', fs=200, output='sos') and sosfreqz: |H| = 0.99996, 0.70711, 0.01878
ok &= expect(sos.size() == 2 && std::fabs(gainAt(sos, 10.0) - 0.9999564172449813) < 1e-9 && std::fabs(gainAt(sos, 30.0) - 0.7071067811865477) < 1e-9 && std::fabs(gainAt(sos, 60.0) - 0.018777212012474308) < 1e-9,
"Butterworth gain at 10/30/60 Hz = scipy");
RowVectorXd only20(n);
for (int t = 0; t < n; ++t) {
only20(t) = std::sin(2.0 * kPi * 20.0 * t / kSFreq);
}
// scipy.signal.sosfiltfilt deviates from the 20 Hz sine by 0.02593 in the interior (|H(20 Hz)|^2 < 1)
const double lowPassErr = (lowPassed - only20).segment(50, n - 100).cwiseAbs().maxCoeff();
ok &= expect(std::fabs(lowPassErr - 0.02592545936305224) < 1e-3,
QString("zero-phase low-pass: 55 Hz removed, 20 Hz in phase (deviation %1, scipy 0.02593)").arg(lowPassErr));
Authors of this file
- Christoph Dinh <christoph.dinh@mne-cpp.org>