From 3eedbbf1ae859aaa96805daf6fe3ad3f251b3751 Mon Sep 17 00:00:00 2001 From: Marco Ratto <marco.ratto@ec.europa.eu> Date: Mon, 26 Aug 2024 15:57:35 +0200 Subject: [PATCH] better handling errors in occbin update step (cherry picked from commit 5ad067f1eebd6647e7976cdff9944594df0a4e9a) --- matlab/+occbin/kalman_update_algo_1.m | 18 ++++++++++++++---- matlab/+occbin/kalman_update_algo_3.m | 2 +- matlab/+occbin/kalman_update_engine.m | 9 +++++++++ matlab/get_error_message.m | 10 ++++++++++ .../missing_observations_kalman_filter.m | 6 ------ 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/matlab/+occbin/kalman_update_algo_1.m b/matlab/+occbin/kalman_update_algo_1.m index 11205e63e0..83cbd587ba 100644 --- a/matlab/+occbin/kalman_update_algo_1.m +++ b/matlab/+occbin/kalman_update_algo_1.m @@ -213,7 +213,12 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1)) if M_.occbin.constraint_nbr==1 regime_end(niter) = regimes_(1).regimestart(end); end - [a, a1, P, P1, v, alphahat, etahat, lik, V] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance); + [a, a1, P, P1, v, alphahat, etahat, lik, V, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance); + if error_flag + etahat=NaN(size(QQQ,1),1); + warning(orig_warning_state); + return; + end etahat_hist(niter) = {etahat}; lik_hist(niter) = lik; opts_simul.SHOCKS(1,:) = etahat(:,2)'; @@ -278,7 +283,12 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1)) TT(:,:,2)=ss.T(my_order_var,my_order_var,1); RR(:,:,2)=ss.R(my_order_var,:,1); CC(:,2)=ss.C(my_order_var,1); - [a, a1, P, P1, v, alphahat, etahat, lik, V] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance); + [a, a1, P, P1, v, alphahat, etahat, lik, V, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance); + if error_flag + etahat=NaN(size(QQQ,1),1); + warning(orig_warning_state); + return; + end end else error_flag = 330; @@ -294,7 +304,7 @@ end error_flag = out.error_flag; if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) - error_flag = 1; + error_flag = 331; end if ~error_flag @@ -357,7 +367,7 @@ else F = ZZ*P(:,:,t)*ZZ' + H(di,di); sig=sqrt(diag(F)); if any(any(isnan(F))) - error_flag=1; + error_flag=325; warning(orig_warning_state); return; end diff --git a/matlab/+occbin/kalman_update_algo_3.m b/matlab/+occbin/kalman_update_algo_3.m index 457c474806..efffc9badb 100644 --- a/matlab/+occbin/kalman_update_algo_3.m +++ b/matlab/+occbin/kalman_update_algo_3.m @@ -282,7 +282,7 @@ end error_flag = out.error_flag; if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) %fixed point algorithm did not converge - error_flag = 1; + error_flag = 331; end if ~error_flag diff --git a/matlab/+occbin/kalman_update_engine.m b/matlab/+occbin/kalman_update_engine.m index fe2346436a..92c13d72e1 100644 --- a/matlab/+occbin/kalman_update_engine.m +++ b/matlab/+occbin/kalman_update_engine.m @@ -328,4 +328,13 @@ if options_.occbin.likelihood.loss_function_regime_guess && (info0 || info1) %|| end end end + +if info(1)==0 + if isnan(likx) + info = 323; + elseif any(any(isnan(ax))) + info = 324; + end +end + end diff --git a/matlab/get_error_message.m b/matlab/get_error_message.m index 1694dde4e2..f15f8c34a7 100644 --- a/matlab/get_error_message.m +++ b/matlab/get_error_message.m @@ -198,6 +198,16 @@ switch info(1) message = 'Occbin: there was a problem in running the smoother. Simulation within smoother failed.'; case 322 message = 'Occbin: smoother did not converge.'; + case 323 + message = 'Piecewise linear Kalman filter: the likelihood is NaN.'; + case 324 + message = 'Piecewise linear Kalman filter: updated state vector is NaN.'; + case 325 + message = 'Piecewise linear Kalman filter: filter covariance NaN.'; + case 330 + message = 'Piecewise linear Kalman filter: update step did not reach a fixed point (periodic loop).'; + case 331 + message = 'Piecewise linear Kalman filter: update step did not reach a fixed point (max number of iterations reached).'; case 401 message = 'Cycle reduction reached the iteration limit. Try increasing maxit.'; case 402 diff --git a/matlab/kalman/likelihood/missing_observations_kalman_filter.m b/matlab/kalman/likelihood/missing_observations_kalman_filter.m index adfdda7652..67b3adf614 100644 --- a/matlab/kalman/likelihood/missing_observations_kalman_filter.m +++ b/matlab/kalman/likelihood/missing_observations_kalman_filter.m @@ -276,12 +276,6 @@ while notsteady && t<=last [ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regx, info, M_, likx] = occbin.kalman_update_engine(a0(:,t-1),a1(:,t-1:t),P0(:,:,t-1),P1(:,:,t-1:t),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),base_regime,d_index,M_,dr, endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options); % [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_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options); end - if isnan(likx) || any(any(isnan(ax))) - if options_.debug - fprintf('\nmissing_observations_kalman_filter:PKF failed in period %u with: NaN in likelihood value\n', t); - end - return - end if info if options_.debug fprintf('\nmissing_observations_kalman_filter:PKF failed in period %u with: %s\n', t, get_error_message(info,options_)); -- GitLab