diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 38c7cec691cfb4a636d9cc4f64cd9158e7a30121..c2dad5ce74b6f0d1d3e39f7436eeae72c47733c3 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -1214,13 +1214,16 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (lag != 0) output << lag; output << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; } + else if (output_type == ExprNodeOutputType::matlabDseries) + // Only writing dseries for epilogue_static, hence no need to check lag + output << "ds." << datatree.symbol_table.getName(symb_id); else { cerr << "VariableNode::writeOutput: Impossible case" << endl; exit(EXIT_FAILURE); } + break; case SymbolType::unusedEndogenous: cerr << "ERROR: You cannot use an endogenous variable in an expression if that variable has not been used in the model block." << endl; exit(EXIT_FAILURE); diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc index 3f88da46b1e0569d3569651142e9c0344ab3bcbf..04f257406cc0d88c52baeed9d5947ffd80a431f8 100644 --- a/src/ModelEquationBlock.cc +++ b/src/ModelEquationBlock.cc @@ -379,14 +379,14 @@ Epilogue::writeEpilogueFile(const string &basename) const if (dynamic_def_table.empty()) return; - writeEpilogueFile(basename, true); - writeEpilogueFile(basename, false); + writeDynamicEpilogueFile(basename); + writeStaticEpilogueFile(basename); } void -Epilogue::writeEpilogueFile(const string & basename, bool dynamic_file) const +Epilogue::writeStaticEpilogueFile(const string & basename) const { - string filename = packageDir(basename) + "/epilogue_" + (dynamic_file ? "dynamic" : "static") + ".m"; + string filename = packageDir(basename) + "/epilogue_static.m"; ofstream output; output.open(filename, ios::out | ios::binary); if (!output.is_open()) @@ -395,12 +395,44 @@ Epilogue::writeEpilogueFile(const string & basename, bool dynamic_file) const exit(EXIT_FAILURE); } - output << "function ds = epilogue_" << (dynamic_file ? "dynamic" : "static") << "(params, ds)" << endl - << "% function ds = epilogue_" << (dynamic_file ? "dynamic" : "static") << "(params, ds)" << endl + output << "function ds = epilogue_static(params, ds)" << endl + << "% function ds = epilogue_static(params, ds)" << endl + << "% Epilogue file generated by Dynare preprocessor" << endl; + + for (const auto & [symb_id, expr] : static_def_table) + { + // Rewrite external function TEF term for every equation as argument values could have been changed + // in between two calls to the same function; + deriv_node_temp_terms_t tef_terms; + temporary_terms_t temporary_terms; + temporary_terms_idxs_t temporary_terms_idxs; + if (expr->containsExternalFunction()) + expr->writeExternalFunctionOutput(output, ExprNodeOutputType::matlabDseries, temporary_terms, temporary_terms_idxs, tef_terms); + output << "ds." << symbol_table.getName(symb_id) << " = "; + expr->writeOutput(output, ExprNodeOutputType::matlabDseries, temporary_terms, temporary_terms_idxs, tef_terms); + output << ";" << endl; + } + output << "end" << endl; + output.close(); +} + +void +Epilogue::writeDynamicEpilogueFile(const string & basename) const +{ + string filename = packageDir(basename) + "/epilogue_dynamic.m"; + ofstream output; + output.open(filename, ios::out | ios::binary); + if (!output.is_open()) + { + cerr << "ERROR: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + + output << "function ds = epilogue_dynamic(params, ds)" << endl + << "% function ds = epilogue_dynamic(params, ds)" << endl << "% Epilogue file generated by Dynare preprocessor" << endl << endl << "simul_end_date = lastdate(ds);" << endl; - int def_table_idx = 0; deriv_node_temp_terms_t tef_terms; temporary_terms_t temporary_terms; temporary_terms_idxs_t temporary_terms_idxs; @@ -419,20 +451,14 @@ Epilogue::writeEpilogueFile(const string & basename, bool dynamic_file) const output << ", "; output << "'" << symbol_table.getName(*it1) << "'"; } - if (dynamic_file) - output << "}) + " << max_lag << " + 1;" << endl; - else - output << "});" << endl; - output << "if ~ds.exist('" << symbol_table.getName(symb_id) << "')" << endl + output << "}) + " << max_lag << " + 1;" << endl + << "if ~ds.exist('" << symbol_table.getName(symb_id) << "')" << endl << " ds = [ds dseries(NaN(ds.nobs,1), ds.firstdate, '" << symbol_table.getName(symb_id)<< "')];" << endl << "end" << endl << "from simul_begin_date to simul_end_date do " << "ds." << symbol_table.getName(symb_id) << "(t) = "; - 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++; + + expr->writeOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms); output << ";" << endl << endl; } output << "end" << endl; diff --git a/src/ModelEquationBlock.hh b/src/ModelEquationBlock.hh index 05f2b398b5b65b9e91702b1930c0259f5f8da3d6..19871b594484fc5d7181fdea48f274f86c283106 100644 --- a/src/ModelEquationBlock.hh +++ b/src/ModelEquationBlock.hh @@ -103,7 +103,8 @@ public: void writeOutput(ostream &output) const; private: //! Helper for public writeEpilogueFile - void writeEpilogueFile(const string & basename, bool dynamic_file) const; + void writeStaticEpilogueFile(const string & basename) const; + void writeDynamicEpilogueFile(const string & basename) const; };