Matlab: How do I simulate the model after state estimation from Kalman filter - matlab

I am trying to implement the basic Equations for Kalman filter for the following 1 dimensional AR model:
x(t) = a_1x(t-1) + a_2x(t-2) + w(t)
y(t) = Cx(t) + v(t);
The KF state space model :
x(t+1) = Ax(t) + w(t)
y(t) = Cx(t) + v(t)
w(t) = N(0,Q)
v(t) = N(0,R)
where
% A - state transition matrix
% C - observation (output) matrix
% Q - state noise covariance
% R - observation noise covariance
% x0 - initial state mean
% P0 - initial state covariance
%%% Matlab script to simulate data and process usiung Kalman for the state
%%% estimation of AR(2) time series.
% Linear system representation
% x_n+1 = A x_n + Bw_n
% y_n = Cx_n + v_n
% w = N(0,Q); v = N(0,R)
clc
clear all
T = 100; % number of data samples
order = 2;
% True coefficients of AR model
a1 = 0.195;
a2 = -0.95;
A = [ a1 a2;
1 0 ];
C = [ 1 0 ];
B = [1;
0];
x =[ rand(order,1) zeros(order,T-1)];
sigma_2_w =1; % variance of the excitation signal for driving the AR model(process noise)
sigma_2_v = 0.01; % variance of measure noise
Q=eye(order);
P=Q;
%Simulate AR model time series, x;
sqrtW=sqrtm(sigma_2_w);
%simulation of the system
for t = 1:T-1
x(:,t+1) = A*x(:,t) + B*sqrtW*randn(1,1);
end
%noisy observation
y = C*x + sqrt(sigma_2_v)*randn(1,T);
%R=sigma_2_v*diag(diag(x));
%R = diag(R);
R = var(y);
z = zeros(1,length(y));
z = y;
x0=mean(y);
for i=1:T-1
[xpred, Ppred] = predict(x0,P, A, Q);
[nu, S] = innovation(xpred, Ppred, z(i), C, R);
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
end
%plot
xhat = xnew';
plot(xhat(:,1),'red');
hold on;
plot(x(:,1));
function [xpred, Ppred] = predict(x0,P, A, Q)
xpred = A*x0;
Ppred = A*P*A' + 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] = innovation_update(xpred, Ppred, nu, S, C)
K = Ppred*C'*inv(S); %% Kalman gain
xnew = xpred + K*nu; %% new state
Pnew = Ppred - Ppred*K*C; %% new covariance
end
Question: I want to see how close the estimated state xnew is to the actual state x by a plot. But, the xnew returned by the function innovation_update is a 2by2 matrix! How do I simulate a time series with the estimated values?

You don't need to initialise x to anything, just set the initial state x(:,1) and the "simulation of the system" loop will fill in the rest. Oops, I see you were already doing that!
Later, in the loop that infers the state xnew from the noisy observations y you can add the line:
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
yhat(i) = C*xnew; % Observed value at time step i, assuming inferred state xnew
Finally, you should plot yhat and y for comparison.
If you want to add error bars for the uncertainty on the estimate then you should also store Phat(i) = sqrt(C*P*C') and call errorbar(yhat,Phat) instead of plot(yhat).

Related

filter Kalman in Matlab

There is a error that I can't solve, here is the code in matlab:
% Define the system matrices A, C, and the initial state
A = [1 1
0 1]; % state transition matrix
C = [1 0]; % measurement matrix
x0 = [1 0]; % initial state
% Define the number of time steps and the noise covariance matrices
N = 50; % number of time steps
Q_values = 0.1; % values of Q to consider
R_values = 0.25; % values of R to consider
% Pre-allocate memory for the states and estimated states
x = zeros(2, N); % real state
xhat = zeros(2, N); % state estimate
xpred = zeros(2, N); % prediction state
% Loop over each value of Q and R
for i = 1:length(Q_values)
for j = 1:length(R_values)
Q = Q_values(i) * eye(2); % covariance of process noise
R = R_values(j) * eye(2); % covariance of measurement noise
% Initialize the state estimate and its covariance
xhat(:, 1) = x0;
P = eye(2); % initial covariance of state estimate
% Generate the real state and measurements with noise
for k = 1:N
w = sqrt(Q) * randn(2, 1); % process noise
v = sqrt(R) * randn(1, 1); % measurement noise
x(:, k+1) = A * x(:, k) + w; % real state
yk = C * x(:, k) + v; % measurement
% Predict the state and covariance at time k
xpred(:, k+1) = A * xhat(:, k); % state prediction
P_pred = A * P * A' + Q; % covariance prediction
% Compute the Kalman gain
K = P_pred * C' / (C * P_pred * C');
% Update the state estimate and covariance
xhat(:, k+1) = A * xpred(:, k+1) + K .* (yk - C .* xpred(:, k+1));
P = (eye(2) - K * C) * P_pred;
end
end
error is here:
Unable to perform assignment because the size of the left side is 2-by-1 and the size of the right side
is 2-by-2.
Error in Untitled (line 42)
xhat(:, k+1) = A * xpred(:, k+1) + K .* (yk - C .* xpred(:, k+1));
Do you guys have some ideas how to change my code?

