浅谈自适应滤波器

article/2025/10/9 22:22:25

在通常的滤波场合中,从频域的角度进行滤波,其相关的理论已经相当的成熟,只要给出相应的设计指标就可以很方便的设计出满足要求的滤波器。然而在更一般的情况下,人们所需要的滤波器工作的环境是时变的,这就导致事先已经设计好的滤波器性能下降甚至不能被使用。例如,在水下声纳通信中,信息通过声波在水中进行传播到达接收端,其信道是时变的(这种情况比电磁波在空气中传播要严重的多),如果只是简单的用固定系数的滤波器对信道进行均衡,那么得到的结果往往难以令人满意。解决的办法之一就是利用自适应滤波器,让其时实的跟踪信道的特性然后不断的调整均衡器的参数使其保持在最优的状态。再比如,我们日常使用的扩音设备,如果不注意将麦克风和喇叭靠的太近则会产生令人厌烦的啸叫声,采用自适应滤波技术将能有效的避免这种情况。
自适应滤波器一般是调整固定阶数的横向滤波器(FIR滤波器,当然也有IIR滤波器的,但是这种滤波器自己本身滤波系数设计不当就会导致不稳定,再加上自适应算法的话就更加容易不稳定了,而要想使其变得稳定则需要更加复杂的算法,为了更一般的说明自适应滤波器,故以FIR滤波器为例更适合)的系数来实现自适应滤波,自适应滤波器有两个输入端,分别是横向滤波器输入端信号x(t)、期望信号d(t)。同时也有两个输出端,分别是横向滤波器输出端信号y(t)、误差信号e(t)。下面是它的结构示意图:
自适应滤波器结构图

其主要有四大类经典应用包括系统辨识、信道均衡、信号增强和预测等。
系统辨识
系统辨识
信道均衡
信道均衡
信号增强
信号增强[其中n1(k)和n2(k)是相关信号]
信号预测
信号预测

关于自适应滤波的算法主要有最小均方误差算法(LMS)和最小二乘算法(RLS),以及它们的各种变形和衍生的算法。下面来分别介绍这两种算法最简单的形式。


最小均方(LMS)误差算法:

最简单的LMS算法是通过每一次迭代输入的数据对当前的目标函数的梯度进行估计,从而得到相应输入信号的自相关矩阵R与互相关向量p。则得到的梯度估计值为:
gw(k) = -2p(k) + 2R(k)w(k) = 2x(k)(-d(k) + w(k)(k)) = -2e(k)x(k)
则滤波系数更新方程为: w(k+1) = w(k) + 2niu*e(k)x(k)
整理可得LMS算法:
初始化部分:
w(k) = [0 0 … 0]T
单次迭代部分:
e(k)= d(k) - w(k)(k)
w(k+1) = w(k) + 2niu*e(k)x(k)

其中niu参数表示单次调节的步长,是一个常数需要在实际的应用中进行确定。我们可以得到单次迭代所需要进行的乘法次数为O[N]量级,N表示FIR滤波器的系数矢量w(k)的维数,该算法已经具有一定的实际应用的价值,如果对滤波的精度要求不是很高,而且对每次迭代速度有很高的要求的话,此算法非常合适。


递归最小二乘(RLS)算法:

在上一节中我们知道,基于瞬时梯度估计的LMS算法实际上只使用了当前时刻的输入信号矢量x(k)和期望信号d(k),没有利用过去的信息这就导致梯度估计的误差很大算法收敛的数度慢,一个很直接的想法就是如果能把过去的信息利用起来,那么梯度估计的误差就会大大的减小,算法很快就会收敛。最小二乘(RL)算法正好就实现了这一过程,它旨在使期望信号与模型滤波器输出之差的平方和最小。具体的算法推导比较的复杂,这里不方便编辑公式同时也没有必要,在这里给出了其算法实现语言描述部分。
常规RLS算法

下面对其中的一些相关变量名做一下解释,SD(k)表示输入信号矢量的确定性自相关矩阵(RD(k))的逆,e(k)表示先验误差,epsilon(k)表示后验误差(就是图片中的希腊字母epsilon,由于不方便输入所以用它代替了 ,后面还有一个哦 ),lambda表示遗忘因子,意思就是随着时间的推移以前的“旧”的信号对滤波器系数调整的影响越小,主要由更新的数据决定,从这个角度说明了该算法对非平稳的信号也能进行自适应滤波。其它的变量同上。从上面的描述可以看出单次迭代运算量在O[N2]量级,比LMS的计算量要大。


