Matlab: фильтр Калмана Как смягчить предупреждение: матрица является единственной или плохо масштабируется

При выполнении инновационного обновления для фильтра Калмана я получаю предупреждения

Предупреждение: матрица близка к единственной или плохо масштабируется. Результаты могут быть неточными. RCOND = 2,169130e-017.

Возможно из-за этого результат не точный. Как я могу решить эту проблему? Я попытался ввести цикл

[R,p] = chol(Ppred);
if p> 0;
                count = 300;
              return;
          end

где count — это просто переменная для остановки кода до тех пор, пока не будет найдена хорошая матрица. но это не помогает.

ОБНОВЛЕНИЕ:

Линейное системное представление скользящей средней, модель MA(2)

 x_n+1 = Bw_n
 y_n = Cx_n + v_n
% w = N(0,Q); v = N(0,R)
%true coefficients, h = [1 0.5 -0.9];

ФРАГМЕНТЫ КОДА

Это функции для 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

person SKM    schedule 11.09.2015    source источник
comment
Я бы рекомендовал предоставить код, который воспроизводит вашу проблему.   -  person excaza    schedule 11.09.2015
comment
@excaza: Пожалуйста, посмотрите мое обновление, где я разместил код. Спасибо за помощь.   -  person SKM    schedule 11.09.2015


Ответы (1)


Численные проблемы - обычная проблема с фильтрами Калмана. Вы не предоставили достаточно кода, чтобы быть уверенным (особенно Q), но ошибки округления часто приводят к тому, что P становится неположительно определенным (особенно с формой обновления P, которую вы использовали).

Если вы погуглите «Числовая стабильность фильтра Калмана», вы можете найти много ссылок на эту тему. В этом случае можно попробовать просто увеличить Q (он же «фиктивный шум процесса»), чтобы избежать плохо обусловленного P, использовать форму Джозефа обновления ковариации или заставить P быть симметричным, установив P = 0.5 * ( P + P' ).

Более сложные варианты включают переключение на форму квадратного корня (например, UDU') или использование представления с плавающей запятой с большей точностью (например, double вместо float, что в основном сложно, потому что вы, вероятно, уже в двойном).

person Ben Jackson    schedule 12.09.2015
comment
В моем случае соблюдение симметрии P = 0,5 * (P + P') отлично работает, спасибо! - person Kepler; 29.03.2021