Why does my Markov cluster algorithm (MCL) produce NaN as a result in Matlab?

I have tried the Markov cluster algorithm (MCL) in Matalb but sadly I got a matrix of size 67*67 and all their elements have NaN.
Could anyone tell me what's wrong?
function adjacency_matrixmod2= mcl(adjacency_matrixmod2)
% test the explanations in stijn van dongens thesis.
%
% #author gregor :: arbylon . net
if nargin < 1
% m contains T(G3 + I) as stochastic matrix
load -ascii adjacency_matrixmod2.txt
end
p = 2;
minval = 0.001;
e = 1.;
emax = 0.001;
while e > emax
fprintf('iteration %i before expansion:\n', i);
adjacency_matrixmod2
fprintf('iteration %i after expansion/before inflation:\n', i);
m2 = expand(adjacency_matrixmod2)
fprintf('inflation:\n')
[adjacency_matrixmod2, e] = inflate(m2, p, minval);
fprintf('residual energy: %f\n', e);
end % while e
end % mcl
% expand by multiplying m * m
% this preserves column (or row) normalisation
function m2 = expand(adjacency_matrixmod2)
m2 = adjacency_matrixmod2 *adjacency_matrixmod2;
end
% inflate by Hadamard potentiation
% and column re-normalisation
% prune elements of m that are below minval
function [m2, energy] = inflate(adjacency_matrixmod2, p, minval)
% inflation
m2 = adjacency_matrixmod2 .^ p;
% pruning
m2(find(m2 < minval)) = 0;
% normalisation
dinv = diag(1./sum(m2));
m2 = m2 * dinv;
% calculate residual energy
maxs = max(m2);
sqsums = sum(m2 .^ 2);
energy = max(maxs - sqsums);
end
This is the code I have used, and its input is an adjacency matrix.

How to use fast Fourier transform for the complex values in MATLAB

I solved a differential equation and the solutions of that are the complex values in the time domain. I have to transform it to the frequency domain with FFT. I have used FFT in MATLAB, but the answers are not correct. How can I choose my interval of frequency?
The time domain is between -10 and 60 and the number of steps is 1000.
function r = fur()
clc
clear
format long
a = -10; % tmin
b = 60; % tmax
m = 1000; % Number of steps
t = zeros(1, m);
y = zeros(1, m);
t(1) = a; % Boundary condition
y(1) = 0; % Boundary condition
t0 = 0.01;
h = (b-a)/m;
for j=1:m
T = t(j); Y = y(j);
k1 = h*Fun(T, Y);
k2 = h*Fun(T + h/2, Y + k1/2);
k3 = h*Fun(T + h/2, Y + k2/2);
k4 = h*Fun(T + h, Y + k3);
y(j+1) = Y + (k1 + 2*k2 + 2*k3 + k4)/6;
t(j+1) = a + h*(j);
end
% real_y = real(y);
% imag_y = imag(y);
y;
%% Fast Fourier transformation for P(W)
NFFT = length(y);
fs = 2*pi/h;
X = fftshift(fft(y, NFFT));
fVals = (0:NFFT-1)*fs/NFFT;
figure(1)
plot(fVals, abs(X), '-b');
title('Fast Fourier transform');
xlabel('Frequency (THz)')
ylabel('p(w)');
hold on
%% Fast Fourier transformation for E(W)
NFFT = length(y);
fs = 2*pi/h;
Z = fftshift(fft(Et(t, t0), NFFT));
fVals = (0:NFFT-1)*fs/NFFT;
figure (2)
plot(fVals, abs(Z), '-r');
title('Fast Fourier Transform');
xlabel('Frequency (THz)')
ylabel('E(w)');
hold on
%% Linear susceptibility
f = X./Z;
f_imag = imag(f);
f_real = real(f);
fVal = (0:NFFT-1)*fs/NFFT;
figure(3)
plot(fVal, f_real, '-r');
title('total part of susceptibility');
xlabel('Frequency (THz)')
ylabel('Kappa(w)');
hold on
figure(4);
plot(fVals, f_imag, '-r');
title('imaginary part of susceptibility');
xlabel('Frequency (THz)')
ylabel('kappa(w)');
hold on
And this is the Fun.m file:
function F = Fun(t, y)
format long
E_g = 1.52; % Binding energy for GaAs
gamma = 0.1*E_g;
t0 = 0.01; % This is a damping operator
k = 1;
F = -i*((((k^2)-i*gamma)*y)-Et(t, t0)); % F = -i*((-i*gamma)*y-1/2);;
And this is the Et.m file:
function e = Et(t, t0)
format long
t0 = 0.1;
e = (1/2)*(exp(-(t/t0).^2));
end

