PAC MCE: fix incorrect detection of the target variable
The detection of the target EC variable to be used when constructing the forward-looking expectation variable is rather fragile. When the PAC model is written with an (non-)optimizing share of agents, restrict the identification of the target variable to the optimizing expression, to minimize the risk of wrong identification. By the way, add a few comments, and a small simplification.issue#70
parent
51b3d5c68f
commit
16f9168fda
|
@ -3997,11 +3997,9 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const
|
||||||
for (auto &equation : equations)
|
for (auto &equation : equations)
|
||||||
if (equation->containsPacExpectation(pac_model_name))
|
if (equation->containsPacExpectation(pac_model_name))
|
||||||
{
|
{
|
||||||
pair<int, int> lhs(-1, -1);
|
|
||||||
set<pair<int, int>> lhss;
|
set<pair<int, int>> lhss;
|
||||||
equation->arg1->collectDynamicVariables(SymbolType::endogenous, lhss);
|
equation->arg1->collectDynamicVariables(SymbolType::endogenous, lhss);
|
||||||
lhs = *lhss.begin();
|
int lhs_symb_id = lhss.begin()->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_symb_id))
|
if (symbol_table.isAuxiliaryVariable(lhs_symb_id))
|
||||||
try
|
try
|
||||||
|
@ -4011,7 +4009,17 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
return equation->arg2->getPacTargetSymbId(lhs_symb_id, lhs_orig_symb_id);
|
auto barg2 = dynamic_cast<BinaryOpNode *>(equation->arg2);
|
||||||
|
assert(barg2);
|
||||||
|
auto [optim_share_index, optim_part, non_optim_part, additive_part]
|
||||||
|
= barg2->getPacOptimizingShareAndExprNodes(lhs_symb_id, lhs_orig_symb_id);
|
||||||
|
/* The algorithm for identifying the target is fragile. Hence, if there
|
||||||
|
is an optimization part, we restrict the search to that part to
|
||||||
|
avoid wrong results. */
|
||||||
|
if (optim_part)
|
||||||
|
return optim_part->getPacTargetSymbId(lhs_symb_id, lhs_orig_symb_id);
|
||||||
|
else
|
||||||
|
return equation->arg2->getPacTargetSymbId(lhs_symb_id, lhs_orig_symb_id);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4939,8 +4939,11 @@ BinaryOpNode::getPacTargetSymbIdHelper(int lhs_symb_id, int undiff_lhs_symb_id,
|
||||||
{
|
{
|
||||||
int id = datatree.symbol_table.getUltimateOrigSymbID(it.first);
|
int id = datatree.symbol_table.getUltimateOrigSymbID(it.first);
|
||||||
if (id == lhs_symb_id || id == undiff_lhs_symb_id)
|
if (id == lhs_symb_id || id == undiff_lhs_symb_id)
|
||||||
found_lagged_lhs = true;
|
found_lagged_lhs = true; // This expression contains the (lagged) LHS
|
||||||
if (id != lhs_symb_id && id != undiff_lhs_symb_id)
|
if (id != lhs_symb_id && id != undiff_lhs_symb_id)
|
||||||
|
/* The first variable that is not the (lagged) LHS is a
|
||||||
|
candidate for the target. FIXME: What happens if there are several
|
||||||
|
such variables? The detection order is not meaningful… */
|
||||||
if (target_symb_id < 0)
|
if (target_symb_id < 0)
|
||||||
target_symb_id = it.first;
|
target_symb_id = it.first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,6 +480,9 @@ public:
|
||||||
virtual int PacMaxLag(int lhs_symb_id) const = 0;
|
virtual int PacMaxLag(int lhs_symb_id) const = 0;
|
||||||
|
|
||||||
//! Get the target variable of the PAC model
|
//! Get the target variable of the PAC model
|
||||||
|
/* The algorithm is rather crude. For a BinaryOpNode, it inspects both
|
||||||
|
arguments. If one of the argument contains the (lagged) LHS, the first
|
||||||
|
variable that is not the (lagged) LHS is returned as the target */
|
||||||
virtual int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const = 0;
|
virtual int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const = 0;
|
||||||
|
|
||||||
virtual expr_t undiff() const = 0;
|
virtual expr_t undiff() const = 0;
|
||||||
|
|
Loading…
Reference in New Issue