3. RLS算法
任务目标
实现递归最小二乘(RLS)自适应滤波器,在相同输入条件下与LMS滤波器对比收敛速度与稳态误差,验证RLS收敛更快但稳态误差更低的特性。
核心原理与实现
RLS通过递推更新逆相关矩阵P(n)和增益向量k(n),使代价函数为指数加权误差平方和。遗忘因子λ控制历史数据权重,通常取0.99~1.0。本案例使用系统辨识场景:未知FIR滤波器h*,自适应滤波器w(n)逼近该未知系统。
完整代码(Python + NumPy)
import numpy as np
import matplotlib.pyplot as plt
def rls_filter(x, d, M, lam=0.99, delta=1.0):
"""RLS自适应滤波器
x: 输入信号, d: 期望信号, M: 滤波器阶数
lam: 遗忘因子, delta: 正则化初始值
返回: 误差序列e, 权重历史w_history
"""
N = len(x)
w = np.zeros(M)
P = np.eye(M) / delta
e = np.zeros(N)
w_history = np.zeros((N, M))
for n in range(N):
x_n = x[max(0, n-M+1):n+1][::-1]
if len(x_n) < M:
x_n = np.pad(x_n, (M-len(x_n), 0))
# 先验误差
y = np.dot(w, x_n)
e[n] = d[n] - y
# 增益向量
Pi = np.dot(P, x_n)
k = Pi / (lam + np.dot(x_n, Pi))
# 更新权重和逆相关矩阵
w = w + k * e[n]
P = (P - np.outer(k, np.dot(x_n, P))) / lam
w_history[n] = w
return e, w_history
def lms_filter(x, d, M, mu):
"""LMS自适应滤波器(用于对比)"""
N = len(x)
w = np.zeros(M)
e = np.zeros(N)
w_history = np.zeros((N, M))
for n in range(N):
x_n = x[max(0, n-M+1):n+1][::-1]
if len(x_n) < M:
x_n = np.pad(x_n, (M-len(x_n), 0))
y = np.dot(w, x_n)
e[n] = d[n] - y
w = w + 2 * mu * e[n] * x_n
w_history[n] = w
return e, w_history
# ===== 仿真参数 =====
np.random.seed(42)
N = 2000 # 样本数
M = 4 # 滤波器阶数
h_true = np.array([0.5, -0.3, 0.8, 0.2]) # 未知系统
# 生成输入信号(白噪声)和期望信号
x = np.random.randn(N)
d = np.convolve(x, h_true)[:N] + 0.01 * np.random.randn(N) # 加观测噪声
# 运行RLS和LMS
e_rls, w_rls = rls_filter(x, d, M, lam=0.99, delta=1.0)
mu = 0.02 # LMS步长(保证收敛)
e_lms, w_lms = lms_filter(x, d, M, mu)
# ===== 验证:权重收敛轨迹 =====
print("RLS最终权重:", w_rls[-1])
print("LMS最终权重:", w_lms[-1])
print("真实权重: ", h_true)
# ===== 绘图对比 =====
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.semilogy(np.abs(e_rls)**2, label='RLS')
plt.semilogy(np.abs(e_lms)**2, label='LMS')
plt.xlabel('迭代次数 n'); plt.ylabel('瞬时误差平方')
plt.legend(); plt.grid(True); plt.title('收敛速度对比')
plt.subplot(1, 2, 2)
for i in range(M):
plt.plot(w_rls[:, i], '--', label=f'RLS w{i}')
plt.plot(w_lms[:, i], ':', label=f'LMS w{i}')
plt.axhline(y=h_true[0], color='k', linewidth=0.5)
plt.xlabel('迭代次数 n'); plt.ylabel('权重值')
plt.legend(loc='center right', fontsize=8)
plt.grid(True); plt.title('权重收敛轨迹')
plt.tight_layout()
plt.savefig('rls_vs_lms.png', dpi=100)
plt.show()
运行与验证
- 依赖安装:
pip install numpy matplotlib - 运行方式:将代码保存为
rls_lms_compare.py,执行python rls_lms_compare.py - 通过判定标准:
- 终端输出RLS最终权重与真实权重
[0.5, -0.3, 0.8, 0.2]的误差小于0.05(RLS收敛后接近真值); - 左图显示RLS误差平方曲线约在50次迭代内快速下降至10⁻⁴以下,LMS需数百次迭代才接近该水平;
- 右图显示RLS权重轨迹在约100次迭代内稳定至真实值附近,LMS轨迹收敛明显更慢且存在更大波动。
- 终端输出RLS最终权重与真实权重
关键说明
- RLS的初始正则化参数
delta取1.0(信噪比较高时),若噪声大需增大至10~100; - 遗忘因子
λ=0.99在平稳系统中接近1.0可获得更低稳态误差,非平稳环境可调至0.95~0.98; - LMS步长
mu=0.02需满足0 < mu < 1/λ_max(输入功率约1,故上限约0.5),此处取值保证稳定但收敛慢,用于突出对比。