pac_model: allow diff as argument to growth option
parent
5f013756f2
commit
341b9c6667
|
@ -260,46 +260,78 @@ PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const
|
|||
PacModelStatement::PacModelStatement(string name_arg,
|
||||
string aux_model_name_arg,
|
||||
string discount_arg,
|
||||
int growth_symb_id_arg,
|
||||
int growth_lag_arg,
|
||||
expr_t growth_arg,
|
||||
double steady_state_growth_rate_number_arg,
|
||||
int steady_state_growth_rate_symb_id_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
name{move(name_arg)},
|
||||
aux_model_name{move(aux_model_name_arg)},
|
||||
discount{move(discount_arg)},
|
||||
growth_symb_id{growth_symb_id_arg},
|
||||
growth_lag{growth_lag_arg},
|
||||
growth{growth_arg},
|
||||
steady_state_growth_rate_number{steady_state_growth_rate_number_arg},
|
||||
steady_state_growth_rate_symb_id{steady_state_growth_rate_symb_id_arg},
|
||||
symbol_table{symbol_table_arg}
|
||||
{
|
||||
growth_symb_id = -1;
|
||||
growth_lag = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PacModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
||||
{
|
||||
mod_file_struct.pac_params.insert(symbol_table.getID(discount));
|
||||
if (growth_symb_id >= 0)
|
||||
if (growth == nullptr)
|
||||
return;
|
||||
|
||||
VariableNode *vn = dynamic_cast<VariableNode *>(growth);
|
||||
if (vn != nullptr)
|
||||
{
|
||||
switch (symbol_table.getType(growth_symb_id))
|
||||
{
|
||||
case SymbolType::endogenous:
|
||||
case SymbolType::exogenous:
|
||||
case SymbolType::parameter:
|
||||
break;
|
||||
default:
|
||||
mod_file_struct.pac_params.insert(vn->symb_id);
|
||||
mod_file_struct.pac_params.insert(vn->lag);
|
||||
}
|
||||
|
||||
UnaryOpNode *uon = dynamic_cast<UnaryOpNode *>(growth);
|
||||
if (uon != nullptr)
|
||||
if (uon->op_code == UnaryOpcode::diff)
|
||||
{
|
||||
VariableNode *uonvn = dynamic_cast<VariableNode *>(uon->arg);
|
||||
UnaryOpNode *uon1 = dynamic_cast<UnaryOpNode *>(uon->arg);
|
||||
while (uonvn == nullptr && uon1 != nullptr)
|
||||
{
|
||||
cerr << "ERROR: The Expression passed to the growth option of pac_model must be an "
|
||||
<< "endogenous (lagged or not), exogenous (lagged or not), or parameter" << endl;
|
||||
uonvn = dynamic_cast<VariableNode *>(uon1->arg);
|
||||
uon1 = dynamic_cast<UnaryOpNode *>(uon1->arg);
|
||||
}
|
||||
if (uonvn == nullptr)
|
||||
{
|
||||
cerr << "Pac growth parameter must be either a variable or a diff unary op of a variable" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
mod_file_struct.pac_params.insert(growth_symb_id);
|
||||
mod_file_struct.pac_params.insert(growth_lag);
|
||||
mod_file_struct.pac_params.insert(uonvn->symb_id);
|
||||
mod_file_struct.pac_params.insert(uonvn->lag);
|
||||
}
|
||||
|
||||
if (vn == nullptr && uon == nullptr)
|
||||
{
|
||||
cerr << "Pac growth parameter must be either a variable or a diff unary op of a variable" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PacModelStatement::overwriteGrowth(expr_t new_growth)
|
||||
{
|
||||
if (new_growth == nullptr || growth == nullptr)
|
||||
return;
|
||||
|
||||
growth = new_growth;
|
||||
VariableNode *vn = dynamic_cast<VariableNode *>(growth);
|
||||
if (vn == nullptr)
|
||||
{
|
||||
cerr << "PacModelStatement::overwriteGrowth: Internal Dynare error: should not arrive here" << endl;
|
||||
}
|
||||
growth_symb_id = vn->symb_id;
|
||||
growth_lag = vn->lag;
|
||||
}
|
||||
|
||||
void
|
||||
PacModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
|
||||
{
|
||||
|
|
|
@ -138,22 +138,23 @@ class PacModelStatement : public Statement
|
|||
{
|
||||
public:
|
||||
const string name, aux_model_name, discount;
|
||||
const int growth_symb_id, growth_lag;
|
||||
expr_t growth;
|
||||
private:
|
||||
const double steady_state_growth_rate_number;
|
||||
const int steady_state_growth_rate_symb_id;
|
||||
const SymbolTable &symbol_table;
|
||||
vector<int> lhs;
|
||||
public:
|
||||
int growth_symb_id;
|
||||
int growth_lag;
|
||||
PacModelStatement(string name_arg,
|
||||
string aux_model_name_arg,
|
||||
string discount_arg,
|
||||
int growth_symb_id_arg,
|
||||
int growth_lag_arg,
|
||||
expr_t growth_arg,
|
||||
double steady_state_growth_rate_number_arg,
|
||||
int steady_state_growth_rate_symb_id_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
||||
void overwriteGrowth(expr_t new_growth);
|
||||
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
||||
void writeJsonOutput(ostream &output) const override;
|
||||
};
|
||||
|
|
|
@ -6303,7 +6303,7 @@ DynamicModel::substituteUnaryOps(StaticModel &static_model, diff_table_t &nodes,
|
|||
}
|
||||
|
||||
void
|
||||
DynamicModel::substituteDiff(StaticModel &static_model, diff_table_t &diff_table, ExprNode::subst_table_t &diff_subst_table)
|
||||
DynamicModel::substituteDiff(StaticModel &static_model, diff_table_t &diff_table, ExprNode::subst_table_t &diff_subst_table, vector<expr_t> &pac_growth)
|
||||
{
|
||||
set<int> used_local_vars;
|
||||
for (const auto & equation : equations)
|
||||
|
@ -6354,6 +6354,10 @@ DynamicModel::substituteDiff(StaticModel &static_model, diff_table_t &diff_table
|
|||
equation = substeq;
|
||||
}
|
||||
|
||||
for (auto & it : pac_growth)
|
||||
if (it != nullptr)
|
||||
it = it->substituteDiff(static_model, diff_table, diff_subst_table, neweqs);
|
||||
|
||||
// Add new equations
|
||||
for (auto & neweq : neweqs)
|
||||
addEquation(neweq, -1);
|
||||
|
|
|
@ -444,7 +444,7 @@ public:
|
|||
void substituteUnaryOps(StaticModel &static_model, diff_table_t &nodes, ExprNode::subst_table_t &subst_table, vector<int> &eqnumbers);
|
||||
|
||||
//! Substitutes diff operator
|
||||
void substituteDiff(StaticModel &static_model, diff_table_t &diff_table, ExprNode::subst_table_t &diff_subst_table);
|
||||
void substituteDiff(StaticModel &static_model, diff_table_t &diff_table, ExprNode::subst_table_t &diff_subst_table, vector<expr_t> &pac_growth);
|
||||
|
||||
//! Substitute VarExpectation operators
|
||||
void substituteVarExpectation(const map<string, expr_t> &subst_table);
|
||||
|
|
|
@ -388,7 +388,7 @@ trend_component_model_options : o_trend_component_model_name
|
|||
| o_trend_component_model_eq_tags
|
||||
;
|
||||
|
||||
pac_model : PAC_MODEL '(' pac_model_options_list ')' ';' { driver.pac_model(); } ;
|
||||
pac_model : PAC_MODEL '(' { driver.begin_pac_model(); } pac_model_options_list ')' ';' { driver.pac_model(); };
|
||||
|
||||
pac_model_options_list : pac_model_options_list COMMA pac_model_options
|
||||
| pac_model_options
|
||||
|
@ -3131,9 +3131,7 @@ o_file : FILE EQUAL filename { driver.option_str("file", $3); };
|
|||
o_pac_name : MODEL_NAME EQUAL symbol { driver.option_str("pac.model_name", $3); };
|
||||
o_pac_aux_model_name : AUXILIARY_MODEL_NAME EQUAL symbol { driver.option_str("pac.aux_model_name", $3); };
|
||||
o_pac_discount : DISCOUNT EQUAL symbol { driver.option_str("pac.discount", $3); };
|
||||
o_pac_growth : GROWTH EQUAL symbol { driver.set_pac_growth($3, 0); }
|
||||
| GROWTH EQUAL symbol '(' MINUS INT_NUMBER ')' { driver.set_pac_growth($3, stoi($6)); }
|
||||
;
|
||||
o_pac_growth : GROWTH { driver.begin_pac_growth(); } EQUAL hand_side { driver.set_pac_growth($4); };
|
||||
o_pac_steady_state_growth : STEADY_STATE_GROWTH EQUAL signed_number { driver.set_pac_steady_state_growth($3); }
|
||||
| STEADY_STATE_GROWTH EQUAL symbol { driver.set_pac_steady_state_growth($3); }
|
||||
;
|
||||
|
|
|
@ -370,8 +370,13 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
|
|||
for (auto & statement : statements)
|
||||
{
|
||||
auto pms = dynamic_cast<PacModelStatement *>(statement.get());
|
||||
if (pms != nullptr && pms->aux_model_name == "")
|
||||
dynamic_model.declarePacModelConsistentExpectationEndogs(pms->name);
|
||||
if (pms != nullptr)
|
||||
{
|
||||
if (pms->growth != nullptr)
|
||||
pac_growth.push_back(pms->growth);
|
||||
if (pms->aux_model_name == "")
|
||||
dynamic_model.declarePacModelConsistentExpectationEndogs(pms->name);
|
||||
}
|
||||
}
|
||||
dynamic_model.substituteAdl();
|
||||
dynamic_model.setLeadsLagsOrig();
|
||||
|
@ -409,7 +414,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
|
|||
// Create auxiliary variable and equations for Diff operators
|
||||
diff_table_t diff_table;
|
||||
ExprNode::subst_table_t diff_subst_table;
|
||||
dynamic_model.substituteDiff(diff_static_model, diff_table, diff_subst_table);
|
||||
dynamic_model.substituteDiff(diff_static_model, diff_table, diff_subst_table, pac_growth);
|
||||
|
||||
// Fill Trend Component Model Table
|
||||
dynamic_model.fillTrendComponentModelTable();
|
||||
|
@ -419,11 +424,15 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
|
|||
original_model.fillVarModelTableFromOrigModel(diff_static_model);
|
||||
|
||||
// Pac Model
|
||||
int i = 0;
|
||||
for (auto & statement : statements)
|
||||
{
|
||||
auto pms = dynamic_cast<PacModelStatement *>(statement.get());
|
||||
if (pms != nullptr)
|
||||
{
|
||||
if (pms->growth != nullptr)
|
||||
pms->overwriteGrowth(pac_growth.at(i++));
|
||||
|
||||
int max_lag;
|
||||
vector<int> lhs;
|
||||
vector<bool> nonstationary;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2018 Dynare Team
|
||||
* Copyright (C) 2006-2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -130,6 +130,7 @@ private:
|
|||
void writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const;
|
||||
void writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const;
|
||||
void writeJsonFileHelper(const string &fname, ostringstream &output) const;
|
||||
vector<expr_t> pac_growth;
|
||||
public:
|
||||
//! Add a statement
|
||||
void addStatement(unique_ptr<Statement> st);
|
||||
|
|
|
@ -2607,6 +2607,22 @@ ParsingDriver::add_pac_expectation(const string &var_model_name)
|
|||
return data_tree->AddPacExpectation(var_model_name);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::begin_pac_growth()
|
||||
{
|
||||
set_current_data_tree(&mod_file->dynamic_model);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::begin_pac_model()
|
||||
{
|
||||
parsing_pac_model = true;
|
||||
pac_growth = nullptr;
|
||||
pac_steady_state_growth_rate_number = -1;
|
||||
pac_steady_state_growth_rate_symb_id = -1;
|
||||
options_list.clear();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::pac_model()
|
||||
{
|
||||
|
@ -2626,13 +2642,6 @@ ParsingDriver::pac_model()
|
|||
}
|
||||
else
|
||||
aux_model_name = it->second;
|
||||
else
|
||||
if (pac_growth_symb_id >= 0 && mod_file->symbol_table.getType(pac_growth_symb_id) == SymbolType::parameter
|
||||
&& (pac_steady_state_growth_rate_number >= 0 || pac_steady_state_growth_rate_symb_id >=0))
|
||||
warning("If growth option is constant, steady_state_growth is ignored");
|
||||
else if (pac_growth_symb_id >= 0 && mod_file->symbol_table.getType(pac_growth_symb_id) != SymbolType::parameter
|
||||
&& (pac_steady_state_growth_rate_number < 0 || pac_steady_state_growth_rate_symb_id < 0))
|
||||
error("The steady state growth rate of the target must be provided (steady_state_growth option) if option growth is not constant");
|
||||
|
||||
if (pac_steady_state_growth_rate_symb_id >= 0
|
||||
&& mod_file->symbol_table.getType(pac_steady_state_growth_rate_symb_id) != SymbolType::parameter)
|
||||
|
@ -2644,24 +2653,18 @@ ParsingDriver::pac_model()
|
|||
auto discount = it->second;
|
||||
|
||||
mod_file->addStatement(make_unique<PacModelStatement>(name, aux_model_name, discount,
|
||||
pac_growth_symb_id, pac_growth_lag,
|
||||
pac_growth,
|
||||
pac_steady_state_growth_rate_number,
|
||||
pac_steady_state_growth_rate_symb_id,
|
||||
mod_file->symbol_table));
|
||||
pac_growth_symb_id = -1;
|
||||
pac_growth_lag = 0;
|
||||
pac_steady_state_growth_rate_number = -1;
|
||||
pac_steady_state_growth_rate_symb_id = -1;
|
||||
options_list.clear();
|
||||
parsing_pac_model = false;
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::set_pac_growth(const string &name, int lag)
|
||||
ParsingDriver::set_pac_growth(expr_t pac_growth_arg)
|
||||
{
|
||||
if (!mod_file->symbol_table.exists(name))
|
||||
error("Unknown symbol used in pac_growth option: " + name + "\n");
|
||||
pac_growth_symb_id = mod_file->symbol_table.getID(name);
|
||||
pac_growth_lag = -lag;
|
||||
pac_growth = pac_growth_arg;
|
||||
reset_data_tree();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2981,7 +2984,7 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b
|
|||
expr_t nid;
|
||||
if (mod_file->symbol_table.exists(function_name))
|
||||
if (mod_file->symbol_table.getType(function_name) != SymbolType::externalFunction)
|
||||
if (!in_model_block && !parsing_epilogue)
|
||||
if (!in_model_block && !parsing_epilogue && !parsing_pac_model)
|
||||
{
|
||||
if (stack_external_function_args.top().size() > 0)
|
||||
error(string("Symbol ") + function_name + string(" cannot take arguments."));
|
||||
|
|
|
@ -255,8 +255,7 @@ private:
|
|||
WarningConsolidation &warnings;
|
||||
|
||||
//! Temporary storage for growth declared in pac_model
|
||||
int pac_growth_symb_id = -1;
|
||||
int pac_growth_lag = 0;
|
||||
expr_t pac_growth;
|
||||
double pac_steady_state_growth_rate_number = -1;
|
||||
int pac_steady_state_growth_rate_symb_id = -1;
|
||||
|
||||
|
@ -271,6 +270,9 @@ private:
|
|||
//! True when parsing the epilogue block
|
||||
bool parsing_epilogue{false};
|
||||
|
||||
//! True when parsing pac_model statement
|
||||
bool parsing_pac_model{false};
|
||||
|
||||
public:
|
||||
ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) :
|
||||
warnings{warnings_arg}, nostrict{nostrict_arg} { };
|
||||
|
@ -732,9 +734,11 @@ public:
|
|||
//! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree
|
||||
expr_t add_pac_expectation(const string &var_model_name);
|
||||
//! Creates pac_model statement
|
||||
void begin_pac_growth();
|
||||
void begin_pac_model();
|
||||
void pac_model();
|
||||
//! Adds growth for pac
|
||||
void set_pac_growth(const string &name, int lag = 0);
|
||||
void set_pac_growth(expr_t pac_growth_arg);
|
||||
//! Adds steady state growth for pac
|
||||
void set_pac_steady_state_growth(const string &name_or_number);
|
||||
//! Writes token "diff(arg1)" to model tree
|
||||
|
|
Loading…
Reference in New Issue