diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 156c696be4f69a9a9a86087ddd0e6811563b86f8..d4a3a672ba5ef7f9643ed1a57fe3e2ef5463b56e 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -4243,7 +4243,7 @@ DynamicModel::walkPacParameters()
       pair<int, int> lhs (-1, -1);
       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;
+      vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants;
 
       if (equation->containsPacExpectation())
         {
@@ -4271,12 +4271,12 @@ DynamicModel::walkPacParameters()
             {
               optim_share_index = *(optim_share.begin());
               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);
+              non_optim_vars_params_and_constants = non_optim_part->getPacNonOptimizingPart();
             }
           equation->addParamInfoToPac(lhs,
                                       optim_share_index,
                                       ec_params_and_vars, ar_params_and_vars,
-                                      non_optim_params_vars_and_scaling_factor);
+                                      non_optim_vars_params_and_constants);
         }
     }
 }
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index 27fd7876678bfae1f403c4650484d900418270e2..2ebdfa0da4e0f531d418720f06b21e9285224bca 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -675,13 +675,7 @@ NumConstNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-NumConstNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                      &params_vars_and_scaling_factor) const
-{
-}
-
-void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
 }
 
@@ -1951,23 +1945,6 @@ VariableNode::isParamTimesEndogExpr() const
   return false;
 }
 
-void
-VariableNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                      &params_vars_and_scaling_factor) const
-{
-  if (get_type() != SymbolType::endogenous
-      && get_type() != SymbolType::exogenous)
-    {
-      cerr << "ERROR VariableNode::getPacNonOptimizingPart: Error in parsing PAC equation"
-           << endl;
-      exit(EXIT_FAILURE);
-    }
-
-  params_vars_and_scaling_factor.emplace(make_pair(-1,
-                                                   make_pair(make_pair(symb_id, lag),
-                                                             1.0)));
-}
-
 void
 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
@@ -1982,7 +1959,7 @@ VariableNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
 }
 
@@ -3767,12 +3744,6 @@ UnaryOpNode::isParamTimesEndogExpr() const
   return arg->isParamTimesEndogExpr();
 }
 
-void
-UnaryOpNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                     &params_vars_and_scaling_factor) const
-{
-  arg->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-}
 
 void
 UnaryOpNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
@@ -3790,9 +3761,9 @@ UnaryOpNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
-  arg->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
+  arg->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
 }
 
 void
@@ -5570,83 +5541,6 @@ BinaryOpNode::getPacOptimizingPart(int lhs_orig_symb_id, pair<int, pair<vector<i
   arg2->getPacOptimizingPart(lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars);
 }
 
-void
-BinaryOpNode::getPacNonOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
-                                            set<pair<int, pair<pair<int, int>, double>>>
-                                            &params_vars_and_scaling_factor) const
-{
-  eval_context_t ec;
-  set<int> params;
-  set<pair<int, int>> vars;
-  arg1->collectDynamicVariables(SymbolType::endogenous, vars);
-  arg1->collectDynamicVariables(SymbolType::exogenous, vars);
-
-  if (vars.size() == 0)
-    return;
-
-  if (vars.size() > 1)
-    {
-      cerr << "ERROR BinaryOpNode::getPacNonOptimizingPartHelper: Error in parsing PAC equation"
-           << endl;
-      exit(EXIT_FAILURE);
-    }
-  ec[(*(vars.begin())).first] = 1.0;
-
-  arg2->collectVariables(SymbolType::parameter, params);
-  if (params.size() > 1)
-    {
-      cerr << "ERROR BinaryOpNode::getPacNonOptimizingPartHelper: 2 Error in parsing PAC equation"
-           << endl;
-      exit(EXIT_FAILURE);
-    }
-
-  int param_idx;
-  if (params.size() == 1)
-    {
-      param_idx = *(params.begin());
-      ec[param_idx] = 1.0;
-    }
-  else
-    param_idx = -1;
-
-  double scaling_factor = 1.0;
-  try
-    {
-      scaling_factor = this->eval(ec);
-    }
-  catch (...)
-    {
-    }
-
-  params_vars_and_scaling_factor.emplace(param_idx,
-                                         make_pair(*(vars.begin()), scaling_factor));
-}
-
-void
-BinaryOpNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                      &params_vars_and_scaling_factor) const
-{
-  if (op_code == BinaryOpcode::times
-    || op_code == BinaryOpcode::divide)
-    {
-      size_t orig_size = params_vars_and_scaling_factor.size();
-      getPacNonOptimizingPartHelper(arg1, arg2, params_vars_and_scaling_factor);
-      if (orig_size == params_vars_and_scaling_factor.size())
-        getPacNonOptimizingPartHelper(arg2, arg1, params_vars_and_scaling_factor);
-      if (orig_size == params_vars_and_scaling_factor.size())
-        {
-          cerr << "ERROR BinaryOpNode::getPacNonOptimizingPart: Error in parsing PAC equation"
-               << endl;
-          exit(EXIT_FAILURE);
-        }
-    }
-  else
-    {
-      arg1->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-      arg2->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-    }
-}
-
 bool
 BinaryOpNode::isParamTimesEndogExpr() const
 {
@@ -5895,10 +5789,10 @@ BinaryOpNode::getPacLHS(pair<int, int> &lhs)
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
-  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);
+  arg1->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
+  arg2->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
 }
 
 void
