- clc; clear all;
- %% lms
- N = 2048; % 信号的取样点数
- M = 10; % 抽头的个数
- iter = N; % 迭代次数
- t = 1 : N;
- s = 5 * sin(2 * pi * 0.01 * t); % 源信号
- x = s + 0.5 * randn(1, N); % 输入信号
- x = x';
- d = s'; % 期望信号
- e = zeros(iter, 1);
- w = zeros(M, iter);
- rho_max = max(eig(x * x')); % 输入信号相关矩阵的最大特征值
- mu = rand(1) * (2 / rho_max) ; % 收敛因子 0 < mu < 2/rho
- for n = M + 1 : iter -1
- w( :, n + 1) = w( :, n) + mu * x(n - 1 : -1 : n - M) * conj(e(n));
- y(n + 1) = w( :, n + 1)' * x(n : -1 : n - M + 1);
- e(n + 1) = d(n + 1, : ) - y(n + 1);
- end
- %% 画输入输出信号以及输出信号和预期输出信号的误差
- figure(1);
- subplot(2, 1, 1);
- plot(t, x);
- grid;
- title('输入信号');
- xlabel('样点数');
- ylabel('幅值');
- subplot(2,1,2);
- plot(t, y);
- grid;
- title('输出信号');
- xlabel('样点数');
- ylabel('幅值');
- % 绘制自适应滤波器输出信号,预期输出信号和两者的误差
- figure(2)
- subplot(3, 1, 1);
- plot(t, d);
- grid;
- title('预期输出');
- xlabel('样点数');
- ylabel('幅值');
- subplot(3, 1, 2);
- plot(t, y);
- grid;
- title('自适应滤波器输出');
- xlabel('样点数');
- ylabel('幅值');
- subplot(3, 1, 3);
- plot(t, e);
- grid;
- title('误差');
- xlabel('样点数');
- ylabel('幅值');
在来一个难一点的。引用《现代数字信号处理及其应用》—何子述、夏威 课后的一个仿真题。
- clc; clear all;
- %% 产生512点输入序列
- M = 2; % AR 阶数
- N = 512; % 样本数
- trials = 100; % 试验次数
- a1 = -0.975; % AR parameter
- a2 = 0.95;
- var = 0.0731; % 噪声方差
- v = 0 + sqrt(var).* randn(N, 1); % 产生v(n)
- u0 = [0, 0]; % u(0)初始化
- a = [1 a1 a2];
- b = 1;
- zi = filtic(b, a, u0); % 初始化滤波器 直接II型
- [u, zf] = filter(b, a, v, zi); % 产生观测信号u(n)
- %% 用LMS算法计算w1和w2
- mu1 = 0.05;
- mu2 = 0.005;
- w1 = zeros(M, N); % 初始化权向量
- w2 = zeros(M, N);
- w1_trials = zeros(M, N, trials);
- w2_trials = zeros(M, N, trials);
-
- e1 = zeros(N, 1); % 初始化误差
- e2 = zeros(N, 1);
- e1_trials = zeros(N, 1, trials);
- e2_trials = zeros(N, 1, trials);
- d1 = zeros(N, 1); % 初始化期望响应
- d2 = zeros(N, 1);
- wopt = zeros(2, trials);
- Jmin = zeros(1, trials);
- sum_eig = zeros(1, trials);
- for i = 1 : trials
- v = 0 + sqrt(var).* randn(N, 1);
- zi = filtic(b, a, u0);
- [u, zf] = filter(b, a, v, zi);
-
- uu = zeros(M, N - M + 1);
- for k = 1 : (N - M + 1)
- uu( :, k) = u(k + M - 1 : -1 : k).';
- end
- R = uu * uu' / (N - M + 1); % u(n)自相关矩阵
- p = sum(uu(:, 1 : N - M) * diag(u(3 : N)), 2) / (N - M);
- [v, d] = eig(R);
- wopt( :, i) = inv(R) * p;
- Jmin(i) = R(1, 1) - p' * wopt( :, i); % Jmin
- sum_eig(i) = d(1, 1) + d(2, 2); % 特征值之和
-
- for n = 3 : N -1
- w1( :, n + 1) = w1( :, n) + mu1 * u(n - 1 : -1 : n - 2, :) * conj(e1(n));
- d1(n + 1) = w1( :, n + 1)' * u(n : -1 : n - 1, : );
- e1(n + 1) = u(n + 1, : ) - d1(n + 1);
-
- w2( :, n + 1) = w2( :, n) + mu2 * u(n - 1 : -1 : n - 2, :) * conj(e2(n));
- d2(n + 1) = w2( :, n + 1)' * u(n : -1 : n - 1, : );
- e2(n + 1) = u(n + 1, : ) - d2(n + 1);
- end
- w1_trials ( :, :, i) = w1;
- e1_trials ( :, :, i) = e1 .* conj(e1);
-
- w2_trials ( :, :, i) = w2;
- e2_trials ( :, :, i) = e2 .* conj(e2);
- end
- w1_trials_ave = sum(w1_trials , 3) ./ trials;
- e1_trials_ave = sum(e1_trials , 3) ./ trials;
- w2_trials_ave = sum(w2_trials , 3) ./ trials;
- e2_trials_ave = sum(e2_trials , 3) ./ trials;
- sJmin = sum(Jmin) / trials; % 维纳误差 平均
- Jex1 = e1_trials_ave - sJmin; % 剩余均方误差
- Jex2 = e2_trials_ave - sJmin; % 剩余均方误差
- sum_eig_trials = sum(sum_eig) / trials; % 平均特征值之和
- Jexfin1 = mu1 * sJmin * (sum_eig_trials / (2 - mu1 * sum_eig_trials));
- Jexfin2 = mu2 * sJmin * (sum_eig_trials / (2 - mu2 * sum_eig_trials));
- M1 = Jexfin1 / sJmin; % 失调参数
- M2 = Jexfin2 / sJmin; % 失调参数
- disp(M1);
- disp(M2);
- %% 画滤波器的权向量和学习曲线
- figure(1); % 画权值迭代过程
- plot(w1(1, :), 'b'); % 单次估计 w1
- hold on
- plot(w1(2, :), 'r');
- hold on
- plot(w1_trials_ave(1, :), 'b'); % 估计平均 w1
- hold on
- plot(w1_trials_ave(2, :), 'r');
- xlabel('迭代次数n');
- ylabel('抽头权值');
- title('滤波器权系数的更新过程 \mu=0.05');
- figure(2); % 画权值迭代过程
- plot(w2(1, :), 'b'); % 单次估计 w2
- hold on
- plot(w2(2, :), 'r');
- hold on
- plot(w2_trials_ave(1, :), 'b'); % 估计平均 w2
- hold on
- plot(w2_trials_ave(2, :), 'r');
- xlabel('迭代次数n');
- ylabel('抽头权值');
- title('滤波器权系数的更新过程 \mu=0.005');
- figure(3); % 画学习曲线
- plot(Jex1, 'b'); % 画mu1时的学习曲线
- hold on
- plot(Jex2, 'r'); % 画mu2时的学习曲线
- hold on
- axis([0,550,0,1]);
- xlabel('迭代次数n');
- ylabel('MSE');
- title('LMS算法的学习曲线');
- legend('\mu1=0.05', '\mu2=0.005');
接下来在看看开发板附赠程序LMS的代码- #include"math.h"
- #define PI 3.1415926
- #define COEFFNUMBER 16
- #define INPUTNUMBER 1024
- int FIRLMS(int *nx,float *nh,int nError,int nCoeffNumber);
- float h[COEFFNUMBER],fU;
- int xx[INPUTNUMBER],rr[INPUTNUMBER],wc[INPUTNUMBER];
- main()
- {
- int i,nLastOutput;
-
- nLastOutput=0;
- fU=0.0005;
- for ( i=0;i<COEFFNUMBER;i++ ) h[i]=0;
- for ( i=0;i<INPUTNUMBER;i++ )
- {
- xx[i]=256*sin(i*2*PI/34);
- rr[i]=wc[i]=0;
- }
- for ( i=COEFFNUMBER+1;i<INPUTNUMBER;i++ )
- {
- nLastOutput=FIRLMS(xx+i,h,nLastOutput-xx[i-1],COEFFNUMBER); // break point
- rr[i]=nLastOutput;
- wc[i]=rr[i]-xx[i];
- }
- exit(0);
- }
- int FIRLMS(int *nx,float *nh,int nError,int nCoeffNumber)
- {
- int i,r;
- float fWork;
-
- r=0;
- for ( i=0;i<nCoeffNumber;i++ )
- {
- fWork=nx[i]*nError*fU;
- nh[i]+=fWork;
- r+=(nx[i-i]*nh[i]);
- }
- r/=128;
- return r;
- }
DSPLIB库中提供了LMS函数。
- // LMS FIR (delayed version)
- ushort dlms (DATA *x, DATA *h, DATA *r, DATA *des,DATA *dbuffer, DATA step, ushort nh, ushort nx)
- // Adaptive delayed LMS filter (fast implemented)
- ushort oflag = dlmsfast (DATA *x, DATA *h, DATA *r, DATA*des, DATA *dbuffer, DATA step, ushort nh, ushort nx)