Factorize methods for writing set auxiliary variables/series files

master
Sébastien Villemot 2023-03-28 16:37:05 +02:00
parent 0d41e0ce3d
commit 1ef5feec15
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
6 changed files with 84 additions and 132 deletions

View File

@ -2460,75 +2460,13 @@ DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const strin
else // MATLAB/Octave
writeSparseModelMFiles<true>(basename);
writeSetAuxiliaryVariables(basename, julia);
writeSetAuxiliaryVariablesFile<true>(basename, julia);
// Support for model debugging
if (!julia)
writeDebugModelMFiles<true>(basename);
}
void
DynamicModel::writeSetAuxiliaryVariables(const string &basename, bool julia) const
{
ostringstream output_func_body;
writeAuxVarRecursiveDefinitions(output_func_body, julia ? ExprNodeOutputType::juliaTimeDataFrame
: ExprNodeOutputType::matlabDseries);
if (output_func_body.str().empty())
return;
string func_name = julia ? "dynamic_set_auxiliary_series!" : "dynamic_set_auxiliary_series";
string comment = julia ? "#" : "%";
stringstream output;
output << "function ";
if (!julia)
output << "ds = ";
output << func_name + "(ds, params)" << endl
<< comment << endl
<< comment << " Status : Computes Auxiliary variables of the " << modelClassName() << " and returns a dseries" << endl
<< comment << endl
<< comment << " Warning : this file is generated automatically by Dynare" << endl
<< comment << " from model file (.mod)" << endl << endl;
if (julia)
output << "@inbounds begin" << endl;
output << output_func_body.str()
<< "end" << endl;
if (julia)
output << "end" << endl;
if (julia)
writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "DynamicSetAuxiliarySeries.jl");
else
{
/* Calling writeToFileIfModified() is useless here since we write inside
a subdirectory deleted at each preprocessor run. */
filesystem::path filename {packageDir(basename) / (func_name + ".m")};
ofstream output_file{filename, ios::out | ios::binary};
if (!output_file.is_open())
{
cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
exit(EXIT_FAILURE);
}
output_file << output.str();
output_file.close();
}
}
void
DynamicModel::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const
{
deriv_node_temp_terms_t tef_terms;
for (auto aux_eq : aux_equations)
if (aux_eq->containsExternalFunction())
aux_eq->writeExternalFunctionOutput(output, output_type, {}, {}, tef_terms);
for (auto aux_eq : aux_equations)
{
aux_eq->writeOutput(output, output_type, {}, {}, tef_terms);
output << ";" << endl;
}
}
void
DynamicModel::clearEquations()
{

View File

@ -116,9 +116,6 @@ private:
//! Writes the code of the model in virtual machine bytecode
void writeDynamicBytecode(const string &basename) const;
void writeSetAuxiliaryVariables(const string &basename, bool julia) const;
void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
// Write the block structure of the model in the driver file
void writeBlockDriverOutput(ostream &output) const;

View File

@ -1978,3 +1978,17 @@ ModelTree::computeCSCColPtr(const SparseColumnMajorOrderMatrix &matrix, int ncol
}
return colptr;
}
void
ModelTree::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const
{
deriv_node_temp_terms_t tef_terms;
for (auto aux_equation : aux_equations)
if (aux_equation->containsExternalFunction())
aux_equation->writeExternalFunctionOutput(output, output_type, {}, {}, tef_terms);
for (auto aux_equation : aux_equations)
{
aux_equation->writeOutput(output, output_type, {}, {}, tef_terms);
output << ";" << endl;
}
}

View File

