常用的数字滤波器包括IIR与FIR,常用的表示方法有以下几种形式:差分方程、单位序列响应 h ( n ) h(n) h(n) ,系统函数 H ( z ) H(z) H(z)以及系统框图,本篇博文着重以系统框图的形式来讲述IIR与FIR。基础的系统框图如图1所示:
由于本文中会涉及滤波器零极点的知识,所以先列举一下零极点对一个滤波器的影响:
零点控制幅频响应的峰谷,零点越接近于单位圆,峰谷值越小,当零点在单位圆上时,n对应点幅频特性值为零。
极点控制幅频特性的峰值,极点越接近于单位元,峰值越大,极点在单位圆上时,系统不稳定。
在原点处的零极点不改变系统的幅频特性。
IIR(Infinite-duration Impulse Responses)即无限长冲激响应响应滤波器,其特点是:
IIR的基本结构分为直接Ⅰ型、直接Ⅱ型、级联型与并联型结构。
直接Ⅱ型只需要N个延时单元即可,比直接Ⅰ型少M个,计算起来更简单一些,对于直接Ⅰ型和直接Ⅱ型的结构,优点是简单直观,缺点就是系数对滤波器的控制关系不明显(零极点不明显,难以调整)
级联型结构有这几个特点:调整零极点结构方便;运算误差比直接型小,但是误差会逐级积累。
并联型结构的特点是:子系统的误差不相互影响;并联可单独调整极点,单不能调整零点。
FIR(Finite-duration Impulse Responses)滤波器即有限长单位冲激响应滤波器,其特点是:
FIR的基本结构包括直接型、
该结构的优点是便于控制零点,缺点是所需系数较多,所需的乘法较多。
关于线性相位FIR结构,后续会有专门的一篇博文来介绍。
function x = impseq(n0, n1, n2)
% impseq:产生一个冲激函数
% 参数:在n0-n2之间,n1处为1,其余为0
% 返回: x是冲激序列
n = n0:n2;
x = [(n-n1) == 0];
end
然后我们就可以实现直接型滤波器了,直接型滤波器是后面几种类型的基础,级联型和并联型都可以由直接型转化而来,我们要实现的滤波器的系统传递函数如下所示,求出该滤波器的单位冲激响应和单位阶跃响应:
% 直接型IIR滤波器实现
% 系统传递函数的分子系数
b = [1, 1];
% 系统传递函数的分母系数
a = [1, -0.6];
% 单位冲激响应h(n)
N = 30;
delta = impseq(0, 0, N);
h = filter(b, a, delta);
% 输入为单位阶跃响应
X = [ones(1,5), zeros(1, N-5)];
% 对应得输出
y = filter(b, a, X);
% 绘图
subplot(211); stem(h); title('单位冲激响应h(n)');
subplot(212); stem(y); title('单位阶跃响应y(n)');
function y = casfilter(b0, B, A, X)
% casfilter: 级联型IIR滤波器的实现
% 参数:
% b0: 增益系数
% B: 系统传递函数的分子系数矩阵
% A: 系统传递函数的分母系数矩阵
% X: 输入序列
% y: 经过滤波器的输出序列
% 得到系数矩阵的维度,K行,L列
[K, L] = size(B);
% 得到输入序列的长度
N = length(X);
% 建立K+1行,N列的零矩阵
% 该矩阵第一行存放输入序列,第二行存放经过第一个级联节点的输出序列,第i行存放
% 经过第i-1个级联节点的输出序列,第K+1行存放最终的输出序列
w = zeros(K+1, N);
% 令第一个行等于输入序列
w(1,:) = X;
% 计算每一个级联节点的输出序列并作为下一级的输入序列
for i = 1:1:K
w(i+1,:) = filter(B(i,:), A(i,:),w(i,:));
end
% 最终的滤波结果为最后的输出序列乘上增益系数
y = b0*w(K+1, :);
end
下面我们对目标滤波器进行实现:
% 级联型IIR滤波器
% 初始化参数
b0 = 3; % 增益系数
N =30; % 输入序列长度
B = [1, 1, 0;
1, -3.1415926, 1]; % 系统传递函数的分子系数矩阵
A = [1, -0.6, 0;
1, 0.7, 0.72]; % 系统传递函数的分母系数矩阵
% 获得单位冲激序列
delta = impseq(0, 0, N);
% 获得单位阶跃序列
X = [ones(1, 5), zeros(1, N-5)];
% 该滤波器的单位冲激响应
h = casfilter(b0, B, A, delta);
% 该滤波器的单位阶跃响应
y = casfilter(b0, B, A, X);
% 绘制曲线
subplot(211); stem(h); title('单位冲激响应h(n)');
subplot(212); stem(y); title('单位阶跃响应y(n)');
function y = parfilter( C, B, A, X )
% casfilter: 并联型IIR滤波器的实现
% 参数:
% C: B的长度等于A的长度时,多项式的部分, 大部分时候为0
% B: 系统传递函数的分子系数矩阵
% A: 系统传递函数的分母系数矩阵
% X: 输入序列
% y: 经过滤波器的输出序列
% 得到系数矩阵的维度,K行,L列
[K, L] = size(B);
% 得到输入序列的长度
N = length(X);
% 建立K+1行,N列的零矩阵
w = zeros(K+1, N);
w(1,:) = filter(C, 1, X);
% 单独计算每一个并联联节点的输出序列
for i = 1:1:K
w(i+1,:) = filter(B(i,:),A(i,:),X);
end
% 将所有并联节点的输出相加即最后的输出结果
y = sum(w);
end
下面我们来实现下面这个滤波器的单位冲激响应和单位阶跃响应:
代码如下:
% 并联型IIR滤波器
% 初始化参数
C = 0;
N =30; % 输入序列长度
B = [-13.65, -14.81;
32.60, -16.37]; % 系统传递函数的分子系数矩阵
A = [1, -2.95, 3.14;
1, -1, 0.5]; % 系统传递函数的分母系数矩阵
% 获得单位冲激序列
delta = impseq(0, 0, N);
% 获得单位阶跃序列
X = [ones(1, 5), zeros(1, N-5)];
% 该滤波器的单位冲激响应
h = parfilter(C, B, A, delta);
% 该滤波器的单位阶跃响应
y = parfilter(C, B, A, X);
% 绘制曲线
subplot(211); stem(h); title('单位冲激响应h(n)');
subplot(212); stem(y); title('单位阶跃响应y(n)');
% 直接型FIR滤波器实现
% 系统传递函数的分子系数
b = [1, 1.5, 5, 2];
% 系统传递函数的分母系数,IIR的分母变为1就是FIR
a = 1;
% 单位冲激响应h(n)
N = 30;
delta = impseq(0, 0, N);
h = filter(b, a, delta);
% 输入为单位阶跃响应
X = [ones(1,5), zeros(1, N-5)];
% 对应得输出
y = filter(b, a, X);
% 绘图
subplot(211); stem(h); title('单位冲激响应h(n)');
subplot(212); stem(y); title('单位阶跃响应y(n)');
% 级联型FIR滤波器
% 初始化参数
b0 = 1; % 增益系数
N =30; % 输入序列长度
B = [1, 0.5, 0;
1, 2, 4]; % 系统传递函数的分子系数矩阵
A = [1, 0, 0;
1, 0, 0]; % 系统传递函数的分母系数矩阵
% 获得单位冲激序列
delta = impseq(0, 0, N);
% 获得单位阶跃序列
X = [ones(1, 5), zeros(1, N-5)];
% 该滤波器的单位冲激响应
h = casfilter(b0, B, A, delta);
% 该滤波器的单位阶跃响应
y = casfilter(b0, B, A, X);
% 绘制曲线
subplot(211); stem(h); title('单位冲激响应h(n)');
subplot(212); stem(y); title('单位阶跃响应y(n)');