diff --git a/DynareBison.yy b/DynareBison.yy index a4a0885bcbec49e0a8cdc214842c86deb41e3b69..ce4c49fb36a288085c1991c5eedf7506055bacdd 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -94,7 +94,7 @@ class ParsingDriver; %token BVAR_DENSITY BVAR_FORECAST %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN -%token BVAR_REPLIC BYTECODE +%token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED %token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF CYCLE_REDUCTION LOGARITHMIC_REDUCTION %token DATAFILE FILE DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH @@ -130,7 +130,7 @@ class ParsingDriver; %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE %token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL -%token XLS_SHEET XLS_RANGE +%token XLS_SHEET XLS_RANGE %left COMMA %left EQUAL_EQUAL EXCLAMATION_EQUAL %left LESS GREATER LESS_EQUAL GREATER_EQUAL @@ -510,13 +510,20 @@ expression_or_empty : {$$ = driver.add_nan_constant();} ; initval : INITVAL ';' initval_list END ';' - { driver.end_initval(); } + { driver.end_initval(false); } + | INITVAL '(' ALL_VALUES_REQUIRED ')' ';' initval_list END ';' + { driver.end_initval(true); } + ; initval_file : INITVAL_FILE '(' FILENAME EQUAL filename ')' ';' { driver.initval_file($5); } ; -endval : ENDVAL ';' initval_list END ';' { driver.end_endval(); }; +endval : ENDVAL ';' initval_list END ';' + { driver.end_endval(false); } + | ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' initval_list END ';' + { driver.end_endval(true); } + ; initval_list : initval_list initval_elem | initval_elem diff --git a/DynareFlex.ll b/DynareFlex.ll index 14cc17c9ee647f48482164f53f2aa091d0ca69ed..eba4ff972f4b009ccb999cc2896fbd1abd6425f1 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -555,6 +555,7 @@ string eofbuff; <DYNARE_BLOCK>use_dll {return token::USE_DLL;} <DYNARE_BLOCK>block {return token::BLOCK;} <DYNARE_BLOCK>bytecode {return token::BYTECODE;} +<DYNARE_BLOCK>all_values_required {return token::ALL_VALUES_REQUIRED;} <DYNARE_BLOCK>no_static {return token::NO_STATIC;} <DYNARE_STATEMENT,DYNARE_BLOCK>linear {return token::LINEAR;} diff --git a/NumericalInitialization.cc b/NumericalInitialization.cc index 98327d66383d53cf03f3f821dbeebad8a2d69633..1c26d74f559a61c7a33976cebc61f53c84a468c3 100644 --- a/NumericalInitialization.cc +++ b/NumericalInitialization.cc @@ -64,9 +64,11 @@ InitParamStatement::fillEvalContext(eval_context_t &eval_context) const } InitOrEndValStatement::InitOrEndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg) : + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg) : init_values(init_values_arg), - symbol_table(symbol_table_arg) + symbol_table(symbol_table_arg), + all_values_required(all_values_required_arg) { } @@ -87,6 +89,34 @@ InitOrEndValStatement::fillEvalContext(eval_context_t &eval_context) const } } +set<int> +InitOrEndValStatement::getUninitializedVariables(SymbolType type) +{ + set<int> unused; + if (!all_values_required) + return unused; + + if (type == eEndogenous) + unused = symbol_table.getEndogenous(); + else if (type == eExogenous) + unused = symbol_table.getExogenous(); + else + { + cerr << "ERROR: Shouldn't arrive here." << endl; + exit(EXIT_FAILURE); + } + + set<int>::iterator sit; + for (init_values_t::const_iterator it = init_values.begin(); + it != init_values.end(); it++) + { + sit = unused.find(it->first); + if (sit != unused.end()) + unused.erase(sit); + } + return unused; +} + void InitOrEndValStatement::writeInitValues(ostream &output) const { @@ -113,9 +143,36 @@ InitOrEndValStatement::writeInitValues(ostream &output) const } InitValStatement::InitValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg) : - InitOrEndValStatement(init_values_arg, symbol_table_arg) + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg) : + InitOrEndValStatement(init_values_arg, symbol_table_arg, all_values_required_arg) +{ +} + +void +InitValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { + set<int> exogs = getUninitializedVariables(eExogenous); + set<int> endogs = getUninitializedVariables(eEndogenous); + + if (endogs.size() > 0) + { + cerr << "ERROR: You have not set the following endogenous variables in initval:"; + for (set<int>::const_iterator it = endogs.begin(); it != endogs.end(); it++) + cerr << " " << symbol_table.getName(*it); + cerr << endl; + } + + if (exogs.size() > 0) + { + cerr << "ERROR: You have not set the following exogenous variables in initval:"; + for (set<int>::const_iterator it = exogs.begin(); it != exogs.end(); it++) + cerr << " " << symbol_table.getName(*it); + cerr << endl; + } + + if (endogs.size() > 0 || exogs.size() > 0) + exit(EXIT_FAILURE); } void @@ -142,14 +199,37 @@ InitValStatement::writeOutputPostInit(ostream &output) const } EndValStatement::EndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg) : - InitOrEndValStatement(init_values_arg, symbol_table_arg) + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg) : + InitOrEndValStatement(init_values_arg, symbol_table_arg, all_values_required_arg) { } void EndValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { + set<int> exogs = getUninitializedVariables(eExogenous); + set<int> endogs = getUninitializedVariables(eEndogenous); + + if (endogs.size() > 0) + { + cerr << "ERROR: You have not set the following endogenous variables in endval:"; + for (set<int>::const_iterator it = endogs.begin(); it != endogs.end(); it++) + cerr << " " << symbol_table.getName(*it); + cerr << endl; + } + + if (exogs.size() > 0) + { + cerr << "ERROR: You have not set the following exogenous variables in endval:"; + for (set<int>::const_iterator it = exogs.begin(); it != exogs.end(); it++) + cerr << " " << symbol_table.getName(*it); + cerr << endl; + } + + if (endogs.size() > 0 || exogs.size() > 0) + exit(EXIT_FAILURE); + if (mod_file_struct.shocks_present_but_simul_not_yet) { cerr << "ERROR: Putting a \"shocks\" block before an \"endval\" block is not permitted. Please swap the two blocks. This limitation will be removed in a future release of Dynare." << endl; diff --git a/NumericalInitialization.hh b/NumericalInitialization.hh index e5ae059c1fdffe7d34e51383ed98a6774958a2c2..f92144103dd7bebd55405988c4475415c171fc55 100644 --- a/NumericalInitialization.hh +++ b/NumericalInitialization.hh @@ -56,9 +56,13 @@ public: protected: const init_values_t init_values; const SymbolTable &symbol_table; + const bool all_values_required; public: InitOrEndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg); + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg); + //! Return set of unused variables by type + set<int> getUninitializedVariables(SymbolType type); //! Fill eval context with variables values void fillEvalContext(eval_context_t &eval_context) const; protected: @@ -69,7 +73,9 @@ class InitValStatement : public InitOrEndValStatement { public: InitValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg); + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg); + virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; //! Writes initializations for oo_.exo_simul and oo_.exo_det_simul void writeOutputPostInit(ostream &output) const; @@ -79,7 +85,8 @@ class EndValStatement : public InitOrEndValStatement { public: EndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg); + const SymbolTable &symbol_table_arg, + const bool &all_values_required_arg); //! Workaround for trac ticket #35 virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 76a4e951546b7783974a743e93d1413ab08eab74..ee72245f6f53fdaf9d6f10e02ba2804d5638dc05 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -519,16 +519,16 @@ ParsingDriver::transform_logpow() } void -ParsingDriver::end_initval() +ParsingDriver::end_initval(bool all_values_required) { - mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table)); + mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table, all_values_required)); init_values.clear(); } void -ParsingDriver::end_endval() +ParsingDriver::end_endval(bool all_values_required) { - mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table)); + mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table, all_values_required)); init_values.clear(); } diff --git a/ParsingDriver.hh b/ParsingDriver.hh index fdf188c3aed378e204b02522e5b4b50d7517e7bf..203ab6c8b27963d31e6fcfc1939428a6281c6940 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -300,9 +300,9 @@ public: /*! Second argument "val1" can be NULL if no initial value provided */ void homotopy_val(string *name, expr_t val1, expr_t val2); //! Writes end of an initval block - void end_initval(); + void end_initval(bool all_values_required); //! Writes end of an endval block - void end_endval(); + void end_endval(bool all_values_required); //! Writes end of an histval block void end_histval(); //! Writes end of an homotopy_setup block diff --git a/SymbolTable.cc b/SymbolTable.cc index f68d879e1191f00565649fe77e9d51a3d27aef71..a53dc9a27cf80db44f2e77d02f82cf92a5ba6f32 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -506,3 +506,25 @@ SymbolTable::getTrendVarIds() const trendVars.push_back(it->second); return trendVars; } + +set<int> +SymbolTable::getExogenous() const +{ + set <int> exogs; + for (symbol_table_type::const_iterator it = symbol_table.begin(); + it != symbol_table.end(); it++) + if (getType(it->second) == eExogenous) + exogs.insert(it->second); + return exogs; +} + +set<int> +SymbolTable::getEndogenous() const +{ + set <int> endogs; + for (symbol_table_type::const_iterator it = symbol_table.begin(); + it != symbol_table.end(); it++) + if (getType(it->second) == eEndogenous) + endogs.insert(it->second); + return endogs; +} diff --git a/SymbolTable.hh b/SymbolTable.hh index 8b3763c5eb4fb73c4b72cd95dbcc3908dd4f38e4..a9b7e460e09cf605f03e6912a8d0290131c4a150 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -293,6 +293,10 @@ public: //! Return the index of a given observed variable in the vector of all observed variables int getObservedVariableIndex(int symb_id) const; vector <int> getTrendVarIds() const; + //! Get list of exogenous variables + set <int> getExogenous() const; + //! Get list of endogenous variables + set <int> getEndogenous() const; }; inline bool