diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 5e38925f..894928cb 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3334,6 +3334,24 @@ DynamicModel::getVarModelVariablesFromEqTags(vector &var_model_eqtags, } } +void +DynamicModel::checkVarMinLag(vector &eqnumber) const +{ + int eqn = 1; + for (vector::const_iterator it = eqnumber.begin(); + it != eqnumber.end(); it++, eqn++) + { + int min_lag = -1; + min_lag = equations[*it]->get_arg2()->VarMinLag(); + if (min_lag <= 0) + { + cerr << "ERROR in VAR Equation #" << eqn << ". " + << "Leaded exogenous variables and leaded or contemporaneous endogenous variables not allowed in VAR"; + exit(EXIT_FAILURE); + } + } +} + int DynamicModel::getVarMaxLag(StaticModel &static_model, vector &eqnumber) const { diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index bd56dc8e..ee9f981c 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -294,6 +294,9 @@ public: vector > > &rhs, vector &nonstationary) const; + //! Returns the max lag of the VAR + void checkVarMinLag(vector &eqnumber) const; + //! Returns the max lag of the VAR int getVarMaxLag(StaticModel &static_model, vector &eqnumber) const; diff --git a/src/ExprNode.cc b/src/ExprNode.cc index c4812ebd..f6018f93 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -468,6 +468,12 @@ NumConstNode::undiff() const return const_cast(this); } +int +NumConstNode::VarMinLag() const +{ + return 1; +} + void NumConstNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { @@ -1342,6 +1348,25 @@ VariableNode::maxLead() const } } +int +VariableNode::VarMinLag() const +{ + switch (type) + { + case eEndogenous: + return -lag; + case eExogenous: + if (lag > 0) + return -lag; + else + return 1; // Can have contemporaneus exog in VAR + case eModelLocalVariable: + return datatree.local_variables_table[symb_id]->VarMinLag(); + default: + return 1; + } +} + int VariableNode::maxLag() const { @@ -2934,6 +2959,12 @@ UnaryOpNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int & } } +int +UnaryOpNode::VarMinLag() const +{ + return arg->VarMinLag(); +} + int UnaryOpNode::PacMaxLag(vector &lhs) const { @@ -4252,6 +4283,12 @@ BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int & dynamic, steady_dynamic, tef_terms); } +int +BinaryOpNode::VarMinLag() const +{ + return min(arg1->VarMinLag(), arg2->VarMinLag()); +} + void BinaryOpNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { @@ -5615,6 +5652,12 @@ TrinaryOpNode::undiff() const return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } +int +TrinaryOpNode::VarMinLag() const +{ + return min(min(arg1->VarMinLag(), arg2->VarMinLag()), arg3->VarMinLag()); +} + void TrinaryOpNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { @@ -6039,6 +6082,16 @@ AbstractExternalFunctionNode::undiff() const return buildSimilarExternalFunctionNode(arguments_subst, datatree); } +int +AbstractExternalFunctionNode::VarMinLag() const +{ +int val = 0; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + val = min(val, (*it)->VarMinLag()); + return val; +} + void AbstractExternalFunctionNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { @@ -7555,6 +7608,12 @@ VarExpectationNode::undiff() const return const_cast(this); } +int +VarExpectationNode::VarMinLag() const +{ + return 1; +} + void VarExpectationNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { @@ -7984,6 +8043,12 @@ PacExpectationNode::undiff() const return const_cast(this); } +int +PacExpectationNode::VarMinLag() const +{ + return 1; +} + void PacExpectationNode::VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const { diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 59f4ebcb..f1c1772f 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -264,6 +264,9 @@ class ExprNode */ virtual void collectDynamicVariables(SymbolType type_arg, set > &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 void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const = 0; @@ -569,6 +572,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -656,6 +660,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -763,6 +768,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -890,6 +896,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -992,6 +999,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -1096,6 +1104,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -1282,6 +1291,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; @@ -1364,6 +1374,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual int VarMinLag() const; virtual void VarMaxLag(DataTree &static_datatree, set &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector &lhs) const; virtual expr_t undiff() const; diff --git a/src/ModFile.cc b/src/ModFile.cc index 65e7fbfe..0ad90e61 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -392,6 +392,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const vector eqtags = var_model_eq_tags[var_model_name]; dynamic_model.getVarModelVariablesFromEqTags(eqtags, eqnumber, lhs, lhs_expr_t, rhs, nonstationary); + original_model.checkVarMinLag(eqnumber); int max_lag = original_model.getVarMaxLag(diff_static_model, eqnumber); original_model.getVarLhsDiffAndInfo(eqnumber, diff, orig_diff_var); vms->fillVarModelInfoFromEquations(eqnumber, lhs, rhs, nonstationary,