From 8584323563a2eeed5fb247f72b51149061ad66e1 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Tue, 4 Sep 2018 10:39:05 +0200
Subject: [PATCH] provide information on order of ec.vars

---
 src/DynamicModel.cc | 16 ++++++++--
 src/ExprNode.cc     | 75 ++++++++++++++++++++++++++-------------------
 src/ExprNode.hh     | 43 +++++++++++++-------------
 3 files changed, 79 insertions(+), 55 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index cc3ea366..a3ac4b67 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -4028,7 +4028,7 @@ DynamicModel::walkPacParameters()
   for (auto & equation : equations)
     {
       pair<int, int> lhs (-1, -1);
-      pair<int, vector<int>> ec_params_and_vars;
+      pair<int, pair<vector<int>, vector<bool>>> ec_params_and_vars;
       set<pair<int, pair<int, int>>> ar_params_and_vars;
       set<pair<int, pair<pair<int, int>, double>>> non_optim_params_vars_and_scaling_factor;
 
@@ -4039,15 +4039,25 @@ DynamicModel::walkPacParameters()
           expr_t optim_part = nullptr;
           expr_t non_optim_part = nullptr;
           equation->getPacLHS(lhs);
+          int lhs_orig_symb_id = lhs.first;
+          if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id))
+            try
+              {
+                lhs_orig_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_orig_symb_id);
+              }
+            catch (...)
+              {
+              }
+
           equation->get_arg2()->getPacOptimizingShareAndExprNodes(optim_share,
                                                                   optim_part,
                                                                   non_optim_part);
           if (optim_part == nullptr)
-            equation->get_arg2()->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+            equation->get_arg2()->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
           else
             {
               optim_share_index = *(optim_share.begin());
-              optim_part->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+              optim_part->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
               non_optim_part->getPacNonOptimizingPart(non_optim_params_vars_and_scaling_factor);
             }
           equation->addParamInfoToPac(lhs,
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index c5c47f24..43ac5fc7 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -662,7 +662,7 @@ NumConstNode::isParamTimesEndogExpr() const
 }
 
 void
-NumConstNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+NumConstNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                    set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
 }
@@ -681,7 +681,7 @@ NumConstNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>
 }
 
 void
-NumConstNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+NumConstNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
 }
 
@@ -1858,7 +1858,7 @@ VariableNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>
 }
 
 void
-VariableNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+VariableNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                    set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
 }
@@ -1871,7 +1871,7 @@ VariableNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-VariableNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+VariableNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
 }
 
@@ -3484,10 +3484,10 @@ UnaryOpNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>
 }
 
 void
-UnaryOpNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+UnaryOpNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                   set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
-  arg->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+  arg->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
 }
 
 void
@@ -3499,7 +3499,7 @@ UnaryOpNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-UnaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+UnaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
   arg->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
 }
@@ -5157,7 +5157,8 @@ BinaryOpNode::findTrendVariable(int lhs_symb_id) const
 
 void
 BinaryOpNode::getPacOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
-                                         pair<int, vector<int>> &ec_params_and_vars,
+                                         int lhs_orig_symb_id,
+                                         pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                          set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
   set<int> params;
@@ -5179,35 +5180,43 @@ BinaryOpNode::getPacOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
           if (test_arg1 != nullptr && test_arg2 != nullptr)
             {
               vector<int> endog_ids;
+              vector<bool> order;
               endogs.clear();
               test_arg1->collectDynamicVariables(SymbolType::endogenous, endogs);
               endog_ids.push_back(endogs.begin()->first);
+              if (endogs.begin()->first == lhs_orig_symb_id)
+                order.push_back(true);
+              else
+                order.push_back(false);
 
               endogs.clear();
               test_arg2->collectDynamicVariables(SymbolType::endogenous, endogs);
               endog_ids.push_back(endogs.begin()->first);
+              if (endogs.begin()->first == lhs_orig_symb_id)
+                order.push_back(true);
+              else
+                order.push_back(false);
 
-              ec_params_and_vars = make_pair(*(params.begin()), endog_ids);
+              ec_params_and_vars = make_pair(*(params.begin()), make_pair(endog_ids, order));
             }
         }
     }
 }
 
 void
-BinaryOpNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+BinaryOpNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                    set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
   if (op_code == BinaryOpcode::times)
     {
       int orig_ar_params_and_vars_size = ar_params_and_vars.size();
-      getPacOptimizingPartHelper(arg1, arg2, ec_params_and_vars, ar_params_and_vars);
-      if ((int)ar_params_and_vars.size() == orig_ar_params_and_vars_size
-          && ec_params_and_vars.second.empty())
-        getPacOptimizingPartHelper(arg2, arg1, ec_params_and_vars, ar_params_and_vars);
+      getPacOptimizingPartHelper(arg1, arg2, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
+      if ((int)ar_params_and_vars.size() == orig_ar_params_and_vars_size && ec_params_and_vars.second.first.empty())
+        getPacOptimizingPartHelper(arg2, arg1, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
     }
 
-  arg1->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
-  arg2->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+  arg1->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
+  arg2->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
 }
 
 void
@@ -5402,7 +5411,7 @@ BinaryOpNode::getPacLHS(pair<int, int> &lhs)
 }
 
 void
-BinaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+BinaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
   arg1->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
   arg2->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
@@ -6285,12 +6294,12 @@ TrinaryOpNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double
 }
 
 void
-TrinaryOpNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+TrinaryOpNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                     set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
-  arg1->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
-  arg2->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
-  arg3->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+  arg1->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
+  arg2->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
+  arg3->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
 }
 
 void
@@ -6304,7 +6313,7 @@ TrinaryOpNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-TrinaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+TrinaryOpNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
   arg1->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
   arg2->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
@@ -6821,11 +6830,11 @@ AbstractExternalFunctionNode::getPacNonOptimizingPart(set<pair<int, pair<pair<in
 }
 
 void
-AbstractExternalFunctionNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+AbstractExternalFunctionNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                                    set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
   for (auto argument : arguments)
-    argument->getPacOptimizingPart(ec_params_and_vars, ar_params_and_vars);
+    argument->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
 }
 
 void
@@ -6838,7 +6847,7 @@ AbstractExternalFunctionNode::getPacOptimizingShareAndExprNodes(set<int> &optim_
 }
 
 void
-AbstractExternalFunctionNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+AbstractExternalFunctionNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
   for (auto argument : arguments)
     argument->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
@@ -8396,7 +8405,7 @@ VarExpectationNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, d
 }
 
 void
-VarExpectationNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+VarExpectationNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                          set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
 }
@@ -8409,7 +8418,7 @@ VarExpectationNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-VarExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+VarExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
 }
 
@@ -8504,8 +8513,12 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
   output << "M_.pac." << model_name << ".ec.params = "
          << datatree.symbol_table.getTypeSpecificID(ec_params_and_vars.first) + 1 << ";" << endl
          << "M_.pac." << model_name << ".ec.vars = [";
-  for (auto it : ec_params_and_vars.second)
+  for (auto it : ec_params_and_vars.second.first)
       output << datatree.symbol_table.getTypeSpecificID(it) + 1 << " ";
+  output << "];" << endl
+         << "M_.pac." << model_name << ".ec.vars = [";
+  for (auto it : ec_params_and_vars.second.second)
+    output << (it ? "true" : "false") << " ";
   output << "];" << endl
          << "M_.pac." << model_name << ".ar.params = [";
   for (auto it = ar_params_and_vars.begin();
@@ -8924,7 +8937,7 @@ PacExpectationNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, d
 }
 
 void
-PacExpectationNode::getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+PacExpectationNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                          set<pair<int, pair<int, int>>> &ar_params_and_vars) const
 {
 }
