仿射投影算法 (Affine projection algorithm) 是运算量介于 LMS 和 RLS 之间的一种自适应算法 。
其中,X(n)是输入向量矩阵,是w(n)的共轭转置
令滤波器的实际输出作为期望输出d(n),则先验误差向量表示为:
为了简化,我们令μ=1,把y(n)代入e(n)中,则:
我们发现滤波器系数的更新量,是由L个线性方程组成的线性方程组决定的
线性方程组相关知识补充:
对于线性方程组:
考虑(行/列)满秩的情况,分下面三种情况:
(一)如果m=n,则:具有唯一精确解
(二)如果m<n(行数小于列数)即方程的个数小于未知数的个数 此时方程组有无穷多个解 。 为了得到唯一解 必须增加约束条件 要求 x 的范数最小 这样得到的解称为最小范数解,即:具有最小范数解
(三)如果m>n(行数大于列数)即方程的个数大于未知数的个数 此时方程组不存在精确解 只存在近似解 。 我们自然希望找到一个使方程组两边的误差平方和为最小的解 即最小二乘解,即:具有最小二乘解
利用线性方程组的结论,重新观察公式:
分为两种情况讨论:
情况1:1≤L<N,方程组为欠定方程,具有唯一的最小范数解
此时,权重更新公式变为:
如果L=1,则退化为 NLMS 算法:
实际中,L 取 2 、 3 就足够了。
情况2:L≥N,方程组为超定方程,其唯一解为最小二乘解:
此时,权重更新公式变为:
- 优点:收敛速度和计算复杂度介于 LMS 和RLS 之间
% 参考:
% https://github.com/rohillarohan/System-Identification-for-Echo-Cancellation
% https://github.com/3arbouch/ActiveNoiseCancelling/blob/c29ccfcd869657a5f58e1ce7755fe08c3a195bd9/ANC/BookExamples/MATLAB/APLMS_AEC_mono.m
function [e,y,w] = myAP(d,x,mu,M,L,psi)
% input:
% d -- 麦克风信号
% x -- 远端语音
% mu -- 步长
% M -- 滤波器阶数 40
% L -- 列数 2
% psi -- 1e-4
%
% Outputs:
% e - 输出误差 the output error vector of size Ns
% y - 输出系数 output coefficients
% w - 滤波器参数 filter parameters
d_length = length(d);
if (d_length <= M)
print('error: 信号长度小于滤波器阶数!');
return;
end
if (d_length ~= length(x))
print('error: 输入信号和参考信号长度不同!');
return;
end
XAF = zeros(M,L);
w1 = zeros(M,1); % 滤波器权重 (40, 1)
y = zeros(d_length,1); % 估计的近端语音
e = zeros(d_length,1); % 误差
for m = M+L:d_length % 采样点数
for k = 1:L % 列数
XAF(:,k) = x(m-k+1:-1:m-k+1-M+1); % (40,2)
end
% y(m) = (XAF'*w)'*(XAF'*w); % 不太确定是不是这样(40,2)'*(40,1)=(2,1)
E = d(m:-1:m-L+1) -XAF'*w1; % (2,1)-(2,1)
w1 = w1 + mu*XAF*inv((XAF'*XAF + psi*eye(L)))*E;
w(:,m) = w1; % (40, 73113)
e(m) = E(1)'*E(1);
end
end
参考链接: