Matlab:卡尔曼滤波器——如何减轻警告:矩阵奇异或严重缩放

Matlab:卡尔曼滤波器——如何减轻警告:矩阵奇异或严重缩放,matlab,kalman-filter,Matlab,Kalman Filter,执行的创新更新时,我收到警告 警告:矩阵接近单数或比例严重。结果可能是 不准确的。RCOND=2.169130e-017 也许正因为如此,结果并不准确。我怎样才能解决这个问题?我试着引入一个循环 [R,p] = chol(Ppred); if p> 0; count = 300; return; end 其中count只是一个变量,用于暂停代码,直到找到一个好的矩阵。但这没有帮助 更新: 移动平均线的线性系统

执行的创新更新时,我收到警告

警告:矩阵接近单数或比例严重。结果可能是 不准确的。RCOND=2.169130e-017

也许正因为如此,结果并不准确。我怎样才能解决这个问题?我试着引入一个循环

[R,p] = chol(Ppred);
if p> 0;
                count = 300;
              return;
          end
其中count只是一个变量,用于暂停代码,直到找到一个好的矩阵。但这没有帮助

更新:

移动平均线的线性系统表示,MA(2)模型

代码片段

这些是卡尔曼滤波器3个模块的功能

C = [ 1 0 0 ];

B = [1 0.5  -0.9 ;
     0  1     0.5;
     0  0     1]; 

noise_var = rand(1,1); % measurement noise

 order = 2;
 xpred = rand(order,1); 
 P = 10* eye(d,d);

 A = P;
 P = P + B*sqrt(noise_var)*B';
P = dlyap(A,B*B');
for i = 1:N
 [xpred, Ppred] = predict(xpred,B,Ppred, Q); 

  [nu, S] = innovation(xpred, Ppred, y(i), C, noise_var);

  [xnew, Ppred, yhat, KalmanGain] = innovation_update(xpred,Ppred,nu,S,C);
    if(isnan(Ppred))
         count = 300;
         return;
    end

end

function [xpred, Ppred] = predict(input_t,B,P, Q)
xpred =  B*input_t;
Ppred = P + Q;
end

function [nu, S] = innovation(xpred, Ppred, y, C, R)
nu = y - C*xpred; %% innovation

S = R + C*Ppred*C'; %% innovation covariance

end

function [xnew, Pnew, yhat, K] = innovation_update(xpred, Ppred, nu, S, C)
K1 = Ppred*C';
K = K1'*inv(S);
xnew = xpred + K'*nu; %% new state
Pnew = Ppred - Ppred*K'*C; %% new covariance
 yhat = C*xnew;

end

数值问题是卡尔曼滤波器的常见问题。您没有共享足够的代码以确保(尤其是
Q
),但舍入错误会导致
P
变得非正定(尤其是使用
P
更新表单时)

如果你在谷歌上搜索“卡尔曼滤波数值稳定性”,你可以找到很多关于这个主题的参考资料。在这种情况下,简单的尝试是增加
Q
(也称为“虚拟过程噪声”),以避免病态的
P
,使用协方差更新的约瑟夫形式,或者通过设置
P=0.5*(P+P')
强制
P
对称


更复杂的选项包括切换到平方根形式(如UDU),或使用精度更高的浮点表示法(如用double代替float,这主要是因为您可能已经使用了double)。我建议提供重现您的问题的代码。@excaza:请参阅我的更新,我把代码放在哪里了。谢谢你的帮助。在我的例子中,对称强制P=0.5*(P+P')非常有效,谢谢!
C = [ 1 0 0 ];

B = [1 0.5  -0.9 ;
     0  1     0.5;
     0  0     1]; 

noise_var = rand(1,1); % measurement noise

 order = 2;
 xpred = rand(order,1); 
 P = 10* eye(d,d);

 A = P;
 P = P + B*sqrt(noise_var)*B';
P = dlyap(A,B*B');
for i = 1:N
 [xpred, Ppred] = predict(xpred,B,Ppred, Q); 

  [nu, S] = innovation(xpred, Ppred, y(i), C, noise_var);

  [xnew, Ppred, yhat, KalmanGain] = innovation_update(xpred,Ppred,nu,S,C);
    if(isnan(Ppred))
         count = 300;
         return;
    end

end

function [xpred, Ppred] = predict(input_t,B,P, Q)
xpred =  B*input_t;
Ppred = P + Q;
end

function [nu, S] = innovation(xpred, Ppred, y, C, R)
nu = y - C*xpred; %% innovation

S = R + C*Ppred*C'; %% innovation covariance

end

function [xnew, Pnew, yhat, K] = innovation_update(xpred, Ppred, nu, S, C)
K1 = Ppred*C';
K = K1'*inv(S);
xnew = xpred + K'*nu; %% new state
Pnew = Ppred - Ppred*K'*C; %% new covariance
 yhat = C*xnew;

end