-
Notifications
You must be signed in to change notification settings - Fork 3
/
abcKalmanLike.m
77 lines (58 loc) · 2.03 KB
/
abcKalmanLike.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
function LLF = abcKalmanLike(A, B, C, Ydata, X00, cholSigma00, sqrtR)
% abcKalmanLike
% ....
% Coded by Elmar Mertens, em@elmarmertens.com
%% parse inputs
Nx = size(A, 1);
[Ny, T] = size(Ydata);
if nargin < 7
sqrtR = [];
end
%% init Variables and allocate memory
if ~isempty(sqrtR) && ismatrix(sqrtR)
sqrtR = repmat(sqrtR, [1 1 T]);
end
if ismatrix(A)
A = repmat(A, [1 1 T]);
end
if ismatrix(B)
B = repmat(B, [1 1 T]);
end
if ismatrix(C)
C = repmat(C, [1 1 T]);
end
I = eye(Nx);
%% Forward Loop: Kalman Forecasts
Sigmatt = cholSigma00 * cholSigma00';
Xtt = X00;
LLF = 0;
% llf = NaN(T,1);
for t = 1 : T
% priors
Sigmattm1 = A(:,:,t) * Sigmatt * A(:,:,t)' + B(:,:,t) * B(:,:,t)';
Xttm1 = A(:,:,t) * Xtt;
% observed innovation
if isempty(sqrtR)
SigmaYttm1 = C(:,:,t) * Sigmattm1 * C(:,:,t)';
else
SigmaYttm1 = C(:,:,t) * Sigmattm1 * C(:,:,t)' + ...
sqrtR(:,:,t) * sqrtR(:,:,t)';
end
sqrtSigmaYttm1 = chol(SigmaYttm1, 'lower');
logdetY = 2 * sum(log(diag(sqrtSigmaYttm1)));
Ztilde = sqrtSigmaYttm1 \ (Ydata(:,t) - C(:,:,t) * Xttm1);
LLF = LLF + logdetY + sum(Ztilde.^2);
% llf(t) = -.5 * (Ny * log(2 * pi) +logdetY + sum(Ztilde.^2));
% Kalman Gain
Ctilde = sqrtSigmaYttm1 \ C(:,:,t);
Ktilde = Sigmattm1 * Ctilde';
ImKC = I - Ktilde * Ctilde;
% K = Sigmattm1 * C(:,:,t)' / SigmaYttm1;
% checkdiff(K, Ktilde / sqrtSigmaYttm1);
% checkdiff(K * C(:,:,t), Ktilde * Ctilde);
% posteriors
Sigmatt = ImKC * Sigmattm1 * ImKC'; % Joseph form for numerical stability
Xtt = Xttm1 + Ktilde * Ztilde;
end
LLF = -.5 * (Ny * log(2 * pi) * T + LLF);
% checkdiff(LLF, sum(llf));