diff --git a/src/DynareBison.yy b/src/DynareBison.yy index fb3a72b2..36df7ca2 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -135,7 +135,7 @@ class ParsingDriver; %token ALPHA_RMSE ALPHA2_RMSE /* end of GSA analysis*/ %token FREQ INITIAL_YEAR INITIAL_SUBPERIOD FINAL_YEAR FINAL_SUBPERIOD DATA VLIST -%token VLISTLOG VLISTPER SPECTRAL_DENSITY +%token VLISTLOG VLISTPER SPECTRAL_DENSITY INIT2SHOCKS %token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST %token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA %token ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET DIAGONAL OPTIMAL @@ -305,6 +305,7 @@ statement : parameters | gmm_estimation | smm_estimation | shock_groups + | init2shocks | det_cond_forecast | var_expectation_model ; @@ -2834,6 +2835,7 @@ plot_shock_decomposition_option : o_use_shock_groups | o_psd_diff | o_psd_flip | o_psd_nograph + | o_psd_init2shocks ; initial_condition_decomposition_options_list : initial_condition_decomposition_option COMMA initial_condition_decomposition_options_list @@ -3089,6 +3091,20 @@ shock_name_list : shock_name_list COMMA symbol {driver.add_shock_group_element($ | symbol {driver.add_shock_group_element($1);} ; +init2shocks : INIT2SHOCKS ';' init2shocks_list END ';' + { driver.end_init2shocks("default"); } + | INIT2SHOCKS '(' NAME EQUAL symbol ')' ';' init2shocks_list END ';' + {driver.end_init2shocks($5);} + ; + +init2shocks_list : init2shocks_list init2shocks_element + | init2shocks_element + ; + +init2shocks_element : symbol symbol ';' { driver.add_init2shocks($1, $2); } + | symbol COMMA symbol ';' { driver.add_init2shocks($1, $3); } + ; + o_dr_algo : DR_ALGO EQUAL INT_NUMBER { if ($3 == "0") driver.warning("dr_algo option is now deprecated, and may be removed in a future version of Dynare"); @@ -3232,6 +3248,9 @@ o_save_realtime : SAVE_REALTIME EQUAL vec_int { driver.option_vec_int("shock_dec o_fast_realtime : FAST_REALTIME EQUAL INT_NUMBER { driver.option_num("shock_decomp.fast_realtime", $3); }; o_nodisplay : NODISPLAY { driver.option_num("nodisplay", "true"); }; o_psd_nodisplay : NODISPLAY { driver.option_num("plot_shock_decomp.nodisplay", "true"); }; +o_psd_init2shocks : INIT2SHOCKS { driver.option_str("plot_shock_decomp.init2shocks", "default"); } + | INIT2SHOCKS EQUAL symbol { driver.option_str("plot_shock_decomp.init2shocks", $3); } + ; o_graph_format : GRAPH_FORMAT EQUAL allowed_graph_formats { driver.process_graph_format_option(); } | GRAPH_FORMAT EQUAL '(' list_allowed_graph_formats ')' diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll index e88ebef1..2d9265db 100644 --- a/src/DynareFlex.ll +++ b/src/DynareFlex.ll @@ -202,6 +202,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2])) histval {BEGIN DYNARE_BLOCK; return token::HISTVAL;} shocks {BEGIN DYNARE_BLOCK; return token::SHOCKS;} shock_groups {BEGIN DYNARE_BLOCK; return token::SHOCK_GROUPS;} +init2shocks {BEGIN DYNARE_BLOCK; return token::INIT2SHOCKS;} mshocks {BEGIN DYNARE_BLOCK; return token::MSHOCKS;} estimated_params {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS;} epilogue {BEGIN DYNARE_BLOCK; return token::EPILOGUE;} @@ -404,6 +405,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2])) use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;} hybrid {return token::HYBRID;} default {return token::DEFAULT;} +init2shocks {return token::INIT2SHOCKS;} number_of_particles {return token::NUMBER_OF_PARTICLES;} resampling {return token::RESAMPLING;} diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 58c1902f..de9b2abb 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -3407,6 +3407,29 @@ ParsingDriver::end_shock_groups(const string &name) shock_groups.clear(); } +void +ParsingDriver::add_init2shocks(const string &endo_name, const string &exo_name) +{ + check_symbol_existence(endo_name); + check_symbol_existence(exo_name); + int symb_id_endo = mod_file->symbol_table.getID(endo_name); + if (mod_file->symbol_table.getType(symb_id_endo) != SymbolType::endogenous) + error("init2shocks: " + endo_name + " should be an endogenous variable"); + + int symb_id_exo = mod_file->symbol_table.getID(exo_name); + if (mod_file->symbol_table.getType(symb_id_exo) != SymbolType::exogenous) + error("init2shocks: " + exo_name + " should be an exogenous variable"); + + init2shocks.push_back(make_pair(symb_id_endo, symb_id_exo)); +} + +void +ParsingDriver::end_init2shocks(const string &name) +{ + mod_file->addStatement(make_unique(init2shocks, name, mod_file->symbol_table)); + init2shocks.clear(); +} + void ParsingDriver::var_expectation_model() { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index c944dc2c..06622d16 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -235,6 +235,8 @@ private: //! Temporary storage for shock_groups vector shock_group; vector shock_groups; + //! Temporary storage for init2shocks + vector> init2shocks; //! Temporary storage for ramsey policy. Workaround for issue #1355 vector ramsey_policy_list; //! reset the values for temporary storage @@ -860,6 +862,10 @@ public: void add_shock_group(string name); //! End shock groups declaration void end_shock_groups(const string &name); + //! Add a set of init2shocks + void add_init2shocks(const string &endo_name, const string &exo_name); + //! End init2shocks declaration + void end_init2shocks(const string &name); //! Add an element to the ramsey policy list void add_to_ramsey_policy_list(string name); void smoother2histval(); diff --git a/src/Shocks.cc b/src/Shocks.cc index 366939d6..33e22781 100644 --- a/src/Shocks.cc +++ b/src/Shocks.cc @@ -686,3 +686,46 @@ ShockGroupsStatement::writeJsonOutput(ostream &output) const } output << "]}"; } + +Init2shocksStatement::Init2shocksStatement(vector> init2shocks_arg, string name_arg, + const SymbolTable &symbol_table_arg) + : init2shocks{move(init2shocks_arg)}, name{move(name_arg)}, symbol_table{symbol_table_arg} +{ +} + +void +Init2shocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +{ + for (size_t i = 0; i < init2shocks.size(); i++) + for (size_t j = i + 1; j < init2shocks.size(); j++) + if (init2shocks.at(i).first == init2shocks.at(j).first) + { + cerr << "Init2shocks(" << name << "): enogenous variable '" + << symbol_table.getName(init2shocks.at(i).first) + << "' appears more than once in the init2shocks statement" << endl; + exit(EXIT_FAILURE); + } +} + +void +Init2shocksStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const +{ + output << "M_.init2shocks." << name << " = {" << endl; + for (auto & it : init2shocks) + output << "{'" << symbol_table.getName(it.first) << "', '" << symbol_table.getName(it.second) << "'};" << endl; + output << "};" << endl; +} + +void +Init2shocksStatement::writeJsonOutput(ostream &output) const +{ + output << R"({"statementName": "init2shocks", "name": ")" << name << R"(", "groups": [)"; + for (auto & it : init2shocks) + { + if (it != *(init2shocks.begin())) + output << ","; + output << R"({"endogenous": ")" << symbol_table.getName(it.first) << R"(", )" + << R"( "exogenous": ")" << symbol_table.getName(it.second) << R"("})"; + } + output << "]}"; +} diff --git a/src/Shocks.hh b/src/Shocks.hh index d4caad0a..38ffb8b8 100644 --- a/src/Shocks.hh +++ b/src/Shocks.hh @@ -167,4 +167,17 @@ public: void writeJsonOutput(ostream &output) const override; }; +class Init2shocksStatement : public Statement +{ +private: + const vector> init2shocks; + const string name; + const SymbolTable &symbol_table; +public: + Init2shocksStatement(vector> init2shocks_arg, string name_arg, const SymbolTable &symbol_table_arg); + void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; + void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream &output) const override; +}; + #endif