New option “relative_to_initval” to “mshocks” block

master
Sébastien Villemot 2023-10-18 13:48:45 -04:00
parent f179ec4dac
commit f78c428d99
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
6 changed files with 96 additions and 28 deletions

View File

@ -33,6 +33,13 @@ class ParsingDriver;
}
%code requires {
#include <string>
#include <vector>
#include <map>
#include <utility>
#include <tuple>
#include <variant>
#include "CommonEnums.hh"
#include "ExprNode.hh"
}
@ -196,7 +203,7 @@ class ParsingDriver;
%token ENDVAL_STEADY STEADY_SOLVE_ALGO STEADY_MAXIT STEADY_TOLF STEADY_TOLX STEADY_MARKOWITZ
%token HOMOTOPY_MAX_COMPLETION_SHARE HOMOTOPY_MIN_STEP_SIZE HOMOTOPY_INITIAL_STEP_SIZE HOMOTOPY_STEP_SIZE_INCREASE_SUCCESS_COUNT
%token HOMOTOPY_LINEARIZATION_FALLBACK HOMOTOPY_MARGINAL_LINEARIZATION_FALLBACK FROM_INITVAL_TO_ENDVAL
%token STATIC_MFS
%token STATIC_MFS RELATIVE_TO_INITVAL
%token <vector<string>> SYMBOL_VEC
@ -228,6 +235,8 @@ class ParsingDriver;
%type <pair<string, expr_t>> occbin_constraints_regime_option
%type <PacTargetKind> pac_target_kind
%type <vector<tuple<string, string, vector<pair<string, string>>>>> symbol_list_with_tex_and_partition
%type <map<string, variant<bool, string>>> mshocks_options_list
%type <pair<string, variant<bool, string>>> mshocks_option
%%
%start statement_list;
@ -1280,13 +1289,39 @@ svar_options : o_coefficients
| o_chain
;
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); }
mshocks : MSHOCKS ';' mshock_list END ';'
{ driver.end_mshocks(false, false); }
| MSHOCKS '(' mshocks_options_list ')' ';' mshock_list END ';'
{
/* NB: the following relies of the fact that bool is the first
alternative in the variant, so that default initialization of the
variant by the [] operator will give false */
if ($3.contains("learnt_in"))
driver.end_mshocks_learnt_in(get<string>($3.at("learnt_in")), get<bool>($3["overwrite"]), get<bool>($3["relative_to_initval"]));
else
driver.end_mshocks(get<bool>($3["overwrite"]), get<bool>($3["relative_to_initval"]));
}
;
mshocks_options_list : mshocks_option
{ $$ = { $1 }; }
| mshocks_options_list mshocks_option
{
$$ = $1;
auto [it, success] = $$.insert($2);
if (!success)
driver.error("The '" + $2.first + "' option is declared multiple times");
}
;
mshocks_option : OVERWRITE
{ $$ = { "overwrite", true }; }
| LEARNT_IN EQUAL INT_NUMBER
{ $$ = { "learnt_in", $3 }; }
| RELATIVE_TO_INITVAL
{ $$ = { "relative_to_initval", true }; }
;
mshock_list : mshock_list det_shock_elem
| det_shock_elem
;

View File

@ -829,6 +829,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
yylval->build<string>(yytext);
return token::ERROR_RELAX;
}
<DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;}
<DYNARE_BLOCK>; {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_BLOCK># {return Dynare::parser::token_type (yytext[0]);}

View File

@ -887,9 +887,10 @@ ParsingDriver::end_shocks(bool overwrite)
}
void
ParsingDriver::end_mshocks(bool overwrite)
ParsingDriver::end_mshocks(bool overwrite, bool relative_to_initval)
{
mod_file->addStatement(make_unique<MShocksStatement>(overwrite, move(det_shocks),
mod_file->addStatement(make_unique<MShocksStatement>(overwrite, relative_to_initval,
move(det_shocks),
mod_file->symbol_table));
det_shocks.clear();
if (!learnt_shocks_add.empty())
@ -960,14 +961,14 @@ ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwri
}
void
ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite)
ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite, bool relative_to_initval)
{
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);
end_mshocks(overwrite, relative_to_initval);
return;
}
@ -977,11 +978,14 @@ ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwr
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;
const auto type { relative_to_initval ?
ShocksLearntInStatement::LearntShockType::multiplyInitialSteadyState :
ShocksLearntInStatement::LearntShockType::multiplySteadyState };
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);
v2.emplace_back(type, period1, period2, value);
learnt_shocks[id] = v2;
}

View File

