diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 6057fad5378f7d8e08f5d8c5a1ffaee6de33403c..4e95890d2a3ccf4c6f9e6d164f7abcb6018d9ec0 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -397,6 +397,109 @@ RamseyModelStatement::writeOutput(ostream &output, const string &basename, bool options_list.writeOutput(output); } +RamseyConstraintsStatement::RamseyConstraintsStatement(const constraints_t &constraints_arg) : + constraints(constraints_arg) +{ +} + +void +RamseyConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +{ + if ((mod_file_struct.ramsey_model_present != true) || ( mod_file_struct.ramsey_policy_present != true)) + cerr << "ramsey_constraints: can only be used with ramsey_model or ramsey_policy" << endl; +} + +void +RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const +{ + output << "M_.ramsey_model_constraints = {" << endl; + for (RamseyConstraintsStatement::constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); ++it) + { + if (it != constraints.begin()) + output << ", "; + output << "{" << it->endo + 1 << ", '"; + switch(it->code) + { + case oLess: + output << '<'; + break; + case oGreater: + output << '>'; + break; + case oLessEqual: + output << "<="; + break; + case oGreaterEqual: + output << ">="; + break; + default: + cerr << "Ramsey constraints: this shouldn't happen." << endl; + exit(1); + } + output << "', '"; + it->expression->writeOutput(output); + output << "'}" << endl; + } + output << "};" << endl; +} + +// Statement * +// RamseyConstraintsStatement::cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) +// { +// vector<string> errors; +// SymbolList new_symbol_list, new_options_symbol_list; +// OptionsList new_options_list = options_list; +// SymbolTable *new_symbol_table = dynamic_datatree.getSymbolTable(); +// vector<string> symbols = symbol_list.get_symbols(); + +// for (vector<string>::const_iterator it = symbols.begin(); it != symbols.end(); it++) +// try +// { +// new_symbol_table->getID(*it); +// new_symbol_list.addSymbol(*it); +// } +// catch (SymbolTable::UnknownSymbolIDException &e) +// { +// errors.push_back(orig_symbol_table.getName(e.id)); +// } +// catch (SymbolTable::UnknownSymbolNameException &e) +// { +// errors.push_back(e.name); +// } + +// OptionsList::symbol_list_options_t::const_iterator it = options_list.symbol_list_options.find("instruments"); +// if (it != options_list.symbol_list_options.end()) +// { +// symbols = it->second.get_symbols(); +// for (vector<string>::const_iterator it1 = symbols.begin(); it1 != symbols.end(); it1++) +// try +// { +// new_symbol_table->getID(*it1); +// new_options_symbol_list.addSymbol(*it1); +// } +// catch (SymbolTable::UnknownSymbolIDException &e) +// { +// errors.push_back(orig_symbol_table.getName(e.id)); +// } +// catch (SymbolTable::UnknownSymbolNameException &e) +// { +// errors.push_back(e.name); +// } +// new_options_list.symbol_list_options["instruments"] = new_options_symbol_list; +// } + +// if (!errors.empty()) +// { +// cerr << endl +// << "ERROR: The following vars were used in the ramsey_policy statement(s) but were not declared." << endl +// << " This likely means that you declared them as varexo and that they're not in the model" << endl; +// for (vector<string>::const_iterator it = errors.begin(); it != errors.end(); it++) +// cerr << *it << endl; +// exit(EXIT_FAILURE); +// } +// return new RamseyPolicyStatement(new_symbol_list, options_list); +// } + RamseyPolicyStatement::RamseyPolicyStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 572d8016d6c771b43943c548d452c5282df2bce0..b9b65d465795d869150424a93eb4347e0164037e 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -125,6 +125,24 @@ public: virtual Statement *cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table); }; +class RamseyConstraintsStatement : public Statement +{ +public: + struct Constraint { + int endo; + BinaryOpcode code; + expr_t expression; + }; + typedef vector<Constraint> constraints_t; +private: + const constraints_t constraints; +public: + RamseyConstraintsStatement(const constraints_t &constraints_arg); + virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); + virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + // virtual Statement *cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table); +}; + class RamseyPolicyStatement : public Statement { private: diff --git a/DynareBison.yy b/DynareBison.yy index 5893b6dc154e60e931bf91348ab233eb99a2c4c6..d886fb0f6f2c3a02f623497b094178f91f33851f 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -122,7 +122,7 @@ class ParsingDriver; %token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD %token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS %token STDERR STEADY STOCH_SIMUL SURPRISE SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME -%token TEX RAMSEY_MODEL RAMSEY_POLICY PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL +%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL %token <string_val> TEX_NAME %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED %token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES @@ -239,7 +239,8 @@ statement : parameters | planner_objective | ramsey_model | ramsey_policy - | discretionary_policy + | ramsey_constraints + | discretionary_policy | bvar_density | bvar_forecast | sbvar @@ -1903,6 +1904,24 @@ ramsey_policy : RAMSEY_POLICY ';' { driver.ramsey_policy(); } ; +ramsey_constraints : RAMSEY_CONSTRAINTS ';' ramsey_constraints_list END ';' + { driver.add_ramsey_constraints_statement(); } + ; + +ramsey_constraints_list : ramsey_constraints_list ramsey_constraint + | ramsey_constraint + ; + +ramsey_constraint : NAME LESS expression ';' + { driver.ramsey_constraint_add_less($1,$3); } + | NAME GREATER expression ';' + { driver.ramsey_constraint_add_greater($1,$3); } + | NAME LESS_EQUAL expression ';' + { driver.ramsey_constraint_add_less_equal($1,$3); } + | NAME GREATER expression ';' + { driver.ramsey_constraint_add_greater_equal($1,$3); } + ; + discretionary_policy : DISCRETIONARY_POLICY ';' { driver.discretionary_policy(); } | DISCRETIONARY_POLICY '(' discretionary_policy_options_list ')' ';' diff --git a/DynareFlex.ll b/DynareFlex.ll index 92d52ecfe64c42049c56eae44838b17a8e250d03..5dcd575d28de12abecbbb7af708561c723f10f27 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -199,6 +199,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 <INITIAL>svar_identification {BEGIN DYNARE_BLOCK; return token::SVAR_IDENTIFICATION;} <INITIAL>moment_calibration {BEGIN DYNARE_BLOCK; return token::MOMENT_CALIBRATION;} <INITIAL>irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;} +<INITIAL>ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;} /* For the semicolon after an "end" keyword */ <INITIAL>; {return Dynare::parser::token_type (yytext[0]);} diff --git a/ParsingDriver.cc b/ParsingDriver.cc index ba541ec818e250c5f2acef060062be0457151306..94679f0aab21956de7b0217eb168c22453b011f7 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -2772,3 +2772,54 @@ ParsingDriver::perfect_foresight_solver() mod_file->addStatement(new PerfectForesightSolverStatement(options_list)); options_list.clear(); } + +void +ParsingDriver::add_ramsey_constraints_statement() +{ + mod_file->addStatement(new RamseyConstraintsStatement(ramsey_constraints)); + ramsey_constraints.clear(); +} + +void +ParsingDriver::ramsey_constraint_add_less(const string *name, const expr_t rhs) +{ + add_ramsey_constraint(name,oLess,rhs); +} + +void +ParsingDriver::ramsey_constraint_add_greater(const string *name, const expr_t rhs) +{ + add_ramsey_constraint(name,oGreater,rhs); +} + +void +ParsingDriver::ramsey_constraint_add_less_equal(const string *name, const expr_t rhs) +{ + add_ramsey_constraint(name,oLessEqual,rhs); +} + +void +ParsingDriver::ramsey_constraint_add_greater_equal(const string *name, const expr_t rhs) +{ + add_ramsey_constraint(name,oGreaterEqual,rhs); +} + +void +ParsingDriver::add_ramsey_constraint(const string *name, BinaryOpcode op_code, const expr_t rhs) +{ + check_symbol_existence(*name); + int symb_id = mod_file->symbol_table.getID(*name); + SymbolType type = mod_file->symbol_table.getType(symb_id); + + if (type != eEndogenous) + error("ramsey_constraints: " + *name + " should be an endogenous variable"); + + RamseyConstraintsStatement::Constraint C; + C.endo = symb_id; + C.code = op_code; + C.expression = rhs; + ramsey_constraints.push_back(C); + + delete name; +} + diff --git a/ParsingDriver.hh b/ParsingDriver.hh index dd93276c08e2b9f96b6cf861ca2299fd9563cae3..d7da536cd0c56d6b5fe6549f32a78b51d0393d0f 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -157,6 +157,8 @@ private: MomentCalibration::constraints_t moment_calibration_constraints; //! Temporary storage for irf_calibration IrfCalibration::constraints_t irf_calibration_constraints; + //! Temporary storage for ramsey_constraints + RamseyConstraintsStatement::constraints_t ramsey_constraints; //! Temporary storage for svar_identification blocks SvarIdentificationStatement::svar_identification_restrictions_t svar_ident_restrictions; //! Temporary storage for mapping the equation number to the restrictions within an svar_identification block @@ -506,6 +508,18 @@ public: void end_planner_objective(expr_t expr); //! Ramsey model statement void ramsey_model(); + //! Ramsey constraints statement + void add_ramsey_constraints_statement(); + //! Ramsey less constraint + void ramsey_constraint_add_less(const string *name, const expr_t rhs); + //! Ramsey greater constraint + void ramsey_constraint_add_greater(const string *name, const expr_t rhs); + //! Ramsey less or equal constraint + void ramsey_constraint_add_less_equal(const string *name, const expr_t rhs); + //! Ramsey greater or equal constraint + void ramsey_constraint_add_greater_equal(const string *name, const expr_t rhs); + //! Ramsey constraint helper function + void add_ramsey_constraint(const string *name, BinaryOpcode op_code, const expr_t rhs); //! Ramsey policy statement void ramsey_policy(); //! Discretionary policy statement