From a234176d3cc76f10940a87fd26f333782aa1dc64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Wed, 14 Dec 2022 12:35:03 +0100
Subject: [PATCH] Julia: do not rewrite derivatives w.r.t. parameters files
 when unmodified

Closes: #105
---
 src/DynamicModel.hh | 69 +++++++++++++++++++++++----------------------
 src/StaticModel.hh  | 65 ++++++++++++++++++++++--------------------
 2 files changed, 70 insertions(+), 64 deletions(-)

diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index 81cadf95..fb276f9b 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -873,16 +873,15 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const
   auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output]
     { writeParamsDerivativesFileHelper<output_type>() };
 
-  const filesystem::path filename {julia ? filesystem::path{basename} / "model" / "julia" / "DynamicParamsDerivs.jl" : packageDir(basename) / "dynamic_params_derivs.m"};
-  ofstream paramsDerivsFile { filename, ios::out | ios::binary };
-  if (!paramsDerivsFile.is_open())
-    {
-      cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
-      exit(EXIT_FAILURE);
-    }
-
   if constexpr(!julia)
     {
+      filesystem::path filename {packageDir(basename) / "dynamic_params_derivs.m"};
+      ofstream paramsDerivsFile {filename, ios::out | ios::binary};
+      if (!paramsDerivsFile.is_open())
+        {
+          cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
+          exit(EXIT_FAILURE);
+        }
       paramsDerivsFile << "function [rp, gp, rpp, gpp, hp, g3p] = dynamic_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl
                        << "%" << endl
                        << "% Compute the derivatives of the dynamic model with respect to the parameters" << endl
@@ -957,33 +956,37 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const
                        << g3p_output.str()
                        << "end" << endl
                        << "end" << endl;
+      paramsDerivsFile.close();
     }
   else
-    paramsDerivsFile << "# NB: this file was automatically generated by Dynare" << endl
-                     << "#     from " << basename << ".mod" << endl
-                     << "#" << endl
-                     << "function dynamic_params_derivs(y, x, params, steady_state, it_,"
-                     << "ss_param_deriv, ss_param_2nd_deriv)" << endl
-		     << "@inbounds begin" << endl
-                     << tt_output.str()
-                     << "rp = zeros(" << equations.size() << ", "
-                     << symbol_table.param_nbr() << ");" << endl
-                     << rp_output.str()
-                     << "gp = zeros(" << equations.size() << ", " << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl
-                     << gp_output.str()
-                     << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl
-                     << rpp_output.str()
-                     << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl
-                     << gpp_output.str()
-                     << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl
-                     << hp_output.str()
-                     << "g3p = zeros(" << params_derivatives.at({ 3, 1 }).size() << ",6);" << endl
-                     << g3p_output.str()
-		     << "end" << endl
-                     << "return (rp, gp, rpp, gpp, hp, g3p)" << endl
-                     << "end" << endl;
-
-  paramsDerivsFile.close();
+    {
+      stringstream output;
+      output << "# NB: this file was automatically generated by Dynare" << endl
+             << "#     from " << basename << ".mod" << endl
+             << "#" << endl
+             << "function dynamic_params_derivs(y, x, params, steady_state, it_,"
+             << "ss_param_deriv, ss_param_2nd_deriv)" << endl
+             << "@inbounds begin" << endl
+             << tt_output.str()
+             << "rp = zeros(" << equations.size() << ", "
+             << symbol_table.param_nbr() << ");" << endl
+             << rp_output.str()
+             << "gp = zeros(" << equations.size() << ", " << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl
+             << gp_output.str()
+             << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl
+             << rpp_output.str()
+             << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl
+             << gpp_output.str()
+             << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl
+             << hp_output.str()
+             << "g3p = zeros(" << params_derivatives.at({ 3, 1 }).size() << ",6);" << endl
+             << g3p_output.str()
+             << "end" << endl
+             << "return (rp, gp, rpp, gpp, hp, g3p)" << endl
+             << "end" << endl;
+
+      writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "DynamicParamsDerivs.jl");
+    }
 }
 
 #endif
diff --git a/src/StaticModel.hh b/src/StaticModel.hh
index 002ffff2..3d4ebd06 100644
--- a/src/StaticModel.hh
+++ b/src/StaticModel.hh
@@ -231,16 +231,15 @@ StaticModel::writeParamsDerivativesFile(const string &basename) const
     { writeParamsDerivativesFileHelper<output_type>() };
   // g3p_output is ignored
 
-  filesystem::path filename {julia ? filesystem::path{basename} / "model" / "julia" / "StaticParamsDerivs.jl" : packageDir(basename) / "static_params_derivs.m"};
-  ofstream paramsDerivsFile { filename, ios::out | ios::binary };
-  if (!paramsDerivsFile.is_open())
-    {
-      cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
-      exit(EXIT_FAILURE);
-    }
-
   if constexpr(!julia)
     {
+      filesystem::path filename {packageDir(basename) / "static_params_derivs.m"};
+      ofstream paramsDerivsFile {filename, ios::out | ios::binary};
+      if (!paramsDerivsFile.is_open())
+        {
+          cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
+          exit(EXIT_FAILURE);
+        }
       paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = static_params_derivs(y, x, params)" << endl
                        << "%" << endl
                        << "% Status : Computes derivatives of the static model with respect to the parameters" << endl
@@ -292,31 +291,35 @@ StaticModel::writeParamsDerivativesFile(const string &basename) const
                        << hp_output.str()
                        << "end" << endl
                        << "end" << endl;
+      paramsDerivsFile.close();
     }
   else
-    paramsDerivsFile << "# NB: this file was automatically generated by Dynare" << endl
-                     << "#     from " << basename << ".mod" << endl
-                     << "#" << endl
-                     << "function static_params_derivs(y, x, params)" << endl
-		     << "@inbounds begin" << endl
-                     << tt_output.str()
-                     << "rp = zeros(" << equations.size() << ", "
-                     << symbol_table.param_nbr() << ");" << endl
-                     << rp_output.str()
-                     << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", "
-                     << symbol_table.param_nbr() << ");" << endl
-                     << gp_output.str()
-                     << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl
-                     << rpp_output.str()
-                     << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl
-                     << gpp_output.str()
-                     << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl
-                     << hp_output.str()
-		     << "end" << endl
-                     << "return (rp, gp, rpp, gpp, hp)" << endl
-                     << "end" << endl;
-
-  paramsDerivsFile.close();
+    {
+      stringstream output;
+      output << "# NB: this file was automatically generated by Dynare" << endl
+             << "#     from " << basename << ".mod" << endl
+             << "#" << endl
+             << "function static_params_derivs(y, x, params)" << endl
+             << "@inbounds begin" << endl
+             << tt_output.str()
+             << "rp = zeros(" << equations.size() << ", "
+             << symbol_table.param_nbr() << ");" << endl
+             << rp_output.str()
+             << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", "
+             << symbol_table.param_nbr() << ");" << endl
+             << gp_output.str()
+             << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl
+             << rpp_output.str()
+             << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl
+             << gpp_output.str()
+             << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl
+             << hp_output.str()
+             << "end" << endl
+             << "return (rp, gp, rpp, gpp, hp)" << endl
+             << "end" << endl;
+
+      writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "StaticParamsDerivs.jl");
+    }
 }
 
 #endif
-- 
GitLab