From 6af84b8cac54777bc97d4bc232452f8cf9b4498c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 17 Oct 2023 14:52:00 -0400 Subject: [PATCH] =?UTF-8?q?The=20=E2=80=9Cmshocks=E2=80=9D=20block=20now?= =?UTF-8?q?=20accepts=20the=20=E2=80=9Clearnt=5Fin=3D=E2=80=A6=E2=80=9D=20?= =?UTF-8?q?option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DynareBison.yy | 3 +++ src/ParsingDriver.cc | 45 ++++++++++++++++++++++++++++++++++++++++---- src/ParsingDriver.hh | 4 +++- src/Shocks.cc | 2 ++ src/Shocks.hh | 15 ++++++++------- 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/DynareBison.yy b/src/DynareBison.yy index 8c29deb7..7e21d57d 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -1282,6 +1282,9 @@ svar_options : o_coefficients mshocks : MSHOCKS ';' mshock_list END ';' { driver.end_mshocks(false); } | MSHOCKS '(' OVERWRITE ')' ';' mshock_list END ';' { driver.end_mshocks(true); } + | MSHOCKS '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' mshock_list END ';' { driver.end_mshocks_learnt_in($5, false); } + | MSHOCKS '(' LEARNT_IN EQUAL INT_NUMBER COMMA OVERWRITE ')' ';' mshock_list END ';' { driver.end_mshocks_learnt_in($5, true); } + | MSHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL INT_NUMBER ')' ';' mshock_list END ';' { driver.end_mshocks_learnt_in($7, true); } ; mshock_list : mshock_list det_shock_elem diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 0cbba3a3..f8ce2cac 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -921,10 +921,11 @@ ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwri end_shocks(overwrite); return; } - for (auto &[symb_id, vals] : det_shocks) - for (auto [period1, period2, expr] : vals) - if (period1 < learnt_in_period_int) - error("shocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")"); + for (auto &storage : { det_shocks, learnt_shocks_add, learnt_shocks_multiply } ) + for (auto &[symb_id, vals] : storage) + for (auto [period1, period2, expr] : vals) + if (period1 < learnt_in_period_int) + error("shocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")"); // Aggregate the three types of shocks ShocksLearntInStatement::learnt_shocks_t learnt_shocks; @@ -958,6 +959,42 @@ ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwri learnt_shocks_multiply.clear(); } +void +ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite) +{ + int learnt_in_period_int = stoi(learnt_in_period); + if (learnt_in_period_int < 1) + error("mshocks: value '" + learnt_in_period + "' is not allowed for 'learnt_in' option"); + if (learnt_in_period_int == 1) + { + end_mshocks(overwrite); + return; + } + + for (auto &[symb_id, vals] : det_shocks) + for (auto [period1, period2, expr] : vals) + if (period1 < learnt_in_period_int) + error("mshocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")"); + + ShocksLearntInStatement::learnt_shocks_t learnt_shocks; + for (const auto &[id, v] : det_shocks) + { + vector<tuple<ShocksLearntInStatement::LearntShockType, int, int, expr_t>> v2; + for (auto [period1, period2, value] : v) + v2.emplace_back(ShocksLearntInStatement::LearntShockType::multiplySteadyState, period1, period2, value); + learnt_shocks[id] = v2; + } + + mod_file->addStatement(make_unique<ShocksLearntInStatement>(learnt_in_period_int, overwrite, + move(learnt_shocks), + mod_file->symbol_table)); + det_shocks.clear(); + if (!learnt_shocks_add.empty()) + error("mshocks: 'add' keyword not allowed"); + if (!learnt_shocks_multiply.empty()) + error("mshocks: 'multiply' keyword not allowed"); +} + void ParsingDriver::end_heteroskedastic_shocks(bool overwrite) { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index d1acbae2..7c6f7144 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -149,7 +149,7 @@ private: //! Temporary storage of covariances from optim_weights OptimWeightsStatement::covar_weights_t covar_weights; /* Temporary storage for deterministic shocks. Also used for - conditional_forecast paths, for shocks(surprise), and shocks(learnt_in=…) + conditional_forecast paths, for mshocks, shocks(surprise) and shocks(learnt_in=…) (for the latter, only used for shocks declared in level through “valuesâ€). */ ShocksStatement::det_shocks_t det_shocks; // Temporary storage for shocks declared with “add†and “multiply†in shocks(learnt_in=…) @@ -452,6 +452,8 @@ public: void end_shocks_surprise(bool overwrite); //! Writes a shocks(learnt_in=…) block void end_shocks_learnt_in(const string &learnt_in_period, bool overwrite); + //! Writes a mshocks(learnt_in=…) block + void end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite); //! Writes a heteroskedastic_shocks statement void end_heteroskedastic_shocks(bool overwrite); /* Adds a deterministic shock, a path element inside a diff --git a/src/Shocks.cc b/src/Shocks.cc index 1204a0d7..3924c1a4 100644 --- a/src/Shocks.cc +++ b/src/Shocks.cc @@ -524,6 +524,8 @@ ShocksLearntInStatement::typeToString(LearntShockType type) return "add"; case LearntShockType::multiply: return "multiply"; + case LearntShockType::multiplySteadyState: + return "multiply_steady_state"; } exit(EXIT_FAILURE); // Silence GCC warning } diff --git a/src/Shocks.hh b/src/Shocks.hh index 01114a16..e5743d02 100644 --- a/src/Shocks.hh +++ b/src/Shocks.hh @@ -106,20 +106,21 @@ public: void writeJsonOutput(ostream &output) const override; }; -/* Represents a shocks(learnt_in=…) block. - Given the differences with the plain “shocks†block, it was easier to make - it a separate class. */ +/* Represents a shocks(learnt_in=…) or mshocks(learnt_in=…) block. + Given the differences with the plain “shocks†and “mshocks†blocks, + it was easier to make it a separate class. */ class ShocksLearntInStatement : public Statement { public: const int learnt_in_period; - //! Does this "shocks(learnt_in=…)" statement replace the previous ones? + //! Does this “shocks(learnt_in=…)†or “mshocks(learnt_in=…)†block replace the previous ones? const bool overwrite; enum class LearntShockType { - level, - add, - multiply + level, // The value is the level of the exogenous (“values†statement in “shocks(learnt_in=…)â€) + add, // The value is the additive change of the exogenous compared to previous information period (“add†statement in “shocks(learnt_in=…)â€) + multiply, // The value is the multiplicative change of the exogenous compared to previous information period (“multiply†statement in “shocks(learnt_in=…)â€) + multiplySteadyState // The value is the ratio of the exogenous over its (terminal) steady state as anticipated in the same informational period (“values†statement in “mshocks(learnt_in=…)â€) }; // The tuple is (type, period1, period2, value) using learnt_shocks_t = map<int, vector<tuple<LearntShockType, int, int, expr_t>>>; -- GitLab