IIR 滤波器的极数、阶和二阶部分之间的关​​系

信息处理 过滤器设计 无限脉冲响应 带通
2022-02-20 00:27:11

我已将Iowa Hills Code Kit移植到 mcu 以计算 IIR 滤波器系数。它们用于使用直接形式 II 转置结构初始化 CMSIS 双二阶级联 IIR 滤波器

尝试将我的 mcu 程序的输出与使用 SciPy 编写的类似 python 脚本进行比较,我意识到两者之间存在差异,如下所述。

科学派

在 SciPy 中使用以下公式计算 4 阶带通 IIR 滤波器,

sos = scipy.signal.iirfilter(4,
                            [1500, 2500],
                            btype='bandpass', 
                            analog=False, 
                            ftype='bessel',
                            output='sos',
                            fs=50000)

产生 8 个零点和 8 个极点,然后将其转换为 4 个二阶部分。这给

订单 = \frac{NumPoles_{BandPass}{2}

然而,我的理解是,上面的代码正在生成一个 8 阶滤波器,并且 4 阶滤波器应该表示为 2 个二阶部分,并且应该有 4 个极点和零点。我可能遗漏了一些非常明显的东西,但我不确定为什么 signal.iirfilter 会产生这个结果!

爱荷华山

但是,要使用 IowaHills 计算 4 阶带通 IIR 拟合器,我必须输入 numPoles=2 以获得 2 个二阶部分,如下所示,

TIIRCoeff coeffs = {0};              // filter coefficients struct (IowaHills)
TIIRFilterParams fparams;            // filter parameters struct (IowaHills)
fparams.IIRPassType = iirBPF;        // bandpass filter
fparams.ProtoType = BESSEL;          // proto bessel
fparams.BW = 0.10;                   // filter width
fparams.dBGain = 1.0;                // gain
fparams.Gamma = 0.0;                 // transition bandwith
// NumPoles = [order / 2] for BandPass and BandStop
// NumPoles = [order]     for LowPass and HighPass
fparams.NumPoles = 2;                // 4th order
fparams.OmegaC = 0.41;               // centre frequency for bandpass
fparams.Ripple = 0.0;                // only for chebyshev/elliptical
fparams.StopBanddB = 0.0;            // only for chebyshev/elliptical
coeffs = CalcIIRFilterCoeff(fparams);

这给了

Order = NumPoles_{BandPass} \times 2

谁能解释为什么两个程序中的极数和滤波器阶数之间的关系不同?我假设它们都是正确的,那么解释输出的正确方法是什么?

1个回答

滤波器阶数等于极数,这是事实。人们如何在软件中调用和使用参数是一个完全不同的问题。许多设计标准 IIR 滤波器的例程使用频率变换从原型低通滤波器设计带通或带阻滤波器。通常,指定的滤波器阶数是原型低通滤波器的阶数,但转换会将该阶数加倍,从而生成的带通或带阻滤波器的阶数是例程调用中指定的阶数的两倍。它在 Matlab/Octave 中以这种方式工作。也许这也是您使用 SciPy 例程和使用 Iowa Hills 软件获得两倍指定过滤器顺序的原因。请注意,在这两种情况下,您都会获得两倍的指定滤波器阶数(或极点数)。