%--------------------------------------------------------------------------
%   [yn,ref_dn,W,en] = lms2(xn,dn,M,mu)
%--------------------------------------------------------------------------
%   功能：
%   LMS自适应滤波器 带通道时延
%--------------------------------------------------------------------------
%   输入:
%           xn  输入信号的序列 列向量
%           dn  所期望的响应序列 列向量
%           M   滤波器阶数
%           mu  收敛因子(步长)
%   输出:
%           W   滤波器的权值矩阵     大小为M * iter
%           en  误差序列（itr * 1） 列向量
%           yn  实际输出序列        列向量
%--------------------------------------------------------------------------
%   例子：
%   暂无
%--------------------------------------------------------------------------
function [yn,ref_dn,W,en] = lms2(xn,dn,M,mu)
if rem(M,2)==0
    disp('请将滤波器阶数为奇数')
    return
end

w_ref = [zeros((M-1)/2,1);1;zeros((M-1)/2,1)];                              %正常延迟信号 延迟(M-1)/2个点
xn = xn(:);
dn =conv(w_ref,dn(:));                                                      %正常信号延迟
ref_dn = dn;
itr = length(xn);
en = zeros(itr,1);                                                          %误差序列，en(k)表示第k次迭代时预期输出与实际输出的误差
W = zeros(M,itr);                                                           %滤波器的权值矩阵（矩阵）
%--------------------------------------------------------------------------
%   迭代计算
%--------------------------------------------------------------------------
for idx = M:itr                                                             %第k次迭代
    x = xn(idx:-1:idx-M+1);                                                 %滤波器M个抽头的输入
    y = W(:,idx-1).'*x;                                                     %滤波器的输出
    en(idx) = dn(idx) - y;                                                  %第k次迭代的误差
    %----------------------------------------------------------------------
    %   滤波器权值计算的迭代式
    %----------------------------------------------------------------------
    W(:,idx) = W(:,idx-1) + 2*mu*en(idx)*x;
end

%--------------------------------------------------------------------------
%   求最优时滤波器的输出序列，r如果没有yn的返回参数可以不要下面的
%--------------------------------------------------------------------------
yn = conv(W(:,end),xn);