是否有广泛可用的自适应、递归、数值稳定的 IIR 滤波器实现?

信息处理 无限脉冲响应 自适应滤波器
2022-02-08 08:29:55

我需要确定可以用经典状态空间公式描述的线性、因果、时不变物理系统的系数。

为了这个例子,假设系统有两个状态,只有一个被观察到,一个输入。假设这个状态空间由以下矩阵描述:

  a = 
               x1          x2
   x1   -1.25e-05    1.25e-05
   x2   1.389e-05  -2.083e-05

  b = 
              u1
   x1          0
   x2  6.944e-06

  c = 
       x1  x2
   y1   1   0

  d = 
       u1
   y1   0

离散、等效、零阶保持传递函数由下式给出:

  3.481e-05 z + 3.446e-05
  -----------------------
   z^2 - 1.97 z + 0.9704

在滤波器术语中,这显然是一个 IIR 滤波器,因为分母中的高阶系数。

我正在寻找一种合适的自适应滤波器算法,它将:

  • 数值稳定
  • 允许在线更新,即递归

从我目前的研究来看,如果您将记录的信号值视为此滤波器的输入,则可以将此滤波器视为 FIR 滤波器。这称为方程误差法。然后可以应用例如 QR-RLS 自适应 FIR 滤波器来查找系数。

但是在我对真实系统的试验中,我经常发现物理上不可能的滤波器系数,我只是不知道我手工制作的自适应滤波器是否正确。我想尝试使用这种自适应滤波器的“官方”实现。

因此,我的问题是是否存在(对于 MATLAB 或在 C 中)具有与 QR-RLS FIR 自适应滤波器相同优点的自适应 IIR 滤波器的免费实现。

2个回答

虽然我可能不是最终权威,但我已经对此进行了调查。简而言之,没有。

根据我自己的研究,问题在于稳定性。当滤波器扩展为具有更宽的带宽时,这当然意味着 y[n] 值和滞后“移动迅速”,然后被淬火到较低带宽,其中 y[n] 值和滞后“移动缓慢” ',y[n] 缓冲区可能会加载快速振荡的条目,这些条目显示为低带宽滤波器的初始条件。过滤器很容易变得不稳定。如果以绝热方式改变带宽,则可以避免这种不稳定性(我猜想),但是您的适应性会受到额外的限制。

现在,你不必相信我的话。在“自适应滤波器:理论和应用”(第 2 页)第 5 页(亚马逊)中,Boroujeny 写道,“然而,正如我们将在后面的章节中看到的那样,由于 IIR 滤波器的适应涉及许多困难,它们在该领域的应用自适应滤波器的数量相当有限。” 作者指出,适应过程可以将(数字)极点放在单位圆之外,即使它们是在单位圆内开始的。他的书的其余部分主要致力于 FIR 滤波器。

我希望这个信息帮助。

方程误差方法应该有效(假设您的模型与未知系统的阶数相同)。虽然它不如 QRD-RLS 算法高效,但您始终可以使用卡尔曼滤波器来执行递归最小二乘法。

这里有一个开源卡尔曼滤波工具箱以下是如何解决您提供的示例系统的参数估计问题的示例。

基本思想是将未知系统的输出建模为延迟输出和输入的加权组合(也称为 ARMA 模型)。权重是未知的,因此它们成为卡尔曼滤波器试图估计的状态,而输入和输出形成时变观察矩阵。

clear all
close all

addpath ekfukf

% unknown system
z = tf('z');
unknown_tf = (3.481e-5*z + 3.446e-5)/(z^2 - 1.97*z + 0.9704);
unknown_ss = ss(unknown_tf);
A = unknown_ss.a;
B = unknown_ss.b;
C = unknown_ss.c;
D = unknown_ss.d;
x = zeros(2, 1);

M = 1000; % simulation length
u = randn(M, 1); % vector of observed inputs
y = zeros(M, 1); % initialize output vector
e = zeros(M, 1); % output prediction error

% kalman filter parameters
dim = 4; % number of unknown parameters (2 numerator coeffs, 2 denominator)
F = eye(dim); % state transition matrix
R = 1e-6; % measurement noise variance  
Q = 0*eye(dim); % process noise covariance
P = 10*eye(dim); % state-error covariance
alpha = zeros(2, 1); % initial estimate of denominator coefficiens 
beta = zeros(2, 1); % initial estimate of numerator coefficients
state = [alpha; beta]; 
Hu = zeros(2, 1); % observation vector containing observed inputs
Hy = zeros(2, 1); % observation vector containing observed outputs

for k=2:M
    % compute kalman filter time-update
    [state, P] = kf_predict(state, P, F, Q);

    % update observation vectors
    Hy = circshift(Hy, 1);
    Hy(1) = y(k-1);
    Hu = circshift(Hu, 1);
    Hu(1) = u(k);

    % observe system output
    x = A*x + B*u(k);
    y(k) = C*x + D*u(k);

    % compute kalman filter measurement update
    [state, P, K, yfilt, S, likelihood] = kf_update(state, P, y(k), [Hy; Hu]', R); 
    e(k) = y(k) - yfilt;
end

% exctract numerator and denominator coefficients
alpha = state(1:2);
beta = state(3:4);

% construct numerator and denominator polynomial estimates
est_num = [0, beta'];
est_den = [1, -alpha'];

% plot estimated and true frequency response
W = pi*logspace(-3, 0, 300);
Ghat = freqz(est_num, est_den, W);
G = freqz(unknown_tf.num{1}, unknown_tf.den{1}, W);
semilogx(W./pi, 20*log10(abs(G)), 'k', 'linewidth', 2)
hold on
semilogx(W./pi, 20*log10(abs(Ghat)), 'g')
title('estimated (green) and true (black) magnitude response')
ylabel('magnitude (dB)');
xlabel('normalized frequency');

% plot prediction error 
figure
plot(e)
title('prediction error vs. time');
ylabel('error');
xlabel('sample index');

有用! 在此处输入图像描述

预测误差(试图预测未知系统的输出)让我们了解模型收敛的速度。收敛速度高度依赖于测量噪声方差。 在此处输入图像描述