From e2c72a1b753427e1eeec908c4caf681d0f8f62cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Wed, 4 Jan 2023 16:18:53 +0100
Subject: [PATCH] Drop ModelTree::getEquationTags(), and replace it by calls to
 better interfaces

---
 src/DynamicModel.cc | 19 +++++++++++++++++++
 src/DynamicModel.hh | 15 ++++++++-------
 src/ModFile.cc      | 29 +++++------------------------
 src/ModelTree.cc    |  7 +++----
 src/ModelTree.hh    |  7 -------
 5 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 96d78b0f..8c22a5d7 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -4790,3 +4790,22 @@ DynamicModel::checkNoRemainingPacTargetNonstationary() const
         exit(EXIT_FAILURE);
       }
 }
+
+void
+DynamicModel::checkIsLinear() const
+{
+  if (!nonzero_hessian_eqs.empty())
+    {
+      cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl
+           << "       The following equations have non-zero second derivatives:" << endl;
+      for (auto it : nonzero_hessian_eqs)
+        {
+          cerr << "       * Eq # " << it+1;
+          if (optional<string> eqname { equation_tags.getTagValueByEqnAndKey(it, "name") };
+              eqname)
+            cerr << " [" << *eqname << "]";
+          cerr << endl;
+        }
+      exit(EXIT_FAILURE);
+    }
+}
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index fb276f9b..a71b08cc 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2022 Dynare Team
+ * Copyright © 2003-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -372,12 +372,13 @@ public:
   {
     return computed_derivs_order >= 2;
   }
-  //! Returns equations that have non-zero second derivatives
-  set<int>
-  getNonZeroHessianEquations() const
-  {
-    return nonzero_hessian_eqs;
-  }
+
+  /* Check whether the model is linear, by verifying that the hessian is zero,
+     and error out otherwise.
+     Must be called after computingPass().
+     FIXME: this check always passes if derivsOrder = 1, i.e. for a perfect
+     foresight model, because the Hessian is not computed in that case. */
+  void checkIsLinear() const;
 
   //! Fill the trend component model table with information available from the transformed model
   void fillTrendComponentModelTable() const;
diff --git a/src/ModFile.cc b/src/ModFile.cc
index a582b966..326155b2 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006-2022 Dynare Team
+ * Copyright © 2006-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -738,30 +738,11 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
       else // No computing task requested, compute derivatives up to 2nd order by default
         dynamic_model.computingPass(2, 0, global_eval_context, no_tmp_terms, block, use_dll);
 
-      /* Check that the model is linear.
-         FIXME: this check always passes if derivsOrder = 1, i.e. for a perfect
-         foresight model, because the Hessian is not computed in that case. */
       if (linear)
-        {
-          set<int> eqs = mod_file_struct.ramsey_model_present ?
-            orig_ramsey_dynamic_model.getNonZeroHessianEquations() :
-            dynamic_model.getNonZeroHessianEquations();
-
-          if (!eqs.empty())
-            {
-              cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl
-                   << "       The following equations have non-zero second derivatives:" << endl;
-              for (const auto &it : eqs)
-                {
-                  cerr << "       * Eq # " << it+1;
-                  auto tags = dynamic_model.getEquationTags(it);
-                  if (auto it2 = tags.find("name"); it2 != tags.end())
-                    cerr << " [" << it2->second << "]";
-                  cerr << endl;
-                }
-              exit(EXIT_FAILURE);
-            }
-        }
+        if (mod_file_struct.ramsey_model_present)
+          orig_ramsey_dynamic_model.checkIsLinear();
+        else
+          dynamic_model.checkIsLinear();
     }
 
   // Those matrices can only be filled here, because we use derivatives
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 1986485b..ee42a36b 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2022 Dynare Team
+ * Copyright © 2003-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -1418,8 +1418,7 @@ void
 ModelTree::findConstantEquationsWithoutMcpTag(map<VariableNode *, NumConstNode *> &subst_table) const
 {
   for (size_t i = 0; i < equations.size(); i++)
-    if (auto tags = getEquationTags(i);
-        tags.find("mcp") == tags.end())
+    if (!equation_tags.exists(i, "mcp"))
       equations[i]->findConstantEquations(subst_table);
 }
 
@@ -1587,7 +1586,7 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
           if (equations_lineno[eq])
             output << R"(, "line": )" << *equations_lineno[eq];
 
-          if (auto eqtags = getEquationTags(eq);
+          if (auto eqtags = equation_tags.getTagsByEqn(eq);
               !eqtags.empty())
             {
               output << R"(, "tags": {)";
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 3e1533f6..6156a511 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -659,13 +659,6 @@ public:
   // Waits until the MEX compilation queue is empty
   static void waitForMEXCompilationWorkers();
 
-  //! Returns all the equation tags associated to an equation
-  map<string, string>
-  getEquationTags(int eq) const
-  {
-    return equation_tags.getTagsByEqn(eq);
-  }
-
   //! Returns the vector of non-zero derivative counts
   const vector<int> &
   getNNZDerivatives() const
-- 
GitLab