@ -447,13 +447,13 @@ public:
//! Writes a shocks statement
void end_shocks(bool overwrite);
//! Writes a mshocks statement
void end_mshocks(bool overwrite);
void end_mshocks(bool overwrite, bool relative_to_initval);
//! Writes a shocks(surprise) statement
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);
void end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite, bool relative_to_initval);
//! Writes a heteroskedastic_shocks statement
void end_heteroskedastic_shocks(bool overwrite);
/* Adds a deterministic shock, a path element inside a

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2003-2022 Dynare Team
* Copyright © 2003-2023 Dynare Team
*
* This file is part of Dynare.
*
@ -24,12 +24,11 @@
#include "Shocks.hh"
AbstractShocksStatement::AbstractShocksStatement(bool mshocks_arg,
bool overwrite_arg,
AbstractShocksStatement::AbstractShocksStatement(bool overwrite_arg, ShockType type_arg,
det_shocks_t det_shocks_arg,
const SymbolTable &symbol_table_arg) :
mshocks{mshocks_arg},
overwrite{overwrite_arg},
type{type_arg},
det_shocks{move(det_shocks_arg)},
symbol_table{symbol_table_arg}
{
@ -48,7 +47,7 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
<< boolalpha
<< "struct('exo_det'," << exo_det
<< ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1
<< ",'multiplicative'," << mshocks
<< ",'type','" << typeToString(type) << "'"
<< ",'periods'," << period1 << ":" << period2
<< ",'value',";
value->writeOutput(output);
@ -87,6 +86,21 @@ AbstractShocksStatement::writeJsonDetShocks(ostream &output) const
output << "]";
}
string
AbstractShocksStatement::typeToString(ShockType type)
{
switch (type)
{
case ShockType::level:
return "level";
case ShockType::multiplySteadyState:
return "multiply_steady_state";
case ShockType::multiplyInitialSteadyState:
return "multiply_initial_steady_state";
}
__builtin_unreachable(); // Silence GCC warning
}
ShocksStatement::ShocksStatement(bool overwrite_arg,
det_shocks_t det_shocks_arg,
var_and_std_shocks_t var_shocks_arg,
@ -94,7 +108,7 @@ ShocksStatement::ShocksStatement(bool overwrite_arg,
covar_and_corr_shocks_t covar_shocks_arg,
covar_and_corr_shocks_t corr_shocks_arg,
const SymbolTable &symbol_table_arg) :
AbstractShocksStatement{false, overwrite_arg, move(det_shocks_arg), symbol_table_arg},
AbstractShocksStatement{overwrite_arg, ShockType::level, move(det_shocks_arg), symbol_table_arg},
var_shocks{move(var_shocks_arg)},
std_shocks{move(std_shocks_arg)},
covar_shocks{move(covar_shocks_arg)},
@ -400,10 +414,13 @@ ShocksStatement::has_calibrated_measurement_errors() const
return false;
}
MShocksStatement::MShocksStatement(bool overwrite_arg,
MShocksStatement::MShocksStatement(bool overwrite_arg, bool relative_to_initval_arg,
det_shocks_t det_shocks_arg,
const SymbolTable &symbol_table_arg) :
AbstractShocksStatement{true, overwrite_arg, move(det_shocks_arg), symbol_table_arg}
AbstractShocksStatement{overwrite_arg,
relative_to_initval_arg ? ShockType::multiplyInitialSteadyState : ShockType::multiplySteadyState,
move(det_shocks_arg), symbol_table_arg},
relative_to_initval{relative_to_initval_arg}
{
}
@ -425,7 +442,8 @@ void
MShocksStatement::writeJsonOutput(ostream &output) const
{
output << R"({"statementName": "mshocks")"
<< R"(, "overwrite": )" << boolalpha << overwrite;
<< R"(, "overwrite": )" << boolalpha << overwrite
<< R"(, "relative_to_initval": )" << boolalpha << relative_to_initval;
if (!det_shocks.empty())
{
output << ", ";
@ -526,6 +544,8 @@ ShocksLearntInStatement::typeToString(LearntShockType type)
return "multiply";
case LearntShockType::multiplySteadyState:
return "multiply_steady_state";
case LearntShockType::multiplyInitialSteadyState:
return "multiply_initial_steady_state";
}
__builtin_unreachable(); // Silence GCC warning
}

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2003-2022 Dynare Team
* Copyright © 2003-2023 Dynare Team
*
* This file is part of Dynare.
*
@ -35,17 +35,23 @@ class AbstractShocksStatement : public Statement
public:
// The tuple is (period1, period2, value)
using det_shocks_t = map<int, vector<tuple<int, int, expr_t>>>;
enum class ShockType
{
level, // The value is the level of the exogenous (“values” statement in “shocks”)
multiplySteadyState, // The value is the ratio of the exogenous over its (terminal) steady state (“values” statement in “mshocks”)
multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady state (“values” statement in “mshocks(relative_to_initval)”)
};
protected:
//! Is this statement a "mshocks" statement ? (instead of a "shocks" statement)
const bool mshocks;
//! Does this "shocks" statement replace the previous ones?
const bool overwrite;
const ShockType type; // Type of shocks represented by this block
const det_shocks_t det_shocks;
const SymbolTable &symbol_table;
void writeDetShocks(ostream &output) const;
void writeJsonDetShocks(ostream &output) const;
static string typeToString(ShockType type);
AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg,
AbstractShocksStatement(bool overwrite_arg, ShockType type_arg,
det_shocks_t det_shocks_arg,
const SymbolTable &symbol_table_arg);
};
@ -79,7 +85,8 @@ public:
class MShocksStatement : public AbstractShocksStatement
{
public:
MShocksStatement(bool overwrite_arg,
const bool relative_to_initval;
MShocksStatement(bool overwrite_arg, bool relative_to_initval_arg,
det_shocks_t det_shocks_arg,
const SymbolTable &symbol_table_arg);
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
@ -120,7 +127,8 @@ public:
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=…)”)
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=…)”)
multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady state as anticipated in the same informational period (“values” statement in “mshocks(learnt_in=…, relative_to_initval)”)
};
// The tuple is (type, period1, period2, value)
using learnt_shocks_t = map<int, vector<tuple<LearntShockType, int, int, expr_t>>>;