From 712b11a04575e15f0a5080b469fcd4d7e02b597f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Thu, 23 Mar 2023 17:58:20 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Incorrect=20stochastic=20transfo?= =?UTF-8?q?rmation=20with=20endo=20lead=20=E2=A9=BE=202=20or=20exo=20lead?= =?UTF-8?q?=20=E2=A9=BE=201=20in=20external=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an endogenous with a lead ⩾ 2 or an exogenous with a lead ⩾ 1 appeared in the argument(s) of a call to an external function, the auxiliary variable transformation was incorrect (the variable was replaced inside the function call, while it is the whole function call that has to be replaced). This could lead to incorrect results in stochastic contexts, when the external function is nonlinear. --- src/ExprNode.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ExprNode.cc b/src/ExprNode.cc index c366b085..dc166264 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -6928,7 +6928,12 @@ AbstractExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const expr_t AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const { - return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, deterministic_model); + if (maxEndoLead() < 2) + return const_cast<AbstractExternalFunctionNode *>(this); + else if (deterministic_model) + return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, deterministic_model); + else + return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); } expr_t @@ -6940,7 +6945,12 @@ AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &sub expr_t AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const { - return recurseTransform(&ExprNode::substituteExoLead, subst_table, neweqs, deterministic_model); + if (maxExoLead() == 0) + return const_cast<AbstractExternalFunctionNode *>(this); + else if (deterministic_model) + return recurseTransform(&ExprNode::substituteExoLead, subst_table, neweqs, deterministic_model); + else + return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); } expr_t -- GitLab