LMS算法
直接求解维纳—霍夫方程是不现实的,因为不仅无法事先得知输入信号的统计特性,也无法利用FPGA硬件平台快速实现诸如矩阵求逆等复杂的运算。一种可行的途径是寻找到一种迭代算法,通过不断迭代运算算法,通过不断迭代运算,使滤波器系数最终收敛到最佳值,尽量接近维纳—霍夫方程的最优解。这节就介绍一下如何使用MATLAB实现LMS算法。
1.LMS算法的原理
LMS 算法是由 Widrow和 Hoff于1960年提出的48%,该算法基于最小均方误差准则,在梯度法的基础上[46],通过改进均方误差梯度的估计值计算方法,取单个误差样本平方的梯度作为均方误差梯度的估计值。LMS 算法可以用下面一组递推公式来表示,即
y
(
n
)
=
W
H
(
n
)
X
(
n
)
e
(
n
)
=
d
(
n
)
−
y
(
n
)
W
(
n
+
1
)
=
W
(
n
)
+
2
μ
X
(
n
)
e
∗
(
n
)
(1)
y(n)=W^{H}(n)X(n) \\ e(n)=d(n)-y(n)\tag{1} \\ W(n+1)=W(n)+2\mu X(n)e*(n)
y(n)=WH(n)X(n)e(n)=d(n)−y(n)W(n+1)=W(n)+2μX(n)e∗(n)(1)
式中,W(n)为滤波器系数向量,也可以看作输入信号的加权矢量;X(n)是由输入信号组成的一组输入向量;y(n)是输出信号;d(n)是期望信号;e(n)是误差信号;
μ
\mu
μ为权矢量更新时的步长因子,
μ
\mu
μ越大,则算法收敛越快,但同时收敛后的误差信号也越大,
μ
\mu
μ越小,则算法收敛速度越慢,但同时收敛后的误差信号也相应减小,稳态性能更好,因此可以通过调整步长因子
μ
\mu
μ的值来调整LMS 算法的性能。由于算法收敛速度与稳态性能之间存在矛盾,可以采用变步长LMS算法来解决这一矛盾,即在算法初始阶段采用较大的
μ
\mu
μ值加快收敛,当算法收敛后再采用较小的p值来提高收敛后的稳态性能。
将(1)式前两个带入三个式子可得:
W
(
n
+
1
)
=
W
(
n
)
+
2
μ
X
(
n
)
[
d
(
n
)
−
W
H
X
(
n
)
]
∗
W(n+1)=W(n)+2\mu X(n)[d(n)-W^{H}X(n)]^{*}
W(n+1)=W(n)+2μX(n)[d(n)−WHX(n)]∗
2.蒙特-卡罗仿真方法
Monte Carlo仿真方法是通过大量的计算机模拟来检验系统的动态特性并归纳出统计结果的一种随机分析方法,它包括伪随机数的产生、Monte Carlo仿真设计,以及结果解释等内容,其作用在于用数学方法模拟真实物理环境,并验证系统的可靠性与可行性。MonteCarlo仿真方法又称为统计实验方法,它是一种采用统计抽样理论近似求解数学、物理及工学问题的方法。它解决问题的基本思想是,首先建立与描述该问题相似的概率模型,然后对模型进行随机模拟或统计抽样,在利用所得到的结果求出特征的统计估计值作为原问题的近似解,并对解的精度做出某些估计。Monte Carlo仿真方法的主要理论依据是大数定理,其主要手段为随机变量的抽样分析。
前面章节对诸如FIR滤波器、多速率处理滤波器等设计的仿真其实都是一次性仿真,也就是说数据源及仿真过程都是一次性的,没有进行统计平均等计算、处理、分析。在本节将要实现的LMS算法仿真中,为了对算法的收敛性能进行更为准确的测试,需要多次运行仿真过程,通过对统计特性相同的多组数据进行仿真,并分析处理仿真结果来达到了解算法的收敛性能。
3.采用MATLAB仿真LMS算法
采用Monte Carlo方法进行LMS算法仿真。要求输入信号采用正弦信号及高斯白噪声合成信号模型,分别对信噪比为-3 dB及3 dB,期望信号分别为正弦信号及噪声信号的情况进行仿真,算法步长因子设置为1/256,FIR滤波器长度为128。其中输入信号具体表达式为
x
(
n
)
=
2
s
(
n
)
+
1
0
−
S
N
R
/
10
j
(
n
)
(2)
x(n)=\sqrt{2}s(n)+\sqrt{10^{-SNR/10}}j(n)\tag{2}
x(n)=2s(n)+10−SNR/10j(n)(2)
式中,x(n)为输入信号序列,s(n)为正弦信号,j(n)为均值为0、功率为1的高斯白噪声信号,SNR为信噪比(单位为dB)。
输入信号是正弦信号与高斯白噪声信号的叠加信号,为了得到更具一般性的仿真结论,我们采用Monte Carlo仿真方法来进行仿真,也就是说依次进行多次仿真,然后对算法收敛性能进行统计平均,这样绘出的误差信号曲线显得更为平滑、更具普遍性。MATLAB代码如下
%My_E7_1_LMSSim.m
%参数定义
g = 100; %Monte Carlo仿真统计次数
N = 1024; %输入信号的序列长度
k = 128; %滤波器长度
u = 1/256; %算法步长因子
snr = [3 -3]; %信噪比
pp = zeros(g,N-k); %将每次循环仿真的误差信号结果存于矩阵PP中,以便求取统计平均
%产生信号
t = 1:N;
s = sin(0.5*pi*t); %正弦信号
xn = zeros(1,N); %输入信号
y = zeros(1,N); %期望信号
e = zeros(1,N-k); %误差信号
wn = zeros(k,1);%滤波器系数向量 或输入信号的加权向量
for type=1:4 %期望信号分四种情况分析
for q = 1:g %仿真g次 每次噪声不一样
noise = rand(1,length(s)); %噪声 信号
if type == 1 %第一种情况
SNR = snr(1); %信噪比为3
d = s; %期望信号为正弦信号
elseif type == 2 %第二种情况
SNR = snr(1); %信噪比为3
d = sqrt(10^(-SNR/10))*noise; %期望信号为噪声
elseif type == 3 %第三种情况
SNR = snr(2); %信噪比为-3
d = s; %期望信号为正弦波
else
SNR = snr(2); %信噪比为-3
d = sqrt(10^(-SNR/10))*noise; %期望信号为噪声
end
xn = s + sqrt(10^(-SNR/10))*noise; %真实的输入信号 噪声+正弦波
y(1:k) = xn(1:k); %仿真是从K+1开始计算y的值的,所以前k个和输入相同
% LMS算法 每次新q循环中,由于xn输入信号发生变化由于每次计算使用的
% 输入信号xn都是新生成的,因此滤波器系数也会根据新的输入信号进行调整。
% 因此,不需要对滤波器系数wn进行重新初始化。
for n=k+1:N
Xn = xn((n-k+1):n); %最后一个是xn(i) 对应输出y(i)
y(n) = wn'*Xn'; %得到输出
e(n-k) = d(n) - y(n); %得到此时的误差信号
wn = wn + u*e(n-k)'*Xn';
end
pp(q,:) = e.^2; %求每次仿真后误差信号的平方值
end
%画出原始正弦信号以及加了不同噪声后的正弦信号波形
figure(1);
subplot(311);
plot(s(300:450)); %截取信号的一段进行绘图
title("信号S时域波形");
if type == 1
subplot(312);
plot(xn(300:450));
title("信号S加噪声后的时域波形(SNR=3dB)");
elseif type == 3
subplot(313);
plot(xn(300:450));
title("信号s加噪声后的时域波形(SNR=-3dB)");
end
%求取各次循环仿真的误差统计均值,完成Monte Carlo仿真
bi = zeros(1,N-k);
for b=1:N-k
bi(b)=sum(pp(:,b))/g;
end
%绘制自适应滤波后的输出信号
figure(2)
if type == 1
subplot(411)
plot(y(300:450));
title("自适应滤波后的输出时域信号(SNR=3dB),期望信号为正弦波");
elseif type == 2
subplot(412)
y = xn - y; %由于期望信号为噪声信号,系统相当于干扰抵消系统
plot(y(300:450));
title("自适应滤波后的输出时域信号(SNR=3dB),期望信号为噪声");
elseif type == 3
subplot(413)
plot(y(300:450));
title("自适应滤波后的输出时域信号(SNR=-3dB),期望信号为正弦波");
elseif type == 4
subplot(414)
y = xn - y; %由于期望信号为噪声信号,系统相当于干扰抵消系统
plot(y(300:450));
title("自适应滤波后的输出时域信号(SNR=-3dB),期望信号为噪声");
end
%绘制误差信号图
figure(3)
if type == 1
subplot(411)
plot(bi(1:100));
title("均方误差(SNR=3dB),期望信号为正弦波");
elseif type == 2
subplot(412)
plot(bi(1:100));
title("均方误差(SNR=3dB),期望信号为噪声");
elseif type == 3
subplot(413)
plot(bi(1:100));
title("均方误差(SNR=-3dB),期望信号为正弦波");
elseif type == 4
subplot(414)
plot(bi(1:100));
title("均方误差(SNR=-3dB),期望信号为噪声");
end
end
3.1实验结果及分析
程序运行结果如图2、图3和图4所示,从仿真结果可以看出,LMS 算法的收敛性能较好,期望信号选择噪声信号或正弦信号均可以得到比较好的结果,输入信号均可以收敛到期望信号。需要注意的是,LMS 算法的收敛速度及性能与步长因子u及滤波器阶数有很大的关系。