@@ -8937,7 +8950,7 @@ PacExpectationNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-PacExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
+PacExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg)
 {
   if (lhs_arg.first == -1)
     {
@@ -8945,7 +8958,7 @@ PacExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_a
       exit(EXIT_FAILURE);
     }
 
-  if (ec_params_and_vars_arg.second.empty() || ar_params_and_vars_arg.empty())
+  if (ec_params_and_vars_arg.second.first.empty() || ar_params_and_vars_arg.empty())
     {
       cerr << "Pac Expectation: error in obtaining RHS parameters." << endl;
       exit(EXIT_FAILURE);
diff --git a/src/ExprNode.hh b/src/ExprNode.hh
index 2e7363e2..d77f9a6f 100644
--- a/src/ExprNode.hh
+++ b/src/ExprNode.hh
@@ -527,8 +527,8 @@ class ExprNode
       //! Returns true if model_info_name is referenced by a VarExpectationNode
       virtual bool isVarModelReferenced(const string &model_info_name) const = 0;
 
-      //! Fills parameter information related to PAC equation
-      virtual void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+      //! Fills parameter information rerhs_symblated to PAC equation
+      virtual void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                         set<pair<int, pair<int, int>>> &params_and_vars) const = 0;
 
       //! Fills info for non optimizing part of PAC equation
@@ -545,7 +545,7 @@ class ExprNode
                                                      expr_t &optim_part,
                                                      expr_t &non_optim_part) const = 0;
       //! Adds PAC equation param info to pac_expectation
-      virtual void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) = 0;
+      virtual void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) = 0;
 
       //! Fills var_model info for pac_expectation node
       virtual void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) = 0;
@@ -634,12 +634,12 @@ public:
   expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -733,12 +733,12 @@ public:
   expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -856,12 +856,12 @@ public:
   expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -955,7 +955,8 @@ public:
                                      set<pair<int, pair<pair<int, int>, double>>>
                                      &params_vars_and_scaling_factor) const;
   void getPacOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
-                                  pair<int, vector<int>> &ec_params_and_vars,
+                                  int lhs_orig_symb_id,
+                                  pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                                   set<pair<int, pair<int, int>>> &ar_params_and_vars) const;
   void getPacLHS(pair<int, int> &lhs);
   expr_t toStatic(DataTree &static_datatree) const override;
@@ -1008,10 +1009,10 @@ public:
   //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
   expr_t getNonZeroPartofEquation() const;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -1115,12 +1116,12 @@ public:
   expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -1236,12 +1237,12 @@ public:
   expr_t cloneDynamic(DataTree &dynamic_datatree) const override = 0;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -1444,12 +1445,12 @@ public:
   expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
@@ -1474,7 +1475,7 @@ private:
   vector<int> h0_indices, h1_indices;
   int growth_param_index, equation_number;
   int optim_share_index;
-  pair<int, vector<int>> ec_params_and_vars;
+  pair<int, pair<vector<int>, vector<bool>>> ec_params_and_vars;
   set<pair<int, pair<int, int>>> ar_params_and_vars;
   set<pair<int, pair<pair<int, int>, double>>> params_vars_and_scaling_factor;
 public:
@@ -1540,12 +1541,12 @@ public:
   expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
   expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
   bool isInStaticForm() const override;
-  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, vector<int>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
+  void addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_arg, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg, set<pair<int, pair<pair<int, int>, double>>> &params_vars_and_scaling_factor_arg) override;
   void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, int pac_max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
   bool containsPacExpectation(const string &pac_model_name = "") const override;
   void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
                                &params_vars_and_scaling_factor) const override;
-  void getPacOptimizingPart(pair<int, vector<int>> &ec_params_and_vars,
+  void getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
                             set<pair<int, pair<int, int>>> &params_and_vars) const override;
   void getPacOptimizingShareAndExprNodes(set<int> &optim_share,
                                          expr_t &optim_part,
-- 
GitLab