级联双二阶部分以实现高阶滤波器的工作原理?


20

我正在尝试实现8阶IIR滤波器,并且我阅读的每个应用笔记和教科书都说,最好将2阶以上的任何滤波器实现为二阶部分。我tf2sos在MATLAB中使用了二阶部分的系数,这与我预期的4个二阶部分的6x4系数有关。在实施为SOS之前,八阶滤波器需要存储7个先前的采样值(以及输出值)。现在,当实现为二阶部分时,流程如何从输入到输出工作,我是否仅需要存储2个先前的样本值?还是第一个滤波器的输出馈x_in入第二个滤波器,依此类推?


您需要为每个阶段存储以前的状态,具体取决于该阶段中过滤器的顺序,因此不会像您提到的那样仅是2

Answers:


13

这是您说的最后一句话(“或者第一个过滤器的输出作为x_in馈入第二个过滤器,依此类推?”)。这个想法很简单:您将双二阶视为级联的单独的二阶滤波器。第一个滤波器的输出是第二个滤波器的输入,依此类推,因此延迟线分布在各个滤波器之间。如果需要在内存受限的环境中优化结构,则可以注意到相邻的二元模型具有冗余延迟存储器(即,阶段1的最后几个输出样本与阶段2的最后几个输入样本相同,因此您不必不必像单独隔离过滤器那样单独存储它们)。


谢谢!我只是设法在MATLAB中快速做到这一点。早期混乱的原因是,我忘乘以增益(啊!),因此思想种种开始爬行。
anasimtiaz

如果您不费吹灰之力从tf2sos请求增益作为输出arg(就像在我发布的示例代码中一样),那么您就不必费心将其再次乘回。
Learnvst 2012年

9

实际上,有两种方法可以实现二阶部分:并行和串行。在串行版本中,N部分的输出是N + 1部分的输入。在并行版本中,所有部分都具有相同的输入(并且只有一个实零而不是共轭复数对零),并且将每个部分的输出简单地求和。这两种方法是通过Z域传递函数的部分分数展开而建立的。警告:这是一个数值棘手的问题,对于极点靠近单位圆的典型音频滤波器,标准的Matlab实现“残差”可能会产生很大的数值误差。


6

这里有一些演示代码,以说明为什么更好地级联二阶部分。

clc

sr = 44100;
order = 13;

[b,a] = butter(order,1000/(sr/2),'low');
[sos] = tf2sos(b,a);

x = [1; zeros(299,1)]; %impulse


% all in one
Y = filter(b,a,x);

% cascaded biquads
Z = x;
for nn = 1:size(sos,1);
    Z = filter(sos(nn,1:3),sos(nn,4:6), Z );
end


cla; plot(Y, 'k'); hold on; plot(Z,':r'); hold off

对于上面示例中给出的低通滤波器,大约12到13的数量级,对于不使用级联双二阶的实现,数值误差会逐渐增加,从而给出明显不同的脉冲响应。取决于过滤器,您的行驶里程会有所不同。

订单= 10

在此处输入图片说明

订单= 13

在此处输入图片说明


@learvst如果我错了,请指正我,但是您的代码错过了收获。不应该这样:[sos gain] = tf2sos(b,a); // Rest of code for nn = 1:size(sos,1); Z = filter(sos(nn,1:3),sos(nn,4:6), Z ); end Z = filter(gain,1,Z);
user915783
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.