diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 92ebad6f535694830b4c00ce9135244f7a71103a..ef1319bab9950e8ad08a9b766e445fccde137462 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3329,11 +3329,41 @@ DynamicModel::getVarModelVariablesFromEqTags(vector<string> &var_model_eqtags, } } +int +DynamicModel::getVarMaxLag(StaticModel &static_model, vector<int> &eqnumber) const +{ + set<expr_t> lhs; + for (vector<int>::const_iterator it = eqnumber.begin(); + it != eqnumber.end(); it++) + { + set<expr_t> lhs_set; + equations[*it]->get_arg1()->collectVARLHSVariable(lhs_set); + if (lhs_set.size() != 1) + { + cerr << "ERROR: in Equation " + << ". A VAR may only have one endogenous variable on the LHS. " << endl; + exit(EXIT_FAILURE); + } + lhs.insert(*(lhs_set.begin())); + } + + set<expr_t> lhs_static; + for(set<expr_t>::const_iterator it = lhs.begin(); + it != lhs.end(); it++) + lhs_static.insert((*it)->toStatic(static_model)); + + int max_lag = 0; + for (vector<int>::const_iterator it = eqnumber.begin(); + it != eqnumber.end(); it++) + equations[*it]->get_arg2()->VarMaxLag(static_model, lhs_static, max_lag); + + return max_lag; +} + void -DynamicModel::getVarMaxLagAndLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff, - vector<int> &orig_diff_var, int &max_lag) const +DynamicModel::getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff, + vector<int> &orig_diff_var) const { - max_lag = 0; for (vector<int>::const_iterator it = eqnumber.begin(); it != eqnumber.end(); it++) { @@ -3352,10 +3382,6 @@ DynamicModel::getVarMaxLagAndLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> } else orig_diff_var.push_back(-1); - - int lag = equations[*it]->get_arg2()->maxEndoLag(); - if (max_lag < lag) - max_lag = lag; } } diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 7a8c7d57163b05b93065e05f852083ded0719ae7..13543f0141839b83483d1debfa53300ad14c4ddb 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -293,9 +293,12 @@ public: vector<set<pair<int, int> > > &rhs, vector<bool> &nonstationary) const; + //! Returns the max lag of the VAR + int getVarMaxLag(StaticModel &static_model, vector<int> &eqnumber) const; + // Get equtaino information on diff operator and max lag info - void getVarMaxLagAndLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff, - vector<int> &orig_diff_var, int &max_lag) const; + void getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff, + vector<int> &orig_diff_var) const; //! Set indices for var expectation in dynamic model file void setVarExpectationIndices(map<string, pair<SymbolList, int> > &var_model_info); diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 3ba356eb8240dc114c989284833d4ee96b89dce9..0b0d2b4ee39d6272733ebe4beb44988144c762ab 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -386,6 +386,11 @@ NumConstNode::compile(ostream &CompileCode, unsigned int &instruction_number, fldc.write(CompileCode, instruction_number); } +void +NumConstNode::collectVARLHSVariable(set<expr_t> &result) const +{ +} + void NumConstNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -457,6 +462,11 @@ NumConstNode::maxLag() const return 0; } +void +NumConstNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ +} + int NumConstNode::PacMaxLag(vector<int> &lhs) const { @@ -1104,6 +1114,18 @@ VariableNode::computeTemporaryTerms(map<expr_t, int> &reference_count, datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); } +void +VariableNode::collectVARLHSVariable(set<expr_t> &result) const +{ + if (type == eEndogenous && lag == 0) + result.insert(const_cast<VariableNode *>(this)); + else + { + cerr << "ERROR: A VAR must have one endogenous variable on the LHS." << endl; + exit(EXIT_FAILURE); + } +} + void VariableNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -1330,6 +1352,19 @@ VariableNode::maxLag() const } } +void +VariableNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ + for (set<expr_t>::const_iterator it = static_lhs.begin(); + it != static_lhs.end(); it++) + if (*it == this->toStatic(static_datatree)) + { + if (-lag > max_lag) + max_lag = -lag; + return; + } +} + int VariableNode::PacMaxLag(vector<int> &lhs) const { @@ -2583,12 +2618,18 @@ UnaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, } void -UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const +UnaryOpNode::collectVARLHSVariable(set<expr_t> &result) const { if (op_code == oDiff) - arg->decreaseLeadsLags(1)->collectDynamicVariables(type_arg, result); + result.insert(const_cast<UnaryOpNode *>(this)); else - arg->collectDynamicVariables(type_arg, result); + arg->collectVARLHSVariable(result); +} + +void +UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const +{ + arg->collectDynamicVariables(type_arg, result); } pair<int, expr_t> @@ -2850,9 +2891,34 @@ UnaryOpNode::maxLead() const int UnaryOpNode::maxLag() const { + if (op_code == oDiff) + return arg->maxLag() + 1; return arg->maxLag(); } +void +UnaryOpNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ + if (op_code != oDiff) + arg->VarMaxLag(static_datatree, static_lhs, max_lag); + else + { + for (set<expr_t>::const_iterator it = static_lhs.begin(); + it != static_lhs.end(); it++) + if (*it == this->toStatic(static_datatree)) + { + int max_lag_tmp = arg->maxLag(); + if (max_lag_tmp > max_lag) + max_lag = max_lag_tmp; + return; + } + int max_lag_tmp = 0; + arg->VarMaxLag(static_datatree, static_lhs, max_lag_tmp); + if (max_lag_tmp + 1 > max_lag) + max_lag = max_lag_tmp + 1; + } +} + int UnaryOpNode::PacMaxLag(vector<int> &lhs) const { @@ -4085,6 +4151,20 @@ BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int & dynamic, steady_dynamic, tef_terms); } +void +BinaryOpNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ + arg1->VarMaxLag(static_datatree, static_lhs, max_lag); + arg2->VarMaxLag(static_datatree, static_lhs, max_lag); +} + +void +BinaryOpNode::collectVARLHSVariable(set<expr_t> &result) const +{ + arg1->collectVARLHSVariable(result); + arg2->collectVARLHSVariable(result); +} + void BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -5312,6 +5392,14 @@ TrinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int dynamic, steady_dynamic, tef_terms); } +void +TrinaryOpNode::collectVARLHSVariable(set<expr_t> &result) const +{ + arg1->collectVARLHSVariable(result); + arg2->collectVARLHSVariable(result); + arg3->collectVARLHSVariable(result); +} + void TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -5423,6 +5511,14 @@ TrinaryOpNode::maxLag() const return max(arg1->maxLag(), max(arg2->maxLag(), arg3->maxLag())); } +void +TrinaryOpNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ + arg1->VarMaxLag(static_datatree, static_lhs, max_lag); + arg2->VarMaxLag(static_datatree, static_lhs, max_lag); + arg3->VarMaxLag(static_datatree, static_lhs, max_lag); +} + int TrinaryOpNode::PacMaxLag(vector<int> &lhs) const { @@ -5733,6 +5829,14 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC return (arguments.size()); } +void +AbstractExternalFunctionNode::collectVARLHSVariable(set<expr_t> &result) const +{ + for (vector<expr_t>::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->collectVARLHSVariable(result); +} + void AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -5821,6 +5925,14 @@ AbstractExternalFunctionNode::maxLag() const return val; } +void +AbstractExternalFunctionNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ + for (vector<expr_t>::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->VarMaxLag(static_datatree, static_lhs, max_lag); +} + int AbstractExternalFunctionNode::PacMaxLag(vector<int> &lhs) const { @@ -7322,6 +7434,11 @@ VarExpectationNode::maxLag() const return 0; } +void +VarExpectationNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ +} + int VarExpectationNode::PacMaxLag(vector<int> &lhs) const { @@ -7380,6 +7497,11 @@ VarExpectationNode::computeXrefs(EquationInfo &ei) const { } +void +VarExpectationNode::collectVARLHSVariable(set<expr_t> &result) const +{ +} + void VarExpectationNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { @@ -7721,6 +7843,11 @@ PacExpectationNode::maxLag() const return 0; } +void +PacExpectationNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const +{ +} + int PacExpectationNode::PacMaxLag(vector<int> &lhs) const { @@ -7771,6 +7898,11 @@ PacExpectationNode::computeXrefs(EquationInfo &ei) const { } +void +PacExpectationNode::collectVARLHSVariable(set<expr_t> &result) const +{ +} + void PacExpectationNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 6de7805983f349db6830a2f329230d4f4ce80bd5..e8057af19d24f1cafef51abcf40cd8def8ad1ec0 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -263,6 +263,12 @@ class ExprNode */ virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const = 0; + //! Find the maximum lag in a VAR: handles case where LHS is diff + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const = 0; + + //! Finds LHS variable in a VAR equation + virtual void collectVARLHSVariable(set<expr_t> &result) const = 0; + //! Computes the set of all variables of a given symbol type in the expression (without information on lags) /*! Variables are stored as symb_id. @@ -545,6 +551,7 @@ public: virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; virtual bool containsExternalFunction() const; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -559,6 +566,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -608,6 +616,7 @@ public: virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; virtual bool containsExternalFunction() const; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void computeTemporaryTerms(map<expr_t, int > &reference_count, temporary_terms_t &temporary_terms, @@ -643,6 +652,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -720,6 +730,7 @@ public: int Curr_block, vector< vector<temporary_terms_t> > &v_temporary_terms, int equation) const; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException); @@ -747,6 +758,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -827,6 +839,7 @@ public: int Curr_block, vector< vector<temporary_terms_t> > &v_temporary_terms, int equation) const; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException); @@ -869,6 +882,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -953,6 +967,7 @@ public: int Curr_block, vector< vector<temporary_terms_t> > &v_temporary_terms, int equation) const; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException); @@ -968,6 +983,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -1050,6 +1066,7 @@ public: int Curr_block, vector< vector<temporary_terms_t> > &v_temporary_terms, int equation) const = 0; + virtual void collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -1069,6 +1086,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; @@ -1253,6 +1271,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual void prepareForDerivation(); @@ -1276,6 +1295,7 @@ public: 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 collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; @@ -1331,6 +1351,7 @@ public: virtual int maxExoLag() const; virtual int maxLead() const; virtual int maxLag() const; + virtual void VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs, int &max_lag) const; virtual int PacMaxLag(vector<int> &lhs) const; virtual expr_t decreaseLeadsLags(int n) const; virtual void prepareForDerivation(); @@ -1354,6 +1375,7 @@ public: 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 collectVARLHSVariable(set<expr_t> &result) const; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; diff --git a/src/ModFile.cc b/src/ModFile.cc index 402a8ab15490af7976fd46ea50cfffcfe6ffb1c0..d9eea19883cbe08e7c5763a1a9f3a5cc5efc526b 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -384,14 +384,14 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const vms->getVarModelName(var_model_name); vms->getVarModelEqTags(var_model_eq_tags); vms->getVarModelInfoForVarExpectation(var_model_info_var_expectation); - int max_lag = 0; vector<int> eqnumber, lhs, orig_diff_var; vector<set<pair<int, int> > > rhs; vector<bool> nonstationary, diff; vector<string> eqtags = var_model_eq_tags[var_model_name]; dynamic_model.getVarModelVariablesFromEqTags(eqtags, eqnumber, lhs, rhs, nonstationary); - original_model.getVarMaxLagAndLhsDiffAndInfo(eqnumber, diff, orig_diff_var, max_lag); + int max_lag = original_model.getVarMaxLag(diff_static_model, eqnumber); + original_model.getVarLhsDiffAndInfo(eqnumber, diff, orig_diff_var); vms->fillVarModelInfoFromEquations(eqnumber, lhs, rhs, nonstationary, diff, orig_diff_var, max_lag); var_model_info_pac_expectation[var_model_name] =