The “mshocks” block now accepts the “learnt_in=…” option

master
Sébastien Villemot 2023-10-17 14:52:00 -04:00
parent 6ec7f580d5
commit 6af84b8cac
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
5 changed files with 57 additions and 12 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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
}

View File

@ -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>>>;