参照我之前的一篇博客改的
https://blog.csdn.net/m1f2c3/article/details/89709050
效果
主程序代码
clc;
clear;
close all;
%% Download data
% load('D:\windows7\data\biancheng\matlab\adaptive\adaptive_for_Coriolis\data\mine\TiChuGrossError.mat');
% TiChuGrossError = a;
% load('D:\windows7\data\biancheng\matlab\adaptive\adaptive_for_Coriolis\data\mine\TiChuNoise.mat');
% TiChuNoise = a;
% x1和x分别为训练集的输入和标准输出
% x1 = TiChuGrossError;
% x = TiChuNoise;
%%
fs = 44100;
% x = wavread('b.wav');
t = -5*pi:pi/100:5*pi;
x = sin(t);
x = x(:);
sx = size(x,1);
subplot(2,2,1);
plot(x);axis([0 sx -1 1]);
% 原信号FFT
xf = fft(x,1024);
subplot(2,2,3);
plot(abs(xf));
% 添加高斯噪声
t = 0 : 1/fs : (sx-1)/fs;
noise = 0.2*randn(size(x)); % 均值为0,方差为0.5的标准正态噪声
x1 = x + noise;
subplot(2,2,2);
plot(x1);axis([0 sx -1 1]);
% 信号加噪声后的FFT
xf = fft(x1,1024);
subplot(2,2,4);
plot(abs(xf));
%再造一个带有噪声的输入信号 lunge
noise = 0.2*randn(size(x)); % 均值为0,方差为0.5的标准正态噪声
x2 = x + noise;
figure,
plot(x2)
%% LMS自适应滤波
param.M = 50;
param.w = ones(param.M, 1) * 0.1;
param.u = 0.00001;
param.max_iter = 1000;
param.min_err = 0.25;
[W, err] = LMS_TRAIN(x1, x, param);
% x2为测试集
x2 = x1;
W = ones(param.M, 1) * 0.1; %%%%%%%%%%%%%%%%%前面的训练都没有用,这里直接将权重赋值成0.1
yn = LMS_TEST(x2, W, param.M);
figure,
plot(yn)
figure
plot(err);
title('err');
LMS_TRAIN
function [W, err] = LMS_TRAIN(xn, dn, param)
% xn 输入信号,带有误差的原始信号
% dn 期望输出
% param Structure for using LMS, must include at least
% .w - 初始化权值
% .u - 学习率
% .M - 滤波器阶数
% .max_iter - 最大迭代次数
% .min_err - 迭代最小误差
%
% W 输出权重
% error 误差输出
W = param.w; % 初始权值
M = param.M; % 滤波器阶数
if length(W) ~= M
error('param.w的长度必须与滤波器阶数相同.\n');
end
% if param.max_iter > length(xn) || param.max_iter < M
% error('迭代次数太大或太小,M<=max_iter<=length(xn)\n');
% end
iter = 1;
for i = 1:param.max_iter
for k = M:length(xn)
x = xn(k:-1:k-M+1); % 滤波器M个抽头的输入
y = (W')*x;
err(iter) = dn(k) - y;
% 更新滤波器权值系数
W = W + 2*param.u*(err(iter))*x;
iter = iter + 1;
% if (abs(err(iter - 1)) < param.min_err); break; end
end
if (abs(err(iter - 1)) < param.min_err); break; end
end
end
LMS_TEST
function [yn] = LMS_TEST(xn1, W, M)
% xn1 输入信号,带有误差的原始信号
% W 滤波器使用的权重系数
% M - 滤波器阶数
%
% yn 滤波之后的输出
% 求最优时滤波器的输出序列
yn = inf * ones(size(xn1));
for k = M:length(xn1)
x = xn1(k:-1:k-M+1);
yn(k) = (W')* x;
end
end
原理
相同角速度,不同初始相位的正弦信号相加之后的结果是相同角速度的正弦信号。附加在正弦信号上的随机噪声(此随机噪声的均值为零)在这种相加过程中会相互抵消。最终达到提高信噪比的目的。
依照上面的原理,我将程序中滤波器的阶数设定成四分之一周期,效果还算不错。
依照上面的原理,如果将滤波器的阶数设定为二分之一周期,效果应该很差,但实际效果依旧很好,不知道是为什么