From 3f907efbcdfde9a2c6a565fb16917bc14d08985e Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Sun, 2 Oct 2016 12:54:36 +0200 Subject: [PATCH 1/3] initial_estimation_checks.m: Add proper check for stochastic singularity --- matlab/initial_estimation_checks.m | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/matlab/initial_estimation_checks.m b/matlab/initial_estimation_checks.m index 967390309..819b72cd2 100644 --- a/matlab/initial_estimation_checks.m +++ b/matlab/initial_estimation_checks.m @@ -130,7 +130,19 @@ ana_deriv = DynareOptions.analytic_derivation; DynareOptions.analytic_derivation=0; if ~isequal(DynareOptions.mode_compute,11) || ... (isequal(DynareOptions.mode_compute,11) && isequal(DynareOptions.order,1)) - [fval,info] = feval(objective_function,xparam1,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults); + %shut off potentially automatic switch to diffuse filter for the + %purpose of checking stochastic singularity + use_univariate_filters_if_singularity_is_detected_old=DynareOptions.use_univariate_filters_if_singularity_is_detected; + DynareOptions.use_univariate_filters_if_singularity_is_detected=0; + [fval,info] = feval(objective_function,xparam1,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults); + if info(1)==50 + fprintf('\ninitial_estimation_checks:: The forecast error variance in the multivariate Kalman filter became singular.\n') + fprintf('initial_estimation_checks:: This is often a sign of stochastic singularity, but can also sometimes happen by chance\n') + fprintf('initial_estimation_checks:: for a particular combination of parameters and data realizations.\n') + error('initial_estimation_checks:: The forecast error variance in the multivariate Kalman filter became singular.') + end + %reset options + DynareOptions.use_univariate_filters_if_singularity_is_detected=use_univariate_filters_if_singularity_is_detected_old; else info=0; fval = 0; From 1da488db527a25b7091d327c3fc37b0120ddfda9 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Sun, 2 Oct 2016 12:56:04 +0200 Subject: [PATCH 2/3] Add test case for stochastic singularity --- tests/Makefile.am | 1 + .../fs2000_stochastic_singularity_xfail.mod | 76 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tests/estimation/fs2000_stochastic_singularity_xfail.mod diff --git a/tests/Makefile.am b/tests/Makefile.am index 674904a42..071ca2782 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -328,6 +328,7 @@ XFAIL_MODFILES = ramst_xfail.mod \ estim_param_in_shock_value_xfail.mod \ optimal_policy/Ramsey/ramsey_ex_wrong_ss_file_xfail.mod \ estimation/fs2000_mixed_ML_xfail.mod \ + estimation/fs2000_stochastic_singularity_xfail.mod \ identification/ident_unit_root/ident_unit_root_xfail.mod \ steady_state/Linear_steady_state_xfail.mod diff --git a/tests/estimation/fs2000_stochastic_singularity_xfail.mod b/tests/estimation/fs2000_stochastic_singularity_xfail.mod new file mode 100644 index 000000000..cdd977d07 --- /dev/null +++ b/tests/estimation/fs2000_stochastic_singularity_xfail.mod @@ -0,0 +1,76 @@ +// See fs2000.mod in the examples/ directory for details on the model + +var m P c e W R k d n l gy_obs gp_obs y dA; +varexo e_a e_m e_junk; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +dA = exp(gam+e_a); +log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; +-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; +W = l/n; +-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; +R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; +1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; +c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); +P*c = m; +m-1+d = l; +e = exp(e_a); +y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); +gy_obs = dA*y/y(-1) + e_junk; +gp_obs = (P/P(-1))*m(-1)/dA; +end; + +steady_state_model; + dA = exp(gam); + gst = 1/dA; + m = mst; + khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); + xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); + nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); + n = xist/(nust+xist); + P = xist + nust; + k = khst*n; + + l = psi*mst*n/( (1-psi)*(1-n) ); + c = mst/P; + d = l - mst + 1; + y = k^alp*n^(1-alp)*gst^alp; + R = mst/bet; + W = l/n; + ist = y-c; + q = 1 - d; + + e = 1; + + gp_obs = m/dA; + gy_obs = dA; +end; + + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +var e_junk; stderr 0.005; +end; + +stoch_simul(order=1,periods=300,irf=0,nomoments) k y c; +datatomfile('fsdat_simul_collinear', char('k','y','c')); + +estimated_params; +alp, beta_pdf, 0.356, 0.02; +end; + +varobs k y c; + + +estimation(order=1,datafile=fsdat_simul_collinear) y m; From 2fe73fafdc4886053f6871daedfecbe8e7fe8d1c Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Sun, 2 Oct 2016 12:56:28 +0200 Subject: [PATCH 3/3] Implement and document keep_kalman_algo_if_singularity_is_detected option --- doc/dynare.texi | 9 +++++++++ matlab/dsge_likelihood.m | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/dynare.texi b/doc/dynare.texi index 23ddc0de2..ce6e3ab0a 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -6020,6 +6020,15 @@ the option is equal to @code{0}, Dynare will not automatically change the filter, but rather use a penalty value for the likelihood when such a singularity is encountered. Default: @code{1}. +@item keep_kalman_algo_if_singularity_is_detected +@anchor{keep_kalman_algo_if_singularity_is_detected} +With the default @ref{use_univariate_filters_if_singularity_is_detected}=1, Dynare will switch +to the univariate Kalman filter when it encounters a singular forecast error variance +matrix during Kalman filtering. Upon encountering such a singularity for the first time, all subsequent +parameter draws and computations will automatically rely on univariate filter, i.e. Dynare will never try +the multivariate filter again. Use the @code{keep_kalman_algo_if_singularity_is_detected} option to have the +@code{use_univariate_filters_if_singularity_is_detected} only affect the behavior for the current draw/computation. + @item qz_zero_threshold = @var{DOUBLE} @xref{qz_zero_threshold}. diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index 2d3406ed5..3da705c9a 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -894,8 +894,10 @@ if imag(fval)~=0 return end -% Update DynareOptions.kalman_algo. -DynareOptions.kalman_algo = kalman_algo; +if ~DynareOptions.kalman.keep_kalman_algo_if_singularity_is_detected + % Update DynareOptions.kalman_algo. + DynareOptions.kalman_algo = kalman_algo; +end if analytic_derivation==0 && nargout>3, lik=lik(start:end,:);