@@ -6790,15 +6684,6 @@ TrinaryOpNode::isParamTimesEndogExpr() const
     || arg3->isParamTimesEndogExpr();
 }
 
-void
-TrinaryOpNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                       &params_vars_and_scaling_factor) const
-{
-  arg1->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-  arg2->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-  arg3->getPacNonOptimizingPart(params_vars_and_scaling_factor);
-}
-
 void
 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
@@ -6819,11 +6704,11 @@ TrinaryOpNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
-  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);
-  arg3->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, params_vars_and_scaling_factor_arg);
+  arg1->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
+  arg2->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
+  arg3->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
 }
 
 void
@@ -7344,15 +7229,6 @@ AbstractExternalFunctionNode::isParamTimesEndogExpr() const
   return false;
 }
 
-void
-AbstractExternalFunctionNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                                      &params_vars_and_scaling_factor) const
-{
-  cerr << "ERROR AbstractExternalFunctionNode::getPacNonOptimizingPart(: Error in parsing PAC equation"
-       << endl;
-  exit(EXIT_FAILURE);
-}
-
 void
 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
@@ -7371,10 +7247,10 @@ AbstractExternalFunctionNode::getPacOptimizingShareAndExprNodes(set<int> &optim_
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
   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);
+    argument->addParamInfoToPac(lhs_arg, optim_share_arg, ec_params_and_vars_arg, ar_params_and_vars_arg, non_optim_vars_params_and_constants);
 }
 
 void
@@ -8973,15 +8849,6 @@ VarExpectationNode::isParamTimesEndogExpr() const
   return false;
 }
 
-void
-VarExpectationNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                            &params_vars_and_scaling_factor) const
-{
-  cerr << "ERROR VarExpectationNode::getPacNonOptimizingPart(: Error in parsing PAC equation"
-       << endl;
-  exit(EXIT_FAILURE);
-}
-
 void
 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
@@ -8996,7 +8863,7 @@ VarExpectationNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants)
 {
 }
 
@@ -9146,45 +9013,45 @@ PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
       output << it->second.second;
     }
   output << "];" << endl;