Matlab仿真实验

接下来利用上面的算法进行的Matlab仿真实验,也就是信号增强仿真。首先给出我写的LMS算法m代码:

   %递归最小均方算法-----利用瞬时值估计梯度矢量
clc;
clear all;
close all;
%************************生成仿真信号**************************************
Fs = 10000;                                                     %设置采样频率
t = 0:1/Fs:7;  
t = t';
Size_t = size(t,1);
F1 = 2;
F2 = 10;
F3 = 20;
F4 = 500;
Signal = sin(2*pi*F1*t) + 0.5*sin(2*pi*F2*t) + 0.25*sin(2*pi*F3*t); %生成信号
noise_amp = 1;                                           %定义噪声的标准差
noise1 = noise_amp*randn(Size_t,1);                        %生成高斯白噪声
noise2 = noise_amp*randn(Size_t,1);
noise3 = 5*sin(2*pi*F4*t+pi/2);noise = noise2;
Signal_noise = Signal + 0.2*noise;                           %加入高斯白噪声
Signal_noise(2:end) = Signal_noise(2:end) + 0.15*noise(1:end-1);
Signal_noise(3:end) = Signal_noise(3:end) + 0.1*noise(1:end-2);subplot(2,1,1);
plot(t,Signal);
title('原始信号');
subplot(2,1,2);
plot(t,Signal_noise);
title('加入干扰噪声的信号');
%*************************************************************************
M = 3;         %定义FIR滤波器阶数
Signal_Len = Size_t - M -1;   %定义信号数据的个数
niu = 0.00041;      %算法调节步长控制因子
y_out = zeros(Signal_Len,1);
error_out = zeros(Signal_Len,1);
Exp_out = zeros(Signal_Len,1);
w_out = zeros(Signal_Len,M);
for i=1:Signal_Len%数据输入if i == 1           %如果是第一次进入w = zeros(M,1); %初始化滤波器抽头系数endd = Signal_noise(i+M-1);                 %输入新的期望信号x = noise((M + i -1):-1:i,1);           %输入新的信号矢量%算法正体y = x' * w;                              %计算滤波器输出error = d - y;                           %计算误差w_forward = w + niu * error * x;         %计算滤波器系数向量%变量更替w = w_forward;%滤波结果存储y_out(i) = y;error_out(i) = error;w_out(i,:) = w';
end
figure;
subplot(2,1,1);
plot(y_out);
title('滤波器输出');
subplot(2,1,2);
plot(error_out);
title('输出误差');figure;
plot(t(1:Signal_Len),w_out(:,1),'r',t(1:Signal_Len),w_out(:,fix(M/2)+1),'b',t(1:Signal_Len),w_out(:,M),'y');
title('自适应滤波器系数');

下面是实验结果:
原始信号与噪声污染的输入信号
滤波器输出与误差输出
自适应滤波器系数
可以看到被严重污染的信号经过LMS滤波器得到了不错的恢复。

接下来是给出的是RLS算法的m代码:

