要回答你的最后一个问题:
为什么估计界忽略了使用离散低通滤波器进行估计?据我所知,这是估计上述信号的最佳方法。
那是因为你给他们提供了错误的信号模型。
TL;DR:为工作使用正确的工具!
血腥细节
任何时候你从卡尔曼滤波器开始,你都假设信号(measurement
在上面的方程中)是这样生成的:
其中
和和是零均值,高斯分布,独立具有协方差的随机变量
至少对于你引用的方程。KF 的更一般应用是可能的,但通常不会这样做。
x[k+1]=Ax[k]+u[k]measurement[k]=Hx[k]+v[k]
A=[1011]H=[10]
uvQ=[1.62.42.44.8]×10−9R=2.35×10−6
所以,可以做的一件事来改进你的估计是确保和更接近现实。从外观上看,您的过程噪声( ] )具有大致相同的方差。让他们更亲近。QRu[k]v[k]
更重要的是,您的信号与您的噪声相关,因为您有谐波噪声,而不是随机噪声。更糟糕的是:您有同步谐波噪声(意味着噪声与您的信号同步移动)。
所以:问题是使用卡尔曼滤波器你的信号模型都是错误的。
更好的信号模型是在频域中:信号是低频的。噪音是高频的。因此,低通滤波器将在改进卡尔曼滤波器希望做的事情方面做得更好。
如果我将卡尔曼滤波器应用于您的问题(对您的方程进行一些修改以考虑和 之间的差异),那么我得到下图。X[k|k−1]X[k|k]
带点的黑色曲线是measurement
. 红色曲线是signal
。蓝色曲线是卡尔曼滤波器的输出。绿色曲线是 5 点移动平均滤波器(简单的低通滤波器)的输出。

卡尔曼滤波器的误差平方和为118.63722
。低通滤波器的相同数字是14.18046
。显然,低通滤波器的信号模型拟合得更好,因为误差更小。
实现这一点的 R 代码如下。
# 26489
T <- 128;
t <- 0:(T-1)/T*70
signal <- 4.4 + sin(0.06*pi*t - 0.1) + sin(0.14*pi*t + 0.07) + sin(0.2*pi*t + 0.4)
noise <- sin(0.06 + 0.5*pi*t) + sin(0.1 - 0.68*pi*t) - sin(0.04 - 0.74*pi*t) + sin(0.03 - 0.93*pi*t)
measurement <- signal + noise
xkm1km1 <- matrix(c(4.4, 0),2,1)
Pkm1km1 <- matrix(c(1,0,0,1),2,2)
H <- matrix(c(1,0),1,2)
A <- matrix(c(1,1,0,1),2,2)
Q <- 10^-6 * matrix(c(1.6,2.4,2.4,4.8),2,2)
R <- 10^-6 * matrix(c(2.35),1,1)
library("MASS") # For pseudo inverse ginv()
zhat <- t*0
for (k in 1:T)
{
xkkm1 <- A %*% xkm1km1
Pkkm1 <- A %*% Pkm1km1 %*% t(A) + Q
K <- Pkkm1 %*% t(H) %*% ginv( H %*% Pkkm1 %*% t(H) + R)
z <- matrix(c(measurement[k]), 1, 1)
xkm1km1 <- xkkm1 + K %*% (z - H %*% xkkm1)
Pkm1km1 <- (matrix(c(1,0,0,1),2,2) - K %*% H) %*% Pkkm1
zhat[k] <- as.numeric(H %*% xkkm1)
}
plot(t, measurement, type="b", pch=19)
lines(t, signal, col="red", lwd=10)
lines(t, zhat, col="blue", lwd=5)
lpf <- filter(measurement, c(0.2,0.2,0.2,0.2,0.2), circular = TRUE)
lines(t,lpf, col="green", lwd=4)
errs <- c(sum((signal - zhat)^2), sum((signal - lpf)^2))
print(errs)