-  if (!params_vars_and_scaling_factor.empty())
+  if (!non_optim_vars_params_and_constants.empty())
     {
       output << "M_.pac." << model_name << ".non_optimizing_behaviour.params = [";
-      for (auto it = params_vars_and_scaling_factor.begin();
-           it != params_vars_and_scaling_factor.end(); it++)
+      for (auto it = non_optim_vars_params_and_constants.begin();
+           it != non_optim_vars_params_and_constants.end(); ++it)
         {
-          if (it != params_vars_and_scaling_factor.begin())
+          if (it != non_optim_vars_params_and_constants.begin())
             output << " ";
-          if (it->first >= 0)
-            output << datatree.symbol_table.getTypeSpecificID(it->first) + 1;
+          if (get<2>(*it) >= 0)
+            output << datatree.symbol_table.getTypeSpecificID(get<2>(*it)) + 1;
           else
             output << "NaN";
         }
       output << "];"
              << "M_.pac." << model_name << ".non_optimizing_behaviour.vars = [";
-      for (auto it = params_vars_and_scaling_factor.begin();
-           it != params_vars_and_scaling_factor.end(); it++)
+      for (auto it = non_optim_vars_params_and_constants.begin();
+           it != non_optim_vars_params_and_constants.end(); ++it)
         {
-          if (it != params_vars_and_scaling_factor.begin())
+          if (it != non_optim_vars_params_and_constants.begin())
             output << " ";
-          output << datatree.symbol_table.getTypeSpecificID(it->second.first.first) + 1;
+          output << datatree.symbol_table.getTypeSpecificID(get<0>(*it)) + 1;
         }
       output << "];" << endl
              << "M_.pac." << model_name << ".non_optimizing_behaviour.lags = [";
-      for (auto it = params_vars_and_scaling_factor.begin();
-           it != params_vars_and_scaling_factor.end(); it++)
+      for (auto it = non_optim_vars_params_and_constants.begin();
+           it != non_optim_vars_params_and_constants.end(); ++it)
         {
-          if (it != params_vars_and_scaling_factor.begin())
+          if (it != non_optim_vars_params_and_constants.begin())
             output << " ";
-          output << it->second.first.second;
+          output << get<1>(*it);
         }
       output << "];" << endl
              << "M_.pac." << model_name << ".non_optimizing_behaviour.scaling_factor = [";
-      for (auto it = params_vars_and_scaling_factor.begin();
-           it != params_vars_and_scaling_factor.end(); it++)
+      for (auto it = non_optim_vars_params_and_constants.begin();
+           it != non_optim_vars_params_and_constants.end(); ++it)
         {
-          if (it != params_vars_and_scaling_factor.begin())
+          if (it != non_optim_vars_params_and_constants.begin())
             output << " ";
-          output << it->second.second;
+          output << get<3>(*it);
         }
       output << "];" << endl;
     }
@@ -9550,12 +9417,6 @@ PacExpectationNode::isParamTimesEndogExpr() const
   return false;
 }
 
-void
-PacExpectationNode::getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                            &params_vars_and_scaling_factor) const
-{
-}
-
 void
 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
@@ -9570,7 +9431,7 @@ PacExpectationNode::getPacOptimizingShareAndExprNodes(set<int> &optim_share,
 }
 
 void
