From 3faaffacc6dc2ca7792b2d2e3b5dfc9d3261dc59 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Sat, 9 Dec 2023 17:46:38 +0100 Subject: [PATCH] perfect foresight: remove globals --- matlab/+gui/+perfect_foresight/run.m | 8 ++--- .../det_cond_forecast.m | 4 +-- .../perfect_foresight_setup.m | 10 +++--- .../perfect_foresight_solver.m | 33 ++++++++++--------- ..._foresight_with_expectation_errors_setup.m | 11 +++++-- ...foresight_with_expectation_errors_solver.m | 24 ++++++-------- 6 files changed, 47 insertions(+), 43 deletions(-) diff --git a/matlab/+gui/+perfect_foresight/run.m b/matlab/+gui/+perfect_foresight/run.m index 2a817effc..9b4b22c72 100644 --- a/matlab/+gui/+perfect_foresight/run.m +++ b/matlab/+gui/+perfect_foresight/run.m @@ -142,11 +142,11 @@ mapkeys = unique(cell2mat([keys(unanticipated_p_shocks) keys(unanticipated_t_sho %% Simulation options_.periods = jm.periods; -perfect_foresight_setup; +oo_=perfect_foresight_setup(M_, options_, oo_); % no surprise shocks present if isempty(mapkeys) - perfect_foresight_solver; + oo_=perfect_foresight_solver(M_, options_, oo_); return end @@ -161,7 +161,7 @@ end if mapkeys(1) ~= 1 % if first unanticipated shock is not in period 1 % simulate until first unanticipated shock and save - perfect_foresight_solver; + oo_=perfect_foresight_solver(M_, options_, oo_); yy = [yy oo_.endo_simul(:, 2:mapkeys(1)+1)]; end @@ -203,7 +203,7 @@ for i = 1:length(mapkeys) last_period = this_period; assert(rows(oo_.exo_simul) == oo_exo_simul_rows, 'error encountered setting oo_.exo_simul'); oo_.endo_simul(:, 1) = yy(:, end); - perfect_foresight_solver; + oo_=perfect_foresight_solver(M_, options_, oo_); if next_period > 0 yy = [yy oo_.endo_simul(:, 2:next_period-this_period+1)]; else diff --git a/matlab/perfect-foresight-models/det_cond_forecast.m b/matlab/perfect-foresight-models/det_cond_forecast.m index 89b723e05..b7468e135 100644 --- a/matlab/perfect-foresight-models/det_cond_forecast.m +++ b/matlab/perfect-foresight-models/det_cond_forecast.m @@ -679,8 +679,8 @@ else not_achieved = 1; alpha = 1; while not_achieved - perfect_foresight_setup; - perfect_foresight_solver; + oo_=perfect_foresight_setup(M_, options_, oo_); + oo_=perfect_foresight_solver(M_, options_, oo_); result = sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint)))) == ny * length(time_index_constraint); if (~oo_.deterministic_simulation.status || ~result) && it > 1 not_achieved = 1; diff --git a/matlab/perfect-foresight-models/perfect_foresight_setup.m b/matlab/perfect-foresight-models/perfect_foresight_setup.m index f187b9dc2..cf943d001 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_setup.m +++ b/matlab/perfect-foresight-models/perfect_foresight_setup.m @@ -1,11 +1,13 @@ -function perfect_foresight_setup() +function oo_=perfect_foresight_setup(M_, options_, oo_) % Prepares a deterministic simulation, by filling oo_.exo_simul and oo_.endo_simul % % INPUTS -% None +% M_ [structure] describing the model +% options_ [structure] describing the options +% oo_ [structure] storing the results % % OUTPUTS -% none +% oo_ [structure] storing the results % % ALGORITHM % @@ -29,8 +31,6 @@ function perfect_foresight_setup() % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -global M_ options_ oo_ - test_for_deep_parameters_calibration(M_); if size(M_.lead_lag_incidence,2)-nnz(M_.lead_lag_incidence(M_.maximum_endo_lag+1,:)) > 0 diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m index 42c8a190b..aa1802ec3 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_solver.m +++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m @@ -1,7 +1,10 @@ -function perfect_foresight_solver(no_error_if_learnt_in_is_present, marginal_linearization_previous_raw_sims) +function oo_=perfect_foresight_solver(M_, options_, oo_, no_error_if_learnt_in_is_present, marginal_linearization_previous_raw_sims) % Computes deterministic simulations % % INPUTS +% M_ [structure] describing the model +% options_ [structure] describing the options +% oo_ [structure] storing the results % no_error_if_learnt_in_is_present [boolean, optional] % if true, then do not error out if a shocks(learnt_in=…) or endval(learnt_in=…) % block is present @@ -12,7 +15,7 @@ function perfect_foresight_solver(no_error_if_learnt_in_is_present, marginal_lin % linearization % % OUTPUTS -% none +% oo_ [structure] storing the results % % ALGORITHM % @@ -36,14 +39,12 @@ function perfect_foresight_solver(no_error_if_learnt_in_is_present, marginal_lin % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -global M_ options_ oo_ - check_input_arguments(options_, M_, oo_); -if nargin < 1 +if nargin < 4 no_error_if_learnt_in_is_present = false; end -if nargin < 2 +if nargin < 5 marginal_linearization_previous_raw_sims = []; end if (~isempty(M_.learnt_shocks) || ~isempty(M_.learnt_endval)) && ~no_error_if_learnt_in_is_present @@ -148,7 +149,7 @@ else endoorig = marginal_linearization_previous_raw_sims.sim1.endo_simul; exoorig = marginal_linearization_previous_raw_sims.sim1.exo_simul; end -[completed_share, endo_simul, exo_simul, steady_state, exo_steady_state, iteration, maxerror, solver_iter, per_block_status] = homotopy_loop(options_.simul.homotopy_max_completion_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, oo_.steady_state, oo_.exo_steady_state); +[completed_share, endo_simul, exo_simul, steady_state, exo_steady_state, iteration, maxerror, solver_iter, per_block_status] = homotopy_loop(M_,options_,oo_,options_.simul.homotopy_max_completion_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, oo_.steady_state, oo_.exo_steady_state); % Do linearization if needed and requested, and put results and solver status information in oo_ if completed_share == 1 @@ -208,7 +209,7 @@ elseif options_.simul.homotopy_marginal_linearization_fallback > 0 && completed_ fprintf('%s\n\n', repmat('*', 1, 80)) end extra_simul_time_counter = tic; - [extra_success, extra_endo_simul, extra_exo_simul, extra_steady_state, extra_exo_steady_state] = create_scenario(extra_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state); + [extra_success, extra_endo_simul, extra_exo_simul, extra_steady_state, extra_exo_steady_state] = create_scenario(M_,options_,oo_,extra_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state); if extra_success [extra_endo_simul, extra_success] = perfect_foresight_solver_core(extra_endo_simul, extra_exo_simul, extra_steady_state, extra_exo_steady_state, M_, options_); end @@ -217,7 +218,7 @@ elseif options_.simul.homotopy_marginal_linearization_fallback > 0 && completed_ fprintf('The extra simulation for %.1f%% of the shock did not run when using the first simulation as a guess value. Now trying a full homotopy loop to get that extra simulation working\n\n', extra_share*100) fprintf('%s\n\n', repmat('*', 1, 80)) end - [extra_completed_share, extra_endo_simul, extra_exo_simul, extra_steady_state, extra_exo_steady_state] = homotopy_loop(extra_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, oo_.steady_state, oo_.exo_steady_state); + [extra_completed_share, extra_endo_simul, extra_exo_simul, extra_steady_state, extra_exo_steady_state] = homotopy_loop(M_,options_,oo_,extra_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, oo_.steady_state, oo_.exo_steady_state); extra_success = (extra_completed_share == extra_share); end extra_simul_time_elapsed = toc(extra_simul_time_counter); @@ -294,8 +295,10 @@ assignin('base', 'Simulated_time_series', ts); oo_.gui.ran_perfect_foresight = oo_.deterministic_simulation.status; -function [completed_share, endo_simul, exo_simul, steady_state, exo_steady_state, iteration, maxerror, solver_iter, per_block_status] = homotopy_loop(max_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, steady_state, exo_steady_state) +function [completed_share, endo_simul, exo_simul, steady_state, exo_steady_state, iteration, maxerror, solver_iter, per_block_status] = homotopy_loop(M_,options_,oo_,max_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, simperiods, lastperiods, recompute_final_steady_state, steady_state, exo_steady_state) % INPUTS +% M_ [structure] describing the model +% options_ [structure] describing the options % share [double] the share of the shock that we want to simulate % simperiods [vector] period indices of simulation periods (between initial and terminal conditions) % endoorig [matrix] path of endogenous corresponding to 100% of the shock (also possibly used as guess value for first iteration if relevant) @@ -312,7 +315,6 @@ function [completed_share, endo_simul, exo_simul, steady_state, exo_steady_state % solver_iter [integer] corresponds to iter as returned by perfect_foresight_solver_core % per_block_status [struct] as returned by perfect_foresight_solver_core -global M_ options_ completed_share = 0; % Share of shock successfully completed so far step = min(options_.simul.homotopy_initial_step_size, max_share); @@ -336,7 +338,7 @@ while step > options_.simul.homotopy_min_step_size iter_time_counter = tic; - [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state] = create_scenario(new_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state); + [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state] = create_scenario(M_,options_,oo_,new_share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state); if steady_success % At the first iteration, use the initial guess given by @@ -431,12 +433,15 @@ end fprintf('\n') -function [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state] = create_scenario(share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state) +function [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state] = create_scenario(M_,options_,oo_,share, shareorig, endoorig, exoorig, endobase, exobase, initperiods, lastperiods, recompute_final_steady_state, endo_simul, steady_state, exo_steady_state) % For a given share, comutes the exogenous path and also the initial and % terminal conditions for the endogenous path (but do not modify the initial % guess for endogenous) % % INPUTS +% M_ [structure] describing the model +% options_ [structure] describing the options +% oo_ [structure] storing the results % share [double] the share of the shock that we want to simulate % shareorig [double] the share to which endoorig and exoorig correspond (typically 100%, except for perfect_foresight_with_expectation_errors_solver with homotopy and marginal linearization) % endoorig [matrix] path of endogenous corresponding to shareorig of the shock (only initial and terminal conditions are used) @@ -457,8 +462,6 @@ function [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state] % steady_state [vector] steady state of endogenous corresponding to the scenario (equal to the input if terminal steady state not recomputed) % exo_steady_state [vector] steady state of exogenous corresponding to the scenario (equal to the input if terminal steady state not recomputed) -global M_ options_ oo_ - % Compute convex combination for the path of exogenous exo_simul = exoorig*share/shareorig + exobase*(1-share); diff --git a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m index 86752ec1c..8074e7beb 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m +++ b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m @@ -1,4 +1,11 @@ -function perfect_foresight_with_expectation_errors_setup +function oo_=perfect_foresight_with_expectation_errors_setup(M_, options_, oo_) +% INPUTS +% M_ [structure] describing the model +% options_ [structure] describing the options +% oo_ [structure] storing the results +% +% OUTPUTS +% oo_ [structure] storing the results % Copyright © 2021-2023 Dynare Team % @@ -17,8 +24,6 @@ function perfect_foresight_with_expectation_errors_setup % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -global M_ oo_ options_ - if ~isempty(M_.endo_histval) error('perfect_foresight_with_expectation_errors_setup: cannot be used in conjunction with histval') end diff --git a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m index 19b3a7211..a7b63bfd5 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m +++ b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_solver.m @@ -1,4 +1,11 @@ -function perfect_foresight_with_expectation_errors_solver +function oo_=perfect_foresight_with_expectation_errors_solver(M_, options_, oo_) +% INPUTS +% M_ [structure] describing the model +% options_ [structure] describing the options +% oo_ [structure] storing the results +% +% OUTPUTS +% oo_ [structure] storing the results % Copyright © 2021-2023 Dynare Team % @@ -17,15 +24,9 @@ function perfect_foresight_with_expectation_errors_solver % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -global M_ oo_ options_ - % Same for periods (it will be modified before calling perfect_foresight_solver if constants_simulation_length option is false) periods = options_.periods; -% Save some options -orig_homotopy_max_completion_share = options_.simul.homotopy_max_completion_share; -orig_endval_steady = options_.simul.endval_steady; - % Retrieve initial paths built by pfwee_setup % (the versions in oo_ will be truncated before calling perfect_foresight_solver) endo_simul = oo_.endo_simul; @@ -78,7 +79,7 @@ while info_period <= periods marginal_linearization_previous_raw_sims = []; end - perfect_foresight_solver(true, marginal_linearization_previous_raw_sims); + oo_= perfect_foresight_solver(M_, options_, oo_, true, marginal_linearization_previous_raw_sims); if ~oo_.deterministic_simulation.status error('perfect_foresight_with_expectation_errors_solver: failed to compute solution for information available at period %d\n', info_period) @@ -106,9 +107,4 @@ end % Set final paths oo_.endo_simul = endo_simul; -oo_.exo_simul = exo_simul; - -% Restore some options -options_.periods = periods; -options_.simul.homotopy_max_completion_share = orig_homotopy_max_completion_share; -options_.simul.endval_steady = orig_endval_steady; +oo_.exo_simul = exo_simul; \ No newline at end of file