Skip to content
Snippets Groups Projects
Verified Commit 4111bc8c authored by Houtan Bastani's avatar Houtan Bastani
Browse files

epilogue: create _dynamic and _static files

#36
parent 34a41b55
Branches
No related tags found
No related merge requests found
...@@ -519,6 +519,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const ...@@ -519,6 +519,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
epilogue.detrend(trend_symbols, nonstationary_symbols); epilogue.detrend(trend_symbols, nonstationary_symbols);
} }
epilogue.toStatic();
mod_file_struct.orig_eq_nbr = dynamic_model.equation_number(); mod_file_struct.orig_eq_nbr = dynamic_model.equation_number();
if (mod_file_struct.ramsey_model_present) if (mod_file_struct.ramsey_model_present)
{ {
......
...@@ -295,8 +295,8 @@ Epilogue::Epilogue(SymbolTable &symbol_table_arg, ...@@ -295,8 +295,8 @@ Epilogue::Epilogue(SymbolTable &symbol_table_arg,
Epilogue::Epilogue(const Epilogue &m) : Epilogue::Epilogue(const Epilogue &m) :
DynamicModel {m} DynamicModel {m}
{ {
for (const auto &it : m.def_table) for (const auto &it : m.dynamic_def_table)
def_table.emplace_back(it.first, it.second->clone(*this)); dynamic_def_table.emplace_back(it.first, it.second->clone(*this));
} }
Epilogue & Epilogue &
...@@ -304,9 +304,9 @@ Epilogue::operator=(const Epilogue &m) ...@@ -304,9 +304,9 @@ Epilogue::operator=(const Epilogue &m)
{ {
DynamicModel::operator=(m); DynamicModel::operator=(m);
def_table.clear(); dynamic_def_table.clear();
for (const auto &it : m.def_table) for (const auto &it : m.dynamic_def_table)
def_table.emplace_back(it.first, it.second->clone(*this)); dynamic_def_table.emplace_back(it.first, it.second->clone(*this));
return *this; return *this;
} }
...@@ -314,17 +314,17 @@ Epilogue::operator=(const Epilogue &m) ...@@ -314,17 +314,17 @@ Epilogue::operator=(const Epilogue &m)
void void
Epilogue::addDefinition(int symb_id, expr_t expr) Epilogue::addDefinition(int symb_id, expr_t expr)
{ {
def_table.emplace_back(symb_id, expr); dynamic_def_table.emplace_back(symb_id, expr);
} }
void void
Epilogue::checkPass(WarningConsolidation &warnings) const Epilogue::checkPass(WarningConsolidation &warnings) const
{ {
if (def_table.size() == 0) if (dynamic_def_table.size() == 0)
return; return;
vector<int> so_far_defined; vector<int> so_far_defined;
for (const auto & it : def_table) for (const auto & it : dynamic_def_table)
if (find(so_far_defined.begin(), so_far_defined.end(), it.first) != so_far_defined.end()) if (find(so_far_defined.begin(), so_far_defined.end(), it.first) != so_far_defined.end())
{ {
cerr << "WARNING: in the 'epilogue' block, variable '" << it.first cerr << "WARNING: in the 'epilogue' block, variable '" << it.first
...@@ -335,25 +335,32 @@ Epilogue::checkPass(WarningConsolidation &warnings) const ...@@ -335,25 +335,32 @@ Epilogue::checkPass(WarningConsolidation &warnings) const
so_far_defined.push_back(it.first); so_far_defined.push_back(it.first);
} }
void
Epilogue::toStatic()
{
for (const auto & [symb_id, expr] : dynamic_def_table)
static_def_table.emplace_back(make_pair(symb_id, expr->toStatic(*this)));
}
void void
Epilogue::detrend(const map<int, expr_t> & trend_symbols_map, Epilogue::detrend(const map<int, expr_t> & trend_symbols_map,
const nonstationary_symbols_map_t & nonstationary_symbols_map) const nonstationary_symbols_map_t & nonstationary_symbols_map)
{ {
for (auto it = nonstationary_symbols_map.crbegin(); for (auto it = nonstationary_symbols_map.crbegin();
it != nonstationary_symbols_map.crend(); it++) it != nonstationary_symbols_map.crend(); it++)
for (auto & [symb_id, expr] : def_table) for (auto & [symb_id, expr] : dynamic_def_table)
{ {
expr = expr->detrend(it->first, it->second.first, it->second.second); expr = expr->detrend(it->first, it->second.first, it->second.second);
assert(expr != nullptr); assert(expr != nullptr);
} }
for (auto & [symb_id, expr] : def_table) for (auto & [symb_id, expr] : dynamic_def_table)
{ {
expr = expr->removeTrendLeadLag(trend_symbols_map); expr = expr->removeTrendLeadLag(trend_symbols_map);
assert(expr != nullptr); assert(expr != nullptr);
} }
for (auto & [symb_id, expr] : def_table) for (auto & [symb_id, expr] : dynamic_def_table)
{ {
expr = expr->replaceTrendVar(); expr = expr->replaceTrendVar();
assert(expr != nullptr); assert(expr != nullptr);
...@@ -363,10 +370,17 @@ Epilogue::detrend(const map<int, expr_t> & trend_symbols_map, ...@@ -363,10 +370,17 @@ Epilogue::detrend(const map<int, expr_t> & trend_symbols_map,
void void
Epilogue::writeEpilogueFile(const string &basename) const Epilogue::writeEpilogueFile(const string &basename) const
{ {
if (def_table.size() == 0) if (dynamic_def_table.empty())
return; return;
string filename = packageDir(basename) + "/epilogue.m"; writeEpilogueFile(basename, true);
writeEpilogueFile(basename, false);
}
void
Epilogue::writeEpilogueFile(const string & basename, bool dynamic_file) const
{
string filename = packageDir(basename) + "/epilogue_" + (dynamic_file ? "dynamic" : "static") + ".m";
ofstream output; ofstream output;
output.open(filename, ios::out | ios::binary); output.open(filename, ios::out | ios::binary);
if (!output.is_open()) if (!output.is_open())
...@@ -375,26 +389,33 @@ Epilogue::writeEpilogueFile(const string &basename) const ...@@ -375,26 +389,33 @@ Epilogue::writeEpilogueFile(const string &basename) const
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
ExprNodeOutputType output_type = ExprNodeOutputType::epilogueFile; output << "function dseries__ = epilogue_" << (dynamic_file ? "dynamic" : "static") << "(params, dseries__)" << endl
output << "function dseries__ = epilogue(params, dseries__)" << endl << "% function dseries__ = epilogue_" << (dynamic_file ? "dynamic" : "static") << "(params, dseries__)" << endl
<< "% function dseries__ = epilogue(params, dseries__)" << endl
<< "% Epilogue file generated by Dynare preprocessor" << endl << endl << "% Epilogue file generated by Dynare preprocessor" << endl << endl
<< "simul_end_date = lastdate(dseries__);" << endl; << "simul_end_date = lastdate(dseries__);" << endl;
int def_table_idx = 0;
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
temporary_terms_t temporary_terms; temporary_terms_t temporary_terms;
temporary_terms_idxs_t temporary_terms_idxs; temporary_terms_idxs_t temporary_terms_idxs;
for (const auto & it : def_table) for (const auto & [symb_id, expr] : dynamic_def_table)
if (it.second->containsExternalFunction()) {
it.second->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); if (expr->containsExternalFunction())
if (dynamic_file)
expr->writeExternalFunctionOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms);
else
static_def_table.at(def_table_idx).second->writeExternalFunctionOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms);
def_table_idx++;
}
output << endl; output << endl;
for (const auto & it : def_table) def_table_idx = 0;
for (const auto & [symb_id, expr] : dynamic_def_table)
{ {
int max_lag = it.second->maxLagWithDiffsExpanded(); int max_lag = expr->maxLagWithDiffsExpanded();
set<int> used_symbols; set<int> used_symbols;
it.second->collectVariables(SymbolType::endogenous, used_symbols); expr->collectVariables(SymbolType::endogenous, used_symbols);
it.second->collectVariables(SymbolType::exogenous, used_symbols); expr->collectVariables(SymbolType::exogenous, used_symbols);
it.second->collectVariables(SymbolType::epilogue, used_symbols); expr->collectVariables(SymbolType::epilogue, used_symbols);
output << "simul_begin_date = firstobservedperiod(dseries__{"; output << "simul_begin_date = firstobservedperiod(dseries__{";
for (auto it1 = used_symbols.begin(); it1 != used_symbols.end(); it1++) for (auto it1 = used_symbols.begin(); it1 != used_symbols.end(); it1++)
...@@ -403,13 +424,20 @@ Epilogue::writeEpilogueFile(const string &basename) const ...@@ -403,13 +424,20 @@ Epilogue::writeEpilogueFile(const string &basename) const
output << ", "; output << ", ";
output << "'" << symbol_table.getName(*it1) << "'"; output << "'" << symbol_table.getName(*it1) << "'";
} }
output << "}) + " << max_lag << " + 1;" << endl if (dynamic_file)
<< "if ~dseries__.exist('" << symbol_table.getName(it.first) << "')" << endl output << "}) + " << max_lag << " + 1;" << endl;
<< " dseries__ = [dseries__ dseries(NaN(dseries__.nobs,1), dseries__.firstdate, '" << symbol_table.getName(it.first)<< "')];" << endl else
output << "});" << endl;
output << "if ~dseries__.exist('" << symbol_table.getName(symb_id) << "')" << endl
<< " dseries__ = [dseries__ dseries(NaN(dseries__.nobs,1), dseries__.firstdate, '" << symbol_table.getName(symb_id)<< "')];" << endl
<< "end" << endl << "end" << endl
<< "from simul_begin_date to simul_end_date do " << "from simul_begin_date to simul_end_date do "
<< "dseries__." << symbol_table.getName(it.first) << "(t) = "; << "dseries__." << symbol_table.getName(symb_id) << "(t) = ";
it.second->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); if (dynamic_file)
expr->writeOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms);
else
static_def_table.at(def_table_idx).second->writeOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms);
def_table_idx++;
output << ";" << endl << endl; output << ";" << endl << endl;
} }
output << "end" << endl; output << "end" << endl;
...@@ -419,17 +447,17 @@ Epilogue::writeEpilogueFile(const string &basename) const ...@@ -419,17 +447,17 @@ Epilogue::writeEpilogueFile(const string &basename) const
void void
Epilogue::writeOutput(ostream &output) const Epilogue::writeOutput(ostream &output) const
{ {
if (def_table.empty()) if (dynamic_def_table.empty())
return; return;
int idx = 1; int idx = 1;
output << "M_.epilogue_names = cell(" << def_table.size() << ",1);" << endl; output << "M_.epilogue_names = cell(" << dynamic_def_table.size() << ",1);" << endl;
for (const auto & [symb_id, expr] : def_table) for (const auto & [symb_id, expr] : dynamic_def_table)
output << "M_.epilogue_names{" << idx++ << "} = '" output << "M_.epilogue_names{" << idx++ << "} = '"
<< symbol_table.getName(symb_id) << "';" << endl; << symbol_table.getName(symb_id) << "';" << endl;
set<int> endogs; set<int> endogs;
for (const auto & [symb_id, expr] : def_table) for (const auto & [symb_id, expr] : dynamic_def_table)
expr->collectVariables(SymbolType::endogenous, endogs); expr->collectVariables(SymbolType::endogenous, endogs);
SymbolList symbol_list; SymbolList symbol_list;
......
...@@ -70,7 +70,7 @@ class Epilogue : public DynamicModel ...@@ -70,7 +70,7 @@ class Epilogue : public DynamicModel
{ {
private: private:
//! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value) //! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value)
vector<pair<int, expr_t>> def_table; vector<pair<int, expr_t>> dynamic_def_table, static_def_table;
public: public:
Epilogue(SymbolTable &symbol_table_arg, Epilogue(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg, NumericalConstants &num_constants_arg,
...@@ -89,6 +89,9 @@ public: ...@@ -89,6 +89,9 @@ public:
//! Checks that no variable is declared twice //! Checks that no variable is declared twice
void checkPass(WarningConsolidation &warnings) const; void checkPass(WarningConsolidation &warnings) const;
//! Creates static epilogue equations
void toStatic();
//! Deal with trend variables in the epilogue block //! Deal with trend variables in the epilogue block
void detrend(const map<int, expr_t> & trend_symbols_map, void detrend(const map<int, expr_t> & trend_symbols_map,
const nonstationary_symbols_map_t & nonstationary_symbols_map); const nonstationary_symbols_map_t & nonstationary_symbols_map);
...@@ -98,6 +101,9 @@ public: ...@@ -98,6 +101,9 @@ public:
//! Write Output //! Write Output
void writeOutput(ostream &output) const; void writeOutput(ostream &output) const;
private:
//! Helper for public writeEpilogueFile
void writeEpilogueFile(const string & basename, bool dynamic_file) const;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment