假设信号,采样于. 我尝试使用巴特沃斯带通滤波器对其进行过滤() 顺序. 但是,结果我得到了一个包含大多数元素的向量NaN(其中一些非常小,大约。 `)。
如果我尝试相同的订单过滤器,我得到了预期的结果。订购的可能原因是什么过滤到“爆炸”?
这是 MATLAB 代码,以防万一我犯了一个我看不到的错误:
[b, a] = butter(4, [60 / fs, 140/fs]);
x_filtered = filter(b, a, x);
假设信号,采样于. 我尝试使用巴特沃斯带通滤波器对其进行过滤() 顺序. 但是,结果我得到了一个包含大多数元素的向量NaN(其中一些非常小,大约。 `)。
如果我尝试相同的订单过滤器,我得到了预期的结果。订购的可能原因是什么过滤到“爆炸”?
这是 MATLAB 代码,以防万一我犯了一个我看不到的错误:
[b, a] = butter(4, [60 / fs, 140/fs]);
x_filtered = filter(b, a, x);
基本上,您永远不想使用传递函数表示(使用b和a),而是使用零极点增益(z, p, k)。这将允许您避免数字错误。在您的情况下,您可以按以下方式设计过滤器:
fs = 44100; % Sampling frequency
Wp = [30, 70]/(fs/2); % Pass band frequencies (as normalized frequency)
Ws = [20, 90]/(fs/2); % Stop band frequencies
Rp = 3; % Ripple at pass band
Rs = 50; % Ripple at stop band
[n, Wn] = buttord(Wp, Ws, Rp, Rs); % Get order and omega vector
[z, p, k] = butter(n, Wn, 'bandpass'); % Design filter accordingly
[sos, g] = zp2sos(z, p, k); % Convert to state matrix
Hd = dfilt.df2sos(sos, g); % Create the filter object
对于一些虚拟随机信号:
x = rand(1,100000);
y = filter(Hd, x);
将产生稳定的输出:

这是滤波器的频率响应(一切看起来都符合要求):

阶数越高,需要安装在一个小的半圆形环周围的极点越多,并且正好位于单位圆的边缘。滤波器的频率与采样率的比值越小,这个圆环相对于单位圆就越小。尝试将足够多的极点填充到足够小的区域中,正常的数字噪声可能会将一个极点移动到一个不好的位置(一个将任何东西放大到无穷大,或除以零的位置)。
一种可能提高稳定性的技术是在巴特沃斯低通滤波器之前以非常大的比率对信号进行下采样。这将扩大半圆形环,从而使两极远离单位圆并远离单位圆。
其他答案解释了如何避免这种情况,但为了澄清实际原因,它是由于超过用于存储样本值的数据类型的精度限制(我认为这是 MATLAB 中的双精度浮点)导致下溢。它只发生在滤波器的阶数越高的原因是阶数越高,系数可能变得越小。非常小的系数乘以非常小的信号值会导致浮点反规范化,这反过来又会导致浮点 NaN(不是数字)。
行话破坏链接: