我正在尝试使用 Scilab 的eqfir函数设计一个半带插值滤波器,该函数在内部使用 Remez 算法:
hn = eqfir(N, [0 .23; .27 .5], [1 0], [1 1]);
尽管过渡带在 0.25 左右对称,但它并没有给我一个真正的半带响应,奇数系数为零。也许我应该直接使用remezb或remez函数,但我不完全理解它们输入参数的含义。
根据互联网上的一些来源(我无法证明),被混淆地称为remez的等效 MATLAB 函数给出了完美的结果。
我正在尝试使用 Scilab 的eqfir函数设计一个半带插值滤波器,该函数在内部使用 Remez 算法:
hn = eqfir(N, [0 .23; .27 .5], [1 0], [1 1]);
尽管过渡带在 0.25 左右对称,但它并没有给我一个真正的半带响应,奇数系数为零。也许我应该直接使用remezb或remez函数,但我不完全理解它们输入参数的含义。
根据互联网上的一些来源(我无法证明),被混淆地称为remez的等效 MATLAB 函数给出了完美的结果。
在商业滤波器设计软件中,当设计奇抽头半带滤波器时,您的中心系数(最大值系数)的值为 0.5。因此,如果您的滤波器系数之一的值为 0.000002,则与最大系数相比,该系数的值是 250,000 的一部分。该超小值系数对滤波器的频率响应的影响可以忽略不计,因此可以将其值设置为零。
在 MATLAB 中,尝试以下操作之一:
hn = remez(26, 2*[0 .23 .27 .5], [1 1 0 0], [1 1])
hn = firpm(26, 2*[0 .23 .27 .5], [1 1 0 0], [1 1])
(注意 '2*' 乘数需要符合 MATLAB 的命令语法!)检查系数的值,发现没有一个是完全零值的。现在绘制滤波器的频率响应(以 dB 为单位的垂直轴)。接下来,使用以下方法将绝对值小于 0.001 的所有系数清零:
hn = hn.*(abs(hn)>0.001)
并绘制新的频率响应(以 dB 为单位)。注意两个频率响应本质上是相同的。
正如理查德莱昂斯的回答中正确指出的那样,大多数实现都会出现一些小的数值错误。
减少这些数值误差(并完全避免奇数系数的误差)的方法是使用本文中记录的技巧来有效地计算半带滤波器的系数。总结这篇论文,一个半带滤波器系数可以从一个全频带滤波器设计产生系数使用关系:
按照参考论文,半带滤波器必须具有奇数个系数(然后必须是形式, 对于某个正整数)。此外,过滤器系数可以简化为一个滤波器,只有通过消除第一个和最后一个索引处产生的零系数来获得系数。因此,我们只需要专注于过滤器的设计系数(即滤波器的顺序),这可以通过以下 Matlab 脚本来实现:
if (0 == rem(N,2))
disp("Number of coefficients needs to be odd (even order)");
else
M = floor((N+1)/4);
K = 2*M;
% design full-band filter
g = firpm(K-1, 4*[0 .23], [1 1], [1]);
% convert to half-band filter
offset = 0;
if (1 == rem(N,4))
disp("Warning: tail coefficients will be zero (effective order reduced by 2)");
offset = 1;
end
hn = zeros(1,N);
hn((1+offset):2:(K-1+offset)) = 0.5*g(1:M);
hn(K+offset) = 0.5;
hn((K+1+offset):2:N) = 0.5*g(M+1:K);
end
最后对于 Scilab,您应该能够通过将firpm调用替换为
g = eqfir(K, 2*[0 .23], [1], [1]);