From 130004ef47618d0ea6917dc54494fe2c266db246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Tue, 5 Jun 2018 15:34:34 +0200
Subject: [PATCH] Simplify types for storing derivatives using std::tuple

---
 src/DynamicModel.cc | 142 ++++++++++++++++++++------------------------
 src/ModelTree.cc    |  70 ++++++++++------------
 src/ModelTree.hh    |   4 +-
 src/StaticModel.cc  | 109 ++++++++++++++++------------------
 4 files changed, 145 insertions(+), 180 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index be88fd09..117c48a9 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -1723,19 +1723,21 @@ DynamicModel::printNonZeroHessianEquations(ostream &output) const
 void
 DynamicModel::setNonZeroHessianEquations(map<int, string> &eqs)
 {
-  for (second_derivatives_t::const_iterator it = second_derivatives.begin();
-       it != second_derivatives.end(); it++)
-    if (nonzero_hessian_eqs.find(it->first.first) == nonzero_hessian_eqs.end())
-      {
-        nonzero_hessian_eqs[it->first.first] = "";
-        for (auto & equation_tag : equation_tags)
-          if (equation_tag.first == it->first.first)
-            if (equation_tag.second.first == "name")
-              {
-                nonzero_hessian_eqs[it->first.first] = equation_tag.second.second;
-                break;
-              }
-      }
+  for (const auto &it : second_derivatives)
+    {
+      int eq = get<0>(it.first);
+      if (nonzero_hessian_eqs.find(eq) == nonzero_hessian_eqs.end())
+        {
+          nonzero_hessian_eqs[eq] = "";
+          for (auto & equation_tag : equation_tags)
+            if (equation_tag.first == eq)
+              if (equation_tag.second.first == "name")
+                {
+                  nonzero_hessian_eqs[eq] = equation_tag.second.second;
+                  break;
+                }
+        }
+    }
   eqs = nonzero_hessian_eqs;
 }
 
@@ -2359,8 +2361,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
 
       for (const auto & first_derivative : first_derivatives)
         {
-          int eq = first_derivative.first.first;
-          int var = first_derivative.first.second;
+          int eq, var;
+          tie(eq, var) = first_derivative.first;
           expr_t d1 = first_derivative.second;
 
           jacobianHelper(jacobian_output, eq, getDynJacobianCol(var), output_type);
@@ -2383,9 +2385,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
       int k = 0; // Keep the line of a 2nd derivative in v2
       for (const auto & second_derivative : second_derivatives)
         {
-          int eq = second_derivative.first.first;
-          int var1 = second_derivative.first.second.first;
-          int var2 = second_derivative.first.second.second;
+          int eq, var1, var2;
+          tie(eq, var1, var2) = second_derivative.first;
           expr_t d2 = second_derivative.second;
 
           int id1 = getDynJacobianCol(var1);
@@ -2453,10 +2454,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
       int k = 0; // Keep the line of a 3rd derivative in v3
       for (const auto & third_derivative : third_derivatives)
         {
-          int eq = third_derivative.first.first;
-          int var1 = third_derivative.first.second.first;
-          int var2 = third_derivative.first.second.second.first;
-          int var3 = third_derivative.first.second.second.second;
+          int eq, var1, var2, var3;
+          tie(eq, var1, var2, var3) = third_derivative.first;
           expr_t d3 = third_derivative.second;
 
           int id1 = getDynJacobianCol(var1);
@@ -4940,8 +4939,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
 
   for (const auto & residuals_params_derivative : residuals_params_derivatives)
     {
-      int eq = residuals_params_derivative.first.first;
-      int param = residuals_params_derivative.first.second;
+      int eq, param;
+      tie(eq, param) = residuals_params_derivative.first;
       expr_t d1 = residuals_params_derivative.second;
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -4954,9 +4953,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
 
   for (const auto & jacobian_params_derivative : jacobian_params_derivatives)
     {
-      int eq = jacobian_params_derivative.first.first;
-      int var = jacobian_params_derivative.first.second.first;
-      int param = jacobian_params_derivative.first.second.second;
+      int eq, var, param;
+      tie(eq, var, param) = jacobian_params_derivative.first;
       expr_t d2 = jacobian_params_derivative.second;
 
       int var_col = getDynJacobianCol(var) + 1;
@@ -4969,13 +4967,11 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
     }
 
   int i = 1;
-  for (auto it = residuals_params_second_derivatives.begin();
-       it != residuals_params_second_derivatives.end(); ++it, i++)
+  for (const auto &it : residuals_params_second_derivatives)
     {
-      int eq = it->first.first;
-      int param1 = it->first.second.first;
-      int param2 = it->first.second.second;
-      expr_t d2 = it->second;
+      int eq, param1, param2;
+      tie(eq, param1, param2) = it.first;
+      expr_t d2 = it.second;
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
       int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
@@ -4990,17 +4986,16 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
                       << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       hessian1_output << ";" << endl;
+
+      i++;
     }
 
   i = 1;
-  for (auto it = jacobian_params_second_derivatives.begin();
-       it != jacobian_params_second_derivatives.end(); ++it, i++)
+  for (const auto &it : jacobian_params_second_derivatives)
     {
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param1 = it->first.second.second.first;
-      int param2 = it->first.second.second.second;
-      expr_t d2 = it->second;
+      int eq, var, param1, param2;
+      tie(eq, var, param1, param2) = it.first;
+      expr_t d2 = it.second;
 
       int var_col = getDynJacobianCol(var) + 1;
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -5018,17 +5013,16 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
                           << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       third_derivs_output << ";" << endl;
+
+      i++;
     }
 
   i = 1;
-  for (auto it = hessian_params_derivatives.begin();
-       it != hessian_params_derivatives.end(); ++it, i++)
+  for (const auto &it : hessian_params_derivatives)
     {
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int param = it->first.second.second.second;
-      expr_t d2 = it->second;
+      int eq, var1, var2, param;
+      tie(eq, var1, var2, param) = it.first;
+      expr_t d2 = it.second;
 
       int var1_col = getDynJacobianCol(var1) + 1;
       int var2_col = getDynJacobianCol(var2) + 1;
@@ -5046,6 +5040,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
                            << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       third_derivs1_output << ";" << endl;
+
+      i++;
     }
 
   string filename = julia ? basename + "DynamicParamsDerivs.jl" : basename + "_params_derivs.m";
@@ -6096,9 +6092,8 @@ DynamicModel::writeSecondDerivativesC_csr(const string &basename, bool cuda) con
   int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
   for (const auto & second_derivative : second_derivatives)
     {
-      int eq = second_derivative.first.first;
-      int var1 = second_derivative.first.second.first;
-      int var2 = second_derivative.first.second.second;
+      int eq, var1, var2;
+      tie(eq, var1, var2) = second_derivative.first;
 
       int id1 = getDynJacobianCol(var1);
       int id2 = getDynJacobianCol(var2);
@@ -6191,10 +6186,8 @@ DynamicModel::writeThirdDerivativesC_csr(const string &basename, bool cuda) cons
   int thirdDerivativesColsNbr = hessianColsNbr*dynJacobianColsNbr;
   for (const auto & third_derivative : third_derivatives)
     {
-      int eq = third_derivative.first.first;
-      int var1 = third_derivative.first.second.first;
-      int var2 = third_derivative.first.second.second.first;
-      int var3 = third_derivative.first.second.second.second;
+      int eq, var1, var2, var3;
+      tie(eq, var1, var2, var3) = third_derivative.first;
 
       int id1 = getDynJacobianCol(var1);
       int id2 = getDynJacobianCol(var2);
@@ -6493,8 +6486,8 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) c
       if (it != first_derivatives.begin())
         jacobian_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second;
+      int eq, var;
+      tie(eq, var) = it->first;
       int col =  getDynJacobianCol(var);
       expr_t d1 = it->second;
 
@@ -6530,9 +6523,8 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) c
       if (it != second_derivatives.begin())
         hessian_output << ", ";
 
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second;
+      int eq, var1, var2;
+      tie(eq, var1, var2) = it->first;
       expr_t d2 = it->second;
       int id1 = getDynJacobianCol(var1);
       int id2 = getDynJacobianCol(var2);
@@ -6576,10 +6568,8 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) c
       if (it != third_derivatives.begin())
         third_derivatives_output << ", ";
 
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int var3 = it->first.second.second.second;
+      int eq, var1, var2, var3;
+      tie(eq, var1, var2, var3) = it->first;
       expr_t d3 = it->second;
 
       if (writeDetails)
@@ -6667,8 +6657,8 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != residuals_params_derivatives.begin())
         jacobian_output << ", ";
 
-      int eq = it->first.first;
-      int param = it->first.second;
+      int eq, param;
+      tie(eq, param) = it->first;
       expr_t d1 = it->second;
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -6699,9 +6689,8 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != jacobian_params_derivatives.begin())
         hessian_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param = it->first.second.second;
+      int eq, var, param;
+      tie(eq, var, param) = it->first;
       expr_t d2 = it->second;
 
       int var_col = getDynJacobianCol(var) + 1;
@@ -6737,9 +6726,8 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != residuals_params_second_derivatives.begin())
         hessian1_output << ", ";
 
-      int eq = it->first.first;
-      int param1 = it->first.second.first;
-      int param2 = it->first.second.second;
+      int eq, param1, param2;
+      tie(eq, param1, param2) = it->first;
       expr_t d2 = it->second;
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -6773,10 +6761,8 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != jacobian_params_second_derivatives.begin())
         third_derivs_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param1 = it->first.second.second.first;
-      int param2 = it->first.second.second.second;
+      int eq, var, param1, param2;
+      tie(eq, var, param1, param2) = it->first;
       expr_t d2 = it->second;
 
       int var_col = getDynJacobianCol(var) + 1;
@@ -6816,10 +6802,8 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != hessian_params_derivatives.begin())
         third_derivs1_output << ", ";
 
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int param = it->first.second.second.second;
+      int eq, var1, var2, param;
+      tie(eq, var1, var2, param) = it->first;
       expr_t d2 = it->second;
 
       int var1_col = getDynJacobianCol(var1) + 1;
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 7783af3b..6afb4c58 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1050,12 +1050,11 @@ ModelTree::computeJacobian(const set<int> &vars)
 void
 ModelTree::computeHessian(const set<int> &vars)
 {
-  for (first_derivatives_t::const_iterator it = first_derivatives.begin();
-       it != first_derivatives.end(); it++)
+  for (const auto &it : first_derivatives)
     {
-      int eq = it->first.first;
-      int var1 = it->first.second;
-      expr_t d1 = it->second;
+      int eq, var1;
+      tie(eq, var1) = it.first;
+      expr_t d1 = it.second;
 
       // Store only second derivatives with var2 <= var1
       for (int var2 : vars)
@@ -1066,7 +1065,7 @@ ModelTree::computeHessian(const set<int> &vars)
           expr_t d2 = d1->getDerivative(var2);
           if (d2 == Zero)
             continue;
-          second_derivatives[{ eq, { var1, var2 } }] = d2;
+          second_derivatives[{ eq, var1, var2 }] = d2;
           if (var2 == var1)
             ++NNZDerivatives[1];
           else
@@ -1078,16 +1077,13 @@ ModelTree::computeHessian(const set<int> &vars)
 void
 ModelTree::computeThirdDerivatives(const set<int> &vars)
 {
-  for (second_derivatives_t::const_iterator it = second_derivatives.begin();
-       it != second_derivatives.end(); it++)
+  for (const auto &it : second_derivatives)
     {
-      int eq = it->first.first;
-
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second;
+      int eq, var1, var2;
+      tie(eq, var1, var2) = it.first;
       // By construction, var2 <= var1
 
-      expr_t d2 = it->second;
+      expr_t d2 = it.second;
 
       // Store only third derivatives such that var3 <= var2 <= var1
       for (int var3 : vars)
@@ -1098,7 +1094,7 @@ ModelTree::computeThirdDerivatives(const set<int> &vars)
           expr_t d3 = d2->getDerivative(var3);
           if (d3 == Zero)
             continue;
-          third_derivatives[{ eq, { var1, { var2, var3 } } }] = d3;
+          third_derivatives[{ eq, var1, var2, var3 }] = d3;
           if (var3 == var2 && var2 == var1)
             ++NNZDerivatives[2];
           else if (var3 == var2 || var2 == var1)
@@ -1843,60 +1839,54 @@ ModelTree::computeParamsDerivatives(int paramsDerivsOrder)
         }
 
       if (paramsDerivsOrder == 2)
-        for (first_derivatives_t::const_iterator it2 = residuals_params_derivatives.begin();
-             it2 != residuals_params_derivatives.end(); it2++)
+        for (const auto &it : residuals_params_derivatives)
           {
-            int eq = it2->first.first;
-            int param1 = it2->first.second;
-            expr_t d1 = it2->second;
+            int eq, param1;
+            tie(eq, param1) = it.first;
+            expr_t d1 = it.second;
 
             expr_t d2 = d1->getDerivative(param);
             if (d2 == Zero)
               continue;
-            residuals_params_second_derivatives[{ eq, { param1, param } }] = d2;
+            residuals_params_second_derivatives[{ eq, param1, param }] = d2;
           }
 
-      for (first_derivatives_t::const_iterator it2 = first_derivatives.begin();
-           it2 != first_derivatives.end(); it2++)
+      for (const auto &it : first_derivatives)
         {
-          int eq = it2->first.first;
-          int var = it2->first.second;
-          expr_t d1 = it2->second;
+          int eq, var;
+          tie(eq, var) = it.first;
+          expr_t d1 = it.second;
 
           expr_t d2 = d1->getDerivative(param);
           if (d2 == Zero)
             continue;
-          jacobian_params_derivatives[{ eq, { var, param } }] = d2;
+          jacobian_params_derivatives[{ eq, var, param }] = d2;
         }
 
       if (paramsDerivsOrder == 2)
         {
-          for (second_derivatives_t::const_iterator it2 = jacobian_params_derivatives.begin();
-               it2 != jacobian_params_derivatives.end(); it2++)
+          for (const auto &it : jacobian_params_derivatives)
             {
-              int eq = it2->first.first;
-              int var = it2->first.second.first;
-              int param1 = it2->first.second.second;
-              expr_t d1 = it2->second;
+              int eq, var, param1;
+              tie(eq, var, param1) = it.first;
+              expr_t d1 = it.second;
 
               expr_t d2 = d1->getDerivative(param);
               if (d2 == Zero)
                 continue;
-              jacobian_params_second_derivatives[{ eq, { var, { param1, param } } }] = d2;
+              jacobian_params_second_derivatives[{ eq, var, param1, param }] = d2;
             }
 
-          for (second_derivatives_t::const_iterator it2 = second_derivatives.begin();
-               it2 != second_derivatives.end(); it2++)
+          for (const auto &it : second_derivatives)
             {
-              int eq = it2->first.first;
-              int var1 = it2->first.second.first;
-              int var2 = it2->first.second.second;
-              expr_t d1 = it2->second;
+              int eq, var1, var2;
+              tie(eq, var1, var2) = it.first;
+              expr_t d1 = it.second;
 
               expr_t d2 = d1->getDerivative(param);
               if (d2 == Zero)
                 continue;
-              hessian_params_derivatives[{ eq, { var1, { var2, param } } }] = d2;
+              hessian_params_derivatives[{ eq, var1, var2, param }] = d2;
             }
         }
     }
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 6b959acb..8f0fc487 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -81,7 +81,7 @@ protected:
   */
   first_derivatives_t first_derivatives;
 
-  using second_derivatives_t = map<pair<int, pair<int, int>>, expr_t>;
+  using second_derivatives_t = map<tuple<int, int, int>, expr_t>;
   //! Second order derivatives
   /*! First index is equation number, second and third are variables w.r. to which is computed the derivative.
     Only non-null derivatives are stored in the map.
@@ -90,7 +90,7 @@ protected:
   */
   second_derivatives_t second_derivatives;
 
-  using third_derivatives_t = map<pair<int, pair<int, pair<int, int>>>, expr_t>;
+  using third_derivatives_t = map<tuple<int, int, int, int>, expr_t>;
   //! Third order derivatives
   /*! First index is equation number, second, third and fourth are variables w.r. to which is computed the derivative.
     Only non-null derivatives are stored in the map.
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 82690507..68836677 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -1376,9 +1376,10 @@ StaticModel::writeStaticModel(const string &basename,
     }
   for (const auto & first_derivative : first_derivatives)
     {
-      int eq = first_derivative.first.first;
-      int symb_id = getSymbIDByDerivID(first_derivative.first.second);
+      int eq, var;
+      tie(eq, var) = first_derivative.first;
       expr_t d1 = first_derivative.second;
+      int symb_id = getSymbIDByDerivID(var);
 
       jacobianHelper(jacobian_output, eq, symbol_table.getTypeSpecificID(symb_id), output_type);
       jacobian_output << "=";
@@ -1400,11 +1401,13 @@ StaticModel::writeStaticModel(const string &basename,
       int k = 0; // Keep the line of a 2nd derivative in v2
       for (const auto & second_derivative : second_derivatives)
         {
-          int eq = second_derivative.first.first;
-          int symb_id1 = getSymbIDByDerivID(second_derivative.first.second.first);
-          int symb_id2 = getSymbIDByDerivID(second_derivative.first.second.second);
+          int eq, var1, var2;
+          tie(eq, var1, var2) = second_derivative.first;
           expr_t d2 = second_derivative.second;
 
+          int symb_id1 = getSymbIDByDerivID(var1);
+          int symb_id2 = getSymbIDByDerivID(var2);
+
           int tsid1 = symbol_table.getTypeSpecificID(symb_id1);
           int tsid2 = symbol_table.getTypeSpecificID(symb_id2);
 
@@ -1469,10 +1472,8 @@ StaticModel::writeStaticModel(const string &basename,
       int k = 0; // Keep the line of a 3rd derivative in v3
       for (const auto & third_derivative : third_derivatives)
         {
-          int eq = third_derivative.first.first;
-          int var1 = third_derivative.first.second.first;
-          int var2 = third_derivative.first.second.second.first;
-          int var3 = third_derivative.first.second.second.second;
+          int eq, var1, var2, var3;
+          tie(eq, var1, var2, var3) = third_derivative.first;
           expr_t d3 = third_derivative.second;
 
           int id1 = getSymbIDByDerivID(var1);
@@ -2506,8 +2507,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
 
   for (const auto & residuals_params_derivative : residuals_params_derivatives)
     {
-      int eq = residuals_params_derivative.first.first;
-      int param = residuals_params_derivative.first.second;
+      int eq, param;
+      tie(eq, param) = residuals_params_derivative.first;
       expr_t d1 = residuals_params_derivative.second;
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -2521,9 +2522,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
 
   for (const auto & jacobian_params_derivative : jacobian_params_derivatives)
     {
-      int eq = jacobian_params_derivative.first.first;
-      int var = jacobian_params_derivative.first.second.first;
-      int param = jacobian_params_derivative.first.second.second;
+      int eq, var, param;
+      tie(eq, var, param) = jacobian_params_derivative.first;
       expr_t d2 = jacobian_params_derivative.second;
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
@@ -2537,13 +2537,11 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
     }
 
   int i = 1;
-  for (auto it = residuals_params_second_derivatives.begin();
-       it != residuals_params_second_derivatives.end(); ++it, i++)
+  for (const auto &it : residuals_params_second_derivatives)
     {
-      int eq = it->first.first;
-      int param1 = it->first.second.first;
-      int param2 = it->first.second.second;
-      expr_t d2 = it->second;
+      int eq, param1, param2;
+      tie(eq, param1, param2) = it.first;
+      expr_t d2 = it.second;
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
       int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
@@ -2558,17 +2556,16 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
                       << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       hessian1_output << ";" << endl;
+
+      i++;
     }
 
   i = 1;
-  for (auto it = jacobian_params_second_derivatives.begin();
-       it != jacobian_params_second_derivatives.end(); ++it, i++)
+  for (const auto &it : jacobian_params_second_derivatives)
     {
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param1 = it->first.second.second.first;
-      int param2 = it->first.second.second.second;
-      expr_t d2 = it->second;
+      int eq, var, param1, param2;
+      tie(eq, var, param1, param2) = it.first;
+      expr_t d2 = it.second;
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -2586,17 +2583,16 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
                           << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       third_derivs_output << ";" << endl;
+
+      i++;
     }
 
   i = 1;
-  for (auto it = hessian_params_derivatives.begin();
-       it != hessian_params_derivatives.end(); ++it, i++)
+  for (const auto &it : hessian_params_derivatives)
     {
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int param = it->first.second.second.second;
-      expr_t d2 = it->second;
+      int eq, var1, var2, param;
+      tie(eq, var1, var2, param) = it.first;
+      expr_t d2 = it.second;
 
       int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1;
       int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1;
@@ -2614,6 +2610,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
                            << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=";
       d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, params_derivs_temporary_terms_idxs, tef_terms);
       third_derivs1_output << ";" << endl;
+
+      i++;
     }
 
   ofstream paramsDerivsFile;
@@ -2766,8 +2764,8 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
       if (it != first_derivatives.begin())
         jacobian_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second;
+      int eq, var;
+      tie(eq, var) = it->first;
       int symb_id = getSymbIDByDerivID(var);
       int col = symbol_table.getTypeSpecificID(symb_id);
       expr_t d1 = it->second;
@@ -2804,9 +2802,10 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
       if (it != second_derivatives.begin())
         hessian_output << ", ";
 
-      int eq = it->first.first;
-      int symb_id1 = getSymbIDByDerivID(it->first.second.first);
-      int symb_id2 = getSymbIDByDerivID(it->first.second.second);
+      int eq, var1, var2;
+      tie(eq, var1, var2) = it->first;
+      int symb_id1 = getSymbIDByDerivID(var1);
+      int symb_id2 = getSymbIDByDerivID(var2);
       expr_t d2 = it->second;
 
       int tsid1 = symbol_table.getTypeSpecificID(symb_id1);
@@ -2850,10 +2849,8 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
       if (it != third_derivatives.begin())
         third_derivatives_output << ", ";
 
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int var3 = it->first.second.second.second;
+      int eq, var1, var2, var3;
+      tie(eq, var1, var2, var3) = it->first;
       expr_t d3 = it->second;
 
       if (writeDetails)
@@ -2938,8 +2935,8 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != residuals_params_derivatives.begin())
         jacobian_output << ", ";
 
-      int eq = it->first.first;
-      int param = it->first.second;
+      int eq, param;
+      tie(eq, param) = it->first;
       expr_t d1 = it->second;
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -2970,9 +2967,8 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != jacobian_params_derivatives.begin())
         hessian_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param = it->first.second.second;
+      int eq, var, param;
+      tie(eq, var, param) = it->first;
       expr_t d2 = it->second;
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
@@ -3006,9 +3002,8 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != residuals_params_second_derivatives.begin())
         hessian1_output << ", ";
 
-      int eq = it->first.first;
-      int param1 = it->first.second.first;
-      int param2 = it->first.second.second;
+      int eq, param1, param2;
+      tie(eq, param1, param2) = it->first;
       expr_t d2 = it->second;
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -3043,10 +3038,8 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != jacobian_params_second_derivatives.begin())
         third_derivs_output << ", ";
 
-      int eq = it->first.first;
-      int var = it->first.second.first;
-      int param1 = it->first.second.second.first;
-      int param2 = it->first.second.second.second;
+      int eq, var, param1, param2;
+      tie(eq, var, param1, param2) = it->first;
       expr_t d2 = it->second;
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
@@ -3084,10 +3077,8 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       if (it != hessian_params_derivatives.begin())
         third_derivs1_output << ", ";
 
-      int eq = it->first.first;
-      int var1 = it->first.second.first;
-      int var2 = it->first.second.second.first;
-      int param = it->first.second.second.second;
+      int eq, var1, var2, param;
+      tie(eq, var1, var2, param) = it->first;
       expr_t d2 = it->second;
 
       int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1;
-- 
GitLab