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).
fix-tolerance-parameters
Sébastien Villemot 2022-01-28 16:28:14 +01:00
parent 28f89261ab
commit 1e77f7c5a7
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
5 changed files with 14 additions and 20 deletions

View File

@ -3139,7 +3139,7 @@ DynamicModel::updateVarAndTrendModel() const
if (!var) if (!var)
{ {
int lhs_symb_id = lhs[lhs_idx++]; int lhs_symb_id = lhs[lhs_idx++];
if (symbol_table.isAuxiliaryVariable(lhs_symb_id)) if (symbol_table.isDiffAuxiliaryVariable(lhs_symb_id))
try try
{ {
lhs_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_symb_id); 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); int trend_var_symb_id = equations[eqn]->arg2->findTargetVariable(lhs_symb_id);
if (trend_var_symb_id >= 0) if (trend_var_symb_id >= 0)
{ {
if (symbol_table.isAuxiliaryVariable(trend_var_symb_id)) if (symbol_table.isDiffAuxiliaryVariable(trend_var_symb_id))
try try
{ {
trend_var_symb_id = symbol_table.getOrigSymbIdForAuxVar(trend_var_symb_id); trend_var_symb_id = symbol_table.getOrigSymbIdForAuxVar(trend_var_symb_id);
@ -3781,7 +3781,7 @@ DynamicModel::analyzePacEquationStructure(const string &name, map<string, string
auto lhs = *lhss.begin(); auto lhs = *lhss.begin();
int lhs_symb_id = lhs.first; int lhs_symb_id = lhs.first;
int lhs_orig_symb_id = lhs_symb_id; int lhs_orig_symb_id = lhs_symb_id;
if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id)) if (symbol_table.isDiffAuxiliaryVariable(lhs_orig_symb_id))
try try
{ {
lhs_orig_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_orig_symb_id); lhs_orig_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_orig_symb_id);
@ -3949,14 +3949,8 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam
auto create_target_lag = [&](int lag) auto create_target_lag = [&](int lag)
{ {
if (symbol_table.isAuxiliaryVariable(pac_target_symb_id)) if (symbol_table.isAuxiliaryVariable(pac_target_symb_id))
{ // We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable()
// We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable() return AddLog(AddVariable(symbol_table.getOrigSymbIdForAuxVar(pac_target_symb_id), lag));
/* We dont use SymbolTable::getOrigSymbIdForAuxVar(), because it
does not work for unary ops, and changing this behaviour might
break stuff that relies on an exception in this case. */
auto avi = symbol_table.getAuxVarInfo(pac_target_symb_id);
return AddLog(AddVariable(avi.get_orig_symb_id(), lag));
}
else else
return dynamic_cast<ExprNode *>(AddVariable(pac_target_symb_id, lag)); return dynamic_cast<ExprNode *>(AddVariable(pac_target_symb_id, lag));
}; };

View File

@ -5210,7 +5210,7 @@ BinaryOpNode::findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const
try 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)) && lhs_symb_id == datatree.symbol_table.getOrigSymbIdForAuxVar(rhs_symb_id))
return true; return true;
} }

View File

@ -627,7 +627,7 @@ VarModelTable::setLhs(map<string, vector<int>> lhs_arg)
{ {
int lhs_last_orig_symb_id = ids; int lhs_last_orig_symb_id = ids;
int lhs_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 try
{ {
lhs_last_orig_symb_id = lhs_orig_symb_id; lhs_last_orig_symb_id = lhs_orig_symb_id;

View File

@ -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::exoLag
|| aux_var.get_type() == AuxVarType::diff || aux_var.get_type() == AuxVarType::diff
|| aux_var.get_type() == AuxVarType::diffLag || 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) && aux_var.get_symb_id() == aux_var_symb_id)
if (int r = aux_var.get_orig_symb_id(); r >= 0) if (int r = aux_var.get_orig_symb_id(); r >= 0)
return r; return r;
else 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); throw UnknownSymbolIDException(aux_var_symb_id);
} }

View File

@ -323,12 +323,10 @@ public:
int searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const noexcept(false); 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 /* Searches aux_vars for the aux var represented by aux_var_symb_id and
returns its associated orig_symb_id. 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 Throws an UnknownSymbolIDException if there is no orig_symb_id associated to
this aux var (either because its of the wrong type, or because there is this auxvar (either because its 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). no such orig var for this specific auxvar, in case of complex expressions
N.B.: some code might rely on the fact that, in particular, it does not work on unaryOp in diff or unaryOp). */
type (to be verified) */
int getOrigSymbIdForAuxVar(int aux_var_symb_id) const noexcept(false); 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 /* Unrolls a chain of diffLag or diffLead aux vars until it founds a (regular) diff aux
var. In other words: var. In other words: