背景
本人最近设计的算法,需要用到带遗忘因子的RLS估计,于是将其封装为函数,后续使用直接进行调用即可。
设计加入的遗忘因子
λ
∈
[
0
,
1
]
\lambda \in[0,1]
λ∈[0,1]可以调节收敛速度,使得可以在收敛速度和波动程度之间灵活调节,遗忘因子的经验值
λ
∈
[
0.9
,
1
]
\lambda \in[0.9,1]
λ∈[0.9,1]
注意:封装的函数仅仅是单一时刻的计算,调用需要在循环体内进行。
函数代码
%Project: 带遗忘因子的递归最小二乘法
%Author: Jace
%Data: 2022/04/10
%====================函数体====================
function [P,xRls]=Rls(Dim,H,R,Pp,xRlsp,y,lambda)
I=eye(Dim);
K=Pp*H'/(H*Pp*H'+R);
xRls=(I-K*H)*xRlsp+K*y;
if nargin==6 %参数个数判断是否含有遗忘因子
P=((I-K*H)*Pp*(I-K*H)'+K*R*K');
elseif nargin==7
P=((I-K*H)*Pp*(I-K*H)'+K*R*K')/lambda;
else
error('参数不足');
end
end
调用方法
[P,xRls]=Rls(Dim,H,R,Pp,xRlsp,y,lambda)
对应
[当前时刻估计协方差P, 当前时刻估计值xRls]=Lkf(状态维度, 量测矩阵H, 量测噪声协方差R, 上一时刻估计协方差Pp, 上一时刻估计值xRlsp, 当前时刻量测值y, 遗忘因子lamda)
注意:输入参数中的lamda为可选参数,实际使用时可以省略,省略时即使用标准RLS。
调用测试函数
测试中的MSE依赖于MSE函数,在前序博文中给出
%Project: 基本一维Rls测试Rls估计函数
%Author: Jace
%Data: 2021/10/06
%====================准备====================
close all;
clear all;
clc;
%====================设定全局参数====================
%--------全局参数--------
N=300;%设定采样点数,即持续时长
%--------设定维度--------
Dim=1;%量测维度
%--------系统参数--------
H=1;
x=ones(1,N);%状态
y=zeros(1,N);%量测
y(1)=x(1);
R=0.1;
v=sqrt(R)*randn(Dim,N);
%--------Rls参数--------
P=zeros(1,1,N);
xRls=zeros(1,N);
P(:,1)=0.1;
xRls(1)=1;
I=eye(Dim);
for k=2:N
%量测模型,标量
y(k)=H*x(k-1)+v(k);
%====================Rls过程====================
[P(:,k),xRls(k)]=Rls(Dim,H,R,P(:,k-1),xRls(k-1),y(k));
%使用遗忘因子时,如下
%[P(:,k),xRls(k)]=Rls(Dim,H,R,P(:,k-1),xRls(k-1),y(k),0.96);
end
%====================MSE计算====================
Step=10;
[MSE]=MSE(Dim,Step,N,xRls,y); %依赖前面文章给出的均方误差计算函数
%====================绘图====================
%状态与估计
figure;
hold on,box on;
plot(x,'-k.');
plot(y,'-r.');
plot(xRls,'-b.');
legend('状态值','量测值','状态量Rls估计值');
xlabel('采样时间');ylabel('数值');
%均方差
figure;
hold on,box on;
plot(MSE,'-k.');
legend('均方误差');
xlabel('采样时间');ylabel('数值');
仿真效果
不选用遗忘因子时
- 状态值、量测值与估计值
- 均方误差
遗忘因子选为0.96时
- 状态值、量测值与估计值
- 均方误差
可以看出加入遗忘因子后,估计算法收敛更快,但波动更大。因此在实际使用中需要根据实际情况选取。