From 76714b34df2d06f49ddab1060f8eb28adb02435c Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 13 Sep 2013 14:37:31 -0400 Subject: [PATCH] new nostrict command-line option does not exit when there are more endogenous than equations (closes #2) --- CodeInterpreter.hh | 3 ++- DynamicModel.cc | 7 +++++++ DynamicModel.hh | 3 +++ DynareMain.cc | 9 ++++++--- DynareMain2.cc | 4 ++-- ExprNode.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++ ExprNode.hh | 9 +++++++++ ModFile.cc | 17 ++++++++++++++-- ModFile.hh | 2 +- 9 files changed, 95 insertions(+), 9 deletions(-) diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh index f8b591a6..e4e3e103 100644 --- a/CodeInterpreter.hh +++ b/CodeInterpreter.hh @@ -149,7 +149,8 @@ enum SymbolType eExternalFunction = 12, //!< External (user-defined) function eTrend = 13, //!< Trend variable eStatementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example) - eLogTrend = 15 //!< Log-trend variable + eLogTrend = 15, //!< Log-trend variable + eUnusedEndogenous = 16 }; enum ExpressionType diff --git a/DynamicModel.cc b/DynamicModel.cc index 82c51e94..52eabbed 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3568,6 +3568,13 @@ DynamicModel::toStatic(StaticModel &static_model) const static_model.addAuxEquation((*it)->toStatic(static_model)); } +void +DynamicModel::findUnusedEndogenous(set &unusedEndogs) +{ + for (int i = 0; i < (int) equations.size(); i++) + equations[i]->findUnusedEndogenous(unusedEndogs); +} + void DynamicModel::computeDerivIDs() { diff --git a/DynamicModel.hh b/DynamicModel.hh index 808dccaa..8cc151a3 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -222,6 +222,9 @@ public: /*! It assumes that the static model given in argument has just been allocated */ void toStatic(StaticModel &static_model) const; + //! Find endogenous variables not used in model + void findUnusedEndogenous(set &unusedEndogs); + //! Copies a dynamic model (only the equations) /*! It assumes that the dynamic model given in argument has just been allocated */ void cloneDynamic(DynamicModel &dynamic_model) const; diff --git a/DynareMain.cc b/DynareMain.cc index f62f6039..44227c9c 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -38,7 +38,7 @@ using namespace std; */ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test + bool parallel_test, bool nostrict #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -49,7 +49,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] " - << " [-D[=]]" + << " [-D[=]] [nostrict]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -95,6 +95,7 @@ main(int argc, char **argv) string cluster_name; bool parallel_slave_open_mode = false; bool parallel_test = false; + bool nostrict = false; map defines; // Parse options @@ -154,6 +155,8 @@ main(int argc, char **argv) parallel_slave_open_mode = true; else if (!strcmp(argv[arg], "parallel_test")) parallel_test = true; + else if (!strcmp(argv[arg], "nostrict")) + nostrict = true; else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8)) { parallel = true; @@ -228,7 +231,7 @@ main(int argc, char **argv) // Do the rest main2(macro_output, basename, debug, clear_all, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, - parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test + parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/DynareMain2.cc b/DynareMain2.cc index aed6e4e6..a8f17602 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -28,7 +28,7 @@ using namespace std; void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test + bool parallel_test, bool nostrict #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -48,7 +48,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm config_file.checkPass(warnings); // Perform transformations on the model (creation of auxiliary vars and equations) - mod_file->transformPass(); + mod_file->transformPass(nostrict); config_file.transformPass(); // Evaluate parameters initialization, initval, endval and pounds diff --git a/ExprNode.cc b/ExprNode.cc index 930ee3e0..e3a5bad8 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -333,6 +333,11 @@ NumConstNode::collectVariables(SymbolType type_arg, set > &result { } +void +NumConstNode::findUnusedEndogenous(set &unusedEndogs) const +{ +} + pair NumConstNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -522,6 +527,7 @@ VariableNode::prepareForDerivation() break; case eModFileLocalVariable: case eStatementDeclaredVariable: + case eUnusedEndogenous: // Such a variable is never derived break; case eExternalFunction: @@ -553,6 +559,9 @@ VariableNode::computeDerivative(int deriv_id) case eStatementDeclaredVariable: cerr << "eStatementDeclaredVariable is not derivable" << endl; exit(EXIT_FAILURE); + case eUnusedEndogenous: + cerr << "eUnusedEndogenous is not derivable" << endl; + exit(EXIT_FAILURE); case eExternalFunction: cerr << "Impossible case!" << endl; exit(EXIT_FAILURE); @@ -767,6 +776,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case eTrend: case eLogTrend: case eStatementDeclaredVariable: + case eUnusedEndogenous: cerr << "Impossible case" << endl; exit(EXIT_FAILURE); } @@ -877,6 +887,14 @@ VariableNode::collectVariables(SymbolType type_arg, set > &result datatree.local_variables_table[symb_id]->collectVariables(type_arg, result); } +void +VariableNode::findUnusedEndogenous(set &unusedEndogs) const +{ + set::iterator it = unusedEndogs.find(symb_id); + if (it != unusedEndogs.end()) + unusedEndogs.erase(it); +} + pair VariableNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -953,6 +971,9 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map &recur case eStatementDeclaredVariable: cerr << "eStatementDeclaredVariable is not derivable" << endl; exit(EXIT_FAILURE); + case eUnusedEndogenous: + cerr << "eUnusedEndogenous is not derivable" << endl; + exit(EXIT_FAILURE); case eExternalFunction: cerr << "Impossible case!" << endl; exit(EXIT_FAILURE); @@ -1991,6 +2012,12 @@ UnaryOpNode::collectVariables(SymbolType type_arg, set > &result) arg->collectVariables(type_arg, result); } +void +UnaryOpNode::findUnusedEndogenous(set &unusedEndogs) const +{ + arg->findUnusedEndogenous(unusedEndogs); +} + pair UnaryOpNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -3063,6 +3090,13 @@ BinaryOpNode::collectVariables(SymbolType type_arg, set > &result arg2->collectVariables(type_arg, result); } +void +BinaryOpNode::findUnusedEndogenous(set &unusedEndogs) const +{ + arg1->findUnusedEndogenous(unusedEndogs); + arg2->findUnusedEndogenous(unusedEndogs); +} + expr_t BinaryOpNode::Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const { @@ -4034,6 +4068,14 @@ TrinaryOpNode::collectVariables(SymbolType type_arg, set > &resul arg3->collectVariables(type_arg, result); } +void +TrinaryOpNode::findUnusedEndogenous(set &unusedEndogs) const +{ + arg1->findUnusedEndogenous(unusedEndogs); + arg2->findUnusedEndogenous(unusedEndogs); + arg3->findUnusedEndogenous(unusedEndogs); +} + pair TrinaryOpNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -4594,6 +4636,14 @@ ExternalFunctionNode::collectVariables(SymbolType type_arg, set > (*it)->collectVariables(type_arg, result); } +void +ExternalFunctionNode::findUnusedEndogenous(set &unusedEndogs) const +{ + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->findUnusedEndogenous(unusedEndogs); +} + void ExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const { diff --git a/ExprNode.hh b/ExprNode.hh index 917643f1..d251f332 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -236,6 +236,9 @@ public: virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const = 0; + //! Removes used endogenous variables from the provided list of endogs + virtual void findUnusedEndogenous(set &unusedEndogs) const = 0; + virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, map > &first_occurence, @@ -436,6 +439,7 @@ public: virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; @@ -481,6 +485,7 @@ public: virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, map > &first_occurence, @@ -560,6 +565,7 @@ public: vector< vector > &v_temporary_terms, int equation) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException); virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -638,6 +644,7 @@ public: vector< vector > &v_temporary_terms, int equation) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException); virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -732,6 +739,7 @@ public: vector< vector > &v_temporary_terms, int equation) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException); virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -803,6 +811,7 @@ public: vector< vector > &v_temporary_terms, int equation) const; virtual void collectVariables(SymbolType type_arg, set > &result) const; + virtual void findUnusedEndogenous(set &unusedEndogs) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); unsigned int compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, diff --git a/ModFile.cc b/ModFile.cc index 13a7641f..4ef0ab43 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -266,8 +266,20 @@ ModFile::checkPass() } void -ModFile::transformPass() +ModFile::transformPass(bool nostrict) { + if (nostrict) + { + set unusedEndogs = symbol_table.getEndogenous(); + dynamic_model.findUnusedEndogenous(unusedEndogs); + for (set::iterator it = unusedEndogs.begin(); it != unusedEndogs.end(); it++) + { + symbol_table.changeType(*it, eUnusedEndogenous); + warnings << "WARNING: '" << symbol_table.getName(*it) + << "' not used in model block, removed by nostrict command-line option" << endl; + } + } + if (symbol_table.predeterminedNbr() > 0) dynamic_model.transformPredeterminedVariables(); @@ -344,9 +356,10 @@ ModFile::transformPass() symbol_table.freeze(); /* - Enforce the same number of equations and endogenous, except in two cases: + Enforce the same number of equations and endogenous, except in three cases: - ramsey_policy is used - a BVAR command is used and there is no equation (standalone BVAR estimation) + - nostrict option is passed and there are more endogs than equations (dealt with before freeze) */ if (!(mod_file_struct.ramsey_policy_present || mod_file_struct.discretionary_policy_present) && !(mod_file_struct.bvar_present && dynamic_model.equation_number() == 0) diff --git a/ModFile.hh b/ModFile.hh index 28a4a2f4..cdbca445 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -118,7 +118,7 @@ public: /*! \todo add check for number of equations and endogenous if ramsey_policy is present */ void checkPass(); //! Perform some transformations on the model (creation of auxiliary vars and equations) - void transformPass(); + void transformPass(bool nostrict); //! Execute computations /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */ void computingPass(bool no_tmp_terms);