From 053ee41ac024f0e54b3434dfbdcdf231c49de83d Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 6 Aug 2013 15:20:36 -0400 Subject: [PATCH] ms-dsge: create C driver file without statements Conflicts: preprocessor/DynareMain2.cc preprocessor/ModFile.cc preprocessor/ModFile.hh preprocessor/Statement.hh --- ComputingTasks.cc | 3 + DynamicModel.cc | 142 ++++++++++++++++++++++++++++++++++++++++++++++ DynamicModel.hh | 2 + DynareMain2.cc | 10 +++- ModFile.cc | 64 ++++++++++++++++++++- ModFile.hh | 5 ++ Statement.hh | 14 +++++ SymbolList.hh | 2 + SymbolTable.cc | 72 +++++++++++++++++++++++ SymbolTable.hh | 2 + 10 files changed, 312 insertions(+), 4 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 8f549dbf..fcbda923 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -1612,6 +1612,9 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo } } } + + if (options_list.symbol_list_options.find("ms.parameters") != options_list.symbol_list_options.end()) + mod_file_struct.ms_dsge_present = true; } void diff --git a/DynamicModel.cc b/DynamicModel.cc index 87239eea..c0363d3c 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -2956,6 +2956,148 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de } +void +DynamicModel::writeCOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const +{ + /* Writing initialisation for M_.lead_lag_incidence matrix + M_.lead_lag_incidence is a matrix with as many columns as there are + endogenous variables and as many rows as there are periods in the + models (nbr of rows = M_.max_lag+M_.max_lead+1) + + The matrix elements are equal to zero if a variable isn't present in the + model at a given period. + */ + + vector state_var, state_equ; + output << endl + << "int lead_lag_incidence[" + << max_lag+max_lead+1 <<"][" + << symbol_table.endo_nbr() << "];" << endl; + // Loop on endogenous variables + int nstatic = 0, + nfwrd = 0, + npred = 0, + nboth = 0; + for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) + { + int sstatic = 1, + sfwrd = 0, + spred = 0, + sboth = 0; + // Loop on periods + for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) + { + // Print variableID if exists with current period, otherwise print 0 + try + { + int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag); + output << "lead_lag_incidence[" << lag + max_endo_lag << "][" << endoID << "] = " + << getDynJacobianCol(varID) << ";" << endl; + if (lag == -1) + { + sstatic = 0; + spred = 1; + } + else if (lag == 1) + { + if (spred == 1) + { + sboth = 1; + spred = 0; + } + else + { + sstatic = 0; + sfwrd = 1; + } + } + } + catch (UnknownDerivIDException &e) + { + output << "lead_lag_incidence[" << lag + max_endo_lag << "][" << endoID << "] = 0;" << endl; + } + } + nstatic += sstatic; + nfwrd += sfwrd; + npred += spred; + nboth += sboth; + } + output << "int nstatic = " << nstatic << ";" << endl + << "int nfwrd = " << nfwrd << ";" << endl + << "int npred = " << npred << ";" << endl + << "int nboth = " << nboth << ";" << endl; + for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) + { + // Loop on periods + for (int lag = -max_endo_lag; lag < 0; lag++) + { + // Print variableID if exists with current period, otherwise print 0 + try + { + getDerivID(symbol_table.getID(eEndogenous, variable_reordered[endoID]), lag); + if (lag < 0 && find(state_var.begin(), state_var.end(), variable_reordered[endoID]+1) == state_var.end()) + state_var.push_back(variable_reordered[endoID]); + } + catch (UnknownDerivIDException &e) + { + } + } + } + + // Writing initialization for some other variables + output << endl + << "int state_var[" << state_var.size() << "] = {"; + for (size_t i = 0; i < state_var.size(); i++) + if (i+1 == state_var.size()) + output << state_var[i]; + else + output << state_var[i] << ", "; + output << "};" << endl; + + output << endl + << "int maximum_lag = " << max_lag << ";" << endl + << "int maximum_lead = " << max_lead << ";" << endl; + + if (symbol_table.endo_nbr()) + output << endl + << "int maximum_endo_lag = " << max_endo_lag << ";" << endl + << "int maximum_endo_lead = " << max_endo_lead << ";" << endl + << "double steady_state[" << symbol_table.endo_nbr() << "];" << endl; + + if (symbol_table.exo_nbr()) + output << endl + << "int maximum_exo_lag = " << max_exo_lag << ";" << endl + << "int maximum_exo_lead = " << max_exo_lead << ";" << endl + << "double exo_steady_state[" << symbol_table.exo_nbr() << "];" << endl; + + if (symbol_table.exo_det_nbr()) + output << endl + << "int maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl + << "int maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl + << "double exo_det_steady_state[" << symbol_table.exo_det_nbr() << "];" << endl; + + if (symbol_table.param_nbr()) + output << endl + << "double params[" << symbol_table.param_nbr() << "];" << endl; + + // Write number of non-zero derivatives + // Use -1 if the derivatives have not been computed + output << endl + << "int NNZDerivatives[3];" << endl + << "NNZDerivatives[0] = " << NNZDerivatives[0] << ";" << endl; + if (order > 1) + { + output << "NNZDerivatives[1] = " << NNZDerivatives[1] << ";" << endl; + if (order > 2) + output << "NNZDerivatives[2] = " << NNZDerivatives[2] << ";" << endl; + else + output << "NNZDerivatives[2] = -1;" << endl; + } + else + output << "NNZDerivatives[1] = -1;" << endl + << "NNZDerivatives[2] = -1;" << endl; +} + map >, expr_t> DynamicModel::collect_first_order_derivatives_endogenous() { diff --git a/DynamicModel.hh b/DynamicModel.hh index 07716efe..e23816a0 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -213,6 +213,8 @@ public: const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode); //! Writes model initialization and lead/lag incidence matrix to output void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const; + //! Writes model initialization and lead/lag incidence matrix to C output + void writeCOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const; //! Adds informations for simulation in a binary file void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, diff --git a/DynareMain2.cc b/DynareMain2.cc index 66ade0c8..c1704989 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -56,7 +56,10 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm mod_file->computingPass(no_tmp_terms); // Write outputs - mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file + if (mod_file->c_driver) + mod_file->writeCOutputFiles(basename); + else + mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif @@ -64,6 +67,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm delete mod_file; - cout << "Preprocessing completed." << endl - << "Starting MATLAB/Octave computing." << endl; + cout << "Preprocessing completed." << endl; + if (!mod_file->use_dll) + cout << "Starting MATLAB/Octave computing." << endl; } diff --git a/ModFile.cc b/ModFile.cc index 2c44e3f2..7571da2d 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -40,7 +40,7 @@ ModFile::ModFile(WarningConsolidation &warnings_arg) linear(false), block(false), byte_code(false), use_dll(false), no_static(false), differentiate_forward_vars(false), nonstationary_variables(false), ramsey_policy_orig_eqn_nbr(0), - warnings(warnings_arg) + warnings(warnings_arg), c_driver(false) { } @@ -444,6 +444,9 @@ ModFile::transformPass(bool nostrict) << "greater than or equal to the number of observed variables." << endl; exit(EXIT_FAILURE); } + + if (mod_file_struct.ms_dsge_present) + c_driver = true; } void @@ -797,3 +800,62 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b cout << "done" << endl; } + +void +ModFile::writeCOutputFiles(const string &basename) const +{ + // Erase possible remnants of previous runs + string dynfile = basename + "_dynamic.m"; + unlink(dynfile.c_str()); + + dynfile = basename + "_dynamic.c"; + unlink(dynfile.c_str()); + + dynfile = basename + "_dynamic_mex.c"; + unlink(dynfile.c_str()); + + string statfile = basename + "_static.m"; + unlink(statfile.c_str()); + + statfile = basename + "_static.c"; + unlink(statfile.c_str()); + + statfile = basename + "_static_mex.c"; + unlink(statfile.c_str()); + + string filename = "cdriver.cc"; + unlink(filename.c_str()); + + ofstream mDriverCFile; + mDriverCFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDriverCFile.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + + mDriverCFile << "/*" << endl + << " * " << filename << " : Driver file for MS-DSGE code" << endl + << " *" << endl + << " * Warning : this file is generated automatically by Dynare" << endl + << " * from model file (.mod)" << endl + << endl + << " */" << endl + << endl + << "#include \"ms_dsge_c_driver.hh\"" << endl + << endl + << "int main()" << endl + << "{" << endl; + + // Write basic info + symbol_table.writeCOutput(mDriverCFile); + + dynamic_model.writeCOutput(mDriverCFile, basename, false, false, true, mod_file_struct.order_option, mod_file_struct.estimation_present); + + mDriverCFile << "}" << endl; + mDriverCFile.close(); + + dynamic_model.writeDynamicFile(basename, false, false, true, mod_file_struct.order_option); + if (!no_static) + static_model.writeStaticFile(basename, false, false, true); +} diff --git a/ModFile.hh b/ModFile.hh index cdbca445..1f8aa0c9 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -98,6 +98,9 @@ public: /*! (i.e. option parallel_local_files of model block) */ vector parallel_local_files; + //! Output C driver file as opposed to Matlab/Octave driver file + bool c_driver; + private: //! List of statements vector statements; @@ -137,6 +140,8 @@ public: , bool cygwin, bool msvc #endif ) const; + //! Writes C output files only => No further Matlab processing + void writeCOutputFiles(const string &basename) const; }; #endif // ! MOD_FILE_HH diff --git a/Statement.hh b/Statement.hh index 7cd7b921..40e37818 100644 --- a/Statement.hh +++ b/Statement.hh @@ -105,6 +105,20 @@ public: set parameters_within_shocks_values; //! Set of estimated parameters (stored as symbol ids) set estimated_parameters; + //! Whether there is a prior statement present + bool prior_statement_present; + //! Whether there is a std prior statement present + bool std_prior_statement_present; + //! Whether there is a corr prior statement present + bool corr_prior_statement_present; + //! Whether there is a options statement present + bool options_statement_present; + //! Whether there is a std options statement present + bool std_options_statement_present; + //! Whether there is a corr options statement present + bool corr_options_statement_present; + //! Whether a Markov Switching DSGE is present + bool ms_dsge_present; }; class Statement diff --git a/SymbolList.hh b/SymbolList.hh index 45c7023f..82f0b794 100644 --- a/SymbolList.hh +++ b/SymbolList.hh @@ -43,6 +43,8 @@ public: void clear(); //! Get a copy of the string vector vector get_symbols() const { return symbols; }; + //! Is Empty + int empty() const { return symbols.empty(); }; }; #endif diff --git a/SymbolTable.cc b/SymbolTable.cc index 1c8652e5..9f670e7f 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -286,6 +286,78 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) } } +void +SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException) +{ + if (!frozen) + throw NotYetFrozenException(); + + output << endl + << "map exo_names, exo_det_names, endo_names, param_names;" << endl; + + output << endl + << "int exo_nbr = " << exo_nbr() << ";" << endl; + if (exo_nbr() > 0) + for (int id = 0; id < exo_nbr(); id++) + output << "exo_names[\"" << getName(exo_ids[id]) << "\"] = " << id << ";" << endl; + + output << endl + << "int exo_det_nbr = " << exo_det_nbr() << ";" << endl; + if (exo_det_nbr() > 0) + for (int id = 0; id < exo_det_nbr(); id++) + output << "exo_det_names[\"" << getName(exo_det_ids[id]) << "\"] = " << id << " ;" << endl; + + output << endl + << "int endo_nbr = " << endo_nbr() << ";" << endl + << "int orig_endo_nbr = " << orig_endo_nbr() << ";" << endl; + if (endo_nbr() > 0) + for (int id = 0; id < endo_nbr(); id++) + output << "endo_names[\"" << getName(endo_ids[id]) << "\"] = " << id << ";" << endl; + + output << endl + << "int param_nbr = " << param_nbr() << ";" << endl; + if (param_nbr() > 0) + for (int id = 0; id < param_nbr(); id++) + output << "param_names[\"" << getName(param_ids[id]) << "\"] = " << id << ";" << endl; + + // Write the auxiliary variable table + output << endl + << "vector aux_vars;" << endl; + if (aux_vars.size() > 0) + for (int i = 0; i < (int) aux_vars.size(); i++) + { + output << "aux_vars_t av" << i << ";" << endl; + output << "av" << i << ".endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id()) << ";" << endl + << "av" << i << ".type = " << aux_vars[i].get_type() << ";" << endl; + switch (aux_vars[i].get_type()) + { + case avEndoLead: + case avExoLead: + case avExpectation: + case avMultiplier: + break; + case avEndoLag: + case avExoLag: + output << "av" << i << ".orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl + << "av" << i << ".orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; + break; + } + output << "aux_vars.push_back(" << "av" << i << ");" << endl; + } + + output << endl + << "vector predetermined_variables, varobs;" << endl; + if (predeterminedNbr() > 0) + for (set::const_iterator it = predetermined_variables.begin(); + it != predetermined_variables.end(); it++) + output << "predetermined_variables.push_back(" << getTypeSpecificID(*it) << ");" << endl; + + if (observedVariablesNbr() > 0) + for (vector::const_iterator it = varobs.begin(); + it != varobs.end(); it++) + output << "varobs.push_back(" << getTypeSpecificID(*it) << ");" << endl; +} + int SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index) throw (FrozenException) { diff --git a/SymbolTable.hh b/SymbolTable.hh index 49c20855..c8716014 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -276,6 +276,8 @@ public: inline int orig_endo_nbr() const throw (NotYetFrozenException); //! Write output of this class void writeOutput(ostream &output) const throw (NotYetFrozenException); + //! Write C output of this class + void writeCOutput(ostream &output) const throw (NotYetFrozenException); //! Mark a symbol as predetermined variable void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException); //! Test if a given symbol is a predetermined variable