diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 6a4885da4638a2680562d7dce0f798682690b012..37ee1ec0f281ccd9d31f60b7dfca616132d38690 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3898,6 +3898,7 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam int discount_symb_id, int pac_eq_max_lag, expr_t growth_correction_term, + string auxname, ExprNode::subst_table_t &diff_subst_table, map<string, int> &pac_aux_var_symb_ids, map<string, vector<int>> &pac_aux_param_symb_ids, @@ -3916,7 +3917,9 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam int neqs = 0; // Create the endogenous representing Z₁ (no orig_expr is given since its definition is recursive) - int mce_z1_symb_id = symbol_table.addPacExpectationAuxiliaryVar("mce_Z1_" + name, nullptr); + if (auxname.empty()) + auxname = "mce_Z1_" + name; + int mce_z1_symb_id = symbol_table.addPacExpectationAuxiliaryVar(auxname, nullptr); pac_aux_var_symb_ids[name] = mce_z1_symb_id; expr_t A = One; @@ -4032,6 +4035,7 @@ DynamicModel::computePacBackwardExpectationSubstitution(const string &name, int max_lag, const string &aux_model_type, expr_t growth_correction_term, + string auxname, map<string, int> &pac_aux_var_symb_ids, map<string, vector<int>> &pac_aux_param_symb_ids, map<string, expr_t> &pac_expectation_substitution) @@ -4072,7 +4076,9 @@ DynamicModel::computePacBackwardExpectationSubstitution(const string &name, subExpr = AddPlus(subExpr, growth_correction_term); - int expect_var_id = symbol_table.addPacExpectationAuxiliaryVar("pac_expectation_" + name, subExpr); + if (auxname.empty()) + auxname = "pac_expectation_" + name; + int expect_var_id = symbol_table.addPacExpectationAuxiliaryVar(auxname, subExpr); expr_t neweq = AddEqual(AddVariable(expect_var_id), subExpr); addEquation(neweq, -1); addAuxEquation(neweq); diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 6907bcda9104bfa01226e12ea02448807ca55080..0605849c34ae3330a9a21506381af697a8b381fa 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -563,6 +563,7 @@ public: void computePacModelConsistentExpectationSubstitution(const string &name, int discount_symb_id, int pac_eq_max_lag, expr_t growth_correction_term, + string auxname, ExprNode::subst_table_t &diff_subst_table, map<string, int> &pac_aux_var_symb_ids, map<string, vector<int>> &pac_aux_param_symb_ids, @@ -578,6 +579,7 @@ public: int max_lag, const string &aux_model_type, expr_t growth_correction_term, + string auxname, map<string, int> &pac_aux_var_symb_ids, map<string, vector<int>> &pac_aux_param_symb_ids, map<string, expr_t> &pac_expectation_substitution); diff --git a/src/DynareBison.yy b/src/DynareBison.yy index 87c0f9ba428b9867215ef031cc66389e3b54683f..5c091413704c5e5ea48ecdf8cdcf06883498a4f4 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -441,6 +441,8 @@ pac_model_options : o_pac_name | o_pac_aux_model_name | o_pac_discount | o_pac_growth + | o_pac_auxname + | o_pac_kind ; var_expectation_model : VAR_EXPECTATION_MODEL '(' var_expectation_model_options_list ')' ';' @@ -3549,6 +3551,8 @@ o_pac_name : MODEL_NAME EQUAL symbol { driver.option_str("pac.model_name", $3); o_pac_aux_model_name : AUXILIARY_MODEL_NAME EQUAL symbol { driver.option_str("pac.aux_model_name", $3); }; o_pac_discount : DISCOUNT EQUAL symbol { driver.option_str("pac.discount", $3); }; o_pac_growth : GROWTH { driver.begin_pac_growth(); } EQUAL hand_side { driver.set_pac_growth($4); }; +o_pac_auxname : AUXNAME EQUAL symbol { driver.set_pac_auxname($3); }; +o_pac_kind : KIND EQUAL pac_target_kind { driver.set_pac_kind($3); }; o_var_name : MODEL_NAME EQUAL symbol { driver.option_str("var.model_name", $3); }; o_series : SERIES EQUAL symbol { driver.option_str("series", $3); }; o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); }; diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll index f9be86f995da44c407fbd87d02ed90c0d78caa95..e35d9253ace190d61f73889fd025c11cfff2d196 100644 --- a/src/DynareFlex.ll +++ b/src/DynareFlex.ll @@ -803,21 +803,21 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) <DYNARE_BLOCK>restriction {return token::RESTRICTION;} <DYNARE_BLOCK>component {return token::COMPONENT;} <DYNARE_BLOCK>target {return token::TARGET;} -<DYNARE_BLOCK>auxname {return token::AUXNAME;} +<DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;} <DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;} -<DYNARE_BLOCK>kind { +<DYNARE_BLOCK,DYNARE_STATEMENT>kind { yylval->build<string>(yytext); return token::KIND; } -<DYNARE_BLOCK>ll { +<DYNARE_BLOCK,DYNARE_STATEMENT>ll { yylval->build<string>(yytext); return token::LL; } -<DYNARE_BLOCK>dl { +<DYNARE_BLOCK,DYNARE_STATEMENT>dl { yylval->build<string>(yytext); return token::DL; } -<DYNARE_BLOCK>dd { +<DYNARE_BLOCK,DYNARE_STATEMENT>dd { yylval->build<string>(yytext); return token::DD; } diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 215148a4266c762c9e65b60ac339e0916ba5efeb..820576d14332b7442a8f497cb503b33554b5fd23 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -2635,6 +2635,8 @@ ParsingDriver::begin_pac_model() { parsing_pac_model = true; pac_growth = nullptr; + pac_auxname.clear(); + pac_kind = PacTargetKind::unspecified; options_list.clear(); } @@ -2657,7 +2659,8 @@ ParsingDriver::pac_model() auto discount = it->second; check_symbol_is_parameter(discount); - mod_file->pac_model_table.addPacModel(name, aux_model_name, discount, pac_growth); + mod_file->pac_model_table.addPacModel(name, aux_model_name, discount, pac_growth, + pac_auxname, pac_kind); parsing_pac_model = false; } @@ -2668,6 +2671,18 @@ ParsingDriver::set_pac_growth(expr_t pac_growth_arg) reset_data_tree(); } +void +ParsingDriver::set_pac_auxname(string auxname) +{ + pac_auxname = move(auxname); +} + +void +ParsingDriver::set_pac_kind(PacTargetKind kind) +{ + pac_kind = kind; +} + expr_t ParsingDriver::add_exp(expr_t arg1) { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 8c9d08fb68ba045683f622dab511ebf4889efa75..78063f7046031c5290bb1edee2fba27e689b30a4 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -258,8 +258,10 @@ private: WarningConsolidation &warnings; - //! Temporary storage for growth declared in pac_model + //! Temporary storage for several options of pac_model expr_t pac_growth; + string pac_auxname; + PacTargetKind pac_kind; bool nostrict; @@ -752,6 +754,10 @@ public: void pac_model(); //! Adds growth for pac void set_pac_growth(expr_t pac_growth_arg); + //! Sets the value of “auxname” option for the current “pac_model” + void set_pac_auxname(string auxname); + //! Sets the value of “kind” option for the current “pac_model” + void set_pac_kind(PacTargetKind kind); //! Writes token "diff(arg1)" to model tree expr_t add_diff(expr_t arg1); //! Writes token "adl(arg1, lag)" to model tree diff --git a/src/SubModel.cc b/src/SubModel.cc index 73d2ce57cb5ac18a34efff77405867ef7f2cd725..8d59e5dd99aecb58aa5341da815e6c105b6fdba3 100644 --- a/src/SubModel.cc +++ b/src/SubModel.cc @@ -760,7 +760,7 @@ PacModelTable::PacModelTable(SymbolTable &symbol_table_arg) : } void -PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg) +PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg) { if (isExistingPacModelName(name_arg)) { @@ -772,6 +772,8 @@ PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string di discount[name_arg] = move(discount_arg); growth[name_arg] = growth_arg; original_growth[name_arg] = growth_arg; + auxname[name_arg] = move(auxname_arg); + kind[name_arg] = kind_arg; names.insert(move(name_arg)); } @@ -801,6 +803,28 @@ PacModelTable::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation gv->collectVariables(SymbolType::exogenous, mod_file_struct.pac_params); } + for (auto &[name, auxn] : auxname) + if (!auxn.empty() && target_info.find(name) != target_info.end()) + { + cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare an 'auxname' option in the 'pac_model' command when there is also a 'pac_target_info' block" << endl; + exit(EXIT_FAILURE); + } + + for (auto &[name, k] : kind) + if (k != PacTargetKind::unspecified) + { + if (target_info.find(name) != target_info.end()) + { + cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare a 'kind' option in the 'pac_model' command when there is also a 'pac_target_info' block" << endl; + exit(EXIT_FAILURE); + } + if (aux_model_name[name].empty()) + { + cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare a 'kind' option in the 'pac_model' command since this is a MCE model" << endl; + exit(EXIT_FAILURE); + } + } + for (const auto &[name, ti] : target_info) for (auto &[expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, gv_info] : get<2>(ti)) if (gv) @@ -1073,6 +1097,7 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, symbol_table.getID(discount[name]), pacEquationMaxLag(name), growth_correction_term, + auxname[name], diff_subst_table, aux_var_symb_ids, aux_param_symb_ids, @@ -1093,6 +1118,7 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, dynamic_model.computePacBackwardExpectationSubstitution(name, lhs[name], max_lag, aux_model_type[name], growth_correction_term, + auxname[name], aux_var_symb_ids, aux_param_symb_ids, pac_expectation_substitution); @@ -1209,6 +1235,11 @@ PacModelTable::writeOutput(const string &basename, ostream &output) const for (auto &[model, type] : aux_model_type) output << "M_.pac." << model << ".auxiliary_model_type = '" << type << "';" << endl; + for (auto &[name, k] : kind) + if (!aux_model_name.empty()) + output << "M_.pac." << name << ".kind = '" + << (k == PacTargetKind::unspecified ? "" : kindToString(k)) << "';" << endl; + for (auto &[name, val] : equation_info) { auto [lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants] = val; diff --git a/src/SubModel.hh b/src/SubModel.hh index 74d924c74045473bfa7dfd3af8921af26ecc79c5..dcbf8a0569dc667b7c219d12a74df7097a2c5722 100644 --- a/src/SubModel.hh +++ b/src/SubModel.hh @@ -206,6 +206,10 @@ private: Each tuple represents a term: (endo_id, lag, param_id, constant) */ using growth_info_t = vector<tuple<int, int, int, double>>; map<string, growth_info_t> growth_info; + // The “auxname” option of pac_model (empty if not passed) + map<string, string> auxname; + // The “kind” option of pac_model (“undefined” if not passed) + map<string, PacTargetKind> kind; /* Stores the name of the PAC equation associated to the model. pac_model_name → eq_name */ @@ -268,7 +272,7 @@ private: public: explicit PacModelTable(SymbolTable &symbol_table_arg); - void addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg); + void addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg); bool isExistingPacModelName(const string &name_arg) const; bool empty() const; void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);