From 8df34c1ca5cc55b4b191aeb01c7a02a56b22f63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 6 Jul 2021 18:42:19 +0200 Subject: [PATCH] VAR and trend component models: improve sanity checks on lead/lags on RHS In particular, forbid lagged exogenous. --- src/DynamicModel.cc | 70 ++++++++++++++++++++++++--------------------- src/ExprNode.cc | 65 ----------------------------------------- src/ExprNode.hh | 13 +-------- 3 files changed, 39 insertions(+), 109 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 54a63e12..463e093e 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3392,13 +3392,6 @@ DynamicModel::fillVarModelTable() const lhs_expr_t.push_back(*(lhs_expr_t_set.begin())); equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_set); - for (const auto &itrhs : rhs_set) - if (itrhs.second > 0) - { - cerr << "ERROR: in Equation " << eqtag - << ". A VAR may not have leaded or contemporaneous variables on the RHS. " << endl; - exit(EXIT_FAILURE); - } rhs.push_back(rhs_set); } eqnums[it.first] = eqnumber; @@ -3427,15 +3420,25 @@ DynamicModel::fillVarModelTableFromOrigModel() const vector<bool> diff_vec; for (auto eqn : it.second) { - // ensure no leads in equations - if (equations[eqn]->arg2->VarMinLag() <= 0) - { - cerr << "ERROR in VAR model Equation (#" << eqn << "). " - << "Leaded exogenous variables " - << "and leaded or contemporaneous endogenous variables not allowed in VAR" - << endl; - exit(EXIT_FAILURE); - } + // Perform some sanity checks on the RHS + string eqtag = equation_tags.getTagValueByEqnAndKey(eqn, "name"); + set<pair<int, int>> rhs_endo_set, rhs_exo_set; + equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_endo_set); + for (const auto &[symb_id, lag] : rhs_endo_set) + if (lag >= 0) + { + cerr << "ERROR: in Equation " << eqtag + << ". A VAR model may not have leaded or contemporaneous endogenous variables on the RHS. " << endl; + exit(EXIT_FAILURE); + } + equations[eqn]->arg2->collectDynamicVariables(SymbolType::exogenous, rhs_exo_set); + for (const auto &[symb_id, lag] : rhs_exo_set) + if (lag != 0) + { + cerr << "ERROR: in Equation " << eqtag + << ". A VAR model may not have lagged or leaded exogenous variables on the RHS. " << endl; + exit(EXIT_FAILURE); + } // save lhs variables equations[eqn]->arg1->collectVARLHSVariable(lhs); @@ -3583,13 +3586,6 @@ DynamicModel::fillTrendComponentModelTable() const lhs_expr_t.push_back(*(lhs_expr_t_set.begin())); equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_set); - for (const auto &itrhs : rhs_set) - if (itrhs.second > 0) - { - cerr << "ERROR: in Equation " << eqtag - << ". A trend component model may not have leaded or contemporaneous variables on the RHS. " << endl; - exit(EXIT_FAILURE); - } rhs.push_back(rhs_set); } eqnums[it.first] = eqnumber; @@ -3645,15 +3641,25 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const vector<bool> diff_vec; for (auto eqn : it.second) { - // ensure no leads in equations - if (equations[eqn]->arg2->VarMinLag() <= 0) - { - cerr << "ERROR in trend component model Equation (#" << eqn << "). " - << "Leaded exogenous variables " - << "and leaded or contemporaneous endogenous variables not allowed in VAR" - << endl; - exit(EXIT_FAILURE); - } + // Perform some sanity checks on the RHS + string eqtag = equation_tags.getTagValueByEqnAndKey(eqn, "name"); + set<pair<int, int>> rhs_endo_set, rhs_exo_set; + equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_endo_set); + for (const auto &[symb_id, lag] : rhs_endo_set) + if (lag >= 0) + { + cerr << "ERROR: in Equation " << eqtag + << ". A trend component model may not have leaded or contemporaneous endogenous variables on the RHS. " << endl; + exit(EXIT_FAILURE); + } + equations[eqn]->arg2->collectDynamicVariables(SymbolType::exogenous, rhs_exo_set); + for (const auto &[symb_id, lag] : rhs_exo_set) + if (lag != 0) + { + cerr << "ERROR: in Equation " << eqtag + << ". A trend component model may not have lagged or leaded exogenous variables on the RHS. " << endl; + exit(EXIT_FAILURE); + } // save lhs variables equations[eqn]->arg1->collectVARLHSVariable(lhs); diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 2cdf55c1..e7acf59f 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -553,12 +553,6 @@ NumConstNode::undiff() const return const_cast<NumConstNode *>(this); } -int -NumConstNode::VarMinLag() const -{ - return 1; -} - int NumConstNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { @@ -1471,25 +1465,6 @@ VariableNode::maxLead() const } } -int -VariableNode::VarMinLag() const -{ - switch (get_type()) - { - case SymbolType::endogenous: - return -lag; - case SymbolType::exogenous: - if (lag > 0) - return -lag; - else - return 1; // Can have contemporaneus exog in VAR - case SymbolType::modelLocalVariable: - return datatree.getLocalVariable(symb_id)->VarMinLag(); - default: - return 1; - } -} - int VariableNode::maxLag() const { @@ -3234,12 +3209,6 @@ UnaryOpNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const return arg->maxLag(); } -int -UnaryOpNode::VarMinLag() const -{ - return arg->VarMinLag(); -} - expr_t UnaryOpNode::substituteAdl() const { @@ -4655,12 +4624,6 @@ BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int & temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); } -int -BinaryOpNode::VarMinLag() const -{ - return min(arg1->VarMinLag(), arg2->VarMinLag()); -} - int BinaryOpNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { @@ -6196,12 +6159,6 @@ TrinaryOpNode::undiff() const return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } -int -TrinaryOpNode::VarMinLag() const -{ - return min(min(arg1->VarMinLag(), arg2->VarMinLag()), arg3->VarMinLag()); -} - int TrinaryOpNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { @@ -6631,15 +6588,6 @@ AbstractExternalFunctionNode::undiff() const return buildSimilarExternalFunctionNode(arguments_subst, datatree); } -int -AbstractExternalFunctionNode::VarMinLag() const -{ - int val = 0; - for (auto argument : arguments) - val = min(val, argument->VarMinLag()); - return val; -} - int AbstractExternalFunctionNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { @@ -8152,13 +8100,6 @@ VarExpectationNode::undiff() const exit(EXIT_FAILURE); } -int -VarExpectationNode::VarMinLag() const -{ - cerr << "VarExpectationNode::VarMinLag not implemented." << endl; - exit(EXIT_FAILURE); -} - int VarExpectationNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { @@ -8552,12 +8493,6 @@ PacExpectationNode::undiff() const return const_cast<PacExpectationNode *>(this); } -int -PacExpectationNode::VarMinLag() const -{ - return 1; -} - int PacExpectationNode::VarMaxLag(const set<expr_t> &lhs_lag_equiv) const { diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 64d4a1fd..dfa9755c 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2020 Dynare Team + * Copyright © 2007-2021 Dynare Team * * This file is part of Dynare. * @@ -371,9 +371,6 @@ public: */ virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const = 0; - //! Find lowest lag for VAR - virtual int VarMinLag() const = 0; - //! Find the maximum lag in a VAR: handles case where LHS is diff virtual int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const = 0; @@ -761,7 +758,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -834,7 +830,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -935,7 +930,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -1042,7 +1036,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -1178,7 +1171,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -1290,7 +1282,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -1461,7 +1452,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; @@ -1534,7 +1524,6 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMinLag() const override; int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; -- GitLab