From 2f23604824cfa9a177f5ed1c2bc4018702470d6d Mon Sep 17 00:00:00 2001 From: Marco Ratto <marco.ratto@ec.europa.eu> Date: Fri, 28 Oct 2022 13:02:57 +0200 Subject: [PATCH] new option max_check_ahead_periods (renaming old undocumented option max_periods), that truncates the number of periods for which agents check ahead the regime (a sort of myopic behavior beyond max_check_ahead_periods), the option is valid for simul, smoother and likelihood. --- matlab/+occbin/DSGE_smoother.m | 1 + matlab/+occbin/IVF_core.m | 1 + matlab/+occbin/set_default_options.m | 4 +++- matlab/+occbin/setup.m | 6 +++--- matlab/+occbin/solve_one_constraint.m | 12 ++++++------ matlab/+occbin/solve_two_constraints.m | 26 +++++++++++++++----------- matlab/+occbin/solver.m | 6 ++++++ matlab/dsge_likelihood.m | 1 + 8 files changed, 36 insertions(+), 21 deletions(-) diff --git a/matlab/+occbin/DSGE_smoother.m b/matlab/+occbin/DSGE_smoother.m index 2a5d919d53..386337edae 100644 --- a/matlab/+occbin/DSGE_smoother.m +++ b/matlab/+occbin/DSGE_smoother.m @@ -106,6 +106,7 @@ opts_simul.maxit = options_.occbin.smoother.maxit; opts_simul.waitbar = options_.occbin.smoother.waitbar; opts_simul.periods = options_.occbin.smoother.periods; opts_simul.check_ahead_periods = options_.occbin.smoother.check_ahead_periods; +opts_simul.max_check_ahead_periods = options_.occbin.smoother.max_check_ahead_periods; opts_simul.periodic_solution = options_.occbin.smoother.periodic_solution; opts_simul.full_output = options_.occbin.smoother.full_output; opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only; diff --git a/matlab/+occbin/IVF_core.m b/matlab/+occbin/IVF_core.m index b9e96622bc..efc3f6e844 100644 --- a/matlab/+occbin/IVF_core.m +++ b/matlab/+occbin/IVF_core.m @@ -57,6 +57,7 @@ opts_simul.maxit = options_.occbin.likelihood.maxit; opts_simul.waitbar = false; opts_simul.periods = options_.occbin.likelihood.periods; opts_simul.check_ahead_periods = options_.occbin.likelihood.check_ahead_periods; +opts_simul.max_check_ahead_periods = options_.occbin.likelihood.max_check_ahead_periods; opts_simul.periodic_solution = options_.occbin.likelihood.periodic_solution; opts_simul.restrict_state_space = options_.occbin.likelihood.restrict_state_space; opts_simul.piecewise_only = 1; diff --git a/matlab/+occbin/set_default_options.m b/matlab/+occbin/set_default_options.m index 0b34a2eca8..17e74a3234 100644 --- a/matlab/+occbin/set_default_options.m +++ b/matlab/+occbin/set_default_options.m @@ -76,6 +76,7 @@ if ismember(flag,{'likelihood','all'}) options_occbin_.likelihood.IVF_shock_observable_mapping = []; options_occbin_.likelihood.maxit = 30; % this is for occbin solver algo options_occbin_.likelihood.max_number_of_iterations = 10; % this is for occbin_kalman_update loop + options_occbin_.likelihood.max_check_ahead_periods=inf; options_occbin_.likelihood.periods = 100; options_occbin_.likelihood.check_ahead_periods=200; options_occbin_.likelihood.periodic_solution=false; @@ -170,7 +171,7 @@ if ismember(flag,{'simul','all'}) options_occbin_.simul.init_binding_indicator=false(0); options_occbin_.simul.exo_pos=1:M_.exo_nbr; options_occbin_.simul.maxit=30; - options_occbin_.simul.max_periods=inf; + options_occbin_.simul.max_check_ahead_periods=inf; options_occbin_.simul.periods=100; options_occbin_.simul.check_ahead_periods=200; options_occbin_.simul.periodic_solution=false; @@ -194,6 +195,7 @@ if ismember(flag,{'smoother','all'}) options_occbin_.smoother.inversion_filter = false; options_occbin_.smoother.linear_smoother = true; options_occbin_.smoother.maxit = 30; % this is for occbin solver algo + options_occbin_.smoother.max_check_ahead_periods=inf; options_occbin_.smoother.max_number_of_iterations = 10; % this is for smoother loop options_occbin_.smoother.periods = 100; options_occbin_.smoother.check_ahead_periods=200; diff --git a/matlab/+occbin/setup.m b/matlab/+occbin/setup.m index 7c4749623f..a050ee787b 100644 --- a/matlab/+occbin/setup.m +++ b/matlab/+occbin/setup.m @@ -2,12 +2,12 @@ function [M_, options_] = setup(M_,options_, options_occbin_) % function [M_, options_] = setup(M_, options_, options_occbin_) % Sets up run of Occbin: creates shock matrix, sets options % -% INPUT: +% INPUT: % - M_ [structure] Matlab's structure describing the model % - options_ [structure] Matlab's structure containing the options % - options_occbin_ [structure] Matlab's structure containing Occbin options % -% OUTPUT: +% OUTPUT: % - M_ [structure] Matlab's structure describing the model % - options_occbin_ [structure] Matlab's structure containing Occbin options @@ -55,7 +55,7 @@ if isfield(M_,'surprise_shocks') && ~isempty(M_.surprise_shocks) for ii = 1:length(M_.surprise_shocks) ivar = M_.surprise_shocks(ii).exo_id; temp(M_.surprise_shocks(ii).periods,ivar) = M_.surprise_shocks(ii).value; - end + end shock_index=~all(temp==0,1); options_.occbin.simul.SHOCKS=temp(:,shock_index); options_.occbin.simul.exo_pos=find(shock_index); diff --git a/matlab/+occbin/solve_one_constraint.m b/matlab/+occbin/solve_one_constraint.m index bf44f4ce26..0fa13a1fc0 100644 --- a/matlab/+occbin/solve_one_constraint.m +++ b/matlab/+occbin/solve_one_constraint.m @@ -139,14 +139,14 @@ for shock_period = 1:n_shocks_periods while (regime_change_this_iteration && iter<max_iter && ~is_periodic && ~is_periodic_loop) iter = iter +1; - if binding_indicator(end) && nperiods_0<opts_simul_.max_periods + if binding_indicator(end) && nperiods_0<opts_simul_.max_check_ahead_periods binding_indicator = [binding_indicator; false ]; nperiods_0 = nperiods_0 + 1; nperiods_endogenously_increased = true; disp_verbose(['nperiods has been endogenously increased up to ' int2str(nperiods_0) '.'],opts_simul_.debug) - elseif nperiods_0>=opts_simul_.max_periods - % enforce endogenously increased nperiods to not violate max_periods - binding_indicator = binding_indicator(1:opts_simul_.max_periods+1); + elseif nperiods_0>=opts_simul_.max_check_ahead_periods + % enforce endogenously increased nperiods to not violate max_check_ahead_periods + binding_indicator = binding_indicator(1:opts_simul_.max_check_ahead_periods+1); binding_indicator(end)=false; end if length(binding_indicator)<(nperiods_0 + 1) @@ -192,8 +192,8 @@ for shock_period = 1:n_shocks_periods [binding, relax, err]=feval([M_.fname,'.occbin_difference'],zdatalinear_+repmat(dr_base.ys',size(zdatalinear_,1),1),M_.params,dr_base.ys); - if ~isinf(opts_simul_.max_periods) && opts_simul_.max_periods<length(binding_indicator) - end_periods = opts_simul_.max_periods; + if ~isinf(opts_simul_.max_check_ahead_periods) && opts_simul_.max_check_ahead_periods<length(binding_indicator) + end_periods = opts_simul_.max_check_ahead_periods; else end_periods = length(binding_indicator); end diff --git a/matlab/+occbin/solve_two_constraints.m b/matlab/+occbin/solve_two_constraints.m index 77514f2733..17d83ab59b 100644 --- a/matlab/+occbin/solve_two_constraints.m +++ b/matlab/+occbin/solve_two_constraints.m @@ -147,17 +147,21 @@ for shock_period = 1:n_shocks_periods while (regime_change_this_iteration && iter<max_iter && ~is_periodic && ~is_periodic_loop) iter = iter +1; - if any(binding_indicator(end,:)) && nperiods_0<opts_simul_.max_periods + if any(binding_indicator(end,:)) && nperiods_0<opts_simul_.max_check_ahead_periods binding_indicator = [binding_indicator; false(1,2)]; nperiods_0 = nperiods_0 + 1; nperiods_endogenously_increased = true; disp_verbose(['nperiods has been endogenously increased up to ' int2str(nperiods_0) '.'],opts_simul_.debug) - elseif nperiods_0>=opts_simul_.max_periods - % enforce endogenously increased nperiods to not violate max_periods - binding_indicator = binding_indicator(1:opts_simul_.max_periods+1,:); + elseif nperiods_0>=opts_simul_.max_check_ahead_periods + % enforce endogenously increased nperiods to not violate max_check_ahead_periods + binding_indicator = binding_indicator(1:opts_simul_.max_check_ahead_periods+1,:); binding_indicator(end,:)=false(1,2); end if size(binding_indicator,1)<(nperiods_0 + 1) + % to ensure the simulation is run for the required nperiods + % even beyond max_check_ahead_periods: the latter controls check ahead periods + % and NOT how many periods we simulate after we are back to + % unconstrained regime (nperiods_0) binding_indicator=[binding_indicator; false(nperiods_0 + 1-size(binding_indicator,1),2)]; end binding_indicator_history{iter}=binding_indicator; @@ -210,13 +214,13 @@ for shock_period = 1:n_shocks_periods [binding, relax, err]=feval([M_.fname,'.occbin_difference'],zdatalinear_+repmat(dr.ys',size(zdatalinear_,1),1),M_.params,dr.ys); - if ~isinf(opts_simul_.max_periods) && opts_simul_.max_periods<length(binding_indicator) - end_periods = opts_simul_.max_periods; + if ~isinf(opts_simul_.max_check_ahead_periods) && opts_simul_.max_check_ahead_periods<length(binding_indicator) + end_periods = opts_simul_.max_check_ahead_periods; else end_periods = length(binding_indicator); end - binding_constraint_new=[binding.constraint_1(1:end_periods);binding.constraint_2(1:end_periods)]; - relaxed_constraint_new = [relax.constraint_1(1:end_periods);relax.constraint_2(1:end_periods)]; + binding_constraint_new=[binding.constraint_1(1:end_periods); binding.constraint_2(1:end_periods)]; + relaxed_constraint_new = [relax.constraint_1(1:end_periods); relax.constraint_2(1:end_periods)]; my_binding_indicator = binding_indicator(1:end_periods,:); err_binding_constraint_new = [err.binding_constraint_1(1:end_periods); err.binding_constraint_2(1:end_periods)]; @@ -248,7 +252,7 @@ for shock_period = 1:n_shocks_periods end binding_indicator = (binding_indicator(:) | binding_constraint_new) & ~ retrench; else - binding_indicator= (binding_indicator(:) | binding_constraint_new) & ~(binding_indicator(:) & relaxed_constraint_new); + binding_indicator = (binding_indicator(:) | binding_constraint_new) & ~(binding_indicator(:) & relaxed_constraint_new); end binding_indicator = reshape(binding_indicator,nperiods_0+1,2); @@ -346,8 +350,8 @@ for shock_period = 1:n_shocks_periods disp_verbose('Did not converge -- infinite loop of guess regimes.',opts_simul_.debug) error_flag = 313; else - disp_verbose('Did not converge -- increase maxit.',opts_simul_.debug) - error_flag = 311; + disp_verbose('Did not converge -- increase maxit.',opts_simul_.debug) + error_flag = 311; end if opts_simul_.waitbar; dyn_waitbar_close(hh); end return; diff --git a/matlab/+occbin/solver.m b/matlab/+occbin/solver.m index 2d9be14053..9dd44f88fa 100644 --- a/matlab/+occbin/solver.m +++ b/matlab/+occbin/solver.m @@ -68,6 +68,12 @@ else oo_.dr=sto_dr; end +if options_.occbin.simul.check_ahead_periods>options_.occbin.simul.max_check_ahead_periods + options_.occbin.simul.check_ahead_periods=options_.occbin.simul.max_check_ahead_periods; + disp(['occbin::options::' simul '_check_ahead_periods cannot exceed ' simul '_max_check_ahead_periods']) + disp(['occbin::options::' simul '_check_ahead_periods is re-set to be equal to ' simul '_max_check_ahead_periods']) +end + if M_.occbin.constraint_nbr==1 [out, ss, error_flag ] = occbin.solve_one_constraint(M_,oo_.dr,options_.occbin.simul,solve_dr); elseif M_.occbin.constraint_nbr==2 diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index 72395f1667..e6fcd04f9d 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -976,6 +976,7 @@ occbin_options.opts_simul.curb_retrench = DynareOptions.occbin.likelihood.curb_r occbin_options.opts_simul.maxit = DynareOptions.occbin.likelihood.maxit; occbin_options.opts_simul.periods = DynareOptions.occbin.likelihood.periods; occbin_options.opts_simul.check_ahead_periods = DynareOptions.occbin.likelihood.check_ahead_periods; +occbin_options.opts_simul.max_check_ahead_periods = DynareOptions.occbin.likelihood.max_check_ahead_periods; occbin_options.opts_simul.periodic_solution = DynareOptions.occbin.likelihood.periodic_solution; occbin_options.opts_simul.restrict_state_space = DynareOptions.occbin.likelihood.restrict_state_space; -- GitLab