From d52f13114d10fbe5fd4d263d5d0b9d7cfda787f6 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 6 Oct 2017 14:49:14 +0200 Subject: [PATCH] preprocessor: interface for generate_irfs block. Closes #1531 --- matlab/global_initialization.m | 5 +++ preprocessor/ComputingTasks.cc | 70 ++++++++++++++++++++++++++++++++++ preprocessor/ComputingTasks.hh | 16 ++++++++ preprocessor/DynareBison.yy | 34 +++++++++++++++-- preprocessor/DynareFlex.ll | 3 ++ preprocessor/ParsingDriver.cc | 45 ++++++++++++++++++++++ preprocessor/ParsingDriver.hh | 10 ++++- 7 files changed, 179 insertions(+), 4 deletions(-) diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m index c7ad9d2a5..077ad3795 100644 --- a/matlab/global_initialization.m +++ b/matlab/global_initialization.m @@ -174,6 +174,11 @@ options_.bandpass.indicator = 0; options_.bandpass.passband = [6; 32]; options_.bandpass.K=12; +options_.irf_opt.diagonal_only = 0; +options_.irf_opt.stderr_multiples = 0; +options_.irf_opt.irf_shock_graphtitles = {}; +options_.irf_opt.irf_shocks = []; + % Extended path options % % Set debug flag diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc index 51d623f65..4a0fac839 100644 --- a/preprocessor/ComputingTasks.cc +++ b/preprocessor/ComputingTasks.cc @@ -4489,3 +4489,73 @@ SMMEstimationStatement::writeJsonOutput(ostream &output) const } output << "}"; } + + + +GenerateIRFsStatement::GenerateIRFsStatement(const OptionsList &options_list_arg, + const vector &generate_irf_names_arg, + const generate_irf_elements_t &generate_irf_elements_arg) : + options_list(options_list_arg), + generate_irf_names(generate_irf_names_arg), + generate_irf_elements(generate_irf_elements_arg) +{ +} + +void +GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const +{ + options_list.writeOutput(output); + + if (generate_irf_names.empty()) + { + output << "options_.irf_opt.irf_shock_graphtitles = {};" << endl + << "options_.irf_opt.irf_shocks = [];" << endl; + return; + } + + output << "options_.irf_opt.irf_shock_graphtitles = { "; + for (vector::const_iterator it = generate_irf_names.begin(); + it != generate_irf_names.end(); it++) + output << "'" << *it << "'; "; + output << "};" << endl; + + int idx = 1; + output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, " << generate_irf_elements.size() << ");" << endl; + for (generate_irf_elements_t::const_iterator it = generate_irf_elements.begin(); + it != generate_irf_elements.end(); it++, idx++) + output << "options_.irf_opt.irf_shocks(M_.exo_names == '" << it->first.first << "', " << idx << ") = " + << it->first.second << ";" << endl + << "options_.irf_opt.irf_shocks(M_.exo_names == '" << it->second.first << "', " << idx << ") = " + << it->second.second << ";" << endl; +} + +void +GenerateIRFsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"generate_irfs\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!generate_irf_elements.empty()) + { + size_t n = generate_irf_elements.size(); + size_t idx = 1; + output << ", \"irf_elements\": ["; + for (generate_irf_elements_t::const_iterator it = generate_irf_elements.begin(); + it != generate_irf_elements.end(); it++) + { + output << "{\"name\": \"" << generate_irf_names[idx-1] << "\", " + << "\"exogenous_variable_1\": \"" << it->first.first << "\", " + << "\"exogenous_variable_1_value\": \"" << it->first.second << "\", " + << "\"exogenous_variable_2\": \"" << it->second.first << "\", " + << "\"exogenous_variable_2_value\": \"" << it->second.second << "\"" + << "}"; + if (++idx <= n) + output << ", "; + } + output << "]"; + } + output << "}"; +} diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh index 37132114f..9d16f3063 100644 --- a/preprocessor/ComputingTasks.hh +++ b/preprocessor/ComputingTasks.hh @@ -1107,4 +1107,20 @@ public: virtual void writeJsonOutput(ostream &output) const; }; +class GenerateIRFsStatement : public Statement +{ +public: + typedef vector, pair > > generate_irf_elements_t; +private: + const OptionsList options_list; + const vector generate_irf_names; + const generate_irf_elements_t generate_irf_elements; +public: + GenerateIRFsStatement(const OptionsList &options_list_arg, + const vector & generate_irf_names_arg, + const generate_irf_elements_t &generate_irf_elements_arg); + virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; +}; + #endif diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 2fe510d3a..28bff0827 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -113,9 +113,9 @@ class ParsingDriver; %token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS %token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION %token NAME -%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE +%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY -%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS +%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS STDERR_MULTIPLES DIAGONAL_ONLY %token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION @@ -276,6 +276,7 @@ statement : parameters | external_function | steady_state_model | trend_var + | generate_irfs | log_trend_var | ms_estimation | ms_simulation @@ -2722,6 +2723,32 @@ calib_smoother_option : o_filtered_vars | o_parameter_set ; +generate_irfs : GENERATE_IRFS ';' END ';' + { driver.end_generate_irfs(); } + | GENERATE_IRFS ';' generate_irfs_element_list END ';' + { driver.end_generate_irfs(); } + | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' END ';' + { driver.end_generate_irfs(); } + | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' generate_irfs_element_list END ';' + { driver.end_generate_irfs(); } + ; + +generate_irfs_options_list : generate_irfs_option COMMA generate_irfs_options_list + | generate_irfs_option + ; + +generate_irfs_option : o_stderr_multiples + | o_diagonal_only + ; + +generate_irfs_element_list : generate_irfs_element_list generate_irfs_element + | generate_irfs_element + ; + +generate_irfs_element : NAME COMMA symbol EQUAL signed_number COMMA symbol EQUAL signed_number ';' + { driver.add_generate_irfs_element($1, $3, $5, $7, $9); } + ; + extended_path : EXTENDED_PATH ';' { driver.extended_path(); } | EXTENDED_PATH '(' extended_path_options_list ')' ';' @@ -3113,7 +3140,8 @@ o_bvar_prior_omega : BVAR_PRIOR_OMEGA EQUAL INT_NUMBER { driver.option_num("bvar o_bvar_prior_flat : BVAR_PRIOR_FLAT { driver.option_num("bvar_prior_flat", "1"); }; o_bvar_prior_train : BVAR_PRIOR_TRAIN EQUAL INT_NUMBER { driver.option_num("bvar_prior_train", $3); }; o_bvar_replic : BVAR_REPLIC EQUAL INT_NUMBER { driver.option_num("bvar_replic", $3); }; - +o_stderr_multiples : STDERR_MULTIPLES { driver.option_num("irf_opt.stderr_multiples", "1"); }; +o_diagonal_only : DIAGONAL_ONLY { driver.option_num("irf_opt.diagonal_only", "1"); }; o_number_of_particles : NUMBER_OF_PARTICLES EQUAL INT_NUMBER { driver.option_num("particle.number_of_particles", $3); }; o_resampling : RESAMPLING EQUAL SYSTEMATIC | RESAMPLING EQUAL NONE {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.none", "1"); } diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index c8cbdf063..67f2c1693 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -210,6 +210,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 moment_calibration {BEGIN DYNARE_BLOCK; return token::MOMENT_CALIBRATION;} irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;} ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;} +generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;} /* For the semicolon after an "end" keyword */ ; {return Dynare::parser::token_type (yytext[0]);} @@ -707,6 +708,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;} no_homotopy {return token::NO_HOMOTOPY;} +stderr_multiples {return token::STDERR_MULTIPLES;} +diagonal_only {return token::DIAGONAL_ONLY;} equation {return token::EQUATION;} exclusion {return token::EXCLUSION;} lag {return token::LAG;} diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 41f8be66b..79d07572f 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -580,6 +580,36 @@ ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2) delete name; } +void +ParsingDriver::end_generate_irfs() +{ + mod_file->addStatement(new GenerateIRFsStatement(options_list, generate_irf_names, generate_irf_elements)); + generate_irf_elements.clear(); + generate_irf_names.clear(); + options_list.clear(); +} + +void +ParsingDriver::add_generate_irfs_element(const string *name, string *exo1, string *value1, string *exo2, string *value2) +{ + check_symbol_is_exogenous(exo1); + check_symbol_is_exogenous(exo2); + for (vector::const_iterator it = generate_irf_names.begin(); + it != generate_irf_names.end(); it++) + if (*it == *name) + error("Names in the generate_irfs block must be unique but you entered '" + *name + "' more than once."); + + generate_irf_names.push_back(*name); + generate_irf_elements.push_back(make_pair(make_pair(*exo1, atof(value1->c_str())), + make_pair(*exo2, atof(value2->c_str())))); + + delete name; + delete exo1; + delete exo2; + delete value1; + delete value2; +} + void ParsingDriver::forecast() { @@ -1630,6 +1660,21 @@ ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name) } } +void +ParsingDriver::check_symbol_is_exogenous(string *name) +{ + check_symbol_existence(*name); + int symb_id = mod_file->symbol_table.getID(*name); + switch (mod_file->symbol_table.getType(symb_id)) + { + case eExogenous: + case eExogenousDet: + break; + default: + error(*name + " is not exogenous."); + } +} + void ParsingDriver::set_std_prior(string *name, string *subsample_name) { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index b0f2fb2ba..b136e21c2 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -93,6 +93,9 @@ private: //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't void check_symbol_is_endogenous_or_exogenous(string *name); + //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't + void check_symbol_is_exogenous(string *name); + //! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at //! the end of the model block void check_symbol_existence_in_model_block(const string &name); @@ -196,7 +199,9 @@ private: Ri_TYPE }; SvarRestrictionType svar_restriction_type; - + //! Temporary storage for generate_irf_elements + GenerateIRFsStatement::generate_irf_elements_t generate_irf_elements; + vector generate_irf_names; //! Temporary storage for argument list of external function stack > stack_external_function_args; //! Temporary storage for parameters in joint prior statement @@ -525,6 +530,9 @@ public: void add_lower_cholesky(); //! Svar_Global_Identification_Check Statement void add_svar_global_identification_check(); + //! generate_irfs Block + void end_generate_irfs(); + void add_generate_irfs_element(const string *name, string *exo1, string *value1, string *exo2, string *value2); //! Forecast Statement void forecast(); void set_trends();