%递归最小二乘算法
clc;
clear all;
close all;
%************************生成仿真信号*************************************
Fs = 10000;                                                     %设置采样频率
t = 0:1/Fs:3.5;  
t = t';
Size_t = size(t,1);
F1 = 2;
F2 = 10;
F3 = 20;
F4 = 1000;
Signal = sin(2*pi*F1*t) + 0.5*sin(2*pi*F2*t) + 0.25*sin(2*pi*F3*t); %生成信号
noise_amp = 1;                                           %定义噪声的标准差
noise1 = noise_amp*randn(Size_t,1);                      %生成高斯白噪声
noise2 = noise_amp*randn(Size_t,1);
noise3 = 5*sin(2*pi*F4*t+pi/2);noise = noise2;
Signal_noise = Signal + 0.2*noise;                           %加入高斯白噪声
Signal_noise(2:end) = Signal_noise(2:end) + 0.15*noise(1:end-1);
Signal_noise(3:end) = Signal_noise(3:end) + 0.1*noise(1:end-2);subplot(2,1,1);
plot(t,Signal);
title('原始信号');
subplot(2,1,2);
plot(t,Signal_noise);
title('加入干扰噪声的信号');
%*************************************************************************
M = 3;                       %定义FIR滤波器阶数
lamda = 1;                %定义遗忘因子
Signal_Len = Size_t - M -1;   %定义信号数据的个数
I = eye(M);                   %生成对应的单位矩阵
c = 1;                   %小正数 保证矩阵P非奇异
y_out = zeros(Signal_Len,1);
Eta_out = zeros(Signal_Len,1);
w_out = zeros(Signal_Len,M);
for i=1:Signal_Len%输入数据if i == 1                 %如果是第一次进入P_last = I/c;w_last = zeros(M,1);  endd = Signal_noise(i+M-1);            %输入新的期望信号x = noise((M + i -1):-1:i,1);      %输入新的信号矢量%算法正体K = (P_last * x)/(lamda + x'* P_last * x);   %计算增益矢量y = x'* w_last;                          %计算FIR滤波器输出Eta = d - y;                             %计算估计的误差w = w_last + K * Eta;                    %计算滤波器系数矢量P = (I - K * x')* P_last/lamda;          %计算误差相关矩阵%变量更替P_last = P;w_last = w;%滤波结果存储y_out(i) = y;Eta_out(i) = Eta;w_out(i,:) = w';
end
figure;
subplot(2,1,1);
plot(y_out);
title('滤波器输出');
subplot(2,1,2);
plot(Eta_out);
title('输出误差');figure;
plot(t(1:Signal_Len),w_out(:,1),'r',t(1:Signal_Len),w_out(:,fix(M/2)+1),'b',t(1:Signal_Len),w_out(:,M),'y');
title('自适应滤波器系数');

下面是实验结果:
滤波器输出与误差输出
自适应滤波器系数

由于输入的信号与LMS一样故只给出了滤波器输出、输出误差及自适应滤波器系数的结果图,通过对比我们就可以发现RLS算法收敛的速度要比LMS的快多了,而且滤波的质量也比LMS要好。但是计算的时间要比LMS的长。


大概就说这些,还有好多想说的,但这里编辑起来太不方便了,如果有兴趣可以私聊我,我们一起讨论和学习 。我现在只是给出了我研究的一小部分,只是简单的给大家科普了一下。还有关于快速的RLS的算法以及它的稳定算法都没有在上面写出来,除了这些还在TI的TMS320C6678 DSP上用C写了相关的代码,进一步的对代码效率进行了优化。在它上面也进行了仿真并且发现了一些和在Matlab上仿真的不一样的部分。而这个相比于Matlab仿真更加的接近工程实际,更有实用价值。


http://chatgpt.dhexx.cn/article/oLjlCulD.shtml

相关文章

自适应滤波原理

在网上,看到一篇不错的自适应滤波原理讲解的文章,原文网址为:自适应滤波原理简介 全文包括: 1. 自适应滤波器简介 2. 自适应干扰抵消原理 3. 自适应滤波原理 4. 最小均方(LMS)算法 5. Matlab实现 一、自适…

自适应滤波算法综述

我要讲的几种方法 绪论自适应滤波的基本原理自适应滤波算法自适应滤波算法种类最小均方误差算法(LMS)递推最小二乘算法(RLS)变换域自适应滤波算法仿射投影算法其他 自适应滤波算法性能评价 自适应滤波的Matlab仿真正弦信号加噪的L…

Java反射机制你还不会?那你怎么看Spring源码

文章目录 1.Java代码在计算机中经历的阶段:三个阶段2.Java识别类和对象信息的两种方式3.什么是反射4.获取Class对象的方式5.Class对象的功能6.通过反射操作类中的成员变量、构造函数、方法7.案例8.反射的优缺点 1.Java代码在计算机中经历的阶段:三个阶段…

Java 反射 理解

Java 反射 定义 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。 简…

Java反射机制的原理和用途

看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用? 开篇前,我们还是要了…

Java反射详解及作用

参考视频链接: 哔哩哔哩视频. 1. 反射概述 能够分析类能力的程序叫做反射(reflective),对于任何一个Class类,反射可以在运行时直接得到这个类的全部成分,包括构造器,成员方法,成员变量。获得的构造器对象为Construct…

JAVA反射机制分析-------spring的通过反射创建bean实例对象以及属性注入的原理解析

JAVA反射机制 java反射机制是在运行状态中,对于任意一个类, 能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为JAVA语言的反射机制。 巧妙的利用ja…

【Spring】spring的反射机制详解

一、什么是反射: (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 &…

Spring————java的反射机制,Spring的IOC和DI

一、认识Spring 1.1、Spring家族 SpringFramework: Spring框架:是Spring中最早核心的技术,也是所有其他技术及的基础。 SpringBoot:Spring是用来简化开发。而SpringBoot是来帮助Spring在简化的基础上能更快速进行开发。 SpringCloud&#xf…

分布式定时任务调度实战

目录 1、为什么需要定时任务 2、定时任务调度框架 2.1 单机 2.2 分布 3、xxl-job和elastic-job对比 3.1 支持集群部署方式 3.2 多节点部署任务执行方式 3.3 日志可追溯 3.4 监控告警 3.5 弹性扩容缩容 3.6 支持并行调度 3.7 高可用策略 3.8 失败处理策略 3.9 动态…

浅谈传统定时任务和分布式定时任务

为什么用定时任务? 定时任务平台可以在后台自动检测数据并进行操作。主要应用在订单状态改变、后台统计、定时发送邮件或短信等。 定时任务怎么部署实现? 传统的定时任务可以通过可定时线程池、timertask、quartz、spring-schedule方式来进行处理。他…

分布式定时任务技术选型

1、目前的定时任务方案 Java中开发大多数使用Spring-Scheduler,只需要在Spring中的bean的对应方法加上sheduler注解即可完成我们的定时任务,但是光是用这个注解还远远不能保证定时任务执行多次,我们需要一些其他手段的保证,一般来…

java 分布式 定时任务_Java中实现分布式定时任务的方法

定时器Scheduler在平时使用比较频繁,在springboot中,配置好Scheduled和EnableScheduling之后,定时器就能正常执行,实现定时任务的功能。 但是在这样的情况下:如果开发的服务需要水平部署实现负载均衡,那么定…

【手把手】分布式定时任务调度解析之Quartz

1、任务调度背景 在业务系统中有很多这样的场景: 1、账单日或者还款日上午 10 点,给每个信用卡客户发送账单通知,还款通知。如何判断客户的账单日、还款日,完成通知的发送? 2、银行业务系统,夜间要完成跑批…

轻量级分布式定时任务框架XXL-Job

轻量级分布式定时任务框架XXL-Job: XXL-JOB是一款轻量级的分布式定时任务框架,上手简单,操作容易,XXL-Job可以到官网下载也可以去gitee上拉取源码,其中核心模块分页两个:1:是分布式调度服务, 2&…

Springboot结合Redis实现分布式定时任务

一、背景 之前分享过分布式定时任务的技术选型方案:分布式定时任务技术选型方案,个人青睐xxl_job,分享了搭建接入流程:xxl_job搭建方案,本次项目需求较为简单,同时时间紧张。下面介绍利用Redis锁实现分布式…

分布式定时任务框架说明

分布式定时任务框架说明 分布式定时任务框架说明Quartz概念架构组件springboot集成方式使用内存使用数据库 TBSchedule:elastic-job概念架构组件执行流程特性 satumxxl-job概念特性架构组件使用 分布式定时任务框架说明 Quartz 概念 Quartz:Java事实上…

分布式定时任务对比

1. 什么是分布式定时任务 把分散的,可靠性差的计划任务纳入统一的平台,并实现集群管理调度和分布式部署的一种定时任务的管理方式。叫做分布式定时任务。 2. 常见开源方案 elastic-job , xxl-job ,quartz , saturn, opencron , antares el…

简单粗暴的分布式定时任务解决方案

分布式定时任务 1.为什么需要定时任务?2.数据库实现分布式定时任务3.基于redis实现 1.为什么需要定时任务? 因为有时候我们需要定时的执行一些操作,比如业务中产生的一些临时文件,临时文件不能立即删除,因为不清楚用户…

Java 实现分布式定时任务

文章目录 前言一、技术点二、代码实践1、引入库2、创建启动线程入口3、表结构4、任务解析5、任务拉取 三、结果展示四、总结 前言 最近有一个需求:需要实现分布式定时任务。而市面上的定时任务大多数都是基于Scheduled注解进行实现。不符合需求。所以根据需求整体思…