From 25ae46e204df6adfcdcb168a1be27ccfaa67ae75 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 27 Jul 2015 17:02:51 +0200 Subject: [PATCH] write dynamic file --- julia/DynareModel.jl | 2 + preprocessor/DynamicModel.cc | 81 +++++++++++++++++++++++++++++++++--- preprocessor/DynamicModel.hh | 6 ++- preprocessor/ExprNode.cc | 27 ++++++++---- preprocessor/ExprNode.hh | 6 +++ preprocessor/ModFile.cc | 18 ++++---- preprocessor/ModelTree.cc | 4 +- 7 files changed, 120 insertions(+), 24 deletions(-) diff --git a/julia/DynareModel.jl b/julia/DynareModel.jl index f23318ad1..f68e1f894 100644 --- a/julia/DynareModel.jl +++ b/julia/DynareModel.jl @@ -105,6 +105,7 @@ type Model sigma_e_is_diagonal::Bool params::Vector{Float64} static::Function + dynamic::Function end function model() @@ -148,6 +149,7 @@ function model() true, # sigma_e_is_diagonal Array(Float64, 0), # params function()end, # static + function()end, # dynamic ) end diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index b6f7e3e7c..9cfd886ec 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -1557,11 +1557,37 @@ DynamicModel::writeDynamicMFile(const string &dynamic_basename) const << "% Warning : this file is generated automatically by Dynare" << endl << "% from model file (.mod)" << endl << endl; - writeDynamicModel(mDynamicModelFile, false); + writeDynamicModel(mDynamicModelFile, false, false); mDynamicModelFile << "end" << endl; // Close *_dynamic function mDynamicModelFile.close(); } +void +DynamicModel::writeDynamicJuliaFile(const string &basename) const +{ + string filename = basename + "Dynamic.jl"; + + ofstream output; + output.open(filename.c_str(), ios::out | ios::binary); + if (!output.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + + output << "module " << basename << "Dynamic" << endl << endl + << "export getDynamicFunction" << endl << endl + << "function getDynamicFunction()" << endl + << " dynamic" << endl + << "end" << endl << endl + << "function dynamic(y, x, params, steady_state, it_)" << endl; + writeDynamicModel(output, false, true); + output << "(residual, g1, g2, g3)" << endl + << "end" << endl + << "end" << endl; + output.close(); +} + void DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) const { @@ -1596,7 +1622,7 @@ DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) writePowerDerivCHeader(mDynamicModelFile); // Writing the function body - writeDynamicModel(mDynamicModelFile, true); + writeDynamicModel(mDynamicModelFile, true, false); writePowerDeriv(mDynamicModelFile, true); mDynamicModelFile.close(); @@ -2085,14 +2111,15 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri } void -DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const +DynamicModel::writeDynamicModel(ostream &DynamicOutput, 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; - ExprNodeOutputType output_type = (use_dll ? oCDynamicModel : oMatlabDynamicModel); + ExprNodeOutputType output_type = (use_dll ? oCDynamicModel : + julia ? oJuliaDynamicModel : oMatlabDynamicModel); deriv_node_temp_terms_t tef_terms; writeModelLocalVariables(model_output, output_type, tef_terms); @@ -2222,7 +2249,7 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const k += k2; } - if (!use_dll) + if (!use_dll && !julia) { DynamicOutput << "%" << endl << "% Model equations" << endl @@ -2271,6 +2298,46 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const DynamicOutput << "end" << endl; } + else if(julia) + { + DynamicOutput << "#" << endl + << "# Model equations" << endl + << "#" << endl + << endl + << "residual = zeros(" << nrows << ", 1);" << endl + << model_output.str() + << "g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");" << endl + << endl + << "#" << endl + << "# Jacobian matrix" << endl + << "#" << endl + << endl + << jacobian_output.str() + << endl + << "#" << endl + << "# Hessian matrix" << endl + << "#" << endl + << endl; + if (second_derivatives.size()) + DynamicOutput << "v2 = zeros(" << NNZDerivatives[1] << ",3);" << endl + << hessian_output.str() + << "g2 = sparse(v2(:,1),v2(:,2),v2(:,3)," << nrows << "," << hessianColsNbr << ");" << endl; + else // Either hessian is all zero, or we didn't compute it + DynamicOutput << "g2 = sparse([],[],[]," << nrows << "," << hessianColsNbr << ");" << endl; + + // Initialize g3 matrix + DynamicOutput << "#" << endl + << "# Third order derivatives" << endl + << "#" << endl + << endl; + int ncols = hessianColsNbr * dynJacobianColsNbr; + if (third_derivatives.size()) + DynamicOutput << "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 + DynamicOutput << "g3 = sparse([],[],[]," << nrows << "," << ncols << ");" << endl; + } else { DynamicOutput << "void Dynamic(double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl @@ -3309,7 +3376,7 @@ DynamicModel::collectBlockVariables() } void -DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order) const +DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const { int r; string t_basename = basename + "_dynamic"; @@ -3333,6 +3400,8 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode } else if (use_dll) writeDynamicCFile(t_basename, order); + else if (julia) + writeDynamicJuliaFile(basename); else writeDynamicMFile(t_basename); } diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index 0bf34f479..c6a02ba91 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -76,6 +76,8 @@ private: //! Writes dynamic model file (Matlab version) void writeDynamicMFile(const string &dynamic_basename) const; + //! Writes dynamic model file (Julia version) + void writeDynamicJuliaFile(const string &dynamic_basename) const; //! Writes dynamic model file (C version) /*! \todo add third derivatives handling */ void writeDynamicCFile(const string &dynamic_basename, const int order) const; @@ -83,7 +85,7 @@ private: void writeSparseDynamicMFile(const string &dynamic_basename, const string &basename) const; //! Writes the dynamic model equations and its derivatives /*! \todo add third derivatives handling in C output */ - void writeDynamicModel(ostream &DynamicOutput, bool use_dll) const; + void writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia) const; //! Writes the Block reordred structure of the model in M output void writeModelEquationsOrdered_M(const string &dynamic_basename) const; //! Writes the code of the Block reordred structure of the model in virtual machine bytecode @@ -219,7 +221,7 @@ public: void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const; //! Writes dynamic model file - void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order) const; + void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const; //! Writes file containing parameters derivatives void writeParamsDerivativesFile(const string &basename) const; diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 0121a991a..1af220532 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -654,6 +654,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case eEndogenous: switch (output_type) { + case oJuliaDynamicModel: case oMatlabDynamicModel: case oCDynamicModel: i = datatree.getDynJacobianCol(datatree.getDerivID(symb_id, lag)) + ARRAY_SUBSCRIPT_OFFSET(output_type); @@ -678,9 +679,10 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oMatlabOutsideModel: output << "oo_.steady_state(" << tsid + 1 << ")"; break; + case oJuliaDynamicSteadyStateOperator: case oMatlabDynamicSteadyStateOperator: case oMatlabDynamicSparseSteadyStateOperator: - output << "steady_state(" << tsid + 1 << ")"; + output << "steady_state" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case oCDynamicSteadyStateOperator: output << "steady_state[" << tsid << "]"; @@ -701,14 +703,18 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); switch (output_type) { + case oJuliaDynamicModel: case oMatlabDynamicModel: case oMatlabDynamicModelSparse: if (lag > 0) - output << "x(it_+" << lag << ", " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (lag < 0) - output << "x(it_" << lag << ", " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); else - output << "x(it_, " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case oCDynamicModel: if (lag == 0) @@ -747,14 +753,18 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); switch (output_type) { + case oJuliaDynamicModel: case oMatlabDynamicModel: case oMatlabDynamicModelSparse: if (lag > 0) - output << "x(it_+" << lag << ", " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (lag < 0) - output << "x(it_" << lag << ", " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); else - output << "x(it_, " << i << ")"; + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case oCDynamicModel: if (lag == 0) @@ -1833,6 +1843,9 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oCDynamicModel: new_output_type = oCDynamicSteadyStateOperator; break; + case oJuliaDynamicModel: + new_output_type = oJuliaDynamicSteadyStateOperator; + break; case oMatlabDynamicModelSparse: new_output_type = oMatlabDynamicSparseSteadyStateOperator; break; diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index ae9fcd46d..c01bb2f97 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -67,6 +67,7 @@ enum ExprNodeOutputType oCDynamicModel, //!< C code, dynamic model oCStaticModel, //!< C code, static model oJuliaStaticModel, //!< Julia code, static model + oJuliaDynamicModel, //!< Julia code, dynamic model oMatlabOutsideModel, //!< Matlab code, outside model block (for example in initval) oLatexStaticModel, //!< LaTeX code, static model oLatexDynamicModel, //!< LaTeX code, dynamic model @@ -74,6 +75,7 @@ enum ExprNodeOutputType oMatlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator oMatlabDynamicSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model, inside a steady state operator oCDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator + oJuliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator oSteadyStateFile, //!< Matlab code, in the generated steady state file oCSteadyStateFile //!< C code, in the generated steady state file }; @@ -87,6 +89,10 @@ enum ExprNodeOutputType || (output_type) == oMatlabDynamicSparseSteadyStateOperator \ || (output_type) == oSteadyStateFile) +#define IS_JULIA(output_type) ((output_type) == oJuliaStaticModel \ + || (output_type) == oJuliaDynamicModel \ + || (output_type) == oJuliaDynamicSteadyStateOperator) + #define IS_C(output_type) ((output_type) == oCDynamicModel \ || (output_type) == oCStaticModel \ || (output_type) == oCDynamicSteadyStateOperator \ diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index ada1e7551..ff341c083 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -814,7 +814,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo static_model.writeParamsDerivativesFile(basename); } - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); dynamic_model.writeParamsDerivativesFile(basename); } @@ -851,7 +851,7 @@ ModFile::writeExternalFilesC(const string &basename, FileOutputType output) cons writeModelC(basename); steady_state_model.writeSteadyStateFileC(basename, mod_file_struct.ramsey_model_present); - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); if (!no_static) static_model.writeStaticFile(basename, false, false, true, false); @@ -956,7 +956,7 @@ ModFile::writeExternalFilesCC(const string &basename, FileOutputType output) con writeModelCC(basename); steady_state_model.writeSteadyStateFileC(basename, mod_file_struct.ramsey_model_present); - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); if (!no_static) static_model.writeStaticFile(basename, false, false, true, false); @@ -1084,8 +1084,8 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) << "using DynareModel" << endl << "using Utils" << endl << "using " << basename << "Static" << endl - << "export dynamicmodel!, staticmodel!, steadystate!" << endl - << "export model__" << endl + << "using " << basename << "Dynamic" << endl << endl + << "export model__" << endl << endl << "model__ = model()" << endl << "model__.fname = \"" << basename << "\"" << endl << "model__.dynare_version = \"" << PACKAGE_VERSION << "\"" << endl @@ -1115,10 +1115,14 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) symbol_table.writeJuliaOutput(jlOutputFile); if (dynamic_model.equation_number() > 0) - if (!no_static) - static_model.writeStaticFile(basename, false, false, false, true); + { + if (!no_static) + static_model.writeStaticFile(basename, false, false, false, true); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, true); + } jlOutputFile << "model__.static = " << basename << "Static.getStaticFunction()" << endl + << "model__.dynamic = " << basename << "Dynamic.getDynamicFunction()" << endl << "end" << endl; jlOutputFile.close(); cout << "done" << endl; diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc index 14149f59a..66edd7d87 100644 --- a/preprocessor/ModelTree.cc +++ b/preprocessor/ModelTree.cc @@ -1471,7 +1471,7 @@ void ModelTree::jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const { output << " g1" << LEFT_ARRAY_SUBSCRIPT(output_type); - if (IS_MATLAB(output_type)) + if (IS_MATLAB(output_type) || IS_JULIA(output_type)) output << eq_nb + 1 << "," << col_nb + 1; else output << eq_nb + col_nb *equations.size(); @@ -1482,7 +1482,7 @@ void ModelTree::sparseHelper(int order, ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const { output << " v" << order << LEFT_ARRAY_SUBSCRIPT(output_type); - if (IS_MATLAB(output_type)) + if (IS_MATLAB(output_type) || IS_JULIA(output_type)) output << row_nb + 1 << "," << col_nb + 1; else output << row_nb + col_nb * NNZDerivatives[order-1];