-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)
+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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants_arg)
 {
   if (lhs_arg.first == -1)
     {
@@ -9588,7 +9449,7 @@ PacExpectationNode::addParamInfoToPac(pair<int, int> &lhs_arg, int optim_share_a
   optim_share_index = optim_share_arg;
   ar_params_and_vars = ar_params_and_vars_arg;
   ec_params_and_vars = ec_params_and_vars_arg;
-  params_vars_and_scaling_factor = params_vars_and_scaling_factor_arg;
+  non_optim_vars_params_and_constants = non_optim_vars_params_and_constants_arg;
 }
 
 
@@ -9669,3 +9530,137 @@ PacExpectationNode::substitutePacExpectation(map<const PacExpectationNode *, con
 
   return subExpr;
 }
+
+void
+ExprNode::decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const
+{
+  terms.emplace_back(const_cast<ExprNode *>(this), current_sign);
+}
+
+void
+UnaryOpNode::decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const
+{
+  if (op_code == UnaryOpcode::uminus)
+    arg->decomposeAdditiveTerms(terms, -current_sign);
+  else
+    ExprNode::decomposeAdditiveTerms(terms, current_sign);
+}
+
+void
+BinaryOpNode::decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const
+{
+  if (op_code == BinaryOpcode::plus || op_code == BinaryOpcode::minus)
+    {
+      arg1->decomposeAdditiveTerms(terms, current_sign);
+      if (op_code == BinaryOpcode::plus)
+        arg2->decomposeAdditiveTerms(terms, current_sign);
+      else
+        arg2->decomposeAdditiveTerms(terms, -current_sign);
+    }
+  else
+    ExprNode::decomposeAdditiveTerms(terms, current_sign);
+}
+
+tuple<int, int, int, double>
+ExprNode::matchVariableTimesConstantTimesParam() const
+{
+  int variable_id = -1, lag = 0, param_id = -1;
+  double constant = 1.0;
+  matchVTCTPHelper(variable_id, lag, param_id, constant, false);
+  if (variable_id == -1)
+    throw MatchFailureException{"No variable in this expression"};
+  return make_tuple(variable_id, lag, param_id, constant);
+}
+
+void
+ExprNode::matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const
+{
+  throw MatchFailureException{"Expression not allowed in linear combination of variables"};
+}
+
+void
+NumConstNode::matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const
+{
+  double myvalue = eval({});
+  if (at_denominator)
+    constant /= myvalue;
+  else
+    constant *= myvalue;
+}
+
+void
+VariableNode::matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const
+{
+  if (at_denominator)
+    throw MatchFailureException{"A variable or parameter cannot appear at denominator"};
+
+  SymbolType type = get_type();
+  if (type == SymbolType::endogenous || type == SymbolType::exogenous)
+    {
+      if (var_id != -1)
+        throw MatchFailureException{"More than one variable in this expression"};
+      var_id = symb_id;
+      lag = this->lag;
+    }
+  else if (type == SymbolType::parameter)
+    {
+      if (param_id != -1)
+        throw MatchFailureException{"More than one parameter in this expression"};
+      param_id = symb_id;
+    }
+  else
+    throw MatchFailureException{"Symbol " + datatree.symbol_table.getName(symb_id) + " not allowed here"};
+}
+
+void
+UnaryOpNode::matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const
+{
+  if (op_code == UnaryOpcode::uminus)
+    {
+      constant = -constant;
+      arg->matchVTCTPHelper(var_id, lag, param_id, constant, at_denominator);
+    }
+  else
+    throw MatchFailureException{"Operator not allowed in this expression"};
+}
+
+void
+BinaryOpNode::matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const
+{
+  if (op_code == BinaryOpcode::times || op_code == BinaryOpcode::divide)
+    {
+      arg1->matchVTCTPHelper(var_id, lag, param_id, constant, at_denominator);
+      if (op_code == BinaryOpcode::times)
+        arg2->matchVTCTPHelper(var_id, lag, param_id, constant, at_denominator);
+      else
+        arg2->matchVTCTPHelper(var_id, lag, param_id, constant, !at_denominator);
+    }
+  else
+    throw MatchFailureException{"Operator not allowed in this expression"};
+}
+
+vector<tuple<int, int, int, double>>
+ExprNode::getPacNonOptimizingPart() const
+{
+  vector<pair<expr_t, int>> terms;
+  decomposeAdditiveTerms(terms);
+
+  vector<tuple<int, int, int, double>> result;
+
+  for (const auto &it : terms)
+    try
+      {
+        expr_t term = it.first;
+        int sign = it.second;
+        auto m = term->matchVariableTimesConstantTimesParam();
+        get<3>(m) *= sign;
+        result.push_back(m);
+      }
+    catch (MatchFailureException &e)
+      {
+        cerr << "ExprNode::getPacNonOptimizingPart: Error in parsing PAC equation: "
+             << e.message << endl;
+        exit(EXIT_FAILURE);
+      }
+    return result;
+}
diff --git a/src/ExprNode.hh b/src/ExprNode.hh
index 077e475ab0bf7437fe1b9882c4702b21787e9a44..8cba78d1bfad065d828b5de523dd12ae7aa2b97c 100644
--- a/src/ExprNode.hh
+++ b/src/ExprNode.hh
@@ -205,6 +205,10 @@ class ExprNode
       bool checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType output_type,
                                          const temporary_terms_t &temporary_terms,
                                          const temporary_terms_idxs_t &temporary_terms_idxs) const;
+
+      // Internal helper for matchVariableTimesConstantTimesParam()
+      virtual void matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const;
+
     public:
       ExprNode(DataTree &datatree_arg, int idx_arg);
       virtual ~ExprNode() = default;
@@ -556,9 +560,11 @@ class ExprNode
       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
-      virtual void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                                           &params_vars_and_scaling_factor) const = 0;
+      //! Analyzes the non optimizing part of PAC equation
+      /*! Returns a list of (variable_id, lag, param_id, constant)
+          corresponding to the terms in the expression. When there is no
+          parameter in a term, param_id == -1 */
+      vector<tuple<int, int, int, double>> getPacNonOptimizingPart() const;
       //! Returns true if expression is of the form:
       //! param * (endog op endog op ...) + param * (endog op endog op ...) + ...
       virtual bool isParamTimesEndogExpr() const = 0;
@@ -570,7 +576,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, 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;
+      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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) = 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;
@@ -587,7 +593,33 @@ class ExprNode
 
       //! Fills map
       virtual void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const = 0;
