dynare/tests/kalman/likelihood/compare_kalman_routines.m

190 lines
5.9 KiB
Matlab

function compare_kalman_routines(experience)
%% This function compares the kalman filter routines.
%%
%%
%% stephane [DOT] adjemian [AT] ens [DOT] fr
pp = experience.Number0fObservedVariables;
mm = experience.SizeOfTheStateVector;
rr = experience.NumberOfStructuralShocks;
measurement_error_flag = experience.MeasurementErrors;
gend = experience.NumberOfPeriods;
PercentageOfMissingObservations = experience.PercentageOfMissingObservations;
PeriodsWithMissingObservations = experience.PeriodsWithMissingObservations;
%% SET VARIOUS PARAMETERS
kalman_tol = 1e-12;
riccati_tol =1e-9;
start = 1;
%% SET THE STATE SPACE MODEL:
% I randomly choose the mm eigenvalues of the transition matrix.
TransitionEigenvalues = rand(mm,1)*2-1;
% I randomly choose the mm eigenvectors of the transition matrix
tmp = rand(mm,mm*100);
TransitionEigenvectors = tmp*tmp'/(mm*100);
TransitionEigenvectors = rand(mm,mm);
% I build the transition matrix
T = TransitionEigenvectors*diag(TransitionEigenvalues)*inv(TransitionEigenvectors);
% I randomly choose matrix R
R = randn(mm,rr);
% I randomly choose the covariance matrix of the structurtal innovations
E = randn(rr,20*rr);
Q = E*transpose(E)/(20*rr);
% If needed I randomly choose the covariance matrix of teh measurement errors
if measurement_error_flag == 0
H = zeros(pp,1);
elseif measurement_error_flag == 1
H = rand(pp,1);
elseif measurement_error_flag == 2
E = randn(pp,20*pp);
H = E*transpose(E)/(20*pp);
else
disp('compare_kalman_routines:: Unknown option!')
end
% Set the selection vector (mf)
MF = transpose(randperm(mm));
mf = MF(1:pp);
P = lyapunov_symm(T,R*Q*R',1.000001);
%% BUILD DATA SET (zero mean):
if measurement_error_flag == 0
Y = simul_state_space_model(T,R,Q,mf,gend);
elseif measurement_error_flag == 1
H = rand(pp,1);
Y = simul_state_space_model(T,R,Q,mf,gend,diag(H));
elseif measurement_error_flag == 2
E = randn(pp,20*pp);
H = E*transpose(E)/(20*pp);
Y = simul_state_space_model(T,R,Q,mf,gend,H);
else
disp('compare_kalman_routines:: Unknown option!')
end
if PeriodsWithMissingObservations
data_1 = Y(:,1:PeriodsWithMissingObservations)';
if PeriodsWithMissingObservations<gend
data_2 = Y(:,PeriodsWithMissingObservations+1:end);
else
data_2 = [];
end
tmp = randperm(1:PeriodsWithMissingObservations*pp);
tmp = tmp(1:round(PercentageOfMissingObservations*length(tmp)));
data_1(tmp) = NaN;
Y = [ transpose(data_1) ; data_2 ];
end
[data_index,number_of_observations,no_more_missing_observations] = describe_missing_data(Y,gend,pp);
if PeriodsWithMissingObservations==0
% kalman_filter.m
if measurement_error_flag==0
HH = 0;
elseif measurement_error_flag==1
HH = diag(H);
elseif measurement_error_flag==2
HH = H;
end
instant0 = clock;
[LIK1,lik1] = kalman_filter(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol);
T1 = etime(clock, instant0);
disp(['kalman_filter = ' num2str(T1)])
% missing_observations_kalman_filter.m
if measurement_error_flag==0
HH = zeros(pp,pp);
elseif measurement_error_flag==1
HH = diag(H);
elseif measurement_error_flag==2
HH = H;
end
instant0 = clock;
[LIK2,lik2] = missing_observations_kalman_filter(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol,data_index,number_of_observations,no_more_missing_observations);
T2 = etime(clock, instant0);
disp(['missing_observations_kalman_filter = ' num2str(T2)])
% univariate_kalman_filter.m
if measurement_error_flag==0
HH = zeros(pp,pp);
elseif measurement_error_flag==1
HH = H;
elseif measurement_error_flag==2
HH = H;
end
if measurement_error_flag<2
instant0 = clock;
[LIK3,lik3] = univariate_kalman_filter(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol,data_index,number_of_observations,no_more_missing_observations);
T3 = etime(clock, instant0);
else
instant0 = clock;
[LIK3,lik3] = univariate_kalman_filter_corr(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol,data_index,number_of_observations,no_more_missing_observations);
T3 = etime(clock, instant0);
end
disp(['univariate_kalman_filter = ' num2str(T3)])
disp(' ')
disp(' ')
if abs(LIK2/LIK1-1)<1e-9
disp('missing data version is Ok')
else
disp('missing data version is wrong')
disp(['percentage dev. = ' num2str((LIK2/LIK1-1)*100)])
end
if abs(LIK3/LIK1-1)<1e-9
disp('univariate version is Ok')
else
disp('univariate version is wrong')
disp(['percentage dev. = ' num2str((LIK3/LIK1-1)*100)])
%[lik1,lik3,lik1-lik3]
%[lik1-lik3]
end
else
% missing_observations_kalman_filter.m
if measurement_error_flag==0
HH = zeros(pp,pp);
elseif measurement_error_flag==1
HH = diag(H);
elseif measurement_error_flag==2
HH = H;
end
instant0 = clock;
LIK2 = missing_observations_kalman_filter(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol,data_index,number_of_observations,no_more_missing_observations);
T2 = etime(clock, instant0);
disp(['missing_observations_kalman_filter = ' num2str(T2)])
% univariate_kalman_filter.m
if measurement_error_flag==0
HH = zeros(pp,pp);
elseif measurement_error_flag==1
HH = H;
elseif measurement_error_flag==2
error('The univariate approach cannot handle correlated measurement errors')
end
instant0 = clock;
LIK3 = univariate_kalman_filter(T,R,Q,HH,P,Y,start,mf,kalman_tol,riccati_tol,data_index,number_of_observations,no_more_missing_observations);
T3 = etime(clock, instant0);
disp(['univariate_kalman_filter = ' num2str(T2)])
disp(' ')
disp(' ')
if abs(LIK3/LIK2-1)<1e-9
disp('univariate version is Ok')
else
disp('univariate version is wrong')
disp(['percentage dev. = ' num2str((LIK3/LIK2-1)*100)])
end
end