%% Filter States in Real Time
% Consider the simulated data and state-space model in docid:econ_ug#mw_ecbf3f04-337b-453a-9af2-b334f528af2d.

T = 100;
ARMdl = arima(AR=0.5,Constant=0,Variance=1);
x0 = 1.5;
rng(1); % For reproducibility

x = simulate(ARMdl,T,Y0=x0);

y = x + 0.75*randn(T,1);

A = 0.5;
B = 1;
C = 1;
D = 0.75;
Mdl = ssm(A,B,C,D);

% Suppose observations are available sequentially, and consider obtaining updated the updated state distribution by filtering each new observation as it is available.
% Simulate the following procedure using a loop.
% Create variables that store the initial state distribution moments.
% Filter the incoming observation through the model specifying the current initial state distribution moments.
% Overwrite the current state distribution moments with the new state distribution moments.
% Repeat 2 and 3 as new observations are available.

currentState = Mdl.Mean0;
currentStateCov = Mdl.Cov0;
newState = zeros(T,1);
newStateCov = zeros(T,1);

for j = 1:T
    [newState(j),newStateCov(j)] = update(Mdl,y(j),currentState,currentStateCov);
    currentState = newState(j);
    currentStateCov = newStateCov(j);
end

% Plot the observations, true state values, and new state means of each period.

figure
plot(1:T,x,'-k',1:T,y,'*g',1:T,newState,':r','LineWidth',2)
xlabel("Period")
legend(["True state values" "Observations" "New state values"])

% Compare the results to the results of filter.

tol = 1e-10;
[fX,~,output] = filter(Mdl,y);
discrepencyMeans = fX - newState;
discrepencyVars = [output.FilteredStatesCov]' - newStateCov;
areMeansEqual = norm(discrepencyMeans) < tol
areVarsEqual = norm(discrepencyVars) < tol

% The real-time filter update, applied to the entire data set sequentially, returns the same state distributions as filter.
% Copyright 2021 The MathWorks, Inc.