when filter is NOT diffuse, allow likelihood to handle violation of constraints in period 1.

silicon
Marco Ratto 2022-11-18 17:36:29 +01:00
parent 6598d615d1
commit a346639020
1 changed files with 77 additions and 49 deletions

View File

@ -105,7 +105,11 @@ if occbin_.status
occbin_options=occbin_.info{4}; occbin_options=occbin_.info{4};
opts_regime.regime_history = occbin_options.opts_simul.init_regime; opts_regime.regime_history = occbin_options.opts_simul.init_regime;
opts_regime.binding_indicator = occbin_options.opts_simul.init_binding_indicator; opts_regime.binding_indicator = occbin_options.opts_simul.init_binding_indicator;
first_period_occbin_update = max(t+1,options_.occbin.likelihood.first_period_occbin_update); if t>1
first_period_occbin_update = max(t+1,options_.occbin.likelihood.first_period_occbin_update);
else
first_period_occbin_update = options_.occbin.likelihood.first_period_occbin_update;
end
if isempty(opts_regime.binding_indicator) && isempty(opts_regime.regime_history) if isempty(opts_regime.binding_indicator) && isempty(opts_regime.regime_history)
opts_regime.binding_indicator=zeros(last+2,M_.occbin.constraint_nbr); opts_regime.binding_indicator=zeros(last+2,M_.occbin.constraint_nbr);
end end
@ -123,8 +127,8 @@ if occbin_.status
TT=repmat(T,1,1,last+1); TT=repmat(T,1,1,last+1);
RR=repmat(R,1,1,last+1); RR=repmat(R,1,1,last+1);
CC=repmat(zeros(mm,1),1,last+1); CC=repmat(zeros(mm,1),1,last+1);
end end
end end
else else
first_period_occbin_update = inf; first_period_occbin_update = inf;
@ -142,6 +146,10 @@ while notsteady && t<=last
QQ = R*Q*transpose(R); % Variance of R times the vector of structural innovations. QQ = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
end end
end end
if t==1
Pinit = P1(:,:,1);
ainit = a1(:,1);
end
s = t-start+1; s = t-start+1;
d_index = data_index{t}; d_index = data_index{t};
if isqvec if isqvec
@ -178,61 +186,81 @@ while notsteady && t<=last
% badly_conditioned_F = true; % badly_conditioned_F = true;
end end
end end
if ~occbin_.status || (occbin_.status && (options_.occbin.likelihood.use_updated_regime==0 || t<first_period_occbin_update)) if badly_conditioned_F && (~occbin_.status || (occbin_.status && t<first_period_occbin_update))
if badly_conditioned_F && (~occbin_.status || (occbin_.status && t<first_period_occbin_update)) if ~all(abs(F(:))<kalman_tol)
if ~all(abs(F(:))<kalman_tol) % Use univariate filter.
% Use univariate filter. return
return
else
% Pathological case, discard draw
return
end
else else
F_singular = false; % Pathological case, discard draw
if rescale_prediction_error_covariance return
log_dF = log(det(F./(sig*sig')))+2*sum(log(sig)); end
iF = inv(F./(sig*sig'))./(sig*sig'); else
rescale_prediction_error_covariance=rescale_prediction_error_covariance0; F_singular = false;
else end
log_dF = log(det(F)); if ~occbin_.status || (occbin_.status && (options_.occbin.likelihood.use_updated_regime==0 || t<first_period_occbin_update))
iF = inv(F); if rescale_prediction_error_covariance
end log_dF = log(det(F./(sig*sig')))+2*sum(log(sig));
lik(s) = log_dF + transpose(v)*iF*v + length(d_index)*log(2*pi); iF = inv(F./(sig*sig'))./(sig*sig');
if t<first_period_occbin_update rescale_prediction_error_covariance=rescale_prediction_error_covariance0;
if Zflag else
K = P*z'*iF; log_dF = log(det(F));
if occbin_.status iF = inv(F);
P0(:,:,t) = (P-K*z*P); end
end lik(s) = log_dF + transpose(v)*iF*v + length(d_index)*log(2*pi);
if t<first_period_occbin_update
P = T*(P-K*z*P)*transpose(T)+QQ; if Zflag
else K = P*z'*iF;
K = P(:,z)*iF;
if occbin_.status
P0(:,:,t) = (P-K*P(z,:));
end
P = T*(P-K*P(z,:))*transpose(T)+QQ;
end
if occbin_.status if occbin_.status
a0(:,t) = (a+K*v); P0(:,:,t) = (P-K*z*P);
vv(d_index,t) = v;
end end
a = T*(a+K*v)+C;
if t>=no_more_missing_observations && ~isqvec && ~occbin_.status P = T*(P-K*z*P)*transpose(T)+QQ;
notsteady = max(abs(K(:)-oldK))>riccati_tol; else
oldK = K(:); K = P(:,z)*iF;
if occbin_.status
P0(:,:,t) = (P-K*P(z,:));
end end
P = T*(P-K*P(z,:))*transpose(T)+QQ;
end
if occbin_.status
a0(:,t) = (a+K*v);
vv(d_index,t) = v;
end
a = T*(a+K*v)+C;
if t>=no_more_missing_observations && ~isqvec && ~occbin_.status
notsteady = max(abs(K(:)-oldK))>riccati_tol;
oldK = K(:);
end end
end end
end end
end end
if occbin_.status && t>=first_period_occbin_update if occbin_.status && t>=first_period_occbin_update
if isqvec
Qt = Qvec(:,:,t-1:t+1);
end
occbin_options.opts_simul.waitbar=0; occbin_options.opts_simul.waitbar=0;
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regimes_(t:t+2), info, M_, likx] = occbin.kalman_update_algo_1(a0(:,t-1),a1(:,t-1:t),P0(:,:,t-1),P1(:,:,t-1:t),data_index(t-1:t),Z,vv(:,t-1:t),Y(:,t-1:t),H,Qt,T0,R0,TT(:,:,t-1:t),RR(:,:,t-1:t),CC(:,t-1:t),regimes_(t:t+1),M_,oo_,options_,occbin_options); if t==1
if isqvec
Qt = cat(3,Q,Qvec(:,:,t:t+1));
end
a00 = ainit;
a10 = [a00 a(:,1)];
P00 = Pinit;
P10 = P1(:,:,[1 1]);
data_index0{1}=[];
data_index0(2)=data_index(1);
v0(:,2)=vv(:,1);
Y0(:,2)=Y(:,1);
Y0(:,1)=nan;
TT01 = cat(3,T,TT(:,:,1));
RR01 = cat(3,R,RR(:,:,1));
CC01 = zeros(size(CC,1),2);
CC01(:,2) = CC(:,1);
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regimes_(t:t+2), info, M_, likx] = occbin.kalman_update_algo_1(a00, a10, P00, P10, data_index0, Z, v0, Y0, H, Qt, T0, R0, TT01, RR01, CC01, regimes_(t:t+1), M_, oo_, options_, occbin_options);
else
if isqvec
Qt = Qvec(:,:,t-1:t+1);
end
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regimes_(t:t+2), info, M_, likx] = occbin.kalman_update_algo_1(a0(:,t-1),a1(:,t-1:t),P0(:,:,t-1),P1(:,:,t-1:t),data_index(t-1:t),Z,vv(:,t-1:t),Y(:,t-1:t),H,Qt,T0,R0,TT(:,:,t-1:t),RR(:,:,t-1:t),CC(:,t-1:t),regimes_(t:t+1),M_,oo_,options_,occbin_options);
end
if info if info
if options_.debug if options_.debug
fprintf('\nmissing_observations_kalman_filter:PKF failed with: %s\n', get_error_message(info,options_)); fprintf('\nmissing_observations_kalman_filter:PKF failed with: %s\n', get_error_message(info,options_));
@ -252,7 +280,7 @@ while notsteady && t<=last
P0(:,:,t) = Px(:,:,1); P0(:,:,t) = Px(:,:,1);
P1(:,:,t) = P1x(:,:,2); P1(:,:,t) = P1x(:,:,2);
P = Px(:,:,2); P = Px(:,:,2);
end end
t = t+1; t = t+1;
end end