@ -396,6 +396,10 @@ protected:
template<bool dynamic>
void writeDebugModelMFiles(const string &basename) const;
// Write the file that sets auxiliary variables given the original variables
template<bool dynamic>
void writeSetAuxiliaryVariablesFile(const string &basename, bool julia) const;
private:
//! Sparse matrix of double to store the values of the static Jacobian
/*! First index is equation number, second index is endogenous type specific ID */
@ -633,6 +637,9 @@ public:
// Waits until the MEX compilation queue is empty
static void waitForMEXCompilationWorkers();
// Write the definitions of the auxiliary variables (assumed to be in recursive order)
void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
//! Returns the vector of non-zero derivative counts
const vector<int> &
getNNZDerivatives() const
@ -2975,3 +2982,64 @@ ModelTree::writeDebugModelMFiles(const string &basename) const
output.close();
}
template<bool dynamic>
void
ModelTree::writeSetAuxiliaryVariablesFile(const string &basename, bool julia) const
{
const auto output_type { julia ? (dynamic ? ExprNodeOutputType::juliaTimeDataFrame : ExprNodeOutputType::juliaStaticModel)
: (dynamic ? ExprNodeOutputType::matlabDseries : ExprNodeOutputType::matlabStaticModel) };
ostringstream output_func_body;
writeAuxVarRecursiveDefinitions(output_func_body, output_type);
if (output_func_body.str().empty())
return;
string func_name { dynamic ? "dynamic_set_auxiliary_series" : "set_auxiliary_variables" };
if (julia)
func_name.push_back('!');
const char comment {julia ? '#' : '%'};
stringstream output;
output << "function ";
if (!julia)
{
if constexpr(dynamic)
output << "ds = ";
else
output << "y = ";
}
output << func_name + "(";
if constexpr(dynamic)
output << "ds";
else
output << "y, x";
output << ", params)" << endl
<< comment << endl
<< comment << " Computes auxiliary variables of the " << modelClassName() << endl
<< comment << endl;
if (julia)
output << "@inbounds begin" << endl;
output << output_func_body.str()
<< "end" << endl;
if (julia)
output << "end" << endl;
if (julia)
writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / (dynamic ? "DynamicSetAuxiliarySeries.jl" : "SetAuxiliaryVariables.jl"));
else
{
/* Calling writeToFileIfModified() is useless here since we write inside
a subdirectory deleted at each preprocessor run. */
filesystem::path filename {packageDir(basename) / (func_name + ".m")};
ofstream output_file{filename, ios::out | ios::binary};
if (!output_file.is_open())
{
cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
exit(EXIT_FAILURE);
}
output_file << output.str();
output_file.close();
}
}

View File

@ -488,7 +488,7 @@ StaticModel::writeStaticFile(const string &basename, bool use_dll, const string
else // MATLAB/Octave
writeSparseModelMFiles<false>(basename);
writeSetAuxiliaryVariables(basename, julia);
writeSetAuxiliaryVariablesFile<false>(basename, julia);
// Support for model debugging
if (!julia)
@ -696,68 +696,6 @@ StaticModel::writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type)
}
}
void
StaticModel::writeSetAuxiliaryVariables(const string &basename, bool julia) const
{
ostringstream output_func_body;
ExprNodeOutputType output_type = julia ? ExprNodeOutputType::juliaStaticModel : ExprNodeOutputType::matlabStaticModel;
writeAuxVarRecursiveDefinitions(output_func_body, output_type);
if (output_func_body.str().empty())
return;
string func_name = julia ? "set_auxiliary_variables!" : "set_auxiliary_variables";
string comment = julia ? "#" : "%";
stringstream output;
output << "function ";
if (!julia)
output << "y = ";
output << func_name << "(y, x, params)" << endl
<< comment << endl
<< comment << " Status : Computes Auxiliary variables of the " << modelClassName() << endl
<< comment << endl
<< comment << " Warning : this file is generated automatically by Dynare" << endl
<< comment << " from model file (.mod)" << endl << endl;
if (julia)
output << "@inbounds begin" << endl;
output << output_func_body.str()
<< "end" << endl;
if (julia)
output << "end" << endl;
if (julia)
writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "SetAuxiliaryVariables.jl");
else
{
/* Calling writeToFileIfModified() is useless here since we write inside
a subdirectory deleted at each preprocessor run. */
filesystem::path filename {packageDir(basename) / (func_name + ".m")};
ofstream output_file{filename, ios::out | ios::binary};
if (!output_file.is_open())
{
cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
exit(EXIT_FAILURE);
}
output_file << output.str();
output_file.close();
}
}
void
StaticModel::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const
{
deriv_node_temp_terms_t tef_terms;
for (auto aux_equation : aux_equations)
if (dynamic_cast<ExprNode *>(aux_equation)->containsExternalFunction())
dynamic_cast<ExprNode *>(aux_equation)->writeExternalFunctionOutput(output, output_type, {}, {}, tef_terms);
for (auto aux_equation : aux_equations)
{
aux_equation->writeOutput(output, output_type, {}, {}, tef_terms);
output << ";" << endl;
}
}
void
StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const
{

View File

@ -169,9 +169,6 @@ public:
//! Writes initializations in oo_.steady_state or steady state file for the auxiliary variables
void writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type) const;
//! Writes definition of the auxiliary variables in a .m or .jl file
void writeSetAuxiliaryVariables(const string &basename, bool julia) const;
void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
void writeLatexAuxVarRecursiveDefinitions(ostream &output) const;
void writeJsonAuxVarRecursiveDefinitions(ostream &output) const;