From 1e77f7c5a72f7f03cbdb81bd60c0c43f8ffa12c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 28 Jan 2022 16:28:14 +0100 Subject: [PATCH] SymbolTable::getOrigSymbIdForAuxVar() now also works on unaryOp and diffForward auxvars This is a more natural semantics. Incidentally, this fixes a bug in the variable mapping (M_.mapping) where some endogenous, appearing in a log() in a VAR or TCM, would not be mentioned (e.g. in the var-expectations/7/example1.mod test, and many others). --- src/DynamicModel.cc | 16 +++++----------- src/ExprNode.cc | 2 +- src/SubModel.cc | 2 +- src/SymbolTable.cc | 6 ++++-- src/SymbolTable.hh | 8 +++----- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index e65a6bb2..5717f017 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3139,7 +3139,7 @@ DynamicModel::updateVarAndTrendModel() const if (!var) { int lhs_symb_id = lhs[lhs_idx++]; - if (symbol_table.isAuxiliaryVariable(lhs_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(lhs_symb_id)) try { lhs_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_symb_id); @@ -3150,7 +3150,7 @@ DynamicModel::updateVarAndTrendModel() const int trend_var_symb_id = equations[eqn]->arg2->findTargetVariable(lhs_symb_id); if (trend_var_symb_id >= 0) { - if (symbol_table.isAuxiliaryVariable(trend_var_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(trend_var_symb_id)) try { trend_var_symb_id = symbol_table.getOrigSymbIdForAuxVar(trend_var_symb_id); @@ -3781,7 +3781,7 @@ DynamicModel::analyzePacEquationStructure(const string &name, map(AddVariable(pac_target_symb_id, lag)); }; diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 77a9e38c..b7975f66 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -5210,7 +5210,7 @@ BinaryOpNode::findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const try { - if (datatree.symbol_table.isAuxiliaryVariable(rhs_symb_id) + if (datatree.symbol_table.isDiffAuxiliaryVariable(rhs_symb_id) && lhs_symb_id == datatree.symbol_table.getOrigSymbIdForAuxVar(rhs_symb_id)) return true; } diff --git a/src/SubModel.cc b/src/SubModel.cc index 3b36e99a..55e7d269 100644 --- a/src/SubModel.cc +++ b/src/SubModel.cc @@ -627,7 +627,7 @@ VarModelTable::setLhs(map> lhs_arg) { int lhs_last_orig_symb_id = ids; int lhs_orig_symb_id = ids; - if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(lhs_orig_symb_id)) try { lhs_last_orig_symb_id = lhs_orig_symb_id; diff --git a/src/SymbolTable.cc b/src/SymbolTable.cc index 72ee3307..62a5307f 100644 --- a/src/SymbolTable.cc +++ b/src/SymbolTable.cc @@ -712,12 +712,14 @@ SymbolTable::getOrigSymbIdForAuxVar(int aux_var_symb_id) const noexcept(false) || aux_var.get_type() == AuxVarType::exoLag || aux_var.get_type() == AuxVarType::diff || aux_var.get_type() == AuxVarType::diffLag - || aux_var.get_type() == AuxVarType::diffLead) + || aux_var.get_type() == AuxVarType::diffLead + || aux_var.get_type() == AuxVarType::diffForward + || aux_var.get_type() == AuxVarType::unaryOp) && aux_var.get_symb_id() == aux_var_symb_id) if (int r = aux_var.get_orig_symb_id(); r >= 0) return r; else - throw UnknownSymbolIDException(aux_var_symb_id); // Some diff var have orig_symb_id == -1 + throw UnknownSymbolIDException(aux_var_symb_id); // Some diff and unaryOp auxvars have orig_symb_id == -1 throw UnknownSymbolIDException(aux_var_symb_id); } diff --git a/src/SymbolTable.hh b/src/SymbolTable.hh index b9cf7287..f888eb2f 100644 --- a/src/SymbolTable.hh +++ b/src/SymbolTable.hh @@ -323,12 +323,10 @@ public: int searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const noexcept(false); /* Searches aux_vars for the aux var represented by aux_var_symb_id and returns its associated orig_symb_id. - Works only for endoLag, exoLag, diff, diffLag, diffLead. Throws an UnknownSymbolIDException if there is no orig_symb_id associated to - this aux var (either because it’s of the wrong type, or because there is - no such orig var for this specific aux var, e.g. a diff for a complex expression). - N.B.: some code might rely on the fact that, in particular, it does not work on unaryOp - type (to be verified) */ + this auxvar (either because it’s of the wrong type, or because there is + no such orig var for this specific auxvar, in case of complex expressions + in diff or unaryOp). */ int getOrigSymbIdForAuxVar(int aux_var_symb_id) const noexcept(false); /* Unrolls a chain of diffLag or diffLead aux vars until it founds a (regular) diff aux var. In other words: