From 77bf21a3331094ebafa0c4e725cef8011c7f14dd Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 30 Jan 2018 10:06:56 +0100 Subject: [PATCH 01/30] preprocessor: pac: change functionality of diff operator --- DynamicModel.cc | 31 ++++++++++++- DynamicModel.hh | 7 ++- ExprNode.cc | 113 ++++++++++++++++++++++++++++++++++++++---------- ExprNode.hh | 30 ++++++++----- ModFile.cc | 5 ++- SymbolTable.cc | 27 ++++++++++++ SymbolTable.hh | 7 ++- 7 files changed, 179 insertions(+), 41 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 054482ad..67b28c81 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -4750,10 +4750,37 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model } void -DynamicModel::substituteAdlAndDiff() +DynamicModel::substituteAdl() { for (int i = 0; i < (int) equations.size(); i++) - equations[i] = dynamic_cast(equations[i]->substituteAdlAndDiff()); + equations[i] = dynamic_cast(equations[i]->substituteAdl()); +} + +void +DynamicModel::substituteDiff() +{ + ExprNode::subst_table_t subst_table; + vector neweqs; + + // Substitute in model local variables + for (map::iterator it = local_variables_table.begin(); + it != local_variables_table.end(); it++) + it->second = it->second->substituteDiff(subst_table, neweqs); + + // Substitute in equations + for (int i = 0; i < (int) equations.size(); i++) + { + BinaryOpNode *substeq = dynamic_cast(equations[i]->substituteDiff(subst_table, neweqs)); + assert(substeq != NULL); + equations[i] = substeq; + } + + // Add new equations + for (int i = 0; i < (int) neweqs.size(); i++) + addEquation(neweqs[i], -1); + + if (subst_table.size() > 0) + cout << "Substitution of Diff operator: added " << neweqs.size() << " auxiliary variables and equations." << endl; } void diff --git a/DynamicModel.hh b/DynamicModel.hh index edd506d2..0d5c94b7 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -366,8 +366,11 @@ public: //! Transforms the model by removing trends specified by the user void detrendEquations(); - //! Substitutes adl and diff operators - void substituteAdlAndDiff(); + //! Substitutes adl operator + void substituteAdl(); + + //! Substitutes diff operator + void substituteDiff(); //! Fill var_expectation_functions_to_write void fillVarExpectationFunctionsToWrite(); diff --git a/ExprNode.cc b/ExprNode.cc index fbdf400d..2b149036 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2017 Dynare Team + * Copyright (C) 2007-2018 Dynare Team * * This file is part of Dynare. * @@ -482,7 +482,13 @@ NumConstNode::substituteExpectation(subst_table_t &subst_table, vector(this); +} + +expr_t +NumConstNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const { return const_cast(this); } @@ -1244,7 +1250,13 @@ VariableNode::maxLead() const } expr_t -VariableNode::substituteAdlAndDiff() const +VariableNode::substituteAdl() const +{ + return const_cast(this); +} + +expr_t +VariableNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const { return const_cast(this); } @@ -2709,22 +2721,15 @@ UnaryOpNode::maxLead() const } expr_t -UnaryOpNode::substituteAdlAndDiff() const +UnaryOpNode::substituteAdl() const { - if (op_code != oDiff && op_code != oAdl) + if (op_code != oAdl) { - expr_t argsubst = arg->substituteAdlAndDiff(); + expr_t argsubst = arg->substituteAdl(); return buildSimilarUnaryOpNode(argsubst, datatree); } - if (op_code == oDiff) - { - expr_t argsubst = arg->substituteAdlAndDiff(); - return datatree.AddMinus(argsubst, - argsubst->decreaseLeadsLags(1)); - } - - expr_t arg1subst = arg->substituteAdlAndDiff(); + expr_t arg1subst = arg->substituteAdl(); expr_t retval; ostringstream inttostr; if (adl_param_lag >= 0) @@ -2765,6 +2770,34 @@ UnaryOpNode::substituteAdlAndDiff() const return retval; } +expr_t +UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const +{ + if (op_code != oDiff) + { + expr_t argsubst = arg->substituteDiff(subst_table, neweqs); + return buildSimilarUnaryOpNode(argsubst, datatree); + } + + subst_table_t::iterator it = subst_table.find(const_cast(this)); + if (it != subst_table.end()) + return const_cast(it->second); + + expr_t argsubst = arg->substituteDiff(subst_table, neweqs); + assert(argsubst != NULL); + + int symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, argsubst); + expr_t newAuxVar = datatree.AddVariable(symb_id, 0); + + //AUX_DIFF_IDX = argsubst - argsubst(-1) + neweqs.push_back(dynamic_cast(datatree.AddEqual(newAuxVar, + datatree.AddMinus(argsubst, argsubst->decreaseLeadsLags(1))))); + + assert(dynamic_cast(newAuxVar) != NULL); + subst_table[this] = dynamic_cast(newAuxVar); + return newAuxVar; +} + expr_t UnaryOpNode::decreaseLeadsLags(int n) const { @@ -4361,10 +4394,18 @@ BinaryOpNode::substituteExpectation(subst_table_t &subst_table, vectorsubstituteAdlAndDiff(); - expr_t arg2subst = arg2->substituteAdlAndDiff(); + expr_t arg1subst = arg1->substituteAdl(); + expr_t arg2subst = arg2->substituteAdl(); + return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); +} + +expr_t +BinaryOpNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const +{ + expr_t arg1subst = arg1->substituteDiff(subst_table, neweqs); + expr_t arg2subst = arg2->substituteDiff(subst_table, neweqs); return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } @@ -5108,11 +5149,20 @@ TrinaryOpNode::substituteExpectation(subst_table_t &subst_table, vectorsubstituteAdlAndDiff(); - expr_t arg2subst = arg2->substituteAdlAndDiff(); - expr_t arg3subst = arg3->substituteAdlAndDiff(); + expr_t arg1subst = arg1->substituteAdl(); + expr_t arg2subst = arg2->substituteAdl(); + expr_t arg3subst = arg3->substituteAdl(); + return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); +} + +expr_t +TrinaryOpNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const +{ + expr_t arg1subst = arg1->substituteDiff(subst_table, neweqs); + expr_t arg2subst = arg2->substituteDiff(subst_table, neweqs); + expr_t arg3subst = arg3->substituteDiff(subst_table, neweqs); return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } @@ -5420,11 +5470,20 @@ AbstractExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, } expr_t -AbstractExternalFunctionNode::substituteAdlAndDiff() const +AbstractExternalFunctionNode::substituteAdl() const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteAdlAndDiff()); + arguments_subst.push_back((*it)->substituteAdl()); + return buildSimilarExternalFunctionNode(arguments_subst, datatree); +} + +expr_t +AbstractExternalFunctionNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const +{ + vector arguments_subst; + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + arguments_subst.push_back((*it)->substituteDiff(subst_table, neweqs)); return buildSimilarExternalFunctionNode(arguments_subst, datatree); } @@ -6892,7 +6951,13 @@ VarExpectationNode::substituteExpectation(subst_table_t &subst_table, vector(this); +} + +expr_t +VarExpectationNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const { return const_cast(this); } diff --git a/ExprNode.hh b/ExprNode.hh index 9fa28e05..e2e20d6a 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2017 Dynare Team + * Copyright (C) 2007-2018 Dynare Team * * This file is part of Dynare. * @@ -457,8 +457,11 @@ enum ExprNodeOutputType */ virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const = 0; - //! Substitute adl and diff operators - virtual expr_t substituteAdlAndDiff() const = 0; + //! Substitute adl operator + virtual expr_t substituteAdl() const = 0; + + //! Substitute diff operator + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const = 0; //! Add ExprNodes to the provided datatree virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; @@ -530,7 +533,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -605,7 +609,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -703,7 +708,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -813,7 +819,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -903,7 +910,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -993,7 +1001,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; @@ -1174,7 +1183,8 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t substituteAdlAndDiff() const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, diff --git a/ModFile.cc b/ModFile.cc index 1de813fc..f81cb096 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -346,7 +346,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const { // Save the original model (must be done before any model transformations by preprocessor) // - except adl and diff which we always want expanded - dynamic_model.substituteAdlAndDiff(); + dynamic_model.substituteAdl(); dynamic_model.setLeadsLagsOrig(); dynamic_model.cloneDynamic(original_model); @@ -381,6 +381,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const if (symbol_table.predeterminedNbr() > 0) dynamic_model.transformPredeterminedVariables(); + // Create auxiliary variable and equations for Diff operator + dynamic_model.substituteDiff(); + // Create auxiliary vars for Expectation operator dynamic_model.substituteExpectation(mod_file_struct.partial_information); diff --git a/SymbolTable.cc b/SymbolTable.cc index dde3d141..4b18946c 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -354,6 +354,7 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) { case avEndoLead: case avExoLead: + case avDiff: break; case avEndoLag: case avExoLag: @@ -475,6 +476,7 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException) case avExpectation: case avMultiplier: case avDiffForward: + case avDiff: break; case avEndoLag: case avExoLag: @@ -568,6 +570,7 @@ SymbolTable::writeCCOutput(ostream &output) const throw (NotYetFrozenException) case avExpectation: case avMultiplier: case avDiffForward: + case avDiff: break; case avEndoLag: case avExoLag: @@ -691,6 +694,29 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t e return symb_id; } +int +SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException) +{ + ostringstream varname; + int symb_id; + + varname << "AUX_DIFF_" << index; + + try + { + symb_id = addSymbol(varname.str(), eEndogenous); + } + catch (AlreadyDeclaredException &e) + { + cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; + exit(EXIT_FAILURE); + } + + aux_vars.push_back(AuxVarInfo(symb_id, avDiff, 0, 0, 0, 0, expr_arg)); + + return symb_id; +} + int SymbolTable::addVarModelEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (AlreadyDeclaredException, FrozenException) { @@ -1001,6 +1027,7 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio { case avEndoLead: case avExoLead: + case avDiff: break; case avEndoLag: case avExoLag: diff --git a/SymbolTable.hh b/SymbolTable.hh index 76aa3896..53ba84d4 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -43,7 +43,8 @@ enum aux_var_t avExpectation = 4, //!< Substitute for Expectation Operator avDiffForward = 5, //!< Substitute for the differentiate of a forward variable avMultiplier = 6, //!< Multipliers for FOC of Ramsey Problem - avVarModel = 7 //!< Variable for var_model with order > abs(min_lag()) present in model + avVarModel = 7, //!< Variable for var_model with order > abs(min_lag()) present in model + avDiff = 8 //!< Variable for Diff operator }; //! Information on some auxiliary variables @@ -283,6 +284,8 @@ public: //! Adds an auxiliary variable when var_model is used with an order that is greater in absolute value //! than the largest lag present in the model. int addVarModelEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (AlreadyDeclaredException, FrozenException); + //! Adds an auxiliary variable when the diff operator is encountered + int addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException); //! Returns the number of auxiliary variables int AuxVarsSize() const From 2d1c67ed1fa46fa305ebf167361239de792fc080 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 30 Jan 2018 16:33:16 +0100 Subject: [PATCH 02/30] preprocessor: pac_expectation operator --- ComputingTasks.cc | 34 ++- ComputingTasks.hh | 4 +- DataTree.cc | 12 +- DataTree.hh | 9 +- DynamicModel.cc | 110 +++++++++- DynamicModel.hh | 17 +- DynareBison.yy | 8 +- DynareFlex.ll | 3 + ExprNode.cc | 543 +++++++++++++++++++++++++++++++++++++++++++++- ExprNode.hh | 87 ++++++++ ModFile.cc | 25 ++- ParsingDriver.cc | 17 ++ ParsingDriver.hh | 2 + 13 files changed, 835 insertions(+), 36 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index f45a4e31..bf5e74bd 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -268,30 +268,28 @@ VarModelStatement::VarModelStatement(const SymbolList &symbol_list_arg, } void -VarModelStatement::getVarModelNameAndVarList(map > &var_model_info) +VarModelStatement::getVarModelNameAndVarList(map, pair > >, set > > >, pair > > &var_model_info) const { - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("var.order"); - if (it != options_list.num_options.end()) - var_model_info[name] = make_pair(symbol_list, atoi(it->second.c_str())); + set > empty_int_set; + map, pair > >, set > > > eqtagmap; + if (!symbol_list.empty()) + { + OptionsList::num_options_t::const_iterator it = options_list.num_options.find("var.order"); + vector empty_str_vec; + var_model_info[name] = make_pair(eqtagmap, make_pair(symbol_list, atoi(it->second.c_str()))); + } + else + { + OptionsList::vec_str_options_t::const_iterator it1 = options_list.vector_str_options.find("var.eqtags"); + for (vector::const_iterator it = it1->second.begin(); it != it1->second.end(); it++) + eqtagmap[make_pair(*it, -1)] = make_pair(make_pair(0, empty_int_set), empty_int_set); + var_model_info[name] = make_pair(eqtagmap, make_pair(symbol_list, 0)); + } } void VarModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { - OptionsList::vec_str_options_t::const_iterator itvs = options_list.vector_str_options.find("var.eqtags"); - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("var.order"); - if ((it == options_list.num_options.end() && itvs == options_list.vector_str_options.end()) - || (it != options_list.num_options.end() && itvs != options_list.vector_str_options.end())) - { - cerr << "ERROR: You must provide either the order or eqtags option to the var_model statement, but not both." << endl; - exit(EXIT_FAILURE); - } - - if (name.empty()) - { - cerr << "ERROR: You must provide the model_name option to the var_model statement." << endl; - exit(EXIT_FAILURE); - } } void diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 8432be9f..1799f37d 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -129,7 +129,7 @@ public: VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, const string &name_arg); - void getVarModelNameAndVarList(map > &var_model_info); + void getVarModelNameAndVarList(map, pair > >, set > > >, pair > > &var_model_info) const; virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void createVarModelMFunction(ostream &output, const map > &var_expectation_functions_to_write) const; diff --git a/DataTree.cc b/DataTree.cc index 50f668ae..f2179a6d 100644 --- a/DataTree.cc +++ b/DataTree.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -520,6 +520,16 @@ DataTree::AddVarExpectation(const int symb_id, const int forecast_horizon, const return new VarExpectationNode(*this, symb_id, forecast_horizon, model_name); } +expr_t +DataTree::AddPacExpectation(const string &model_name, const expr_t discount, const expr_t growth) +{ + pac_expectation_node_map_t::iterator it = pac_expectation_node_map.find(make_pair(model_name, make_pair(discount, growth))); + if (it != pac_expectation_node_map.end()) + return it->second; + + return new PacExpectationNode(*this, model_name, discount, growth); +} + expr_t DataTree::AddEqual(expr_t iArg1, expr_t iArg2) { diff --git a/DataTree.hh b/DataTree.hh index 3cda0bf2..61be6c0b 100644 --- a/DataTree.hh +++ b/DataTree.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -49,6 +49,7 @@ class DataTree friend class FirstDerivExternalFunctionNode; friend class SecondDerivExternalFunctionNode; friend class VarExpectationNode; + friend class PacExpectationNode; protected: //! A reference to the symbol table SymbolTable &symbol_table; @@ -80,6 +81,10 @@ protected: typedef map >, VarExpectationNode *> var_expectation_node_map_t; var_expectation_node_map_t var_expectation_node_map; + // (model_name, (discount, growth)) -> PacExpectationNode + typedef map >, PacExpectationNode *> pac_expectation_node_map_t; + pac_expectation_node_map_t pac_expectation_node_map; + // ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode typedef map, int>, int>, FirstDerivExternalFunctionNode *> first_deriv_external_function_node_map_t; first_deriv_external_function_node_map_t first_deriv_external_function_node_map; @@ -226,6 +231,8 @@ public: expr_t AddEqual(expr_t iArg1, expr_t iArg2); //! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree expr_t AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name); + //! Adds pac_expectation command to model tree + expr_t AddPacExpectation(const string &model_name, expr_t discount, expr_t growth); //! Adds a model local variable with its value void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); //! Adds an external function node diff --git a/DynamicModel.cc b/DynamicModel.cc index 67b28c81..fb23c71d 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3228,14 +3228,62 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context) } void -DynamicModel::setVarExpectationIndices(map > var_model_info) +DynamicModel::getVarModelVariablesFromEqTags(map, pair > >, set > > > > &var_model_info) +{ + for (map, pair > >, set > > > >::iterator it = var_model_info.begin(); it != var_model_info.end(); it++) + { + map, pair > >, set > > > final_map; + for (map, pair > >, set > > >::iterator itvareqs = it->second.begin(); + itvareqs != it->second.end(); itvareqs++) + { + int eqnumber = -1; + set > lhs, rhs; + string eqtag (itvareqs->first.first); + for (vector > >::const_iterator iteqtag = equation_tags.begin(); + iteqtag != equation_tags.end(); iteqtag++) + if (iteqtag->second.first.compare("name") == 0 + && iteqtag->second.second.compare(eqtag) == 0) + { + eqnumber = iteqtag->first; + break; + } + + if (eqnumber == -1) + { + cerr << "ERROR: equation tag '" << eqtag << "' not found in var_model " << it->first << endl; + exit(EXIT_FAILURE); + } + + int nonstationary = 0; + for (vector > >::const_iterator iteqtag = equation_tags.begin(); + iteqtag != equation_tags.end(); iteqtag++) + if (iteqtag->first == eqnumber) + if (iteqtag->second.first.compare("data_type") == 0 + && iteqtag->second.second.compare("nonstationary") == 0) + { + nonstationary = 1; + break; + } + + equations[eqnumber]->get_arg1()->collectDynamicVariables(eEndogenous, lhs); + equations[eqnumber]->get_arg2()->collectDynamicVariables(eEndogenous, rhs); + + final_map[make_pair(eqtag, eqnumber)] = make_pair(make_pair(nonstationary, lhs), rhs); + } + + var_model_info[it->first] = final_map; + } +} + +void +DynamicModel::setVarExpectationIndices(map > &var_model_info) { for (size_t i = 0; i < equations.size(); i++) equations[i]->setVarExpectationIndex(var_model_info); } void -DynamicModel::addEquationsForVar(map > var_model_info) +DynamicModel::addEquationsForVar(map > &var_model_info) { // List of endogenous variables and the minimum lag value that must exist in the model equations map var_endos_and_lags, model_endos_and_lags; @@ -3286,6 +3334,64 @@ DynamicModel::addEquationsForVar(map > var_model_i cout << "Accounting for var_model lags not in model block: added " << count << " auxiliary variables and equations." << endl; } +void +DynamicModel::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + for (size_t i = 0; i < equations.size(); i++) + equations[i]->fillPacExpectationVarInfo(var_model_info); +} + +void +DynamicModel::substitutePacExpectation() +{ + map, vector > > > > > subst_table; + for (map::iterator it = local_variables_table.begin(); + it != local_variables_table.end(); it++) + it->second = it->second->substitutePacExpectation(subst_table); + + for (size_t i = 0; i < equations.size(); i++) + { + BinaryOpNode *substeq = dynamic_cast(equations[i]->substitutePacExpectation(subst_table)); + assert(substeq != NULL); + equations[i] = substeq; + } + + for (map, vector > > > > >::const_iterator it = subst_table.begin(); it != subst_table.end(); it++) + pac_expectation_info[it->second.second.first] = it->second.second.second; +} + +void +DynamicModel::writePacExpectationInfo(ostream &output) const +{ + int i = 1; + for (map, vector > > >::const_iterator it = pac_expectation_info.begin(); + it != pac_expectation_info.end(); it++, i++) + { + output << "M_.pac_expectation(" << i << ").var_model_name = '" + << it->first << "';" << endl + << "M_.pac_expectation(" << i << ").growth_param_index = " + << symbol_table.getTypeSpecificID(it->second.first) + 1 << ";" << endl + << "M_.pac_expectation(" << i << ").h0_param_indices = ["; + for (vector::const_iterator it1 = it->second.second.first.begin(); + it1 != it->second.second.first.end(); it1++) + { + if (it1 != it->second.second.first.begin()) + output << " "; + output << symbol_table.getTypeSpecificID(*it1) + 1; + } + output << "];" << endl + << "M_.pac_expectation(" << i << ").h1_param_indices = ["; + for (vector::const_iterator it1 = it->second.second.second.begin(); + it1 != it->second.second.second.end(); it1++) + { + if (it1 != it->second.second.second.begin()) + output << " "; + output << symbol_table.getTypeSpecificID(*it1) + 1; + } + output << "];" << endl; + } +} + void DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, diff --git a/DynamicModel.hh b/DynamicModel.hh index 0d5c94b7..c2a3fa64 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -226,6 +226,10 @@ private: //! Used for var_expectation and var_model map > var_expectation_functions_to_write; + //! Used for pac_expectation operator + // maps model_name to (growth_idx, (h0_indices, h1_indices)) + map, vector > > > pac_expectation_info; + //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous vector > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; @@ -280,10 +284,19 @@ public: //! Set the equations that have non-zero second derivatives void setNonZeroHessianEquations(map &eqs); + //! Fill var_model_info with variables associated with equation tags + void getVarModelVariablesFromEqTags(map, pair > >, set > > > > &var_model_info); //! Set indices for var expectation in dynamic model file - void setVarExpectationIndices(map > var_model_info); + void setVarExpectationIndices(map > &var_model_info); //! Add aux equations (and aux variables) for variables declared in var_model at max order if they don't already exist - void addEquationsForVar(map > var_model_info); + void addEquationsForVar(map > &var_model_info); + //! Add var_model info to pac_expectation nodes + void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + //! Substitutes pac_expectation operator + void substitutePacExpectation(); + + //! Write Pac Expectation info + void writePacExpectationInfo(ostream &output) const; //! Adds informations for simulation in a binary file void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, diff --git a/DynareBison.yy b/DynareBison.yy index 8ec4ceeb..2b59c861 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -117,7 +117,7 @@ class ParsingDriver; %token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY %token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS MODEL_NAME STDERR_MULTIPLES DIAGONAL_ONLY -%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE +%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE DISCOUNT %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION %token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN MLE_MODE PRUNING @@ -132,7 +132,7 @@ class ParsingDriver; %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 VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL CROSSEQUATIONS COVARIANCE WRITE_LATEX_STEADY_STATE_MODEL -%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL QOQ YOY AOA +%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL QOQ YOY AOA PAC_EXPECTATION %left COMMA %left EQUAL_EQUAL EXCLAMATION_EQUAL %left LESS GREATER LESS_EQUAL GREATER_EQUAL @@ -158,7 +158,7 @@ class ParsingDriver; %token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY %token EQ_CMS TLINDX TLNUMBER BANACT RESTRICTIONS POSTERIOR_SAMPLER_OPTIONS %token OUTPUT_FILE_TAG DRAWS_NBR_BURN_IN_1 DRAWS_NBR_BURN_IN_2 HORIZON -%token SBVAR TREND_VAR DEFLATOR GROWTH_FACTOR MS_IRF MS_VARIANCE_DECOMPOSITION +%token SBVAR TREND_VAR DEFLATOR GROWTH_FACTOR MS_IRF MS_VARIANCE_DECOMPOSITION GROWTH %token MS_ESTIMATION MS_SIMULATION MS_COMPUTE_MDD MS_COMPUTE_PROBABILITIES MS_FORECAST %token SVAR_IDENTIFICATION EQUATION EXCLUSION LAG UPPER_CHOLESKY LOWER_CHOLESKY MONTHLY QUARTERLY %token MARKOV_SWITCHING CHAIN DURATION NUMBER_OF_REGIMES NUMBER_OF_LAGS @@ -908,6 +908,8 @@ hand_side : '(' hand_side ')' { $$ = driver.add_var_expectation($3, new string("1"), $7); } | VAR_EXPECTATION '(' symbol COMMA INT_NUMBER COMMA MODEL_NAME EQUAL NAME ')' { $$ = driver.add_var_expectation($3, $5, $9); } + | PAC_EXPECTATION '(' MODEL_NAME EQUAL NAME COMMA DISCOUNT EQUAL hand_side COMMA GROWTH EQUAL hand_side')' + { $$ = driver.add_pac_expectation($5, $9, $13); } | MINUS hand_side %prec UMINUS { $$ = driver.add_uminus($2); } | PLUS hand_side diff --git a/DynareFlex.ll b/DynareFlex.ll index 1ebe6a5c..6248ed6a 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -676,6 +676,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 } /* Inside a Dynare block */ +growth {return token::GROWTH;} var {return token::VAR;} stderr {return token::STDERR;} values {return token::VALUES;} @@ -821,6 +822,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 steady_state {return token::STEADY_STATE;} expectation {return token::EXPECTATION;} var_expectation {return token::VAR_EXPECTATION;} +pac_expectation {return token::PAC_EXPECTATION;} +discount {return token::DISCOUNT;} varobs {return token::VAROBS;} varexobs {return token::VAREXOBS;} full {return token::FULL;} diff --git a/ExprNode.cc b/ExprNode.cc index 2b149036..694c7f49 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -493,6 +493,12 @@ NumConstNode::substituteDiff(subst_table_t &subst_table, vector return const_cast(this); } +expr_t +NumConstNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + return const_cast(this); +} + expr_t NumConstNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const { @@ -560,6 +566,11 @@ NumConstNode::setVarExpectationIndex(map > &var_mo { } +void +NumConstNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ +} + bool NumConstNode::isVarModelReferenced(const string &model_info_name) const { @@ -1261,6 +1272,12 @@ VariableNode::substituteDiff(subst_table_t &subst_table, vector return const_cast(this); } +expr_t +VariableNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + return const_cast(this); +} + expr_t VariableNode::decreaseLeadsLags(int n) const { @@ -1599,6 +1616,11 @@ VariableNode::setVarExpectationIndex(map > &var_mo { } +void +VariableNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ +} + bool VariableNode::isVarModelReferenced(const string &model_info_name) const { @@ -2798,6 +2820,13 @@ UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector & return newAuxVar; } +expr_t +UnaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + expr_t argsubst = arg->substitutePacExpectation(subst_table); + return buildSimilarUnaryOpNode(argsubst, datatree); +} + expr_t UnaryOpNode::decreaseLeadsLags(int n) const { @@ -2970,6 +2999,12 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod arg->setVarExpectationIndex(var_model_info); } +void +UnaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + arg->fillPacExpectationVarInfo(var_model_info); +} + bool UnaryOpNode::isVarModelReferenced(const string &model_info_name) const { @@ -4409,6 +4444,14 @@ BinaryOpNode::substituteDiff(subst_table_t &subst_table, vector return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } +expr_t +BinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + expr_t arg1subst = arg1->substitutePacExpectation(subst_table); + expr_t arg2subst = arg2->substitutePacExpectation(subst_table); + return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); +} + expr_t BinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const { @@ -4486,6 +4529,13 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo arg2->setVarExpectationIndex(var_model_info); } +void +BinaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + arg1->fillPacExpectationVarInfo(var_model_info); + arg2->fillPacExpectationVarInfo(var_model_info); +} + bool BinaryOpNode::isVarModelReferenced(const string &model_info_name) const { @@ -5166,6 +5216,15 @@ TrinaryOpNode::substituteDiff(subst_table_t &subst_table, vector return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } +expr_t +TrinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + expr_t arg1subst = arg1->substitutePacExpectation(subst_table); + expr_t arg2subst = arg2->substitutePacExpectation(subst_table); + expr_t arg3subst = arg3->substitutePacExpectation(subst_table); + return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); +} + expr_t TrinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const { @@ -5240,6 +5299,14 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m arg3->setVarExpectationIndex(var_model_info); } +void +TrinaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + arg1->fillPacExpectationVarInfo(var_model_info); + arg2->fillPacExpectationVarInfo(var_model_info); + arg3->fillPacExpectationVarInfo(var_model_info); +} + bool TrinaryOpNode::isVarModelReferenced(const string &model_info_name) const { @@ -5487,6 +5554,15 @@ AbstractExternalFunctionNode::substituteDiff(subst_table_t &subst_table, vector< return buildSimilarExternalFunctionNode(arguments_subst, datatree); } +expr_t +AbstractExternalFunctionNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + vector arguments_subst; + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + arguments_subst.push_back((*it)->substitutePacExpectation(subst_table)); + return buildSimilarExternalFunctionNode(arguments_subst, datatree); +} + expr_t AbstractExternalFunctionNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const { @@ -5588,6 +5664,13 @@ AbstractExternalFunctionNode::setVarExpectationIndex(mapsetVarExpectationIndex(var_model_info); } +void +AbstractExternalFunctionNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + (*it)->fillPacExpectationVarInfo(var_model_info); +} + bool AbstractExternalFunctionNode::isVarModelReferenced(const string &model_info_name) const { @@ -6855,7 +6938,7 @@ void VarExpectationNode::prepareForDerivation() { preparedForDerivation = true; - // All derivatives are null, so non_null_derivatives is left empty + // Come back } expr_t @@ -6962,6 +7045,12 @@ VarExpectationNode::substituteDiff(subst_table_t &subst_table, vector(this); } +expr_t +VarExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + return const_cast(this); +} + expr_t VarExpectationNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const { @@ -7040,6 +7129,11 @@ VarExpectationNode::setVarExpectationIndex(map > & yidx = find(vs.begin(), vs.end(), datatree.symbol_table.getName(symb_id)) - vs.begin(); } +void +VarExpectationNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ +} + expr_t VarExpectationNode::substituteStaticAuxiliaryVariable() const { @@ -7059,3 +7153,450 @@ VarExpectationNode::writeJsonOutput(ostream &output, << ", yindex = " << yidx << ")"; } + +PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, + const string &model_name_arg, + const expr_t discount_arg, + const expr_t growth_arg) : + ExprNode(datatree_arg), + model_name(model_name_arg), + discount(discount_arg), + growth(growth_arg) +{ + datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount, growth))] = this; +} + +void +PacExpectationNode::computeTemporaryTerms(map > &reference_count, + map &temp_terms_map, + bool is_matlab, NodeTreeReference tr) const +{ + temp_terms_map[tr].insert(const_cast(this)); +} + +void +PacExpectationNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const +{ + expr_t this2 = const_cast(this); + temporary_terms.insert(this2); + first_occurence[this2] = make_pair(Curr_block, equation); + v_temporary_terms[Curr_block][equation].insert(this2); +} + +expr_t +PacExpectationNode::toStatic(DataTree &static_datatree) const +{ + return static_datatree.AddPacExpectation(model_name, discount, growth); +} + +expr_t +PacExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const +{ + return dynamic_datatree.AddPacExpectation(model_name, discount, growth); +} + +void +PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + assert(output_type != oMatlabOutsideModel); + + if (IS_LATEX(output_type)) + { + output << "PAC_EXPECTATION" << LEFT_PAR(output_type) << model_name << ", "; + discount->writeOutput(output, output_type, temporary_terms, tef_terms); + output << ", "; + growth->writeOutput(output, output_type, temporary_terms, tef_terms); + output << RIGHT_PAR(output_type); + return; + } + + // If current node is a temporary term + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } + + output << "[h0, h1, d] = hVectors(params, H, ids, idns);"; +} + +int +PacExpectationNode::maxEndoLead() const +{ + return 0; +} + +int +PacExpectationNode::maxExoLead() const +{ + return 0; +} + +int +PacExpectationNode::maxEndoLag() const +{ + return 0; +} + +int +PacExpectationNode::maxExoLag() const +{ + return 0; +} + +int +PacExpectationNode::maxLead() const +{ + return 0; +} + +expr_t +PacExpectationNode::decreaseLeadsLags(int n) const +{ + return const_cast(this); +} + +void +PacExpectationNode::prepareForDerivation() +{ + cerr << "PacExpectationNode::prepareForDerivation: shouldn't arrive here." << endl; + exit(EXIT_FAILURE); +} + +expr_t +PacExpectationNode::computeDerivative(int deriv_id) +{ + cerr << "PacExpectationNode::computeDerivative: shouldn't arrive here." << endl; + exit(EXIT_FAILURE); +} + +expr_t +PacExpectationNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) +{ + cerr << "PacExpectationNode::getChainRuleDerivative: shouldn't arrive here." << endl; + exit(EXIT_FAILURE); +} + +bool +PacExpectationNode::containsExternalFunction() const +{ + return false; +} + +double +PacExpectationNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) +{ + cerr << "PacExpectationNode::eval: shouldn't arrive here." << endl; + exit(EXIT_FAILURE); +} + +void +PacExpectationNode::computeXrefs(EquationInfo &ei) const +{ +} + +void +PacExpectationNode::collectDynamicVariables(SymbolType type_arg, set > &result) const +{ +} + +void +PacExpectationNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const +{ + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + temporary_terms_inuse.insert(idx); +} + +void +PacExpectationNode::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 +{ + cerr << "PacExpectationNode::compile not implemented." << endl; + exit(EXIT_FAILURE); +} + +pair +PacExpectationNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const +{ + //COME BACK + return make_pair(0, const_cast(this)); +} + +expr_t +PacExpectationNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteAdl() const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +bool +PacExpectationNode::containsEndogenous(void) const +{ + return true; +} + +bool +PacExpectationNode::containsExogenous() const +{ + return false; +} + +bool +PacExpectationNode::isNumConstNodeEqualTo(double value) const +{ + return false; +} + +expr_t +PacExpectationNode::decreaseLeadsLagsPredeterminedVariables() const +{ + return const_cast(this); +} + +bool +PacExpectationNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const +{ + return false; +} + +expr_t +PacExpectationNode::replaceTrendVar() const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::detrend(int symb_id, bool log_trend, expr_t trend) const +{ + return const_cast(this); +} + +expr_t +PacExpectationNode::removeTrendLeadLag(map trend_symbols_map) const +{ + return const_cast(this); +} + +bool +PacExpectationNode::isInStaticForm() const +{ + return false; +} + +bool +PacExpectationNode::isVarModelReferenced(const string &model_info_name) const +{ + return model_name == model_info_name; +} + +void +PacExpectationNode::getEndosAndMaxLags(map &model_endos_and_lags) const +{ +} + +void +PacExpectationNode::setVarExpectationIndex(map > &var_model_info) +{ +} + +expr_t +PacExpectationNode::substituteStaticAuxiliaryVariable() const +{ + return const_cast(this); +} + +void +PacExpectationNode::writeJsonOutput(ostream &output, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms, + const bool isdynamic) const +{ + output << "pac_expectation(" + << ", model_name = " << model_name + << ", "; + discount->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); + output << ", "; + growth->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); + output << ")"; +} + +void +PacExpectationNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +{ + map, pair > >, set > > > >::const_iterator it = var_model_info.find(model_name); + if (it == var_model_info.end()) + { + cerr << "ERROR: could not find the declaration of " << model_name + << " referenced by pac_expectation operator" << endl; + exit(EXIT_FAILURE); + } + + for (map, pair > >, set > > >::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) + { + if (it1->second.first.second.size() != 1) + { + cerr << "ERROR " << model_name + << ": you may only have one variable on the LHS of a VAR" << endl; + exit(EXIT_FAILURE); + } + set >::const_iterator setit = it1->second.first.second.begin(); + if (setit->second != 0) + { + cerr << "ERROR " << model_name + << ": the LHS variable of a VAR cannot appear with a lead or a lag" << endl; + exit(EXIT_FAILURE); + } + lhs.push_back(setit->first); + rhs.push_back(it1->second.second); + if (it1->second.first.first) + nonstationary_vars.push_back(lhs.back()); + } +} + +expr_t +PacExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) +{ + map, vector > > > > >::iterator myit = + subst_table.find(const_cast(this)); + if (myit != subst_table.end()) + return const_cast(myit->second.first); + + bool stationary_vars_present = true; + if (nonstationary_vars.size() == lhs.size()) + stationary_vars_present = false; + + bool nonstationary_vars_present = true; + if (nonstationary_vars.empty()) + nonstationary_vars_present = false; + + map > all_rhs_vars; // lag -> set< symb_id > (all vars that appear at a given lag) + // Order RHS vars by time (already ordered by equation tag) + for (vector > >::const_iterator it = rhs.begin(); + it != rhs.end(); it++) + for (set >::const_iterator it1 = it->begin(); + it1 != it->end(); it1++) + if (find(lhs.begin(), lhs.end(), it1->first) == lhs.end()) + { + cerr << "ERROR " << model_name << ": " << datatree.symbol_table.getName(it1->first) + << " cannot appear in the VAR because it does not appear on the LHS" << endl; + exit(EXIT_FAILURE); + } + else + { + map >::iterator mit = all_rhs_vars.find(abs(it1->second)); + if (mit == all_rhs_vars.end()) + { + if (it1->second > 0) + { + cerr << "ERROR " << model_name << + ": you cannot have a variable with a lead in a VAR" << endl; + exit(EXIT_FAILURE); + } + set si; + si.insert(it1->first); + all_rhs_vars[abs(it1->second)] = si; + } + else + mit->second.insert(it1->first); + } + + vector h0_indices, h1_indices; + expr_t subExpr = datatree.AddNonNegativeConstant("0"); + if (stationary_vars_present) + for (map >::const_iterator it = all_rhs_vars.begin(); + it != all_rhs_vars.end(); it++) + for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) + { + string param_name_h0("h0_" + model_name + + "_var_" + datatree.symbol_table.getName(*it1) + + "_lag_" + to_string(it->first)); + int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h0, eParameter); + h0_indices.push_back(new_param_symb_id); + subExpr = datatree.AddPlus(subExpr, + datatree.AddTimes(datatree.AddVariable(new_param_symb_id), + datatree.AddVariable(*it1, it->first))); + } + + if (nonstationary_vars_present) + for (map >::const_iterator it = all_rhs_vars.begin(); + it != all_rhs_vars.end(); it++) + for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) + { + string param_name_h1("h1_" + model_name + + "_var_" + datatree.symbol_table.getName(*it1) + + "_lag_" + to_string(it->first)); + int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h1, eParameter); + h1_indices.push_back(new_param_symb_id); + subExpr = datatree.AddPlus(subExpr, + datatree.AddTimes(datatree.AddVariable(new_param_symb_id), + datatree.AddVariable(*it1, it->first))); + } + + int pg_symb_id = datatree.symbol_table.addSymbol("pac_growth_parameter", eParameter); + subExpr = datatree.AddPlus(subExpr, + datatree.AddTimes(datatree.AddVariable(pg_symb_id), + growth)); + + subst_table[const_cast(this)] = + make_pair(dynamic_cast(subExpr), + make_pair(model_name, + make_pair(pg_symb_id, + make_pair(h0_indices, h1_indices)))); + + return subExpr; +} diff --git a/ExprNode.hh b/ExprNode.hh index e2e20d6a..6ec13945 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -137,6 +137,7 @@ enum ExprNodeOutputType friend class TrinaryOpNode; friend class AbstractExternalFunctionNode; friend class VarExpectationNode; + friend class PacExpectationNode; private: //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ @@ -463,6 +464,9 @@ enum ExprNodeOutputType //! Substitute diff operator virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const = 0; + //! Substitute pac_expectation operator + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table) = 0; + //! Add ExprNodes to the provided datatree virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; @@ -481,6 +485,9 @@ enum ExprNodeOutputType //! Returns true if model_info_name is referenced by a VarExpectationNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; + //! Fills var_model info for pac_expectation node + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) = 0; + //! Fills map virtual void getEndosAndMaxLags(map &model_endos_and_lags) const = 0; }; @@ -535,6 +542,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -547,6 +555,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -611,6 +620,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -623,6 +633,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -710,6 +721,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -722,6 +734,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -821,6 +834,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -839,6 +853,7 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -912,6 +927,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -924,6 +940,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1003,6 +1020,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; @@ -1017,6 +1035,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1185,6 +1204,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -1203,6 +1223,73 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual bool isVarModelReferenced(const string &model_info_name) const; + virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; + virtual expr_t substituteStaticAuxiliaryVariable() const; + virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; +}; + +class PacExpectationNode : public ExprNode +{ +private: + const string &model_name; + const expr_t discount, growth; + vector lhs, nonstationary_vars; + vector > > rhs; +public: + PacExpectationNode(DataTree &datatree_arg, const string &model_name, const expr_t discount_arg, const expr_t growth_arg); + virtual void computeTemporaryTerms(map > &reference_count, + map &temp_terms_map, + bool is_matlab, NodeTreeReference tr) const; + virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const; + virtual expr_t toStatic(DataTree &static_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; + virtual int maxEndoLead() const; + virtual int maxExoLead() const; + virtual int maxEndoLag() const; + virtual int maxExoLag() const; + virtual int maxLead() const; + virtual expr_t decreaseLeadsLags(int n) const; + virtual void prepareForDerivation(); + virtual expr_t computeDerivative(int deriv_id); + virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); + virtual bool containsExternalFunction() const; + virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); + virtual void computeXrefs(EquationInfo &ei) const; + virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; + virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; + virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual expr_t substituteAdl() const; + virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; + 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; + virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; + virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; + virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; + virtual bool isNumConstNodeEqualTo(double value) const; + virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; + virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; + virtual expr_t replaceTrendVar() const; + virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; + virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; + virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map > &var_model_info); + virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; diff --git a/ModFile.cc b/ModFile.cc index f81cb096..b6b909e7 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -362,7 +362,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const } // Var Model - map > var_model_info; + map, pair > >, set > > >, pair > > var_model_info; for (vector::const_iterator it = statements.begin(); it != statements.end(); it++) { @@ -373,17 +373,28 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const if (!var_model_info.empty()) { - dynamic_model.setVarExpectationIndices(var_model_info); - dynamic_model.addEquationsForVar(var_model_info); + map > var_model_info_var_expectation; + map, pair > >, set > > > > var_model_info_pac; + for (map, pair > >, set > > >, pair > >::const_iterator it = var_model_info.begin(); it != var_model_info.end(); it++) + { + var_model_info_pac[it->first] = it->second.first; + var_model_info_var_expectation[it->first] = it->second.second; + } + dynamic_model.setVarExpectationIndices(var_model_info_var_expectation); + dynamic_model.addEquationsForVar(var_model_info_var_expectation); + + dynamic_model.getVarModelVariablesFromEqTags(var_model_info_pac); + dynamic_model.fillPacExpectationVarInfo(var_model_info_pac); + dynamic_model.substitutePacExpectation(); } dynamic_model.fillVarExpectationFunctionsToWrite(); - if (symbol_table.predeterminedNbr() > 0) - dynamic_model.transformPredeterminedVariables(); - // Create auxiliary variable and equations for Diff operator dynamic_model.substituteDiff(); + if (symbol_table.predeterminedNbr() > 0) + dynamic_model.transformPredeterminedVariables(); + // Create auxiliary vars for Expectation operator dynamic_model.substituteExpectation(mod_file_struct.partial_information); @@ -750,6 +761,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo // Initialize M_.det_shocks mOutputFile << "M_.det_shocks = [];" << endl; + dynamic_model.writePacExpectationInfo(mOutputFile); + if (linear == 1) mOutputFile << "options_.linear = 1;" << endl; diff --git a/ParsingDriver.cc b/ParsingDriver.cc index cf876011..0a8924a2 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -1506,6 +1506,17 @@ ParsingDriver::var_model() if (it == options_list.string_options.end()) error("You must pass the model_name option to the var_model statement."); const string *name = new string(it->second); + + if (options_list.vector_str_options.find("var.eqtags") != options_list.vector_str_options.end()) + if (!symbol_list.empty()) + error("You cannot pass a symbol list when passing equation tags to the var_model statement"); + else if (options_list.num_options.find("var.order") != options_list.num_options.end()) + error("You cannot pass the order option when passing equation tags to the var_model statement"); + + if (!symbol_list.empty()) + if (options_list.num_options.find("var.order") == options_list.num_options.end()) + error("You must pass the order option when passing a symbol list to the var_model statement"); + mod_file->addStatement(new VarModelStatement(symbol_list, options_list, *name)); var_map[it->second] = symbol_list.getSymbols(); symbol_list.clear(); @@ -2661,6 +2672,12 @@ ParsingDriver::add_var_expectation(string *arg1, string *arg2, string *arg3) return varExpectationNode; } +expr_t +ParsingDriver::add_pac_expectation(string *model_name, expr_t discount, expr_t growth) +{ + return data_tree->AddPacExpectation(*model_name, discount, growth); +} + expr_t ParsingDriver::add_exp(expr_t arg1) { diff --git a/ParsingDriver.hh b/ParsingDriver.hh index 872c3917..bf5c12b1 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -686,6 +686,8 @@ public: expr_t add_expectation(string *arg1, expr_t arg2); //! Writes token "VAR_EXPECTATION(arg1, arg2, arg3)" to model tree expr_t add_var_expectation(string *arg1, string *arg2, string *arg3); + //! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree + expr_t add_pac_expectation(string *model_name, expr_t discount, expr_t growth); //! Writes token "diff(arg1)" to model tree expr_t add_diff(expr_t arg1); //! Writes token "adl(arg1, lag)" to model tree From 802c25f6d1c0dcb25b6a0ee2bd5e37f40e2eeefc Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 6 Feb 2018 15:04:12 +0100 Subject: [PATCH 03/30] preprocessor: to_string() not compatible with older versions of C++ compiler --- ExprNode.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 694c7f49..42254c75 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7562,10 +7562,11 @@ PacExpectationNode::substitutePacExpectation(map::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) { - string param_name_h0("h0_" + model_name - + "_var_" + datatree.symbol_table.getName(*it1) - + "_lag_" + to_string(it->first)); - int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h0, eParameter); + stringstream param_name_h0; + param_name_h0 << "h0_" << model_name + << "_var_" << datatree.symbol_table.getName(*it1) + << "_lag_" << it->first; + int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h0.str(), eParameter); h0_indices.push_back(new_param_symb_id); subExpr = datatree.AddPlus(subExpr, datatree.AddTimes(datatree.AddVariable(new_param_symb_id), @@ -7577,10 +7578,11 @@ PacExpectationNode::substitutePacExpectation(map::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) { - string param_name_h1("h1_" + model_name - + "_var_" + datatree.symbol_table.getName(*it1) - + "_lag_" + to_string(it->first)); - int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h1, eParameter); + stringstream param_name_h1; + param_name_h1 << "h1_" << model_name + << "_var_" << datatree.symbol_table.getName(*it1) + << "_lag_" << it->first; + int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h1.str(), eParameter); h1_indices.push_back(new_param_symb_id); subExpr = datatree.AddPlus(subExpr, datatree.AddTimes(datatree.AddVariable(new_param_symb_id), From 89c6b6b6ad4a550c953c899477d60bd60fa1bbf0 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 7 Feb 2018 10:05:32 +0100 Subject: [PATCH 04/30] pac_expectation_operator: change subst_table to more specific type --- DynamicModel.cc | 5 +++-- DynamicModel.hh | 2 +- ExprNode.cc | 18 +++++++++--------- ExprNode.hh | 21 +++++++++++---------- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index fb23c71d..dc79dcb8 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3344,7 +3344,8 @@ DynamicModel::fillPacExpectationVarInfo(map, pair< void DynamicModel::substitutePacExpectation() { - map, vector > > > > > subst_table; + // maps PacExpectationNode to (subst node, (var_model_name, (growth_id, (h0_idxs, h1_idxs)))) + map, vector > > > > > subst_table; for (map::iterator it = local_variables_table.begin(); it != local_variables_table.end(); it++) it->second = it->second->substitutePacExpectation(subst_table); @@ -3356,7 +3357,7 @@ DynamicModel::substitutePacExpectation() equations[i] = substeq; } - for (map, vector > > > > >::const_iterator it = subst_table.begin(); it != subst_table.end(); it++) + for (map, vector > > > > >::const_iterator it = subst_table.begin(); it != subst_table.end(); it++) pac_expectation_info[it->second.second.first] = it->second.second.second; } diff --git a/DynamicModel.hh b/DynamicModel.hh index c2a3fa64..5edd6b1d 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -227,7 +227,7 @@ private: map > var_expectation_functions_to_write; //! Used for pac_expectation operator - // maps model_name to (growth_idx, (h0_indices, h1_indices)) + // maps var_model_name to (growth_idx, (h0_indices, h1_indices)) map, vector > > > pac_expectation_info; //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous diff --git a/ExprNode.cc b/ExprNode.cc index 42254c75..6d8a4b13 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -494,7 +494,7 @@ NumConstNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -NumConstNode::substitutePacExpectation(map, vector > > > > > &subst_table) +NumConstNode::substitutePacExpectation(map, vector > > > > > &subst_table) { return const_cast(this); } @@ -1273,7 +1273,7 @@ VariableNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -VariableNode::substitutePacExpectation(map, vector > > > > > &subst_table) +VariableNode::substitutePacExpectation(map, vector > > > > > &subst_table) { return const_cast(this); } @@ -2821,7 +2821,7 @@ UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector & } expr_t -UnaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +UnaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) { expr_t argsubst = arg->substitutePacExpectation(subst_table); return buildSimilarUnaryOpNode(argsubst, datatree); @@ -4445,7 +4445,7 @@ BinaryOpNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -BinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +BinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) { expr_t arg1subst = arg1->substitutePacExpectation(subst_table); expr_t arg2subst = arg2->substitutePacExpectation(subst_table); @@ -5217,7 +5217,7 @@ TrinaryOpNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -TrinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +TrinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) { expr_t arg1subst = arg1->substitutePacExpectation(subst_table); expr_t arg2subst = arg2->substitutePacExpectation(subst_table); @@ -5555,7 +5555,7 @@ AbstractExternalFunctionNode::substituteDiff(subst_table_t &subst_table, vector< } expr_t -AbstractExternalFunctionNode::substitutePacExpectation(map, vector > > > > > &subst_table) +AbstractExternalFunctionNode::substitutePacExpectation(map, vector > > > > > &subst_table) { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -7046,7 +7046,7 @@ VarExpectationNode::substituteDiff(subst_table_t &subst_table, vector, vector > > > > > &subst_table) +VarExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) { return const_cast(this); } @@ -7509,9 +7509,9 @@ PacExpectationNode::fillPacExpectationVarInfo(map, } expr_t -PacExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) +PacExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) { - map, vector > > > > >::iterator myit = + map, vector > > > > >::const_iterator myit = subst_table.find(const_cast(this)); if (myit != subst_table.end()) return const_cast(myit->second.first); diff --git a/ExprNode.hh b/ExprNode.hh index 6ec13945..4f1d7297 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -35,6 +35,7 @@ using namespace std; class DataTree; class VariableNode; class BinaryOpNode; +class PacExpectationNode; typedef class ExprNode *expr_t; @@ -123,7 +124,7 @@ enum ExprNodeOutputType #define MIN_COST(is_matlab) ((is_matlab) ? MIN_COST_MATLAB : MIN_COST_C) //! Base class for expression nodes - class ExprNode +class ExprNode { friend class DataTree; friend class DynamicModel; @@ -465,7 +466,7 @@ enum ExprNodeOutputType virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const = 0; //! Substitute pac_expectation operator - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table) = 0; + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table) = 0; //! Add ExprNodes to the provided datatree virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; @@ -542,7 +543,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -620,7 +621,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -721,7 +722,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -834,7 +835,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -927,7 +928,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -1020,7 +1021,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; @@ -1204,7 +1205,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -1270,7 +1271,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, From 544eb615d038c71b014cc776e674d9b490d1f088 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 7 Feb 2018 13:49:57 +0100 Subject: [PATCH 05/30] pac_expectation: streamline writing --- DynamicModel.cc | 47 ++++++---------------- DynamicModel.hh | 6 +-- ExprNode.cc | 101 +++++++++++++++++++++++++++--------------------- ExprNode.hh | 24 ++++++------ ModFile.cc | 2 - 5 files changed, 81 insertions(+), 99 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index dc79dcb8..da197ef8 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3200,6 +3200,13 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de else output << "-1"; output << "];" << endl; + + // Write PacExpectationInfo + deriv_node_temp_terms_t tef_terms; + temporary_terms_t temp_terms_empty; + for (set::const_iterator it = pac_expectation_info.begin(); + it != pac_expectation_info.end(); it++) + (*it)->writeOutput(output, oMatlabDynamicModel, temp_terms_empty, tef_terms); } map >, expr_t> @@ -3344,8 +3351,7 @@ DynamicModel::fillPacExpectationVarInfo(map, pair< void DynamicModel::substitutePacExpectation() { - // maps PacExpectationNode to (subst node, (var_model_name, (growth_id, (h0_idxs, h1_idxs)))) - map, vector > > > > > subst_table; + map subst_table; for (map::iterator it = local_variables_table.begin(); it != local_variables_table.end(); it++) it->second = it->second->substitutePacExpectation(subst_table); @@ -3357,40 +3363,9 @@ DynamicModel::substitutePacExpectation() equations[i] = substeq; } - for (map, vector > > > > >::const_iterator it = subst_table.begin(); it != subst_table.end(); it++) - pac_expectation_info[it->second.second.first] = it->second.second.second; -} - -void -DynamicModel::writePacExpectationInfo(ostream &output) const -{ - int i = 1; - for (map, vector > > >::const_iterator it = pac_expectation_info.begin(); - it != pac_expectation_info.end(); it++, i++) - { - output << "M_.pac_expectation(" << i << ").var_model_name = '" - << it->first << "';" << endl - << "M_.pac_expectation(" << i << ").growth_param_index = " - << symbol_table.getTypeSpecificID(it->second.first) + 1 << ";" << endl - << "M_.pac_expectation(" << i << ").h0_param_indices = ["; - for (vector::const_iterator it1 = it->second.second.first.begin(); - it1 != it->second.second.first.end(); it1++) - { - if (it1 != it->second.second.first.begin()) - output << " "; - output << symbol_table.getTypeSpecificID(*it1) + 1; - } - output << "];" << endl - << "M_.pac_expectation(" << i << ").h1_param_indices = ["; - for (vector::const_iterator it1 = it->second.second.second.begin(); - it1 != it->second.second.second.end(); it1++) - { - if (it1 != it->second.second.second.begin()) - output << " "; - output << symbol_table.getTypeSpecificID(*it1) + 1; - } - output << "];" << endl; - } + for (map::const_iterator it = subst_table.begin(); + it != subst_table.end(); it++) + pac_expectation_info.insert(const_cast(it->first)); } void diff --git a/DynamicModel.hh b/DynamicModel.hh index 5edd6b1d..676718a6 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -227,8 +227,7 @@ private: map > var_expectation_functions_to_write; //! Used for pac_expectation operator - // maps var_model_name to (growth_idx, (h0_indices, h1_indices)) - map, vector > > > pac_expectation_info; + set pac_expectation_info; // PacExpectationNode pointers //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous vector > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; @@ -295,9 +294,6 @@ public: //! Substitutes pac_expectation operator void substitutePacExpectation(); - //! Write Pac Expectation info - void writePacExpectationInfo(ostream &output) const; - //! Adds informations for simulation in a binary file void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const; diff --git a/ExprNode.cc b/ExprNode.cc index 6d8a4b13..79988cb6 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -494,7 +494,7 @@ NumConstNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -NumConstNode::substitutePacExpectation(map, vector > > > > > &subst_table) +NumConstNode::substitutePacExpectation(map &subst_table) { return const_cast(this); } @@ -1273,7 +1273,7 @@ VariableNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -VariableNode::substitutePacExpectation(map, vector > > > > > &subst_table) +VariableNode::substitutePacExpectation(map &subst_table) { return const_cast(this); } @@ -2821,7 +2821,7 @@ UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector & } expr_t -UnaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +UnaryOpNode::substitutePacExpectation(map &subst_table) { expr_t argsubst = arg->substitutePacExpectation(subst_table); return buildSimilarUnaryOpNode(argsubst, datatree); @@ -4445,7 +4445,7 @@ BinaryOpNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -BinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +BinaryOpNode::substitutePacExpectation(map &subst_table) { expr_t arg1subst = arg1->substitutePacExpectation(subst_table); expr_t arg2subst = arg2->substitutePacExpectation(subst_table); @@ -5217,7 +5217,7 @@ TrinaryOpNode::substituteDiff(subst_table_t &subst_table, vector } expr_t -TrinaryOpNode::substitutePacExpectation(map, vector > > > > > &subst_table) +TrinaryOpNode::substitutePacExpectation(map &subst_table) { expr_t arg1subst = arg1->substitutePacExpectation(subst_table); expr_t arg2subst = arg2->substitutePacExpectation(subst_table); @@ -5555,7 +5555,7 @@ AbstractExternalFunctionNode::substituteDiff(subst_table_t &subst_table, vector< } expr_t -AbstractExternalFunctionNode::substitutePacExpectation(map, vector > > > > > &subst_table) +AbstractExternalFunctionNode::substitutePacExpectation(map &subst_table) { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -7046,7 +7046,7 @@ VarExpectationNode::substituteDiff(subst_table_t &subst_table, vector, vector > > > > > &subst_table) +VarExpectationNode::substitutePacExpectation(map &subst_table) { return const_cast(this); } @@ -7161,7 +7161,9 @@ PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, ExprNode(datatree_arg), model_name(model_name_arg), discount(discount_arg), - growth(growth_arg) + growth(growth_arg), + stationary_vars_present(true), + nonstationary_vars_present(true) { datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount, growth))] = this; } @@ -7217,18 +7219,32 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, return; } - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) + output << "M_.pac_expectation." << model_name << ".discount = "; + discount->writeOutput(output, oMatlabOutsideModel, temporary_terms, tef_terms); + output << ";" << endl + << "M_.pac_expectation." << model_name << ".growth = "; + growth->writeOutput(output, oMatlabOutsideModel, temporary_terms, tef_terms); + output << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; + for (vector::const_iterator it = h0_indices.begin(); + it != h0_indices.end(); it++) { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; + if (it != h0_indices.begin()) + output << " "; + output << datatree.symbol_table.getTypeSpecificID(*it) + 1; } - - output << "[h0, h1, d] = hVectors(params, H, ids, idns);"; + output << "];" << endl + << "M_.pac_expectation." << model_name << ".h1_param_indices = ["; + for (vector::const_iterator it = h1_indices.begin(); + it != h1_indices.end(); it++) + { + if (it != h1_indices.begin()) + output << " "; + output << datatree.symbol_table.getTypeSpecificID(*it) + 1; + } + output << "];" << endl; } int @@ -7486,6 +7502,8 @@ PacExpectationNode::fillPacExpectationVarInfo(map, exit(EXIT_FAILURE); } + vector > > rhs; + vector lhs, nonstationary_vars; for (map, pair > >, set > > >::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) { if (it1->second.first.second.size() != 1) @@ -7506,25 +7524,13 @@ PacExpectationNode::fillPacExpectationVarInfo(map, if (it1->second.first.first) nonstationary_vars.push_back(lhs.back()); } -} -expr_t -PacExpectationNode::substitutePacExpectation(map, vector > > > > > &subst_table) -{ - map, vector > > > > >::const_iterator myit = - subst_table.find(const_cast(this)); - if (myit != subst_table.end()) - return const_cast(myit->second.first); - - bool stationary_vars_present = true; if (nonstationary_vars.size() == lhs.size()) stationary_vars_present = false; - bool nonstationary_vars_present = true; if (nonstationary_vars.empty()) nonstationary_vars_present = false; - map > all_rhs_vars; // lag -> set< symb_id > (all vars that appear at a given lag) // Order RHS vars by time (already ordered by equation tag) for (vector > >::const_iterator it = rhs.begin(); it != rhs.end(); it++) @@ -7538,8 +7544,8 @@ PacExpectationNode::substitutePacExpectation(map >::iterator mit = all_rhs_vars.find(abs(it1->second)); - if (mit == all_rhs_vars.end()) + map >::iterator mit = z_vec.find(abs(it1->second)); + if (mit == z_vec.end()) { if (it1->second > 0) { @@ -7549,17 +7555,25 @@ PacExpectationNode::substitutePacExpectation(map si; si.insert(it1->first); - all_rhs_vars[abs(it1->second)] = si; + z_vec[abs(it1->second)] = si; } else mit->second.insert(it1->first); } +} + +expr_t +PacExpectationNode::substitutePacExpectation(map &subst_table) +{ + map::const_iterator myit = + subst_table.find(const_cast(this)); + if (myit != subst_table.end()) + return const_cast(myit->second); - vector h0_indices, h1_indices; expr_t subExpr = datatree.AddNonNegativeConstant("0"); if (stationary_vars_present) - for (map >::const_iterator it = all_rhs_vars.begin(); - it != all_rhs_vars.end(); it++) + for (map >::const_iterator it = z_vec.begin(); + it != z_vec.end(); it++) for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) { stringstream param_name_h0; @@ -7574,8 +7588,8 @@ PacExpectationNode::substitutePacExpectation(map >::const_iterator it = all_rhs_vars.begin(); - it != all_rhs_vars.end(); it++) + for (map >::const_iterator it = z_vec.begin(); + it != z_vec.end(); it++) for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) { stringstream param_name_h1; @@ -7589,16 +7603,13 @@ PacExpectationNode::substitutePacExpectation(mapfirst))); } - int pg_symb_id = datatree.symbol_table.addSymbol("pac_growth_parameter", eParameter); + growth_param_index = datatree.symbol_table.addSymbol(model_name + "_pac_growth_neutrality_correction", + eParameter); subExpr = datatree.AddPlus(subExpr, - datatree.AddTimes(datatree.AddVariable(pg_symb_id), + datatree.AddTimes(datatree.AddVariable(growth_param_index), growth)); - subst_table[const_cast(this)] = - make_pair(dynamic_cast(subExpr), - make_pair(model_name, - make_pair(pg_symb_id, - make_pair(h0_indices, h1_indices)))); + subst_table[const_cast(this)] = dynamic_cast(subExpr); return subExpr; } diff --git a/ExprNode.hh b/ExprNode.hh index 4f1d7297..6600403b 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -466,7 +466,7 @@ class ExprNode virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const = 0; //! Substitute pac_expectation operator - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table) = 0; + virtual expr_t substitutePacExpectation(map &subst_table) = 0; //! Add ExprNodes to the provided datatree virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; @@ -543,7 +543,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -621,7 +621,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -722,7 +722,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -835,7 +835,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -928,7 +928,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -1021,7 +1021,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; @@ -1205,7 +1205,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -1236,8 +1236,10 @@ class PacExpectationNode : public ExprNode private: const string &model_name; const expr_t discount, growth; - vector lhs, nonstationary_vars; - vector > > rhs; + bool stationary_vars_present, nonstationary_vars_present; + map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) + vector h0_indices, h1_indices; + int growth_param_index; public: PacExpectationNode(DataTree &datatree_arg, const string &model_name, const expr_t discount_arg, const expr_t growth_arg); virtual void computeTemporaryTerms(map > &reference_count, @@ -1271,7 +1273,7 @@ public: virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; virtual expr_t substituteAdl() const; virtual expr_t substituteDiff(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substitutePacExpectation(map, vector > > > > > &subst_table); + virtual expr_t substitutePacExpectation(map &subst_table); virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, diff --git a/ModFile.cc b/ModFile.cc index b6b909e7..ee1cc504 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -761,8 +761,6 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo // Initialize M_.det_shocks mOutputFile << "M_.det_shocks = [];" << endl; - dynamic_model.writePacExpectationInfo(mOutputFile); - if (linear == 1) mOutputFile << "options_.linear = 1;" << endl; From 59ffefd1ce817eb436e6be8fc035713f2c86ed19 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 7 Feb 2018 16:50:49 +0100 Subject: [PATCH 06/30] pac_expectation: modify syntax --- DataTree.cc | 9 ++++---- DataTree.hh | 4 ++-- DynareBison.yy | 17 +++++++++++++-- ExprNode.cc | 45 ++++++++++++++++++-------------------- ExprNode.hh | 7 +++--- ParsingDriver.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- ParsingDriver.hh | 10 ++++++++- 7 files changed, 111 insertions(+), 38 deletions(-) diff --git a/DataTree.cc b/DataTree.cc index f2179a6d..a779fd86 100644 --- a/DataTree.cc +++ b/DataTree.cc @@ -521,13 +521,14 @@ DataTree::AddVarExpectation(const int symb_id, const int forecast_horizon, const } expr_t -DataTree::AddPacExpectation(const string &model_name, const expr_t discount, const expr_t growth) +DataTree::AddPacExpectation(const string &model_name, const int discount_id, const int growth_id) { - pac_expectation_node_map_t::iterator it = pac_expectation_node_map.find(make_pair(model_name, make_pair(discount, growth))); + pac_expectation_node_map_t::iterator it = + pac_expectation_node_map.find(make_pair(model_name, make_pair(discount_id, growth_id))); if (it != pac_expectation_node_map.end()) return it->second; - - return new PacExpectationNode(*this, model_name, discount, growth); + cout << "addpacexp " << model_name << endl; + return new PacExpectationNode(*this, model_name, discount_id, growth_id); } expr_t diff --git a/DataTree.hh b/DataTree.hh index 61be6c0b..9dd42fb4 100644 --- a/DataTree.hh +++ b/DataTree.hh @@ -82,7 +82,7 @@ protected: var_expectation_node_map_t var_expectation_node_map; // (model_name, (discount, growth)) -> PacExpectationNode - typedef map >, PacExpectationNode *> pac_expectation_node_map_t; + typedef map >, PacExpectationNode *> pac_expectation_node_map_t; pac_expectation_node_map_t pac_expectation_node_map; // ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode @@ -232,7 +232,7 @@ public: //! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree expr_t AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name); //! Adds pac_expectation command to model tree - expr_t AddPacExpectation(const string &model_name, expr_t discount, expr_t growth); + expr_t AddPacExpectation(const string &model_name, const int discount_id, const int growth_id); //! Adds a model local variable with its value void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); //! Adds an external function node diff --git a/DynareBison.yy b/DynareBison.yy index 2b59c861..75113c92 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -908,8 +908,8 @@ hand_side : '(' hand_side ')' { $$ = driver.add_var_expectation($3, new string("1"), $7); } | VAR_EXPECTATION '(' symbol COMMA INT_NUMBER COMMA MODEL_NAME EQUAL NAME ')' { $$ = driver.add_var_expectation($3, $5, $9); } - | PAC_EXPECTATION '(' MODEL_NAME EQUAL NAME COMMA DISCOUNT EQUAL hand_side COMMA GROWTH EQUAL hand_side')' - { $$ = driver.add_pac_expectation($5, $9, $13); } + | PAC_EXPECTATION '(' pac_expectation_options_list ')' + { $$ = driver.add_pac_expectation(); } | MINUS hand_side %prec UMINUS { $$ = driver.add_uminus($2); } | PLUS hand_side @@ -968,6 +968,19 @@ hand_side : '(' hand_side ')' { $$ = driver.add_steady_state($3); } ; + +pac_expectation_options_list : pac_expectation_options_list COMMA pac_expectation_options + | pac_expectation_options + ; + +pac_expectation_options : MODEL_NAME EQUAL QUOTED_STRING + { driver.add_pac_expectation_model_name($3); } + | DISCOUNT EQUAL symbol + { driver.add_pac_expectation_discount($3); } + | GROWTH EQUAL symbol + { driver.add_pac_expectation_growth($3); } + ; + comma_hand_side : hand_side { driver.add_external_function_arg($1); } | comma_hand_side COMMA hand_side diff --git a/ExprNode.cc b/ExprNode.cc index 79988cb6..dcdfd38b 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7156,16 +7156,16 @@ VarExpectationNode::writeJsonOutput(ostream &output, PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, const string &model_name_arg, - const expr_t discount_arg, - const expr_t growth_arg) : + const int discount_symb_id_arg, + const int growth_symb_id_arg) : ExprNode(datatree_arg), model_name(model_name_arg), - discount(discount_arg), - growth(growth_arg), + discount_symb_id(discount_symb_id_arg), + growth_symb_id(growth_symb_id_arg), stationary_vars_present(true), nonstationary_vars_present(true) { - datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount, growth))] = this; + datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount_symb_id, growth_symb_id))] = this; } void @@ -7193,13 +7193,15 @@ PacExpectationNode::computeTemporaryTerms(map &reference_count, expr_t PacExpectationNode::toStatic(DataTree &static_datatree) const { - return static_datatree.AddPacExpectation(model_name, discount, growth); + cout << "toStatic " << model_name << endl; + return static_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); } expr_t PacExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const { - return dynamic_datatree.AddPacExpectation(model_name, discount, growth); + cout << "cloneDynamic " << model_name << endl; + return dynamic_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); } void @@ -7211,20 +7213,16 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (IS_LATEX(output_type)) { - output << "PAC_EXPECTATION" << LEFT_PAR(output_type) << model_name << ", "; - discount->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ", "; - growth->writeOutput(output, output_type, temporary_terms, tef_terms); + output << "PAC_EXPECTATION" << LEFT_PAR(output_type) << model_name << ", " + << discount_symb_id << ", " << growth_symb_id; output << RIGHT_PAR(output_type); return; } - output << "M_.pac_expectation." << model_name << ".discount = "; - discount->writeOutput(output, oMatlabOutsideModel, temporary_terms, tef_terms); - output << ";" << endl - << "M_.pac_expectation." << model_name << ".growth = "; - growth->writeOutput(output, oMatlabOutsideModel, temporary_terms, tef_terms); - output << ";" << endl + output << "M_.pac_expectation." << model_name << ".discount_param_index = " + << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_name = '" + << datatree.symbol_table.getName(growth_symb_id) << "';" << endl << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; @@ -7484,11 +7482,9 @@ PacExpectationNode::writeJsonOutput(ostream &output, { output << "pac_expectation(" << ", model_name = " << model_name - << ", "; - discount->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ", "; - growth->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ")"; + << ", " << discount_symb_id + << ", " << growth_symb_id + << ")"; } void @@ -7603,11 +7599,12 @@ PacExpectationNode::substitutePacExpectation(mapfirst))); } - growth_param_index = datatree.symbol_table.addSymbol(model_name + "_pac_growth_neutrality_correction", + growth_param_index = datatree.symbol_table.addSymbol(model_name + + "_pac_growth_neutrality_correction", eParameter); subExpr = datatree.AddPlus(subExpr, datatree.AddTimes(datatree.AddVariable(growth_param_index), - growth)); + datatree.AddVariable(growth_symb_id))); subst_table[const_cast(this)] = dynamic_cast(subExpr); diff --git a/ExprNode.hh b/ExprNode.hh index 6600403b..80052b1b 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -1234,14 +1234,15 @@ public: class PacExpectationNode : public ExprNode { private: - const string &model_name; - const expr_t discount, growth; + const string model_name; + const int discount_symb_id, growth_symb_id; bool stationary_vars_present, nonstationary_vars_present; map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; int growth_param_index; public: - PacExpectationNode(DataTree &datatree_arg, const string &model_name, const expr_t discount_arg, const expr_t growth_arg); + PacExpectationNode(DataTree &datatree_arg, const string &model_name, + const int discount_arg, const int growth_arg); virtual void computeTemporaryTerms(map > &reference_count, map &temp_terms_map, bool is_matlab, NodeTreeReference tr) const; diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 0a8924a2..bd771b85 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -2673,9 +2673,62 @@ ParsingDriver::add_var_expectation(string *arg1, string *arg2, string *arg3) } expr_t -ParsingDriver::add_pac_expectation(string *model_name, expr_t discount, expr_t growth) +ParsingDriver::add_pac_expectation() { - return data_tree->AddPacExpectation(*model_name, discount, growth); + if (pac_expectation_model_name.empty()) + error("pac_expectation: you must pass the model_name option"); + + if (pac_expectation_discount.empty()) + error("pac_expectation: you must pass the discount option"); + + if (pac_expectation_growth.empty()) + error("pac_expectation: you must pass the growth option"); + + int pac_expectation_discount_id = + mod_file->symbol_table.getID(pac_expectation_discount); + + int pac_expectation_growth_id = + mod_file->symbol_table.getID(pac_expectation_growth); + + expr_t pac_exp_node = data_tree->AddPacExpectation(pac_expectation_model_name, + pac_expectation_discount_id, + pac_expectation_growth_id); + + pac_expectation_model_name = pac_expectation_discount = pac_expectation_growth = ""; + + return pac_exp_node; +} + +void +ParsingDriver::add_pac_expectation_model_name(string *arg) +{ + if (!pac_expectation_model_name.empty()) + error("pac_expectation: you can only pass the model_name option once"); + pac_expectation_model_name = *arg; + delete arg; +} + +void +ParsingDriver::add_pac_expectation_discount(string *arg) +{ + if (!pac_expectation_discount.empty()) + error("pac_expectation: you can only pass the discount option once"); + check_symbol_is_parameter(arg); + pac_expectation_discount = *arg; + delete arg; +} + +void +ParsingDriver::add_pac_expectation_growth(string *arg) +{ + if (!pac_expectation_growth.empty()) + error("pac_expectation: you can only pass the growth option once"); + check_symbol_existence(*arg); + SymbolType type = mod_file->symbol_table.getType(mod_file->symbol_table.getID(*arg)); + if (type != eParameter && type != eEndogenous) + error("pac_expectation growth argument must either be a parameter or an endogenous variable."); + pac_expectation_growth = *arg; + delete arg; } expr_t diff --git a/ParsingDriver.hh b/ParsingDriver.hh index bf5c12b1..c83793a6 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -251,6 +251,10 @@ private: //! Used by VAR restrictions void clear_VAR_storage(); + + //! Used by pac_expectation + string pac_expectation_model_name, pac_expectation_discount, pac_expectation_growth; + public: ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) { @@ -687,7 +691,11 @@ public: //! Writes token "VAR_EXPECTATION(arg1, arg2, arg3)" to model tree expr_t add_var_expectation(string *arg1, string *arg2, string *arg3); //! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree - expr_t add_pac_expectation(string *model_name, expr_t discount, expr_t growth); + expr_t add_pac_expectation(); + //! Adds arguments for pac_expectation + void add_pac_expectation_model_name(string *arg); + void add_pac_expectation_discount(string *arg); + void add_pac_expectation_growth(string *arg); //! Writes token "diff(arg1)" to model tree expr_t add_diff(expr_t arg1); //! Writes token "adl(arg1, lag)" to model tree From abd3be992861c290707a6ac044f130a78c421d9e Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 7 Feb 2018 16:52:11 +0100 Subject: [PATCH 07/30] preprocessor: remove extraneous print statements --- DataTree.cc | 2 +- ExprNode.cc | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/DataTree.cc b/DataTree.cc index a779fd86..0b3b4b22 100644 --- a/DataTree.cc +++ b/DataTree.cc @@ -527,7 +527,7 @@ DataTree::AddPacExpectation(const string &model_name, const int discount_id, con pac_expectation_node_map.find(make_pair(model_name, make_pair(discount_id, growth_id))); if (it != pac_expectation_node_map.end()) return it->second; - cout << "addpacexp " << model_name << endl; + return new PacExpectationNode(*this, model_name, discount_id, growth_id); } diff --git a/ExprNode.cc b/ExprNode.cc index dcdfd38b..9b940788 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7193,14 +7193,12 @@ PacExpectationNode::computeTemporaryTerms(map &reference_count, expr_t PacExpectationNode::toStatic(DataTree &static_datatree) const { - cout << "toStatic " << model_name << endl; return static_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); } expr_t PacExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const { - cout << "cloneDynamic " << model_name << endl; return dynamic_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); } From ac8e8f641e25f52d681d1751b5e35cf4a69fe099 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 8 Feb 2018 13:07:15 +0100 Subject: [PATCH 08/30] preprocessor: var_model: pac_expectation: add more information to var_model --- ComputingTasks.cc | 164 +++++++++++++++++++++++++++++++++++++++----- ComputingTasks.hh | 16 ++++- DynamicModel.cc | 125 +++++++++++++++++++++++----------- DynamicModel.hh | 16 ++++- ExprNode.cc | 170 ++++++++++++++++++++++++---------------------- ExprNode.hh | 29 +++++--- ModFile.cc | 44 +++++++----- ParsingDriver.cc | 2 +- 8 files changed, 395 insertions(+), 171 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index bf5e74bd..a50236a5 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -260,31 +260,90 @@ PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const VarModelStatement::VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, - const string &name_arg) : + const string &name_arg, + const SymbolTable &symbol_table_arg) : symbol_list(symbol_list_arg), options_list(options_list_arg), - name(name_arg) + name(name_arg), + symbol_table(symbol_table_arg) { } void -VarModelStatement::getVarModelNameAndVarList(map, pair > >, set > > >, pair > > &var_model_info) const +VarModelStatement::getVarModelInfoForVarExpectation(map > &var_model_info) const +{ + if (symbol_list.empty()) + return; + + OptionsList::num_options_t::const_iterator it = options_list.num_options.find("var.order"); + var_model_info[name] = make_pair(symbol_list, atoi(it->second.c_str())); +} + +void +VarModelStatement::getVarModelEqTags(vector &var_model_eqtags) const { - set > empty_int_set; - map, pair > >, set > > > eqtagmap; if (!symbol_list.empty()) - { - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("var.order"); - vector empty_str_vec; - var_model_info[name] = make_pair(eqtagmap, make_pair(symbol_list, atoi(it->second.c_str()))); - } - else - { - OptionsList::vec_str_options_t::const_iterator it1 = options_list.vector_str_options.find("var.eqtags"); - for (vector::const_iterator it = it1->second.begin(); it != it1->second.end(); it++) - eqtagmap[make_pair(*it, -1)] = make_pair(make_pair(0, empty_int_set), empty_int_set); - var_model_info[name] = make_pair(eqtagmap, make_pair(symbol_list, 0)); - } + return; + + OptionsList::vec_str_options_t::const_iterator it1 = + options_list.vector_str_options.find("var.eqtags"); + var_model_eqtags = it1->second; +} + +void +VarModelStatement::fillVarModelInfoFromEquations(vector &eqnumber_arg, vector &lhs_arg, + vector > > &rhs_arg, + vector &nonstationary_arg, + vector &diff_arg, vector &orig_diff_var_arg) +{ + eqnumber = eqnumber_arg; + lhs = lhs_arg; + nonstationary = nonstationary_arg; + diff = diff_arg; + orig_diff_var = orig_diff_var_arg; + + // Order RHS vars by time (already ordered by equation tag) + for (vector > >::const_iterator it = rhs_arg.begin(); + it != rhs_arg.end(); it++) + for (set >::const_iterator it1 = it->begin(); + it1 != it->end(); it1++) + if (find(lhs.begin(), lhs.end(), it1->first) == lhs.end() + && find(orig_diff_var.begin(), orig_diff_var.end(), it1->first) == orig_diff_var.end()) + { + cerr << "ERROR " << name << ": " << symbol_table.getName(it1->first) + << " cannot appear in the VAR because it does not appear on the LHS" << endl; + exit(EXIT_FAILURE); + } + else + { + map >::iterator mit = rhs.find(abs(it1->second)); + if (mit == rhs.end()) + { + if (it1->second > 0) + { + cerr << "ERROR " << name << ": you cannot have a variable with a lead in a VAR" << endl; + exit(EXIT_FAILURE); + } + set si; + si.insert(it1->first); + rhs[abs(it1->second)] = si; + } + else + mit->second.insert(it1->first); + } +} + +void +VarModelStatement::getVarModelName(string &var_model_name) const +{ + var_model_name = name; +} + + +void +VarModelStatement::getVarModelRHS(map > &rhs_arg) const +{ + rhs_arg = rhs; } void @@ -298,8 +357,79 @@ VarModelStatement::writeOutput(ostream &output, const string &basename, bool min options_list.writeOutput(output); if (!symbol_list.empty()) symbol_list.writeOutput("options_.var.var_list_", output); + + output << "options_.var.lhs = ["; + for (vector::const_iterator it = lhs.begin(); + it != lhs.end(); it++) + { + if (it != lhs.begin()) + output << " "; + output << symbol_table.getTypeSpecificID(*it) + 1; + } + output << "];" << endl + << "options_.var.rhs.lag = ["; + for (map >::const_iterator it = rhs.begin(); + it != rhs.end(); it++) + { + if (it != rhs.begin()) + output << " "; + output << it->first; + } + output << "];" << endl; + int i = 1; + for (map >::const_iterator it = rhs.begin(); + it != rhs.end(); it++, i++) + { + output << "options_.var.rhs.vars_at_lag{" << i << "} = ["; + for (set::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << " "; + output << symbol_table.getTypeSpecificID(*it1) + 1; + } + output << "];" << endl; + } + output << "options_.var.nonstationary = logical(["; + for (vector::const_iterator it = nonstationary.begin(); + it != nonstationary.end(); it++) + { + if (it != nonstationary.begin()) + output << " "; + if (*it) + output << "1"; + else + output << "0"; + } + output << "]);" << endl + << "options_.var.diff = logical(["; + for (vector::const_iterator it = diff.begin(); + it != diff.end(); it++) + { + if (it != diff.begin()) + output << " "; + if (*it) + output << "1"; + else + output << "0"; + } + output << "]);" << endl + << "options_.var.orig_diff_var = ["; + for (vector::const_iterator it = orig_diff_var.begin(); + it != orig_diff_var.end(); it++) + { + if (it != orig_diff_var.begin()) + output << " "; + if (*it == -1) + output << -1; + else + output << symbol_table.getTypeSpecificID(*it) + 1; + } + output << "];" << endl; output << "M_.var." << name << " = options_.var;" << endl << "clear options_.var;" << endl; + + cout << "DONE writing varmodel" << endl; } void diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 1799f37d..b0090cf7 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -125,11 +125,23 @@ private: const SymbolList symbol_list; const OptionsList options_list; const string &name; + const SymbolTable &symbol_table; + vector eqnumber, lhs, orig_diff_var; + map > rhs; // lag -> set< symb_id > (all vars that appear at a given lag) + vector nonstationary, diff; public: VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, - const string &name_arg); - void getVarModelNameAndVarList(map, pair > >, set > > >, pair > > &var_model_info) const; + const string &name_arg, + const SymbolTable &symbol_table_arg); + void getVarModelInfoForVarExpectation(map > &var_model_info) const; + void getVarModelEqTags(vector &var_model_eqtags) const; + void fillVarModelInfoFromEquations(vector &eqnumber_arg, vector &lhs_arg, + vector > > &rhs_arg, + vector &nonstationary_arg, + vector &diff_arg, vector &orig_diff_var_arg); + void getVarModelName(string &var_model_name) const; + void getVarModelRHS(map > &rhs_arg) const; virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void createVarModelMFunction(ostream &output, const map > &var_expectation_functions_to_write) const; diff --git a/DynamicModel.cc b/DynamicModel.cc index da197ef8..72494a77 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3235,50 +3235,91 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context) } void -DynamicModel::getVarModelVariablesFromEqTags(map, pair > >, set > > > > &var_model_info) +DynamicModel::getVarModelVariablesFromEqTags(vector &var_model_eqtags, + vector &eqnumber, + vector &lhs, + vector > > &rhs, + vector &nonstationary) const { - for (map, pair > >, set > > > >::iterator it = var_model_info.begin(); it != var_model_info.end(); it++) + for (vector::const_iterator itvareqs = var_model_eqtags.begin(); + itvareqs != var_model_eqtags.end(); itvareqs++) { - map, pair > >, set > > > final_map; - for (map, pair > >, set > > >::iterator itvareqs = it->second.begin(); - itvareqs != it->second.end(); itvareqs++) + int eqnumber_int = -1; + set > lhs_set, lhs_tmp_set, rhs_set; + string eqtag (*itvareqs); + for (vector > >::const_iterator iteqtag = + equation_tags.begin(); iteqtag != equation_tags.end(); iteqtag++) + if (iteqtag->second.first.compare("name") == 0 + && iteqtag->second.second.compare(eqtag) == 0) + { + eqnumber_int = iteqtag->first; + break; + } + + if (eqnumber_int == -1) { - int eqnumber = -1; - set > lhs, rhs; - string eqtag (itvareqs->first.first); - for (vector > >::const_iterator iteqtag = equation_tags.begin(); - iteqtag != equation_tags.end(); iteqtag++) - if (iteqtag->second.first.compare("name") == 0 - && iteqtag->second.second.compare(eqtag) == 0) - { - eqnumber = iteqtag->first; - break; - } - - if (eqnumber == -1) - { - cerr << "ERROR: equation tag '" << eqtag << "' not found in var_model " << it->first << endl; - exit(EXIT_FAILURE); - } - - int nonstationary = 0; - for (vector > >::const_iterator iteqtag = equation_tags.begin(); - iteqtag != equation_tags.end(); iteqtag++) - if (iteqtag->first == eqnumber) - if (iteqtag->second.first.compare("data_type") == 0 - && iteqtag->second.second.compare("nonstationary") == 0) - { - nonstationary = 1; - break; - } - - equations[eqnumber]->get_arg1()->collectDynamicVariables(eEndogenous, lhs); - equations[eqnumber]->get_arg2()->collectDynamicVariables(eEndogenous, rhs); - - final_map[make_pair(eqtag, eqnumber)] = make_pair(make_pair(nonstationary, lhs), rhs); + cerr << "ERROR: equation tag '" << eqtag << "' not found" << endl; + exit(EXIT_FAILURE); } - var_model_info[it->first] = final_map; + bool nonstationary_bool = false; + for (vector > >::const_iterator iteqtag = + equation_tags.begin(); iteqtag != equation_tags.end(); iteqtag++) + if (iteqtag->first == eqnumber_int) + if (iteqtag->second.first.compare("data_type") == 0 + && iteqtag->second.second.compare("nonstationary") == 0) + { + nonstationary_bool = true; + break; + } + + equations[eqnumber_int]->get_arg1()->collectDynamicVariables(eEndogenous, lhs_set); + equations[eqnumber_int]->get_arg1()->collectDynamicVariables(eExogenous, lhs_tmp_set); + equations[eqnumber_int]->get_arg1()->collectDynamicVariables(eParameter, lhs_tmp_set); + + if (lhs_set.size() != 1 || !lhs_tmp_set.empty()) + { + cerr << "ERROR: A VAR may only have one endogenous variable on the LHS" << endl; + exit(EXIT_FAILURE); + } + + set >::const_iterator it = lhs_set.begin(); + if (it->second != 0) + { + cerr << "ERROR: The variable on the LHS of a VAR may not appear with a lead or a lag" << endl; + exit(EXIT_FAILURE); + } + + eqnumber.push_back(eqnumber_int); + lhs.push_back(it->first); + nonstationary.push_back(nonstationary_bool); + + equations[eqnumber_int]->get_arg2()->collectDynamicVariables(eEndogenous, rhs_set); + rhs.push_back(rhs_set); + } +} + +void +DynamicModel::getDiffInfo(vector &eqnumber, vector &diff, vector &orig_diff_var) const +{ + for (vector::const_iterator it = eqnumber.begin(); + it != eqnumber.end(); it++) + { + diff.push_back(equations[*it]->isDiffPresent()); + if (diff.back()) + { + set > diff_set; + equations[*it]->get_arg1()->collectDynamicVariables(eEndogenous, diff_set); + if (diff_set.empty() || diff_set.size() != 1) + { + cerr << "ERROR: problem getting variable for diff operator in equation " << *it << endl; + exit(EXIT_FAILURE); + } + set >::const_iterator it1 = diff_set.begin(); + orig_diff_var.push_back(it1->first); + } + else + orig_diff_var.push_back(-1); } } @@ -3342,10 +3383,12 @@ DynamicModel::addEquationsForVar(map > &var_model_ } void -DynamicModel::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +DynamicModel::fillPacExpectationVarInfo(string &var_model_name, + map > &rhs, + vector &nonstationary) { for (size_t i = 0; i < equations.size(); i++) - equations[i]->fillPacExpectationVarInfo(var_model_info); + equations[i]->fillPacExpectationVarInfo(var_model_name, rhs, nonstationary); } void diff --git a/DynamicModel.hh b/DynamicModel.hh index 676718a6..d87b412b 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -283,14 +283,24 @@ public: //! Set the equations that have non-zero second derivatives void setNonZeroHessianEquations(map &eqs); - //! Fill var_model_info with variables associated with equation tags - void getVarModelVariablesFromEqTags(map, pair > >, set > > > > &var_model_info); + //! Get equation info associated with equation tags from var_model + void getVarModelVariablesFromEqTags(vector &var_model_eqtags, + vector &eqnumber, + vector &lhs, + vector > > &rhs, + vector &nonstationary) const; + + // Get equtaino information on diff operator + void getDiffInfo(vector &eqnumber, vector &diff, vector &orig_diff_var) const; + //! Set indices for var expectation in dynamic model file void setVarExpectationIndices(map > &var_model_info); //! Add aux equations (and aux variables) for variables declared in var_model at max order if they don't already exist void addEquationsForVar(map > &var_model_info); //! Add var_model info to pac_expectation nodes - void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + void fillPacExpectationVarInfo(string &var_model_name, + map > &rhs, + vector &nonstationary); //! Substitutes pac_expectation operator void substitutePacExpectation(); diff --git a/ExprNode.cc b/ExprNode.cc index 9b940788..655c0723 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -294,6 +294,12 @@ ExprNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_ar return false; } +bool +ExprNode::isDiffPresent() const +{ + return false; +} + void ExprNode::getEndosAndMaxLags(map &model_endos_and_lags) const { @@ -307,6 +313,12 @@ NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) : datatree.num_const_node_map[id] = this; } +bool +NumConstNode::isDiffPresent() const +{ + return false; +} + void NumConstNode::prepareForDerivation() { @@ -567,7 +579,7 @@ NumConstNode::setVarExpectationIndex(map > &var_mo } void -NumConstNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +NumConstNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { } @@ -1560,6 +1572,12 @@ VariableNode::detrend(int symb_id, bool log_trend, expr_t trend) const } } +bool +VariableNode::isDiffPresent() const +{ + return false; +} + expr_t VariableNode::removeTrendLeadLag(map trend_symbols_map) const { @@ -1617,7 +1635,7 @@ VariableNode::setVarExpectationIndex(map > &var_mo } void -VariableNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +VariableNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { } @@ -2792,6 +2810,14 @@ UnaryOpNode::substituteAdl() const return retval; } +bool +UnaryOpNode::isDiffPresent() const +{ + if (op_code == oDiff) + return true; + return arg->isDiffPresent(); +} + expr_t UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector &neweqs) const { @@ -3000,9 +3026,9 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod } void -UnaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { - arg->fillPacExpectationVarInfo(var_model_info); + arg->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); } bool @@ -4444,6 +4470,12 @@ BinaryOpNode::substituteDiff(subst_table_t &subst_table, vector return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } +bool +BinaryOpNode::isDiffPresent() const +{ + return arg1->isDiffPresent() || arg2->isDiffPresent(); +} + expr_t BinaryOpNode::substitutePacExpectation(map &subst_table) { @@ -4530,10 +4562,10 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo } void -BinaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { - arg1->fillPacExpectationVarInfo(var_model_info); - arg2->fillPacExpectationVarInfo(var_model_info); + arg1->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg2->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); } bool @@ -5216,6 +5248,12 @@ TrinaryOpNode::substituteDiff(subst_table_t &subst_table, vector return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } +bool +TrinaryOpNode::isDiffPresent() const +{ + return arg1->isDiffPresent() || arg2->isDiffPresent() || arg3->isDiffPresent(); +} + expr_t TrinaryOpNode::substitutePacExpectation(map &subst_table) { @@ -5300,11 +5338,11 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m } void -TrinaryOpNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { - arg1->fillPacExpectationVarInfo(var_model_info); - arg2->fillPacExpectationVarInfo(var_model_info); - arg3->fillPacExpectationVarInfo(var_model_info); + arg1->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg2->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg3->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); } bool @@ -5554,6 +5592,15 @@ AbstractExternalFunctionNode::substituteDiff(subst_table_t &subst_table, vector< return buildSimilarExternalFunctionNode(arguments_subst, datatree); } +bool +AbstractExternalFunctionNode::isDiffPresent() const +{ + bool result = false; + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + result = result || (*it)->isDiffPresent(); + return result; +} + expr_t AbstractExternalFunctionNode::substitutePacExpectation(map &subst_table) { @@ -5665,10 +5712,10 @@ AbstractExternalFunctionNode::setVarExpectationIndex(map, pair > >, set > > > > &var_model_info) +AbstractExternalFunctionNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->fillPacExpectationVarInfo(var_model_info); + (*it)->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); } bool @@ -6969,6 +7016,12 @@ VarExpectationNode::eval(const eval_context_t &eval_context) const throw (EvalEx return it->second; } +bool +VarExpectationNode::isDiffPresent() const +{ + return false; +} + void VarExpectationNode::computeXrefs(EquationInfo &ei) const { @@ -7130,7 +7183,7 @@ VarExpectationNode::setVarExpectationIndex(map > & } void -VarExpectationNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { } @@ -7162,8 +7215,8 @@ PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, model_name(model_name_arg), discount_symb_id(discount_symb_id_arg), growth_symb_id(growth_symb_id_arg), - stationary_vars_present(true), - nonstationary_vars_present(true) + stationary_vars_present(false), + nonstationary_vars_present(false) { datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount_symb_id, growth_symb_id))] = this; } @@ -7341,6 +7394,12 @@ PacExpectationNode::compile(ostream &CompileCode, unsigned int &instruction_numb exit(EXIT_FAILURE); } +bool +PacExpectationNode::isDiffPresent() const +{ + return false; +} + pair PacExpectationNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -7486,74 +7545,23 @@ PacExpectationNode::writeJsonOutput(ostream &output, } void -PacExpectationNode::fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) +PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) { - map, pair > >, set > > > >::const_iterator it = var_model_info.find(model_name); - if (it == var_model_info.end()) + if (model_name != var_model_name) + return; + + z_vec = rhs_arg; + + for (vector::const_iterator it = nonstationary_arg.begin(); + it != nonstationary_arg.end(); it++) { - cerr << "ERROR: could not find the declaration of " << model_name - << " referenced by pac_expectation operator" << endl; - exit(EXIT_FAILURE); - } - - vector > > rhs; - vector lhs, nonstationary_vars; - for (map, pair > >, set > > >::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - { - if (it1->second.first.second.size() != 1) - { - cerr << "ERROR " << model_name - << ": you may only have one variable on the LHS of a VAR" << endl; - exit(EXIT_FAILURE); - } - set >::const_iterator setit = it1->second.first.second.begin(); - if (setit->second != 0) - { - cerr << "ERROR " << model_name - << ": the LHS variable of a VAR cannot appear with a lead or a lag" << endl; - exit(EXIT_FAILURE); - } - lhs.push_back(setit->first); - rhs.push_back(it1->second.second); - if (it1->second.first.first) - nonstationary_vars.push_back(lhs.back()); - } - - if (nonstationary_vars.size() == lhs.size()) - stationary_vars_present = false; - - if (nonstationary_vars.empty()) - nonstationary_vars_present = false; - - // Order RHS vars by time (already ordered by equation tag) - for (vector > >::const_iterator it = rhs.begin(); - it != rhs.end(); it++) - for (set >::const_iterator it1 = it->begin(); - it1 != it->end(); it1++) - if (find(lhs.begin(), lhs.end(), it1->first) == lhs.end()) - { - cerr << "ERROR " << model_name << ": " << datatree.symbol_table.getName(it1->first) - << " cannot appear in the VAR because it does not appear on the LHS" << endl; - exit(EXIT_FAILURE); - } + if (*it) + nonstationary_vars_present = true; else - { - map >::iterator mit = z_vec.find(abs(it1->second)); - if (mit == z_vec.end()) - { - if (it1->second > 0) - { - cerr << "ERROR " << model_name << - ": you cannot have a variable with a lead in a VAR" << endl; - exit(EXIT_FAILURE); - } - set si; - si.insert(it1->first); - z_vec[abs(it1->second)] = si; - } - else - mit->second.insert(it1->first); - } + stationary_vars_present = true; + if (nonstationary_vars_present && stationary_vars_present) + break; + } } expr_t diff --git a/ExprNode.hh b/ExprNode.hh index 80052b1b..156df34a 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -440,6 +440,9 @@ class ExprNode //! Returns true if the expression contains one or several exogenous variable virtual bool containsExogenous() const = 0; + //! Returns true if the expression contains a diff operator + virtual bool isDiffPresent(void) const = 0; + //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise /*! \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg) @@ -487,7 +490,7 @@ class ExprNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; //! Fills var_model info for pac_expectation node - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info) = 0; + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) = 0; //! Fills map virtual void getEndosAndMaxLags(map &model_endos_and_lags) const = 0; @@ -549,6 +552,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -556,7 +560,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -627,6 +631,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -634,7 +639,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -728,6 +733,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -735,7 +741,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -841,6 +847,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -854,7 +861,7 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -934,6 +941,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; @@ -941,7 +949,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1028,6 +1036,7 @@ public: virtual bool isNumConstNodeEqualTo(double value) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; virtual void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const string &ending) const; virtual expr_t replaceTrendVar() const; @@ -1036,7 +1045,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1215,6 +1224,7 @@ public: virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; @@ -1224,7 +1234,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -1284,6 +1294,7 @@ public: virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; + virtual bool isDiffPresent(void) const; virtual bool isNumConstNodeEqualTo(double value) const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; @@ -1293,7 +1304,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(map, pair > >, set > > > > &var_model_info); + virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; diff --git a/ModFile.cc b/ModFile.cc index ee1cc504..7d1f757a 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -361,37 +361,47 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const } } + // Create auxiliary variable and equations for Diff operator + dynamic_model.substituteDiff(); + // Var Model - map, pair > >, set > > >, pair > > var_model_info; + map > var_model_info_var_expectation; for (vector::const_iterator it = statements.begin(); it != statements.end(); it++) { VarModelStatement *vms = dynamic_cast(*it); if (vms != NULL) - vms->getVarModelNameAndVarList(var_model_info); + { + vms->getVarModelInfoForVarExpectation(var_model_info_var_expectation); + + vector var_model_eqtags; + vms->getVarModelEqTags(var_model_eqtags); + if (!var_model_eqtags.empty()) + { + vector eqnumber, lhs, orig_diff_var; + vector > > rhs; + vector nonstationary, diff; + dynamic_model.getVarModelVariablesFromEqTags(var_model_eqtags, + eqnumber, lhs, rhs, nonstationary); + original_model.getDiffInfo(eqnumber, diff, orig_diff_var); + vms->fillVarModelInfoFromEquations(eqnumber, lhs, rhs, nonstationary, diff, orig_diff_var); + string var_model_name; + map > rhs_pac; + vms->getVarModelName(var_model_name); + vms->getVarModelRHS(rhs_pac); + dynamic_model.fillPacExpectationVarInfo(var_model_name, rhs_pac, nonstationary); + dynamic_model.substitutePacExpectation(); + } + } } - if (!var_model_info.empty()) + if (!var_model_info_var_expectation.empty()) { - map > var_model_info_var_expectation; - map, pair > >, set > > > > var_model_info_pac; - for (map, pair > >, set > > >, pair > >::const_iterator it = var_model_info.begin(); it != var_model_info.end(); it++) - { - var_model_info_pac[it->first] = it->second.first; - var_model_info_var_expectation[it->first] = it->second.second; - } dynamic_model.setVarExpectationIndices(var_model_info_var_expectation); dynamic_model.addEquationsForVar(var_model_info_var_expectation); - - dynamic_model.getVarModelVariablesFromEqTags(var_model_info_pac); - dynamic_model.fillPacExpectationVarInfo(var_model_info_pac); - dynamic_model.substitutePacExpectation(); } dynamic_model.fillVarExpectationFunctionsToWrite(); - // Create auxiliary variable and equations for Diff operator - dynamic_model.substituteDiff(); - if (symbol_table.predeterminedNbr() > 0) dynamic_model.transformPredeterminedVariables(); diff --git a/ParsingDriver.cc b/ParsingDriver.cc index bd771b85..47eeba3c 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -1517,7 +1517,7 @@ ParsingDriver::var_model() if (options_list.num_options.find("var.order") == options_list.num_options.end()) error("You must pass the order option when passing a symbol list to the var_model statement"); - mod_file->addStatement(new VarModelStatement(symbol_list, options_list, *name)); + mod_file->addStatement(new VarModelStatement(symbol_list, options_list, *name, mod_file->symbol_table)); var_map[it->second] = symbol_list.getSymbols(); symbol_list.clear(); options_list.clear(); From b60f0d92a098acacf129f542f295b5ce97b627cf Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 8 Feb 2018 16:01:47 +0100 Subject: [PATCH 09/30] preprocessor: remove extraneous write statement --- ComputingTasks.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index a50236a5..f2e35bdc 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -428,8 +428,6 @@ VarModelStatement::writeOutput(ostream &output, const string &basename, bool min output << "];" << endl; output << "M_.var." << name << " = options_.var;" << endl << "clear options_.var;" << endl; - - cout << "DONE writing varmodel" << endl; } void From 2f28aded6e31c239769e7d8c0b02dcac63036ca1 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 8 Feb 2018 17:51:31 +0100 Subject: [PATCH 10/30] preprocessor: pac_expectation fixes --- ComputingTasks.cc | 11 ++++++++++- DataTree.cc | 6 +++--- DataTree.hh | 4 ++-- DynareBison.yy | 6 ++++-- DynareFlex.ll | 1 + ExprNode.cc | 13 ++++++++----- ExprNode.hh | 4 ++-- ParsingDriver.cc | 13 +++++++++++++ ParsingDriver.hh | 3 ++- 9 files changed, 45 insertions(+), 16 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index f2e35bdc..e26c625e 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -358,7 +358,16 @@ VarModelStatement::writeOutput(ostream &output, const string &basename, bool min if (!symbol_list.empty()) symbol_list.writeOutput("options_.var.var_list_", output); - output << "options_.var.lhs = ["; + output << "options_.var.eqn = ["; + for (vector::const_iterator it = eqnumber.begin(); + it != eqnumber.end(); it++) + { + if (it != eqnumber.begin()) + output << " "; + output << *it + 1; + } + output << "];" << endl + << "options_.var.lhs = ["; for (vector::const_iterator it = lhs.begin(); it != lhs.end(); it++) { diff --git a/DataTree.cc b/DataTree.cc index 0b3b4b22..49313722 100644 --- a/DataTree.cc +++ b/DataTree.cc @@ -521,14 +521,14 @@ DataTree::AddVarExpectation(const int symb_id, const int forecast_horizon, const } expr_t -DataTree::AddPacExpectation(const string &model_name, const int discount_id, const int growth_id) +DataTree::AddPacExpectation(const string &model_name, const string &var_model_name, const int discount_id, const int growth_id) { pac_expectation_node_map_t::iterator it = - pac_expectation_node_map.find(make_pair(model_name, make_pair(discount_id, growth_id))); + pac_expectation_node_map.find(make_pair(model_name, make_pair(var_model_name, make_pair(discount_id, growth_id)))); if (it != pac_expectation_node_map.end()) return it->second; - return new PacExpectationNode(*this, model_name, discount_id, growth_id); + return new PacExpectationNode(*this, model_name, var_model_name, discount_id, growth_id); } expr_t diff --git a/DataTree.hh b/DataTree.hh index 9dd42fb4..e55de76c 100644 --- a/DataTree.hh +++ b/DataTree.hh @@ -82,7 +82,7 @@ protected: var_expectation_node_map_t var_expectation_node_map; // (model_name, (discount, growth)) -> PacExpectationNode - typedef map >, PacExpectationNode *> pac_expectation_node_map_t; + typedef map > >, PacExpectationNode *> pac_expectation_node_map_t; pac_expectation_node_map_t pac_expectation_node_map; // ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode @@ -232,7 +232,7 @@ public: //! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree expr_t AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name); //! Adds pac_expectation command to model tree - expr_t AddPacExpectation(const string &model_name, const int discount_id, const int growth_id); + expr_t AddPacExpectation(const string &model_name, const string &var_model_name, const int discount_id, const int growth_id); //! Adds a model local variable with its value void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); //! Adds an external function node diff --git a/DynareBison.yy b/DynareBison.yy index 75113c92..e9aa4509 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -115,7 +115,7 @@ class ParsingDriver; %token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION %token NAME %token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS -%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY +%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY VAR_MODEL_NAME %token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS MODEL_NAME STDERR_MULTIPLES DIAGONAL_ONLY %token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE DISCOUNT %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE @@ -973,7 +973,9 @@ pac_expectation_options_list : pac_expectation_options_list COMMA pac_expectatio | pac_expectation_options ; -pac_expectation_options : MODEL_NAME EQUAL QUOTED_STRING +pac_expectation_options : VAR_MODEL_NAME EQUAL NAME + { driver.add_pac_expectation_var_model_name($3); } + | MODEL_NAME EQUAL NAME { driver.add_pac_expectation_model_name($3); } | DISCOUNT EQUAL symbol { driver.add_pac_expectation_discount($3); } diff --git a/DynareFlex.ll b/DynareFlex.ll index 6248ed6a..8aa307da 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -342,6 +342,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 optim {return token::OPTIM;} periods {return token::PERIODS;} model_name {return token::MODEL_NAME;} +var_model_name {return token::VAR_MODEL_NAME;} endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;} sub_draws {return token::SUB_DRAWS;} minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;} diff --git a/ExprNode.cc b/ExprNode.cc index 655c0723..b3dd523e 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7209,16 +7209,18 @@ VarExpectationNode::writeJsonOutput(ostream &output, PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, const string &model_name_arg, + const string &var_model_name_arg, const int discount_symb_id_arg, const int growth_symb_id_arg) : ExprNode(datatree_arg), model_name(model_name_arg), + var_model_name(var_model_name_arg), discount_symb_id(discount_symb_id_arg), growth_symb_id(growth_symb_id_arg), stationary_vars_present(false), nonstationary_vars_present(false) { - datatree.pac_expectation_node_map[make_pair(model_name, make_pair(discount_symb_id, growth_symb_id))] = this; + datatree.pac_expectation_node_map[make_pair(model_name, make_pair(var_model_name, make_pair(discount_symb_id, growth_symb_id)))] = this; } void @@ -7246,13 +7248,13 @@ PacExpectationNode::computeTemporaryTerms(map &reference_count, expr_t PacExpectationNode::toStatic(DataTree &static_datatree) const { - return static_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); + return static_datatree.AddPacExpectation(string(model_name), string(var_model_name), discount_symb_id, growth_symb_id); } expr_t PacExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const { - return dynamic_datatree.AddPacExpectation(string(model_name), discount_symb_id, growth_symb_id); + return dynamic_datatree.AddPacExpectation(string(model_name), string(var_model_name), discount_symb_id, growth_symb_id); } void @@ -7265,12 +7267,13 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (IS_LATEX(output_type)) { output << "PAC_EXPECTATION" << LEFT_PAR(output_type) << model_name << ", " - << discount_symb_id << ", " << growth_symb_id; + << var_model_name << ", " << discount_symb_id << ", " << growth_symb_id; output << RIGHT_PAR(output_type); return; } - output << "M_.pac_expectation." << model_name << ".discount_param_index = " + output <<"M_.pac_expectation." << model_name << ".var_model_name = '" << var_model_name << "';" << endl + << "M_.pac_expectation." << model_name << ".discount_param_index = " << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl << "M_.pac_expectation." << model_name << ".growth_name = '" << datatree.symbol_table.getName(growth_symb_id) << "';" << endl diff --git a/ExprNode.hh b/ExprNode.hh index 156df34a..a8d417a0 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -1244,14 +1244,14 @@ public: class PacExpectationNode : public ExprNode { private: - const string model_name; + const string model_name, var_model_name; const int discount_symb_id, growth_symb_id; bool stationary_vars_present, nonstationary_vars_present; map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; int growth_param_index; public: - PacExpectationNode(DataTree &datatree_arg, const string &model_name, + PacExpectationNode(DataTree &datatree_arg, const string &model_name, const string &var_model_name, const int discount_arg, const int growth_arg); virtual void computeTemporaryTerms(map > &reference_count, map &temp_terms_map, diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 47eeba3c..bb12cada 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -2678,6 +2678,9 @@ ParsingDriver::add_pac_expectation() if (pac_expectation_model_name.empty()) error("pac_expectation: you must pass the model_name option"); + if (pac_expectation_var_model_name.empty()) + error("pac_expectation: you must pass the var_model_name option"); + if (pac_expectation_discount.empty()) error("pac_expectation: you must pass the discount option"); @@ -2691,6 +2694,7 @@ ParsingDriver::add_pac_expectation() mod_file->symbol_table.getID(pac_expectation_growth); expr_t pac_exp_node = data_tree->AddPacExpectation(pac_expectation_model_name, + pac_expectation_var_model_name, pac_expectation_discount_id, pac_expectation_growth_id); @@ -2708,6 +2712,15 @@ ParsingDriver::add_pac_expectation_model_name(string *arg) delete arg; } +void +ParsingDriver::add_pac_expectation_var_model_name(string *arg) +{ + if (!pac_expectation_var_model_name.empty()) + error("pac_expectation: you can only pass the var_model_name option once"); + pac_expectation_var_model_name = *arg; + delete arg; +} + void ParsingDriver::add_pac_expectation_discount(string *arg) { diff --git a/ParsingDriver.hh b/ParsingDriver.hh index c83793a6..3b4d28ab 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -253,7 +253,7 @@ private: void clear_VAR_storage(); //! Used by pac_expectation - string pac_expectation_model_name, pac_expectation_discount, pac_expectation_growth; + string pac_expectation_model_name, pac_expectation_var_model_name, pac_expectation_discount, pac_expectation_growth; public: ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) @@ -694,6 +694,7 @@ public: expr_t add_pac_expectation(); //! Adds arguments for pac_expectation void add_pac_expectation_model_name(string *arg); + void add_pac_expectation_var_model_name(string *arg); void add_pac_expectation_discount(string *arg); void add_pac_expectation_growth(string *arg); //! Writes token "diff(arg1)" to model tree From bda91e62041c567fbdfde901eadbc6b42f273409 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 8 Feb 2018 19:03:26 +0100 Subject: [PATCH 11/30] preprocessor: temporarily remove check to allow diff operator on RHS of VAR --- ComputingTasks.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index e26c625e..ef38e23f 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -309,10 +309,11 @@ VarModelStatement::fillVarModelInfoFromEquations(vector &eqnumber_arg, vect it1 != it->end(); it1++) if (find(lhs.begin(), lhs.end(), it1->first) == lhs.end() && find(orig_diff_var.begin(), orig_diff_var.end(), it1->first) == orig_diff_var.end()) - { + {/* cerr << "ERROR " << name << ": " << symbol_table.getName(it1->first) << " cannot appear in the VAR because it does not appear on the LHS" << endl; exit(EXIT_FAILURE); + */ } else { From dee8867899c08a72f45968cb0984966e6003d25f Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 12:17:07 +0100 Subject: [PATCH 12/30] preprocessor: fix bug in obtaining diff info --- DynamicModel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 72494a77..f6a54358 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3305,7 +3305,7 @@ DynamicModel::getDiffInfo(vector &eqnumber, vector &diff, vector for (vector::const_iterator it = eqnumber.begin(); it != eqnumber.end(); it++) { - diff.push_back(equations[*it]->isDiffPresent()); + diff.push_back(equations[*it]->get_arg1()->isDiffPresent()); if (diff.back()) { set > diff_set; From 9f47227a67cb76443c887423eed73641a68f1525 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 10:54:28 +0100 Subject: [PATCH 13/30] preprocessor: provide orig_symb_id and orig_lag if diff operator used on one variable --- ExprNode.cc | 8 +++++++- SymbolTable.cc | 35 +++++++++++++++++++++++++++++------ SymbolTable.hh | 1 + 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index b3dd523e..1ccd26d5 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -2834,7 +2834,13 @@ UnaryOpNode::substituteDiff(subst_table_t &subst_table, vector & expr_t argsubst = arg->substituteDiff(subst_table, neweqs); assert(argsubst != NULL); - int symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, argsubst); + int symb_id = -1; + VariableNode *vn = dynamic_cast(argsubst); + if (vn != NULL) + symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, argsubst, vn->get_symb_id(), vn->get_lag()); + else + symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, argsubst); + expr_t newAuxVar = datatree.AddVariable(symb_id, 0); //AUX_DIFF_IDX = argsubst - argsubst(-1) diff --git a/SymbolTable.cc b/SymbolTable.cc index 4b18946c..22f27196 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -354,7 +354,6 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) { case avEndoLead: case avExoLead: - case avDiff: break; case avEndoLag: case avExoLag: @@ -375,6 +374,11 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) aux_vars[i].get_expr_node()->writeOutput(output, oLatexDynamicModel); output << ")';" << endl; break; + case avDiff: + if (aux_vars[i].get_orig_symb_id() >= 0) + output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id())+1 << ";" << endl + << "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; + break; } } @@ -476,7 +480,6 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException) case avExpectation: case avMultiplier: case avDiffForward: - case avDiff: break; case avEndoLag: case avExoLag: @@ -484,6 +487,11 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException) output << "av[" << i << "].orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl << "av[" << i << "].orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; break; + case avDiff: + if (aux_vars[i].get_orig_symb_id() >= 0) + output << "av[" << i << "].orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl + << "av[" << i << "].orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; + break; } } } @@ -570,7 +578,6 @@ SymbolTable::writeCCOutput(ostream &output) const throw (NotYetFrozenException) case avExpectation: case avMultiplier: case avDiffForward: - case avDiff: break; case avEndoLag: case avExoLag: @@ -578,6 +585,11 @@ SymbolTable::writeCCOutput(ostream &output) const throw (NotYetFrozenException) output << "av" << i << ".orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl << "av" << i << ".orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; break; + case avDiff: + if (aux_vars[i].get_orig_symb_id() >= 0) + output << "av" << i << ".orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl + << "av" << i << ".orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; + break; } output << "aux_vars.push_back(" << "av" << i << ");" << endl; } @@ -695,7 +707,7 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t e } int -SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException) +SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lag) throw (FrozenException) { ostringstream varname; int symb_id; @@ -712,11 +724,18 @@ SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenExcept exit(EXIT_FAILURE); } - aux_vars.push_back(AuxVarInfo(symb_id, avDiff, 0, 0, 0, 0, expr_arg)); + cout << "DIFF: " << orig_symb_id << "(" << orig_lag << ")" << endl; + aux_vars.push_back(AuxVarInfo(symb_id, avDiff, orig_symb_id, orig_lag, 0, 0, expr_arg)); return symb_id; } +int +SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException) +{ + return addDiffAuxiliaryVar(index, expr_arg, 0, 0); +} + int SymbolTable::addVarModelEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (AlreadyDeclaredException, FrozenException) { @@ -1027,7 +1046,6 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio { case avEndoLead: case avExoLead: - case avDiff: break; case avEndoLag: case avExoLag: @@ -1035,6 +1053,11 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio output << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) + 1 << ", " << aux_vars[i].get_orig_lead_lag() << ", NaN, NaN"; break; + case avDiff: + if (aux_vars[i].get_orig_symb_id() >= 0) + output << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) + 1 << ", " + << aux_vars[i].get_orig_lead_lag() << ", NaN, NaN"; + break; case avMultiplier: output << "NaN, NaN, " << aux_vars[i].get_equation_number_for_multiplier() + 1 << ", NaN"; diff --git a/SymbolTable.hh b/SymbolTable.hh index 53ba84d4..b754bd96 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -286,6 +286,7 @@ public: int addVarModelEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (AlreadyDeclaredException, FrozenException); //! Adds an auxiliary variable when the diff operator is encountered int addDiffAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException); + int addDiffAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lag) throw (FrozenException); //! Returns the number of auxiliary variables int AuxVarsSize() const From 6138e9c269dd4d53047aa07e6862bca9dd11c37e Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 13:26:04 +0100 Subject: [PATCH 14/30] preprocessor: add equation info for RHS variables --- ComputingTasks.cc | 29 +++++++++++++++++++++++++++-- ComputingTasks.hh | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index ef38e23f..848f6324 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -298,13 +298,14 @@ VarModelStatement::fillVarModelInfoFromEquations(vector &eqnumber_arg, vect { eqnumber = eqnumber_arg; lhs = lhs_arg; + rhs_by_eq = rhs_arg; nonstationary = nonstationary_arg; diff = diff_arg; orig_diff_var = orig_diff_var_arg; // Order RHS vars by time (already ordered by equation tag) - for (vector > >::const_iterator it = rhs_arg.begin(); - it != rhs_arg.end(); it++) + for (vector > >::const_iterator it = rhs_by_eq.begin(); + it != rhs_by_eq.end(); it++) for (set >::const_iterator it1 = it->begin(); it1 != it->end(); it1++) if (find(lhs.begin(), lhs.end(), it1->first) == lhs.end() @@ -436,6 +437,30 @@ VarModelStatement::writeOutput(ostream &output, const string &basename, bool min output << symbol_table.getTypeSpecificID(*it) + 1; } output << "];" << endl; + i = 1; + for (vector > >::const_iterator it = rhs_by_eq.begin(); + it != rhs_by_eq.end(); it++, i++) + { + output << "options_.var.rhs.vars_at_eq{" << i << "}.var = ["; + for (set >::const_iterator it1 = it->begin(); + it1 != it->end(); it1++) + { + if (it1 != it->begin()) + output << " "; + output << symbol_table.getTypeSpecificID(it1->first) + 1; + } + output << "];" << endl + << "options_.var.rhs.vars_at_eq{" << i << "}.lag = ["; + for (set >::const_iterator it1 = it->begin(); + it1 != it->end(); it1++) + { + if (it1 != it->begin()) + output << " "; + output << it1->second; + } + output << "];" << endl; + + } output << "M_.var." << name << " = options_.var;" << endl << "clear options_.var;" << endl; } diff --git a/ComputingTasks.hh b/ComputingTasks.hh index b0090cf7..cb7052d2 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -128,6 +128,7 @@ private: const SymbolTable &symbol_table; vector eqnumber, lhs, orig_diff_var; map > rhs; // lag -> set< symb_id > (all vars that appear at a given lag) + vector > > rhs_by_eq; // rhs by equation vector nonstationary, diff; public: VarModelStatement(const SymbolList &symbol_list_arg, From c1bba660c8687699ab923c7b82b56e8902a3cbab Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 14:09:47 +0100 Subject: [PATCH 15/30] preprocessor: remove extraneous print statement --- SymbolTable.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/SymbolTable.cc b/SymbolTable.cc index 22f27196..993fd7b7 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -724,7 +724,6 @@ SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, i exit(EXIT_FAILURE); } - cout << "DIFF: " << orig_symb_id << "(" << orig_lag << ")" << endl; aux_vars.push_back(AuxVarInfo(symb_id, avDiff, orig_symb_id, orig_lag, 0, 0, expr_arg)); return symb_id; From fa96ccbd7afc1386645c3306404ea1e7ce94880d Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 15:49:55 +0100 Subject: [PATCH 16/30] preprocessor: fix typo --- ExprNode.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 1ccd26d5..e2dbba7e 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7554,9 +7554,9 @@ PacExpectationNode::writeJsonOutput(ostream &output, } void -PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, map > &rhs_arg, vector &nonstationary_arg) { - if (model_name != var_model_name) + if (var_model_name != var_model_name_arg) return; z_vec = rhs_arg; From cb411e5642ecd6978c86d4ad3dfca15fa840c913 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 16:57:12 +0100 Subject: [PATCH 17/30] pac_expectation: fix substitution --- DynamicModel.cc | 3 ++- DynamicModel.hh | 1 + ExprNode.cc | 55 +++++++++++++++++++++++++------------------------ ExprNode.hh | 19 +++++++++-------- ModFile.cc | 2 +- 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index f6a54358..615d0232 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3384,11 +3384,12 @@ DynamicModel::addEquationsForVar(map > &var_model_ void DynamicModel::fillPacExpectationVarInfo(string &var_model_name, + vector &lhs, map > &rhs, vector &nonstationary) { for (size_t i = 0; i < equations.size(); i++) - equations[i]->fillPacExpectationVarInfo(var_model_name, rhs, nonstationary); + equations[i]->fillPacExpectationVarInfo(var_model_name, lhs, rhs, nonstationary); } void diff --git a/DynamicModel.hh b/DynamicModel.hh index d87b412b..598a5c68 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -299,6 +299,7 @@ public: void addEquationsForVar(map > &var_model_info); //! Add var_model info to pac_expectation nodes void fillPacExpectationVarInfo(string &var_model_name, + vector &lhs, map > &rhs, vector &nonstationary); //! Substitutes pac_expectation operator diff --git a/ExprNode.cc b/ExprNode.cc index e2dbba7e..effec690 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -579,7 +579,7 @@ NumConstNode::setVarExpectationIndex(map > &var_mo } void -NumConstNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +NumConstNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { } @@ -1635,7 +1635,7 @@ VariableNode::setVarExpectationIndex(map > &var_mo } void -VariableNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +VariableNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { } @@ -3032,9 +3032,9 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod } void -UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { - arg->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); } bool @@ -4568,10 +4568,10 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo } void -BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { - arg1->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); - arg2->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); } bool @@ -5344,11 +5344,11 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m } void -TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { - arg1->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); - arg2->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); - arg3->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg3->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); } bool @@ -5718,10 +5718,10 @@ AbstractExternalFunctionNode::setVarExpectationIndex(map > &rhs_arg, vector &nonstationary_arg) +AbstractExternalFunctionNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->fillPacExpectationVarInfo(var_model_name, rhs_arg, nonstationary_arg); + (*it)->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); } bool @@ -7189,7 +7189,7 @@ VarExpectationNode::setVarExpectationIndex(map > & } void -VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) +VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) { } @@ -7554,11 +7554,13 @@ PacExpectationNode::writeJsonOutput(ostream &output, } void -PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, map > &rhs_arg, vector &nonstationary_arg) +PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, + map > &rhs_arg, vector &nonstationary_arg) { if (var_model_name != var_model_name_arg) return; + lhs = lhs_arg; z_vec = rhs_arg; for (vector::const_iterator it = nonstationary_arg.begin(); @@ -7581,37 +7583,36 @@ PacExpectationNode::substitutePacExpectation(map(myit->second); + int maxlag = z_vec.size(); expr_t subExpr = datatree.AddNonNegativeConstant("0"); if (stationary_vars_present) - for (map >::const_iterator it = z_vec.begin(); - it != z_vec.end(); it++) - for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) + for (int i = 1; i < maxlag + 1; i++) + for (vector::const_iterator it = lhs.begin(); it != lhs.end(); it++) { stringstream param_name_h0; param_name_h0 << "h0_" << model_name - << "_var_" << datatree.symbol_table.getName(*it1) - << "_lag_" << it->first; + << "_var_" << datatree.symbol_table.getName(*it) + << "_lag_" << i; int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h0.str(), eParameter); h0_indices.push_back(new_param_symb_id); subExpr = datatree.AddPlus(subExpr, datatree.AddTimes(datatree.AddVariable(new_param_symb_id), - datatree.AddVariable(*it1, it->first))); + datatree.AddVariable(*it, i))); } if (nonstationary_vars_present) - for (map >::const_iterator it = z_vec.begin(); - it != z_vec.end(); it++) - for (set::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) + for (int i = 1; i < maxlag + 1; i++) + for (vector::const_iterator it = lhs.begin(); it != lhs.end(); it++) { stringstream param_name_h1; param_name_h1 << "h1_" << model_name - << "_var_" << datatree.symbol_table.getName(*it1) - << "_lag_" << it->first; + << "_var_" << datatree.symbol_table.getName(*it) + << "_lag_" << i; int new_param_symb_id = datatree.symbol_table.addSymbol(param_name_h1.str(), eParameter); h1_indices.push_back(new_param_symb_id); subExpr = datatree.AddPlus(subExpr, datatree.AddTimes(datatree.AddVariable(new_param_symb_id), - datatree.AddVariable(*it1, it->first))); + datatree.AddVariable(*it, i))); } growth_param_index = datatree.symbol_table.addSymbol(model_name + diff --git a/ExprNode.hh b/ExprNode.hh index a8d417a0..37cc2c58 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -490,7 +490,7 @@ class ExprNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; //! Fills var_model info for pac_expectation node - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg) = 0; + virtual void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, map > &rhs_arg, vector &nonstationary_arg) = 0; //! Fills map virtual void getEndosAndMaxLags(map &model_endos_and_lags) const = 0; @@ -560,7 +560,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -639,7 +639,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -741,7 +741,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -861,7 +861,7 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -949,7 +949,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1045,7 +1045,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1234,7 +1234,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -1247,6 +1247,7 @@ private: const string model_name, var_model_name; const int discount_symb_id, growth_symb_id; bool stationary_vars_present, nonstationary_vars_present; + vector lhs; map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; int growth_param_index; @@ -1304,7 +1305,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; diff --git a/ModFile.cc b/ModFile.cc index 7d1f757a..faf33ece 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -389,7 +389,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const map > rhs_pac; vms->getVarModelName(var_model_name); vms->getVarModelRHS(rhs_pac); - dynamic_model.fillPacExpectationVarInfo(var_model_name, rhs_pac, nonstationary); + dynamic_model.fillPacExpectationVarInfo(var_model_name, lhs, rhs_pac, nonstationary); dynamic_model.substitutePacExpectation(); } } From e196e97024bef208a21734d07c5e804250645cff Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 9 Feb 2018 17:24:21 +0100 Subject: [PATCH 18/30] preprocessor: fix eval function --- ExprNode.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index effec690..4761633b 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7371,8 +7371,7 @@ PacExpectationNode::containsExternalFunction() const double PacExpectationNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) { - cerr << "PacExpectationNode::eval: shouldn't arrive here." << endl; - exit(EXIT_FAILURE); + throw EvalException(); } void From f480a893d748b36caeda0e4dd946d2e1c6d226d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 9 Feb 2018 18:25:44 +0100 Subject: [PATCH 19/30] Fixed timing issue in pac_expectation expansion. --- ExprNode.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 4761633b..fd467154 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7596,7 +7596,7 @@ PacExpectationNode::substitutePacExpectation(map Date: Mon, 12 Feb 2018 11:46:02 +0100 Subject: [PATCH 20/30] preprocessor: pac_expectation: make growth parameter optional --- ExprNode.cc | 41 +++++++++++++++++++++++++---------------- ParsingDriver.cc | 8 +++----- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index fd467154..6af8caf5 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7273,19 +7273,24 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (IS_LATEX(output_type)) { output << "PAC_EXPECTATION" << LEFT_PAR(output_type) << model_name << ", " - << var_model_name << ", " << discount_symb_id << ", " << growth_symb_id; + << var_model_name << ", " << discount_symb_id; + if (growth_symb_id >= 0) + output << ", " << growth_symb_id; output << RIGHT_PAR(output_type); return; } output <<"M_.pac_expectation." << model_name << ".var_model_name = '" << var_model_name << "';" << endl << "M_.pac_expectation." << model_name << ".discount_param_index = " - << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".growth_name = '" - << datatree.symbol_table.getName(growth_symb_id) << "';" << endl - << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " - << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; + << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl; + + if (growth_symb_id >= 0) + output << "M_.pac_expectation." << model_name << ".growth_name = '" + << datatree.symbol_table.getName(growth_symb_id) << "';" << endl + << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl; + + output << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; for (vector::const_iterator it = h0_indices.begin(); it != h0_indices.end(); it++) { @@ -7547,9 +7552,10 @@ PacExpectationNode::writeJsonOutput(ostream &output, { output << "pac_expectation(" << ", model_name = " << model_name - << ", " << discount_symb_id - << ", " << growth_symb_id - << ")"; + << ", " << discount_symb_id; + if (growth_symb_id >= 0) + output << ", " << growth_symb_id; + output << ")"; } void @@ -7614,12 +7620,15 @@ PacExpectationNode::substitutePacExpectation(map= 0) + { + growth_param_index = datatree.symbol_table.addSymbol(model_name + + "_pac_growth_neutrality_correction", + eParameter); + subExpr = datatree.AddPlus(subExpr, + datatree.AddTimes(datatree.AddVariable(growth_param_index), + datatree.AddVariable(growth_symb_id))); + } subst_table[const_cast(this)] = dynamic_cast(subExpr); diff --git a/ParsingDriver.cc b/ParsingDriver.cc index bb12cada..b9d7131c 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -2684,14 +2684,12 @@ ParsingDriver::add_pac_expectation() if (pac_expectation_discount.empty()) error("pac_expectation: you must pass the discount option"); - if (pac_expectation_growth.empty()) - error("pac_expectation: you must pass the growth option"); - int pac_expectation_discount_id = mod_file->symbol_table.getID(pac_expectation_discount); - int pac_expectation_growth_id = - mod_file->symbol_table.getID(pac_expectation_growth); + int pac_expectation_growth_id = -1; + if (!pac_expectation_growth.empty()) + pac_expectation_growth_id = mod_file->symbol_table.getID(pac_expectation_growth); expr_t pac_exp_node = data_tree->AddPacExpectation(pac_expectation_model_name, pac_expectation_var_model_name, From beeef36a24ad503437a6ba409d6388492f99d6f7 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 12 Feb 2018 15:21:36 +0100 Subject: [PATCH 21/30] preprocessor: pac_expectation: add equation number info --- DynamicModel.cc | 2 +- ExprNode.cc | 35 ++++++++++++++++++----------------- ExprNode.hh | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 615d0232..74235425 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3389,7 +3389,7 @@ DynamicModel::fillPacExpectationVarInfo(string &var_model_name, vector &nonstationary) { for (size_t i = 0; i < equations.size(); i++) - equations[i]->fillPacExpectationVarInfo(var_model_name, lhs, rhs, nonstationary); + equations[i]->fillPacExpectationVarInfo(var_model_name, lhs, rhs, nonstationary, i); } void diff --git a/ExprNode.cc b/ExprNode.cc index 6af8caf5..7bb79e13 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -579,7 +579,7 @@ NumConstNode::setVarExpectationIndex(map > &var_mo } void -NumConstNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +NumConstNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { } @@ -1635,7 +1635,7 @@ VariableNode::setVarExpectationIndex(map > &var_mo } void -VariableNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +VariableNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { } @@ -3032,9 +3032,9 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod } void -UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { - arg->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); } bool @@ -4568,10 +4568,10 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo } void -BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { - arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); - arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); + arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); } bool @@ -5344,11 +5344,11 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m } void -TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { - arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); - arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); - arg3->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + arg1->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); + arg2->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); + arg3->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); } bool @@ -5718,10 +5718,10 @@ AbstractExternalFunctionNode::setVarExpectationIndex(map &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +AbstractExternalFunctionNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg); + (*it)->fillPacExpectationVarInfo(var_model_name_arg, lhs_arg, rhs_arg, nonstationary_arg, equation_number_arg); } bool @@ -7189,7 +7189,7 @@ VarExpectationNode::setVarExpectationIndex(map > & } void -VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg) +VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { } @@ -7282,7 +7282,8 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output <<"M_.pac_expectation." << model_name << ".var_model_name = '" << var_model_name << "';" << endl << "M_.pac_expectation." << model_name << ".discount_param_index = " - << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl; + << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".equation_number = " << equation_number + 1 << ";" << endl; if (growth_symb_id >= 0) output << "M_.pac_expectation." << model_name << ".growth_name = '" @@ -7559,14 +7560,14 @@ PacExpectationNode::writeJsonOutput(ostream &output, } void -PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, - map > &rhs_arg, vector &nonstationary_arg) +PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { if (var_model_name != var_model_name_arg) return; lhs = lhs_arg; z_vec = rhs_arg; + equation_number = equation_number_arg; for (vector::const_iterator it = nonstationary_arg.begin(); it != nonstationary_arg.end(); it++) diff --git a/ExprNode.hh b/ExprNode.hh index 37cc2c58..1d3a2392 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -490,7 +490,7 @@ class ExprNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; //! Fills var_model info for pac_expectation node - virtual void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, map > &rhs_arg, vector &nonstationary_arg) = 0; + virtual void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) = 0; //! Fills map virtual void getEndosAndMaxLags(map &model_endos_and_lags) const = 0; @@ -560,7 +560,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -639,7 +639,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -741,7 +741,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -861,7 +861,7 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -949,7 +949,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1045,7 +1045,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; //! Substitute auxiliary variables by their expression in static model @@ -1234,7 +1234,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; @@ -1250,7 +1250,7 @@ private: vector lhs; map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; - int growth_param_index; + int growth_param_index, equation_number; public: PacExpectationNode(DataTree &datatree_arg, const string &model_name, const string &var_model_name, const int discount_arg, const int growth_arg); @@ -1305,7 +1305,7 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg); + virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; From 83d1e921b6112938fe3829c603e69eb471d84a8b Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 12 Feb 2018 15:34:04 +0100 Subject: [PATCH 22/30] preprocessor: initialize value to suppress warning --- ExprNode.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExprNode.cc b/ExprNode.cc index 7bb79e13..959074d7 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -2770,7 +2770,7 @@ UnaryOpNode::substituteAdl() const } expr_t arg1subst = arg->substituteAdl(); - expr_t retval; + expr_t retval = NULL; ostringstream inttostr; if (adl_param_lag >= 0) { From 89ae7048065b8754e161908d5ade50e14558204d Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 12 Feb 2018 17:37:53 +0100 Subject: [PATCH 23/30] preprocessor: add PAC equation parameter info to pac_expectation output --- DynamicModel.cc | 13 ++++ DynamicModel.hh | 2 + ExprNode.cc | 156 +++++++++++++++++++++++++++++++++++++++++++++++- ExprNode.hh | 23 +++++++ ModFile.cc | 1 + 5 files changed, 192 insertions(+), 3 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 74235425..4c97c64c 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3382,6 +3382,19 @@ DynamicModel::addEquationsForVar(map > &var_model_ cout << "Accounting for var_model lags not in model block: added " << count << " auxiliary variables and equations." << endl; } +void +DynamicModel::walkPacParameters() +{ + for (size_t i = 0; i < equations.size(); i++) + { + bool pac_encountered = false; + set > > params_and_vals; + equations[i]->walkPacParameters(pac_encountered, params_and_vals); + if (pac_encountered) + equations[i]->addParamInfoToPac(params_and_vals); + } +} + void DynamicModel::fillPacExpectationVarInfo(string &var_model_name, vector &lhs, diff --git a/DynamicModel.hh b/DynamicModel.hh index 598a5c68..afcd72b9 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -297,6 +297,8 @@ public: void setVarExpectationIndices(map > &var_model_info); //! Add aux equations (and aux variables) for variables declared in var_model at max order if they don't already exist void addEquationsForVar(map > &var_model_info); + //! Get Pac equation parameter info + void walkPacParameters(); //! Add var_model info to pac_expectation nodes void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, diff --git a/ExprNode.cc b/ExprNode.cc index 959074d7..aaa4b24c 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -578,6 +578,16 @@ NumConstNode::setVarExpectationIndex(map > &var_mo { } +void +NumConstNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ +} + +void +NumConstNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ +} + void NumConstNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -1634,6 +1644,16 @@ VariableNode::setVarExpectationIndex(map > &var_mo { } +void +VariableNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ +} + +void +VariableNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ +} + void VariableNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -3031,6 +3051,18 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod arg->setVarExpectationIndex(var_model_info); } +void +UnaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ + arg->walkPacParameters(pac_encountered, params_and_vals); +} + +void +UnaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ + arg->addParamInfoToPac(params_and_vals_arg); +} + void UnaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -4567,6 +4599,45 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo arg2->setVarExpectationIndex(var_model_info); } +void +BinaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ + if (op_code == oTimes) + { + set params; + set > endogs; + arg1->collectVariables(eParameter, params); + arg2->collectDynamicVariables(eEndogenous, endogs); + if (params.size() == 1 && endogs.size() == 1) + { + params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); + return; + } + else + { + params.clear(); + endogs.clear(); + arg1->collectDynamicVariables(eEndogenous, endogs); + arg2->collectVariables(eParameter, params); + if (params.size() == 1 && endogs.size() == 1) + { + params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); + return; + } + } + } + + arg1->walkPacParameters(pac_encountered, params_and_vals); + arg2->walkPacParameters(pac_encountered, params_and_vals); +} + +void +BinaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ + arg1->addParamInfoToPac(params_and_vals_arg); + arg2->addParamInfoToPac(params_and_vals_arg); +} + void BinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -5343,6 +5414,22 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m arg3->setVarExpectationIndex(var_model_info); } +void +TrinaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ + arg1->walkPacParameters(pac_encountered, params_and_vals); + arg2->walkPacParameters(pac_encountered, params_and_vals); + arg3->walkPacParameters(pac_encountered, params_and_vals); +} + +void +TrinaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ + arg1->addParamInfoToPac(params_and_vals_arg); + arg2->addParamInfoToPac(params_and_vals_arg); + arg3->addParamInfoToPac(params_and_vals_arg); +} + void TrinaryOpNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -5717,6 +5804,20 @@ AbstractExternalFunctionNode::setVarExpectationIndex(mapsetVarExpectationIndex(var_model_info); } +void +AbstractExternalFunctionNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + (*it)->walkPacParameters(pac_encountered, params_and_vals); +} + +void +AbstractExternalFunctionNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + (*it)->addParamInfoToPac(params_and_vals_arg); +} + void AbstractExternalFunctionNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -7188,6 +7289,16 @@ VarExpectationNode::setVarExpectationIndex(map > & yidx = find(vs.begin(), vs.end(), datatree.symbol_table.getName(symb_id)) - vs.begin(); } +void +VarExpectationNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ +} + +void +VarExpectationNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ +} + void VarExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { @@ -7289,9 +7400,35 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "M_.pac_expectation." << model_name << ".growth_name = '" << datatree.symbol_table.getName(growth_symb_id) << "';" << endl << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " - << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl; - - output << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".equation_params = ["; + for (set > >::const_iterator it = params_and_vals.begin(); + it != params_and_vals.end(); it++) + { + if (it != params_and_vals.begin()) + output << " "; + output << datatree.symbol_table.getTypeSpecificID(it->first) + 1; + } + output << "];" << endl + << "M_.pac_expectation." << model_name << ".equation_vars = ["; + for (set > >::const_iterator it = params_and_vals.begin(); + it != params_and_vals.end(); it++) + { + if (it != params_and_vals.begin()) + output << " "; + output << datatree.symbol_table.getTypeSpecificID(it->second.first) + 1; + } + output << "];" << endl + << "M_.pac_expectation." << model_name << ".equation_var_lags = ["; + for (set > >::const_iterator it = params_and_vals.begin(); + it != params_and_vals.end(); it++) + { + if (it != params_and_vals.begin()) + output << " "; + output << it->second.second; + } + output << "];" << endl + << "M_.pac_expectation." << model_name << ".h0_param_indices = ["; for (vector::const_iterator it = h0_indices.begin(); it != h0_indices.end(); it++) { @@ -7559,6 +7696,19 @@ PacExpectationNode::writeJsonOutput(ostream &output, output << ")"; } +void +PacExpectationNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +{ + pac_encountered = true; +} + +void +PacExpectationNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +{ + params_and_vals = params_and_vals_arg; +} + + void PacExpectationNode::fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) { diff --git a/ExprNode.hh b/ExprNode.hh index 1d3a2392..b292b474 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -489,6 +489,12 @@ class ExprNode //! Returns true if model_info_name is referenced by a VarExpectationNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; + //! Fills parameter information related to PAC equation + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const = 0; + + //! Adds PAC equation param info to pac_expectation + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg) = 0; + //! Fills var_model info for pac_expectation node virtual void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) = 0; @@ -560,6 +566,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -639,6 +647,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -741,6 +751,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -861,6 +873,8 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -949,6 +963,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1045,6 +1061,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1234,6 +1252,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1251,6 +1271,7 @@ private: map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; int growth_param_index, equation_number; + set > > params_and_vals; public: PacExpectationNode(DataTree &datatree_arg, const string &model_name, const string &var_model_name, const int discount_arg, const int growth_arg); @@ -1305,6 +1326,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); + virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; diff --git a/ModFile.cc b/ModFile.cc index faf33ece..eb4a374b 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -389,6 +389,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const map > rhs_pac; vms->getVarModelName(var_model_name); vms->getVarModelRHS(rhs_pac); + dynamic_model.walkPacParameters(); dynamic_model.fillPacExpectationVarInfo(var_model_name, lhs, rhs_pac, nonstationary); dynamic_model.substitutePacExpectation(); } From 7a52ebe14144078f8e765c60be0c1953f2608108 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 13:44:45 +0100 Subject: [PATCH 24/30] preprocessor: pac_expectation: fix typo --- ExprNode.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index aaa4b24c..0501d18a 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7400,8 +7400,9 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << "M_.pac_expectation." << model_name << ".growth_name = '" << datatree.symbol_table.getName(growth_symb_id) << "';" << endl << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " - << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".equation_params = ["; + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl; + + output << "M_.pac_expectation." << model_name << ".equation_params = ["; for (set > >::const_iterator it = params_and_vals.begin(); it != params_and_vals.end(); it++) { From 97fd1324a14ad64d26144ce1d25925a3feacccf5 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 15:34:15 +0100 Subject: [PATCH 25/30] pac_expectation: accept exogenous variables for growth argument --- ParsingDriver.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index b9d7131c..4e2ede10 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -2736,8 +2736,8 @@ ParsingDriver::add_pac_expectation_growth(string *arg) error("pac_expectation: you can only pass the growth option once"); check_symbol_existence(*arg); SymbolType type = mod_file->symbol_table.getType(mod_file->symbol_table.getID(*arg)); - if (type != eParameter && type != eEndogenous) - error("pac_expectation growth argument must either be a parameter or an endogenous variable."); + if (type != eParameter && type != eEndogenous && type != eExogenous) + error("pac_expectation growth argument must either be a parameter or an endogenous or exogenous variable."); pac_expectation_growth = *arg; delete arg; } From 75ba2c4e9f1b0d578754973914ae61e5b533db52 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 15:54:10 +0100 Subject: [PATCH 26/30] pac_expectation: clarify output for growth --- ExprNode.cc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 0501d18a..54bc4189 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7397,10 +7397,26 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, << "M_.pac_expectation." << model_name << ".equation_number = " << equation_number + 1 << ";" << endl; if (growth_symb_id >= 0) - output << "M_.pac_expectation." << model_name << ".growth_name = '" - << datatree.symbol_table.getName(growth_symb_id) << "';" << endl - << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " - << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl; + output << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_index = " + << datatree.symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_type = "; + switch(datatree.symbol_table.getType(growth_symb_id)) + { + case eEndogenous: + output << "'endogenous';" << endl; + break; + case eExogenous: + output << "'exogenous';" << endl; + break; + case eParameter: + output << "'exogenous';" << endl; + break; + default: + cerr << "pac_expectation: error encountered in growth type" << endl; + exit(EXIT_FAILURE); + } output << "M_.pac_expectation." << model_name << ".equation_params = ["; for (set > >::const_iterator it = params_and_vals.begin(); From d89c73b177afac2a904e5c6e89ff55088ab0c5b8 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 15:54:41 +0100 Subject: [PATCH 27/30] =?UTF-8?q?pac=5Fexpectation:=20remove=20=E2=80=9Cpa?= =?UTF-8?q?ram=E2=80=9D=20from=20=E2=80=9Cdiscount=5Fparam=5Findex?= =?UTF-8?q?=E2=80=9D=20because=20it=20is=20always=20a=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ExprNode.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExprNode.cc b/ExprNode.cc index 54bc4189..40251936 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7392,7 +7392,7 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } output <<"M_.pac_expectation." << model_name << ".var_model_name = '" << var_model_name << "';" << endl - << "M_.pac_expectation." << model_name << ".discount_param_index = " + << "M_.pac_expectation." << model_name << ".discount_index = " << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl << "M_.pac_expectation." << model_name << ".equation_number = " << equation_number + 1 << ";" << endl; From c36e6933d1468e0abb4696c8b5ded63cbe8cf7da Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 16:10:01 +0100 Subject: [PATCH 28/30] pac_expectation: output lhs of pac equation --- DynamicModel.cc | 5 +-- ExprNode.cc | 85 +++++++++++++++++++++++++++++++------------------ ExprNode.hh | 37 ++++++++++----------- 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 4c97c64c..10024fc6 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3388,10 +3388,11 @@ DynamicModel::walkPacParameters() for (size_t i = 0; i < equations.size(); i++) { bool pac_encountered = false; + pair lhs (-1, -1); set > > params_and_vals; - equations[i]->walkPacParameters(pac_encountered, params_and_vals); + equations[i]->walkPacParameters(pac_encountered, lhs, params_and_vals); if (pac_encountered) - equations[i]->addParamInfoToPac(params_and_vals); + equations[i]->addParamInfoToPac(lhs, params_and_vals); } } diff --git a/ExprNode.cc b/ExprNode.cc index 40251936..9a4ddd71 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -579,12 +579,12 @@ NumConstNode::setVarExpectationIndex(map > &var_mo } void -NumConstNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +NumConstNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { } void -NumConstNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +NumConstNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { } @@ -1645,12 +1645,12 @@ VariableNode::setVarExpectationIndex(map > &var_mo } void -VariableNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +VariableNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { } void -VariableNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +VariableNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { } @@ -3052,15 +3052,15 @@ UnaryOpNode::setVarExpectationIndex(map > &var_mod } void -UnaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +UnaryOpNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { - arg->walkPacParameters(pac_encountered, params_and_vals); + arg->walkPacParameters(pac_encountered, lhs, params_and_vals); } void -UnaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +UnaryOpNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { - arg->addParamInfoToPac(params_and_vals_arg); + arg->addParamInfoToPac(lhs_arg, params_and_vals_arg); } void @@ -4600,7 +4600,7 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo } void -BinaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +BinaryOpNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { if (op_code == oTimes) { @@ -4626,16 +4626,23 @@ BinaryOpNode::walkPacParameters(bool &pac_encountered, set > general_lhs; + arg1->collectDynamicVariables(eEndogenous, general_lhs); + if (general_lhs.size() == 1) + lhs = *(general_lhs.begin()); + } - arg1->walkPacParameters(pac_encountered, params_and_vals); - arg2->walkPacParameters(pac_encountered, params_and_vals); + arg1->walkPacParameters(pac_encountered, lhs, params_and_vals); + arg2->walkPacParameters(pac_encountered, lhs, params_and_vals); } void -BinaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +BinaryOpNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { - arg1->addParamInfoToPac(params_and_vals_arg); - arg2->addParamInfoToPac(params_and_vals_arg); + arg1->addParamInfoToPac(lhs_arg, params_and_vals_arg); + arg2->addParamInfoToPac(lhs_arg, params_and_vals_arg); } void @@ -5415,19 +5422,19 @@ TrinaryOpNode::setVarExpectationIndex(map > &var_m } void -TrinaryOpNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +TrinaryOpNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { - arg1->walkPacParameters(pac_encountered, params_and_vals); - arg2->walkPacParameters(pac_encountered, params_and_vals); - arg3->walkPacParameters(pac_encountered, params_and_vals); + arg1->walkPacParameters(pac_encountered, lhs, params_and_vals); + arg2->walkPacParameters(pac_encountered, lhs, params_and_vals); + arg3->walkPacParameters(pac_encountered, lhs, params_and_vals); } void -TrinaryOpNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +TrinaryOpNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { - arg1->addParamInfoToPac(params_and_vals_arg); - arg2->addParamInfoToPac(params_and_vals_arg); - arg3->addParamInfoToPac(params_and_vals_arg); + arg1->addParamInfoToPac(lhs_arg, params_and_vals_arg); + arg2->addParamInfoToPac(lhs_arg, params_and_vals_arg); + arg3->addParamInfoToPac(lhs_arg, params_and_vals_arg); } void @@ -5805,17 +5812,17 @@ AbstractExternalFunctionNode::setVarExpectationIndex(map > > ¶ms_and_vals) const +AbstractExternalFunctionNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->walkPacParameters(pac_encountered, params_and_vals); + (*it)->walkPacParameters(pac_encountered, lhs, params_and_vals); } void -AbstractExternalFunctionNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +AbstractExternalFunctionNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->addParamInfoToPac(params_and_vals_arg); + (*it)->addParamInfoToPac(lhs_arg, params_and_vals_arg); } void @@ -7290,12 +7297,12 @@ VarExpectationNode::setVarExpectationIndex(map > & } void -VarExpectationNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +VarExpectationNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { } void -VarExpectationNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +VarExpectationNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { } @@ -7394,7 +7401,10 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output <<"M_.pac_expectation." << model_name << ".var_model_name = '" << var_model_name << "';" << endl << "M_.pac_expectation." << model_name << ".discount_index = " << datatree.symbol_table.getTypeSpecificID(discount_symb_id) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".equation_number = " << equation_number + 1 << ";" << endl; + << "M_.pac_expectation." << model_name << ".equation_number = " << equation_number + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".lhs_var = " + << datatree.symbol_table.getTypeSpecificID(lhs_pac_var.first) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".lhs_lag = " << lhs_pac_var.second << ";" << endl; if (growth_symb_id >= 0) output << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " @@ -7714,14 +7724,27 @@ PacExpectationNode::writeJsonOutput(ostream &output, } void -PacExpectationNode::walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const +PacExpectationNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { pac_encountered = true; } void -PacExpectationNode::addParamInfoToPac(set > > ¶ms_and_vals_arg) +PacExpectationNode::addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) { + if (lhs_arg.first == -1) + { + cerr << "Pac Expectation: error in obtaining LHS varibale." << endl; + exit(EXIT_FAILURE); + } + + if (params_and_vals_arg.size() != 2) + { + cerr << "Pac Expectation: error in obtaining RHS parameters." << endl; + exit(EXIT_FAILURE); + } + + lhs_pac_var = lhs_arg; params_and_vals = params_and_vals_arg; } diff --git a/ExprNode.hh b/ExprNode.hh index b292b474..f674887e 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -490,10 +490,10 @@ class ExprNode virtual bool isVarModelReferenced(const string &model_info_name) const = 0; //! Fills parameter information related to PAC equation - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const = 0; + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const = 0; //! Adds PAC equation param info to pac_expectation - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg) = 0; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg) = 0; //! Fills var_model info for pac_expectation node virtual void fillPacExpectationVarInfo(string &var_model_name, vector &lhs, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg) = 0; @@ -566,8 +566,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -647,8 +647,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -751,8 +751,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -873,8 +873,8 @@ public: expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -963,8 +963,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1061,8 +1061,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1252,8 +1252,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; @@ -1268,6 +1268,7 @@ private: const int discount_symb_id, growth_symb_id; bool stationary_vars_present, nonstationary_vars_present; vector lhs; + pair lhs_pac_var; map > z_vec; // lag -> set< symb_id > (all vars that appear at a given lag) vector h0_indices, h1_indices; int growth_param_index, equation_number; @@ -1326,8 +1327,8 @@ public: virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; virtual void setVarExpectationIndex(map > &var_model_info); - virtual void walkPacParameters(bool &pac_encountered, set > > ¶ms_and_vals) const; - virtual void addParamInfoToPac(set > > ¶ms_and_vals_arg); + virtual void walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const; + virtual void addParamInfoToPac(pair &lhs_arg, set > > ¶ms_and_vals_arg); virtual void fillPacExpectationVarInfo(string &var_model_name_arg, vector &lhs_arg, map > &rhs_arg, vector &nonstationary_arg, int equation_number_arg); virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; From caa019723807fdeb73a4fa55a68f39e22b50a14f Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 15 Feb 2018 17:06:30 +0100 Subject: [PATCH 29/30] pac_expectation: find rho_0 in pac equation --- ExprNode.cc | 76 +++++++++++++++++++++++++++++++++++--------------- ExprNode.hh | 3 ++ SymbolTable.cc | 10 +++++++ SymbolTable.hh | 2 ++ 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 9a4ddd71..6176389e 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -4599,32 +4599,64 @@ BinaryOpNode::setVarExpectationIndex(map > &var_mo arg2->setVarExpectationIndex(var_model_info); } +void +BinaryOpNode::walkPacParametersHelper(const expr_t arg1, const expr_t arg2, + pair &lhs, + set > > ¶ms_and_vals) const +{ + set params; + set > endogs; + arg1->collectVariables(eParameter, params); + arg2->collectDynamicVariables(eEndogenous, endogs); + if (params.size() == 1) + if (endogs.size() == 1) + params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); + else + if (endogs.size() == 2) + { + BinaryOpNode *testarg2 = dynamic_cast(arg2); + VariableNode *test_arg1 = dynamic_cast(testarg2->get_arg1()); + VariableNode *test_arg2 = dynamic_cast(testarg2->get_arg2()); + if (testarg2 != NULL && testarg2->get_op_code() == oMinus + && test_arg1 != NULL &&test_arg2 != NULL + && lhs.first != -1) + { + int find_symb_id = -1; + try + { + // lhs is an aux var (diff) + find_symb_id = datatree.symbol_table.getOrigSymbIdForAuxVar(lhs.first); + } + catch (...) + { + //lhs is not an aux var + find_symb_id = lhs.first; + } + endogs.clear(); + + if (test_arg1->get_symb_id() == find_symb_id) + { + test_arg1->collectDynamicVariables(eEndogenous, endogs); + params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); + } + else if (test_arg2->get_symb_id() == find_symb_id) + { + test_arg2->collectDynamicVariables(eEndogenous, endogs); + params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); + } + } + } +} + void BinaryOpNode::walkPacParameters(bool &pac_encountered, pair &lhs, set > > ¶ms_and_vals) const { if (op_code == oTimes) { - set params; - set > endogs; - arg1->collectVariables(eParameter, params); - arg2->collectDynamicVariables(eEndogenous, endogs); - if (params.size() == 1 && endogs.size() == 1) - { - params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); - return; - } - else - { - params.clear(); - endogs.clear(); - arg1->collectDynamicVariables(eEndogenous, endogs); - arg2->collectVariables(eParameter, params); - if (params.size() == 1 && endogs.size() == 1) - { - params_and_vals.insert(make_pair(*(params.begin()), *(endogs.begin()))); - return; - } - } + int orig_params_and_vals_size = params_and_vals.size(); + walkPacParametersHelper(arg1, arg2, lhs, params_and_vals); + if (params_and_vals.size() == orig_params_and_vals_size) + walkPacParametersHelper(arg2, arg1, lhs, params_and_vals); } else if (op_code == oEqual) { @@ -7738,7 +7770,7 @@ PacExpectationNode::addParamInfoToPac(pair &lhs_arg, set &lhs, + set > > ¶ms_and_vals) const; virtual expr_t toStatic(DataTree &static_datatree) const; virtual void computeXrefs(EquationInfo &ei) const; virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; diff --git a/SymbolTable.cc b/SymbolTable.cc index 993fd7b7..ad61e374 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -809,6 +809,16 @@ SymbolTable::searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const thro throw SearchFailedException(orig_symb_id, orig_lead_lag); } +int +SymbolTable::getOrigSymbIdForAuxVar(int aux_var_symb_id) const throw (UnknownSymbolIDException) +{ + for (size_t i = 0; i < aux_vars.size(); i++) + if ((aux_vars[i].get_type() == avEndoLag || aux_vars[i].get_type() == avExoLag || aux_vars[i].get_type() == avDiff) + && aux_vars[i].get_symb_id() == aux_var_symb_id) + return aux_vars[i].get_orig_symb_id(); + throw UnknownSymbolIDException(aux_var_symb_id); +} + expr_t SymbolTable::getAuxiliaryVarsExprNode(int symb_id) const throw (SearchFailedException) // throw exception if it is a Lagrange multiplier diff --git a/SymbolTable.hh b/SymbolTable.hh index b754bd96..62804a59 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -281,6 +281,8 @@ public: Throws an exception if match not found. */ int searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const throw (SearchFailedException); + //! Serches aux_vars for the aux var represented by aux_var_symb_id and returns its associated orig_symb_id + int getOrigSymbIdForAuxVar(int aux_var_symb_id) const throw (UnknownSymbolIDException); //! Adds an auxiliary variable when var_model is used with an order that is greater in absolute value //! than the largest lag present in the model. int addVarModelEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (AlreadyDeclaredException, FrozenException); From b9295061ec608bf09ba4af51552afe96a6d4e56e Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 20 Feb 2018 09:27:26 +0100 Subject: [PATCH 30/30] pac_expectation: fix bug introduced in c3552e034cfe8d35bdf1cf5e05163822d3820938 --- ExprNode.cc | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 6176389e..687b6bde 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -7439,25 +7439,27 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, << "M_.pac_expectation." << model_name << ".lhs_lag = " << lhs_pac_var.second << ";" << endl; if (growth_symb_id >= 0) - output << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " - << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".growth_index = " - << datatree.symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ";" << endl - << "M_.pac_expectation." << model_name << ".growth_type = "; - switch(datatree.symbol_table.getType(growth_symb_id)) { - case eEndogenous: - output << "'endogenous';" << endl; - break; - case eExogenous: - output << "'exogenous';" << endl; - break; - case eParameter: - output << "'exogenous';" << endl; - break; - default: - cerr << "pac_expectation: error encountered in growth type" << endl; - exit(EXIT_FAILURE); + output << "M_.pac_expectation." << model_name << ".growth_neutrality_param_index = " + << datatree.symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_index = " + << datatree.symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ";" << endl + << "M_.pac_expectation." << model_name << ".growth_type = "; + switch(datatree.symbol_table.getType(growth_symb_id)) + { + case eEndogenous: + output << "'endogenous';" << endl; + break; + case eExogenous: + output << "'exogenous';" << endl; + break; + case eParameter: + output << "'exogenous';" << endl; + break; + default: + cerr << "pac_expectation: error encountered in growth type" << endl; + exit(EXIT_FAILURE); + } } output << "M_.pac_expectation." << model_name << ".equation_params = [";