new nostrict command-line option does not exit when there are more endogenous than equations (closes #2)

issue#70
Houtan Bastani 2013-09-13 14:37:31 -04:00
parent 3e1cc9a2d3
commit 76714b34df
9 changed files with 95 additions and 9 deletions

View File

@ -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

View File

@ -3568,6 +3568,13 @@ DynamicModel::toStatic(StaticModel &static_model) const
static_model.addAuxEquation((*it)->toStatic(static_model));
}
void
DynamicModel::findUnusedEndogenous(set<int> &unusedEndogs)
{
for (int i = 0; i < (int) equations.size(); i++)
equations[i]->findUnusedEndogenous(unusedEndogs);
}
void
DynamicModel::computeDerivIDs()
{

View File

@ -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<int> &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;

View File

@ -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 &parallel_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<variable>[=<value>]]"
<< " [-D<variable>[=<value>]] [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<string, string> 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

View File

@ -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 &parallel_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

View File

@ -333,6 +333,11 @@ NumConstNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result
{
}
void
NumConstNode::findUnusedEndogenous(set<int> &unusedEndogs) const
{
}
pair<int, expr_t >
NumConstNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &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<pair<int, int> > &result
datatree.local_variables_table[symb_id]->collectVariables(type_arg, result);
}
void
VariableNode::findUnusedEndogenous(set<int> &unusedEndogs) const
{
set<int>::iterator it = unusedEndogs.find(symb_id);
if (it != unusedEndogs.end())
unusedEndogs.erase(it);
}
pair<int, expr_t>
VariableNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
@ -953,6 +971,9 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &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<pair<int, int> > &result)
arg->collectVariables(type_arg, result);
}
void
UnaryOpNode::findUnusedEndogenous(set<int> &unusedEndogs) const
{
arg->findUnusedEndogenous(unusedEndogs);
}
pair<int, expr_t>
UnaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
@ -3063,6 +3090,13 @@ BinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result
arg2->collectVariables(type_arg, result);
}
void
BinaryOpNode::findUnusedEndogenous(set<int> &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<pair<int, int> > &resul
arg3->collectVariables(type_arg, result);
}
void
TrinaryOpNode::findUnusedEndogenous(set<int> &unusedEndogs) const
{
arg1->findUnusedEndogenous(unusedEndogs);
arg2->findUnusedEndogenous(unusedEndogs);
arg3->findUnusedEndogenous(unusedEndogs);
}
pair<int, expr_t>
TrinaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
@ -4594,6 +4636,14 @@ ExternalFunctionNode::collectVariables(SymbolType type_arg, set<pair<int, int> >
(*it)->collectVariables(type_arg, result);
}
void
ExternalFunctionNode::findUnusedEndogenous(set<int> &unusedEndogs) const
{
for (vector<expr_t>::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
{

View File

@ -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<int> &unusedEndogs) const = 0;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &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<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &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<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &unusedEndogs) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
@ -560,6 +565,7 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &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<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &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<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &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<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void findUnusedEndogenous(set<int> &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,

View File

@ -266,8 +266,20 @@ ModFile::checkPass()
}
void
ModFile::transformPass()
ModFile::transformPass(bool nostrict)
{
if (nostrict)
{
set<int> unusedEndogs = symbol_table.getEndogenous();
dynamic_model.findUnusedEndogenous(unusedEndogs);
for (set<int>::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)

View File

@ -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);