-    };
+
+      //! Decompose an expression into its additive terms
+      /*! Returns a list of terms, with their sign (either 1 or -1, depending
+        on whether the terms appears with a plus or a minus).
+        The current_sign argument should normally be left to 1.
+        If current_sign == -1, then all signs are inverted */
+      virtual void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign = 1) const;
+
+      // Matches an expression of the form variable*constant*parameter
+      /* Returns a tuple (variable_id, lag, param_id, constant).
+         The variable must be an exogenous or an endogenous.
+         The constant is optional (in which case 1 is returned); there can be
+         several multiplicative constants; constants can also appear at the
+         denominator (i.e. after a divide sign).
+         The parameter is optional (in which case param_id == -1).
+         If the expression is not of the expected form, throws a
+         MatchFailureException */
+      tuple<int, int, int, double> matchVariableTimesConstantTimesParam() const;
+
+      //! Exception thrown by matchVariableTimesConstantTimesParam when matching fails
+      class MatchFailureException
+      {
+      public:
+        const string message;
+        MatchFailureException(string message_arg) : message{move(message_arg)} {};
+      };
+};
 
 //! Object used to compare two nodes (using their indexes)
 /*! Note that in this ordering, a subexpression is always less than the
@@ -667,13 +699,11 @@ public:
   expr_t clone(DataTree &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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -683,6 +713,7 @@ public:
   bool isVarModelReferenced(const string &model_info_name) const override;
   void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
   expr_t substituteStaticAuxiliaryVariable() const override;
+  void matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const override;
 };
 
 //! Symbol or variable node
@@ -764,13 +795,11 @@ public:
   expr_t clone(DataTree &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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -781,6 +810,7 @@ public:
   void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
   //! Substitute auxiliary variables by their expression in static model
   expr_t substituteStaticAuxiliaryVariable() const override;
+  void matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const override;
 };
 
 //! Unary operator node
@@ -890,13 +920,11 @@ public:
   expr_t clone(DataTree &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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -907,6 +935,8 @@ public:
   void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
   //! Substitute auxiliary variables by their expression in static model
   expr_t substituteStaticAuxiliaryVariable() const override;
+  void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const override;
+  void matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const override;
 };
 
 //! Binary operator node
@@ -984,11 +1014,6 @@ public:
   {
     return powerDerivOrder;
   }
-  void getPacNonOptimizingPart(set<pair<int, pair<pair<int, int>, double>>>
-                               &params_vars_and_scaling_factor) const override;
-  void getPacNonOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
-                                     set<pair<int, pair<pair<int, int>, double>>>
-                                     &params_vars_and_scaling_factor) const;
   void getPacOptimizingPartHelper(const expr_t arg1, const expr_t arg2,
                                   int lhs_orig_symb_id,
                                   pair<int, pair<vector<int>, vector<bool>>> &ec_params_and_vars,
@@ -1044,7 +1069,7 @@ 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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRowHelper(expr_t arg1, expr_t arg2,
                                    int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const;
@@ -1066,6 +1091,8 @@ public:
   expr_t substituteStaticAuxiliaryVariable() const override;
   //! Substitute auxiliary variables by their expression in static model auxiliary variable definition
   expr_t substituteStaticAuxiliaryDefinition() const;
+  void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const override;
+  void matchVTCTPHelper(int &var_id, int &lag, int &param_id, double &constant, bool at_denominator) const override;
 };
 
 //! Trinary operator node
@@ -1159,13 +1186,11 @@ public:
   expr_t clone(DataTree &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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -1284,13 +1309,11 @@ public:
   expr_t clone(DataTree &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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -1497,13 +1520,11 @@ 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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,
@@ -1532,7 +1553,7 @@ private:
   int optim_share_index;
   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;
+  vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants;
 public:
   PacExpectationNode(DataTree &datatree_arg, int idx_arg, string model_name);
   void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference>> &reference_count,
@@ -1596,13 +1617,11 @@ 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, 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 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, const vector<tuple<int, int, int, double>> &non_optim_vars_params_and_constants) 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;
   void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const override;
   void fillErrorCorrectionRow(int eqn, const vector<int> &nontrend_lhs, const vector<int> &trend_lhs, map<tuple<int, int, int>, expr_t> &EC) const 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(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,