Matlab: Error in inverse operation when implementing Kalman filter

I am trying to implement the basic Equations for Kalman filter for the following 1 dimensional AR model:
x(t) = a_1x(t-1) + a_2x(t-2) + w(t)
y(t) = Cx(t) + v(t);
The KF state space model :
x(t+1) = Ax(t) + w(t)
y(t) = Cx(t) + v(t)
w(t) = N(0,Q)
v(t) = N(0,R)
where
% A - state transition matrix
% C - observation (output) matrix
% Q - state noise covariance
% R - observation noise covariance
% x0 - initial state mean
% P0 - initial state covariance
%%% Matlab script to simulate data and process usiung Kalman for the state
%%% estimation of AR(2) time series.
% Linear system representation
% x_n+1 = A x_n + Bw_n
% y_n = Cx_n + v_n
% w = N(0,Q); v = N(0,R)
clc
clear all
T = 100; % number of data samples
order = 2;
% True coefficients of AR model
a1 = 0.195;
a2 = -0.95;
A = [ a1 a2;
0 1 ];
C = [ 1 0 ];
B = [1;
0];
x =[ rand(order,1) zeros(order,T-1)];
sigma_2_w =1; % variance of the excitation signal for driving the AR model(process noise)
sigma_2_v = 0.01; % variance of measure noise
Q=eye(order);
P=Q;
%Simulate AR model time series, x;
sqrtW=sqrtm(sigma_2_w);
%simulation of the system
for t = 1:T-1
x(:,t+1) = A*x(:,t) + B*sqrtW*randn(1,1);
end
%noisy observation
y = C*x + sqrt(sigma_2_v)*randn(1,T);
R=sigma_2_v*diag(diag(x));
R = diag(R);
z = zeros(1,length(y));
z = y;
x0=mean(y);
for i=1:T-1
[xpred, Ppred] = predict(x0,P, A, Q);
[nu, S] = innovation(xpred, Ppred, z(i), C, R);
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
end
%plot
xhat = xnew';
plot(xhat(:,1),'red');
hold on;
plot(x(:,1));
function [xpred, Ppred] = predict(x0,P, A, Q)
xpred = A*x0;
Ppred = A*P*A' + 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] = innovation_update(xpred, Ppred, nu, S, C)
K = Ppred*C'*inv(S); %% Kalman gain
xnew = xpred + K*nu; %% new state
Pnew = Ppred - Ppred*K*C; %% new covariance
end
The code is throwing the error
Error using inv
Matrix must be square.
Error in innovation_update (line 2)
K = Ppred*C'*inv(S); %% Kalman gain
Error in Kalman_run (line 65)
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
This is because S matrix is not square. How do I make it square? Is there a problem with the steps before that?
As far as I understand it, the R matrix is supposed to be the covariance matrix for the measurement noise.
The following lines:
R=sigma_2_v*diag(diag(x));
R = diag(R);
Change R from a 2x2 diagonal matrix to a 2x1 column vector.
Since your observation y is a scalar, the observation noise v must also be a scalar. This means R is a 1x1 covariance matrix, or simply the variance of the random variable v.
You should make R a scalar for your code to work properly.

Matlab: Help neede to initialize matrices

