【发布时间】:2015-09-02 06:43:33
【问题描述】:
标准化最小均方算法用于数字滤波,它基本上试图模仿“未知”滤波器,因此它们的差异(被认为是误差)趋于零。收敛的“因素”是误差一开始会很高,随着算法的不断运行,误差会越来越小。
NLMS 和 LMS(它的后继者)的唯一区别是 NLMS 对过滤器的入口进行了归一化处理,因此对高输入功率并不容易。
wiki 页面中的两种算法都有公式:https://en.wikipedia.org/wiki/Least_mean_squares_filter,这与我的实现类似。
我目前正在使用自适应设备,因此我可以将白噪声输入过滤到低通滤波器中,并尝试调整我的算法系数以模仿低通,它在 matlab 中实现:
clear all;close all;clc;
fid = fopen('ruidoBranco.pcm', 'rb');
s = fread(fid, 'int16');
fclose(fid);
itera = length(s);
L = 50;
passo = 0.00000000001;
H = passaBaixa(L,1000,2);
W = zeros(L,1);
y = zeros(itera,1);
sav_erro = zeros(itera,1);
for i=(L+1):itera,
D=0;
Y=0;
for j=1:(L),
Y = Y + W(j,1)*s(i-j,1);
D = D + H(j,1)*s(i-j,1);
end
erro = D-Y;
k=passo*erro;
for j=1:(L),
W(j,1) = W(j,1)+(k*s(i-j,1)/(s(i-j,1)^2+0.000001));
end
sav_erro(i,1) = (erro);
end
subplot(2,1,1);
plot(sav_erro);
subplot(2,1,2);
plot(W);
hold on;
plot(H,'r');
fid = fopen('saidaFIR.pcm', 'wb');
fwrite(fid,sav_erro,'int16');
fclose(fid);
“passaBaixa”函数就是我之前说的低通滤波器:
function H = passaBaixa(M,FC,op)
iteracoes = M;
FS=8000;
FC=FC/FS;
M=iteracoes;
H = zeros(iteracoes,1);
for i=1:iteracoes,
if(i-M/2==0)
H(i,1)=2*pi*FC;
else
H(i,1)=sin(2*pi*FC*(i-M/2))/(i-M/2);
end
if(op==1)
H(i,1)=H(i,1);
else if (op==2)
H(i,1) = H(i,1)*(0.42-0.5*cos(2*pi*i/M)+0.08*cos(4*pi*i/M));
else
H(i,1)=H(i,1)*(0.54-0.46*cos(2*pi*i/M));
end
end
end
soma = sum(H);
for i=1:iteracoes,
H(i,1)=H(i,1)/soma;
end
end
文件 ruidoBranco.pcm 只是一个由 80.000 个样本生成的白噪声。
得到的结果如下:
其中上图是误差,下图是低通滤波器(红色)和“自适应”算法滤波器(蓝色)的脉冲响应。
它没有收敛,它应该看起来像这样:
如您所见,上图收敛到几乎为 0 的误差,而下图不再有蓝色,因为它在红色之后(因为它几乎完美地调整了过滤器的系数)
我想知道我的实现是否存在任何明显的错误,也许这可能是未来有类似错误的人的参考。
【问题讨论】:
标签: algorithm matlab signal-processing