Commit 053ee41a authored by Houtan Bastani's avatar Houtan Bastani Committed by MichelJuillard
Browse files

ms-dsge: create C driver file without statements

Conflicts:
	preprocessor/DynareMain2.cc
	preprocessor/ModFile.cc
	preprocessor/ModFile.hh
	preprocessor/Statement.hh
parent 51649194
......@@ -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
......
......@@ -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<int> 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<pair<int, pair<int, int > >, expr_t>
DynamicModel::collect_first_order_derivatives_endogenous()
{
......
......@@ -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,
......
......@@ -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;
}
......@@ -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);
}
......@@ -98,6 +98,9 @@ public:
/*! (i.e. option parallel_local_files of model block) */
vector<string> parallel_local_files;
//! Output C driver file as opposed to Matlab/Octave driver file
bool c_driver;
private:
//! List of statements
vector<Statement *> 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
......@@ -105,6 +105,20 @@ public:
set<int> parameters_within_shocks_values;
//! Set of estimated parameters (stored as symbol ids)
set<int> 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
......
......@@ -43,6 +43,8 @@ public:
void clear();
//! Get a copy of the string vector
vector<string> get_symbols() const { return symbols; };
//! Is Empty
int empty() const { return symbols.empty(); };
};
#endif
......@@ -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 <string, int > 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_t> 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 <int> predetermined_variables, varobs;" << endl;
if (predeterminedNbr() > 0)
for (set<int>::const_iterator it = predetermined_variables.begin();
it != predetermined_variables.end(); it++)
output << "predetermined_variables.push_back(" << getTypeSpecificID(*it) << ");" << endl;
if (observedVariablesNbr() > 0)
for (vector<int>::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)
{
......
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment