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)
{
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<string, string
auto lhs = *lhss.begin();
int lhs_symb_id = lhs.first;
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
{
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)
{
if (symbol_table.isAuxiliaryVariable(pac_target_symb_id))
{
// We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable()
/* 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));
}
// We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable()
return AddLog(AddVariable(symbol_table.getOrigSymbIdForAuxVar(pac_target_symb_id), lag));
else
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
{
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;
}

View File

@ -627,7 +627,7 @@ VarModelTable::setLhs(map<string, vector<int>> 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;

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::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);
}

View File

@ -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 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).
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 its 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: