From f3c14ec396f9b9c3d2e84eac99388426c9f4ddc1 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 27 Jul 2015 15:33:38 +0200 Subject: [PATCH] write static model --- ExprNode.cc | 3 +++ ExprNode.hh | 1 + ModFile.cc | 5 ++++ StaticModel.cc | 72 ++++++++++++++++++++++++++++++++++++++++++++------ StaticModel.hh | 7 +++-- 5 files changed, 78 insertions(+), 10 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index b9c44055..0121a991 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -660,6 +660,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case oCStaticModel: + case oJuliaStaticModel: case oMatlabStaticModel: case oMatlabStaticModelSparse: i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); @@ -718,6 +719,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "x[it_" << lag << "+" << i << "*nb_row_x]"; break; case oCStaticModel: + case oJuliaStaticModel: case oMatlabStaticModel: case oMatlabStaticModelSparse: output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); @@ -763,6 +765,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "x[it_" << lag << "+" << i << "*nb_row_x]"; break; case oCStaticModel: + case oJuliaStaticModel: case oMatlabStaticModel: case oMatlabStaticModelSparse: output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); diff --git a/ExprNode.hh b/ExprNode.hh index 0500ff6d..ae9fcd46 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -66,6 +66,7 @@ enum ExprNodeOutputType oMatlabDynamicModelSparse, //!< Matlab code, dynamic block decomposed model oCDynamicModel, //!< C code, dynamic model oCStaticModel, //!< C code, static model + oJuliaStaticModel, //!< Julia code, static model oMatlabOutsideModel, //!< Matlab code, outside model block (for example in initval) oLatexStaticModel, //!< LaTeX code, static model oLatexDynamicModel, //!< LaTeX code, dynamic model diff --git a/ModFile.cc b/ModFile.cc index fb2ab886..c371c5a3 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -1113,6 +1113,11 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) cout << "Processing outputs ..." << endl; symbol_table.writeJuliaOutput(jlOutputFile); + if (dynamic_model.equation_number() > 0) + if (!no_static) + static_model.writeStaticFile(basename, false, false, false, &jlOutputFile); + jlOutputFile << "end" << endl; jlOutputFile.close(); + cout << "done" << endl; } diff --git a/StaticModel.cc b/StaticModel.cc index 523c0ab9..b39ca991 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -1175,19 +1175,20 @@ StaticModel::writeStaticMFile(const string &func_name) const << "% Warning : this file is generated automatically by Dynare" << endl << "% from model file (.mod)" << endl << endl; - writeStaticModel(output, false); + writeStaticModel(output, false, false); output << "end" << endl; output.close(); } void -StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const +StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) const { ostringstream model_output; // Used for storing model equations ostringstream jacobian_output; // Used for storing jacobian equations ostringstream hessian_output; // Used for storing Hessian equations ostringstream third_derivatives_output; // Used for storing third order derivatives equations - ExprNodeOutputType output_type = (use_dll ? oCStaticModel : oMatlabStaticModel); + ExprNodeOutputType output_type = (use_dll ? oCStaticModel : + julia ? oJuliaStaticModel : oMatlabStaticModel); deriv_node_temp_terms_t tef_terms; writeModelLocalVariables(model_output, output_type, tef_terms); @@ -1320,7 +1321,7 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const k += k2; } - if (!use_dll) + if (!use_dll && !julia) { StaticOutput << "residual = zeros( " << equations.size() << ", 1);" << endl << endl << "%" << endl @@ -1366,9 +1367,53 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const << " g3 = sparse(v3(:,1),v3(:,2),v3(:,3)," << nrows << "," << ncols << ");" << endl; else // Either 3rd derivatives is all zero, or we didn't compute it StaticOutput << " g3 = sparse([],[],[]," << nrows << "," << ncols << ");" << endl; - } - else + else if (julia) + { + StaticOutput << "residual = zeros( " << equations.size() << ", 1)" << endl << endl + << "#" << endl + << "# Model equations" << endl + << "#" << endl << endl + << model_output.str() + << "if ~isreal(residual)" << endl + << " residual = real(residual)+imag(residual).^2;" << endl + << "end" << endl + << "g1 = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ");" + << endl << endl + << "#" << endl + << "# Jacobian matrix" << endl + << "#" << endl << endl + << jacobian_output.str() + << "if ~isreal(g1)" << endl + << " g1 = real(g1)+2*imag(g1);" << endl + << "end" << endl + << "#" << endl + << "# Hessian matrix" << endl + << "#" << endl; + + if (second_derivatives.size()) + StaticOutput << "v2 = zeros(" << NNZDerivatives[1] << ",3);" << endl + << hessian_output.str() + << "g2 = sparse(v2(:,1),v2(:,2),v2(:,3)," << equations.size() << "," + << g2ncols << ");" << endl; + else + StaticOutput << "g2 = sparse([],[],[]," << equations.size() << "," << g2ncols << ");" << endl; + + // Initialize g3 matrix + StaticOutput << "#" << endl + << "# Third order derivatives" << endl + << "#" << endl; + + int ncols = hessianColsNbr * JacobianColsNbr; + if (third_derivatives.size()) + StaticOutput << "v3 = zeros(" << NNZDerivatives[2] << ",3);" << endl + << third_derivatives_output.str() + << "g3 = sparse(v3(:,1),v3(:,2),v3(:,3)," << nrows << "," << ncols << ");" + << endl; + else // Either 3rd derivatives is all zero, or we didn't compute it + StaticOutput << "g3 = sparse([],[],[]," << nrows << "," << ncols << ");" << endl; + } + else if (use_dll) { StaticOutput << "void Static(double *y, double *x, int nb_row_x, double *params, double *residual, double *g1, double *v2)" << endl << "{" << endl @@ -1440,7 +1485,7 @@ StaticModel::writeStaticCFile(const string &func_name) const writePowerDerivCHeader(output); // Writing the function body - writeStaticModel(output, true); + writeStaticModel(output, true, false); output << "}" << endl << endl; writePowerDeriv(output, true); @@ -1515,7 +1560,16 @@ StaticModel::writeStaticCFile(const string &func_name) const } void -StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll) const +StaticModel::writeStaticJuliaFile(ofstream &jlOutputFile) const +{ + jlOutputFile << "model__.static = function static(y, x, params)" << endl; + writeStaticModel(jlOutputFile, false, true); + jlOutputFile << "(residual, g1, g2, g3)" << endl + << "end" << endl; +} + +void +StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, ofstream *jlOutputFile) const { int r; @@ -1544,6 +1598,8 @@ StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, } else if(use_dll) writeStaticCFile(basename); + else if (jlOutputFile != NULL) + writeStaticJuliaFile(*jlOutputFile); else writeStaticMFile(basename); writeAuxVarRecursiveDefinitions(basename); diff --git a/StaticModel.hh b/StaticModel.hh index e76a5f0f..7c117866 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -50,8 +50,11 @@ private: //! Writes static model file (C version) void writeStaticCFile(const string &func_name) const; + //! Writes static model file (Julia version) + void writeStaticJuliaFile(ofstream &jlOutputFile) const; + //! Writes the static model equations and its derivatives - void writeStaticModel(ostream &StaticOutput, bool use_dll) const; + void writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) const; //! Writes the static function calling the block to solve (Matlab version) void writeStaticBlockMFSFile(const string &basename) const; @@ -168,7 +171,7 @@ public: int &u_count_int, bool &file_open) const; //! Writes static model file - void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll) const; + void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, ofstream *jlOutputFile = NULL) const; //! Writes file containing static parameters derivatives void writeParamsDerivativesFile(const string &basename) const;