I am trying to implement the basic Equations for Kalman filter for the following 1 dimensional AR model:
x(t) = a_1x(t-1) + a_2x(t-2) + w(t)
y(t) = Cx(t) + v(t);
The KF state space model :
x(t+1) = Ax(t) + w(t)
y(t) = Cx(t) + v(t)
w(t) = N(0,Q)
v(t) = N(0,R)
where
% A - state transition matrix
% C - observation (output) matrix
% Q - state noise covariance
% R - observation noise covariance
% x0 - initial state mean
% P0 - initial state covariance
The code for the prediction and update are:
function [xpred, Ppred] = predict(x, P, F, Q)
xpred = A*x;
Ppred = A*P*A’ + Q;
function [nu, S] = innovation(xpred, Ppred, z, H, R)
nu = y - C*xpred; %% innovation
S = R + C*Ppred*C’; %% innovation covariance
function [xnew, Pnew] = innovation_update(xpred, Ppred, n
u, S, C)
K = Ppred*C’*inv(S); %% Kalman gain
xnew = xpred + K*nu; %% new state
Pnew = Ppred - K*S*K’; %% new covariance
I am trying to follow the implementation https://github.com/cswetenham/pmr/blob/master/toolboxes/lds/kalmansmooth.m but getting confused since the parameters A,C are given as matrices.
Do I have to represent A,C as matrices? How do I represent A,C , Q,R for my case?
How do I initialize A,C,Q,R? Since, I have only one variable, Q,R should be 1 by 1. But, what about the others?
Please help.
UPDATE: Here is the full implementation
%%% Matlab script to simulate data and process usiung Kalman for the state
%%% estimation of AR(2) time series.
% Linear system representation
% x_n+1 = A x_n + Bw_n
% y_n = Cx_n + v_n
% w = N(0,Q); v = N(0,R)
clc
clear all
T = 100; % number of data samples
order = 2;
% True coefficients of AR model
a1 = 0.195;
a2 = -0.95;
A = [ a1 a2;
0 1 ];
C = [ 1 0 ];
B = [1;
0];
x =[ rand(order,1) zeros(order,T-1)];
sigma_2_w =1; % variance of the excitation signal for driving the AR model(process noise)
sigma_2_v = 0.01; % variance of measure noise
Q=eye(order);
P=Q;
%Simulate AR model time series, x;
sqrtW=sqrtm(sigma_2_w);
%simulation of the system
for t = 1:T-1
x(:,t+1) = A*x(:,t) + B*sqrtW*randn(1,1);
end
%noisy observation
y = C*x + sqrt(sigma_2_v)*randn(1,T);
R=sigma_2_v*diag(diag(x));
R = diag(R);
z = zeros(1,length(y));
z = y;
x0=mean(y);
for i=1:T-1
[xpred, Ppred] = predict(x0,P, A, Q);
[nu, S] = innovation(xpred, Ppred, z(i), C, R);
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
end
%plot
xhat = xnew';
plot(xhat(:,1),'red');
hold on;
plot(x(:,1));
function [xpred, Ppred] = predict(x0,P, A, Q)
xpred = A*x0;
Ppred = A*P*A' + 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] = innovation_update(xpred, Ppred, nu, S, C)
K = Ppred*C'*inv(S); %% Kalman gain
xnew = xpred + K*nu; %% new state
Pnew = Ppred - Ppred*K*C; %% new covariance
end
I have 3 problems:
(1) Is the initialization of the matrix R correct in terms of dimension and values?
R=sigma_2_v*diag(diag(x));
R = diag(R);
where x is the clean time series.
(2) When creating the noisy observation of the time series, I have used a different variance other than R. I have used sigma_2_v. Should I be using R or sigma_2_v? This is the line where I have created noisy time series
y = C*x + sqrt(sigma_2_v)*randn(1,T);
(3) The code is throwing the error
Error using inv
Matrix must be square.
Error in innovation_update (line 2)
K = Ppred*C'*inv(S); %% Kalman gain
Error in Kalman_run (line 65)
[xnew, P] = innovation_update(xpred, Ppred, nu, S, C);
There are different ways to represent a given AR process as a state space model but I believe you'll have to have a 2 dimensional state representation if it's an AR(2) process (which your model is). So A, C and Q will need to be matrices.
You have scalar observations and so C will be a 1x2 matrix.
x should be a 2 dimensional vector of the form [x(t); x(t-1)]. The first element is the value of x at time t from the AR model and the second element is x at time t-1.
A is of the form [a_1 a_2;1 0]. You can see that Ax is [a_1x(t)+a_2x(t-1);x(t)]. So after applying A to the state x the first element is the predicted next value of x (from the AR model a_1x(t)+a_2x(t-1)) and the second element is x at time t i.e. the elements have been shifted down.
C can be [1 0] i.e. the observation y at time t is simply the first element of the state vector x. Multiplying the state x by C should give use the observation of the state, here we want simply want to observe what the state is at time t and doing [1 0][x(t);x(t-1)] is just x(t).
A, Q, C and R can be learnt from data (e.g. as described here) or set using prior knowledge of your system.
Just because you have one observed variable at each time step doesn't mean Q and R are 1. Q is the system noise covariance and R is the observation noise covariance - setting them to one just specifies the covariance and doesn't do what you seem to think it does.