From d23a684bf64f75bf34e3a2904e3f8d74cb44e9b3 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Wed, 30 Aug 2017 11:32:01 +0200
Subject: [PATCH] preprocessor: add write_latex_steady_steade_model command.
 Closes #1496

---
 ComputingTasks.cc   | 17 +++++++++++++++
 ComputingTasks.hh   | 11 ++++++++++
 DynareBison.yy      |  7 ++++++-
 DynareFlex.ll       |  1 +
 ParsingDriver.cc    |  6 ++++++
 ParsingDriver.hh    |  2 ++
 StaticModel.cc      | 17 +++++++++++++++
 StaticModel.hh      |  1 +
 SteadyStateModel.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++
 SteadyStateModel.hh |  4 +++-
 10 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 400630bb..c3390c27 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -2377,6 +2377,23 @@ WriteLatexOriginalModelStatement::writeJsonOutput(ostream &output) const
   output << "{\"statementName\": \"write_latex_original_model\"}";
 }
 
+WriteLatexSteadyStateModelStatement::WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg) :
+  steady_state_model(steady_state_model_arg)
+{
+}
+
+void
+WriteLatexSteadyStateModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  steady_state_model.writeLatexSteadyStateFile(basename);
+}
+
+void
+WriteLatexSteadyStateModelStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"write_latex_steady_state_model\"}";
+}
+
 ShockDecompositionStatement::ShockDecompositionStatement(const SymbolList &symbol_list_arg,
                                                          const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index 2e5a6970..e371284f 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -27,6 +27,7 @@
 #include "Statement.hh"
 #include "StaticModel.hh"
 #include "DynamicModel.hh"
+#include "SteadyStateModel.hh"
 
 class SteadyStatement : public Statement
 {
@@ -625,6 +626,16 @@ public:
   virtual void writeJsonOutput(ostream &output) const;
 };
 
+class WriteLatexSteadyStateModelStatement : public Statement
+{
+private:
+  const SteadyStateModel &steady_state_model;
+public:
+  WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
+};
+
 class ShockDecompositionStatement : public Statement
 {
 private:
diff --git a/DynareBison.yy b/DynareBison.yy
index 0c1e6f2b..df616c75 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -130,7 +130,7 @@ class ParsingDriver;
 %token <string_val> TEX_NAME
 %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
 %token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
-%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL
+%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL WRITE_LATEX_STEADY_STATE_MODEL
 %token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP QOQ YOY AOA
 %left COMMA
 %left EQUAL_EQUAL EXCLAMATION_EQUAL
@@ -261,6 +261,7 @@ statement : parameters
           | write_latex_dynamic_model
           | write_latex_static_model
           | write_latex_original_model
+          | write_latex_steady_state_model
           | shock_decomposition
           | realtime_shock_decomposition
           | plot_shock_decomposition
@@ -2142,6 +2143,10 @@ write_latex_original_model : WRITE_LATEX_ORIGINAL_MODEL ';'
                             { driver.write_latex_original_model(true); }
                          ;
 
+write_latex_steady_state_model : WRITE_LATEX_STEADY_STATE_MODEL ';'
+                                 { driver.write_latex_steady_state_model(); }
+                               ;
+
 shock_decomposition : SHOCK_DECOMPOSITION ';'
                       {driver.shock_decomposition(); }
                     | SHOCK_DECOMPOSITION '(' shock_decomposition_options_list ')' ';'
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 092d39d9..76e9686c 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -131,6 +131,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
 <INITIAL>write_latex_dynamic_model  {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_DYNAMIC_MODEL;}
 <INITIAL>write_latex_static_model  {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_STATIC_MODEL;}
 <INITIAL>write_latex_original_model  {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_ORIGINAL_MODEL;}
+<INITIAL>write_latex_steady_state_model  {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_STEADY_STATE_MODEL;}
 
 <INITIAL>steady {BEGIN DYNARE_STATEMENT; return token::STEADY;}
 <INITIAL>check {BEGIN DYNARE_STATEMENT; return token::CHECK;}
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index f2615cae..565db4b1 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -1978,6 +1978,12 @@ ParsingDriver::write_latex_original_model(bool write_equation_tags)
   mod_file->addStatement(new WriteLatexOriginalModelStatement(mod_file->original_model, write_equation_tags));
 }
 
+void
+ParsingDriver::write_latex_steady_state_model()
+{
+  mod_file->addStatement(new WriteLatexSteadyStateModelStatement(mod_file->steady_state_model));
+}
+
 void
 ParsingDriver::bvar_density(string *maxnlags)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index 74ee8ff6..2504b808 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -568,6 +568,8 @@ public:
   void write_latex_static_model(bool write_equation_tags);
   //! Adds a write_latex_original_model statement
   void write_latex_original_model(bool write_equation_tags);
+  //! Adds a write_latex_steady_state_model statement
+  void write_latex_steady_state_model();
   //! BVAR marginal density
   void bvar_density(string *maxnlags);
   //! BVAR forecast
diff --git a/StaticModel.cc b/StaticModel.cc
index 97f4f38b..37133f8a 100644
--- a/StaticModel.cc
+++ b/StaticModel.cc
@@ -2173,6 +2173,23 @@ StaticModel::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType
     }
 }
 
+void
+StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  temporary_terms_t temporary_terms;
+  for (int i = 0; i < (int) aux_equations.size(); i++)
+    if (dynamic_cast<ExprNode *>(aux_equations[i])->containsExternalFunction())
+      dynamic_cast<ExprNode *>(aux_equations[i])->writeExternalFunctionOutput(output, oLatexStaticModel,
+                                                                              temporary_terms, tef_terms);
+  for (int i = 0; i < (int) aux_equations.size(); i++)
+    {
+      output << "\\begin{dmath}" << endl;
+      dynamic_cast<ExprNode *>(aux_equations[i]->substituteStaticAuxiliaryDefinition())->writeOutput(output, oLatexStaticModel);
+      output << endl << "\\end{dmath}" << endl;
+    }
+}
+
 void
 StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) const
 {
diff --git a/StaticModel.hh b/StaticModel.hh
index 8c0e9d44..09abf206 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -191,6 +191,7 @@ public:
   //! Writes definition of the auxiliary variables in a .m or .jl file
   void writeSetAuxiliaryVariables(const string &basename, const bool julia) const;
   void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
+  void writeLatexAuxVarRecursiveDefinitions(ostream &output) const;
 
   //! To ensure that no exogenous is present in the planner objective
   //! See #1264
diff --git a/SteadyStateModel.cc b/SteadyStateModel.cc
index 0a6e1536..22792983 100644
--- a/SteadyStateModel.cc
+++ b/SteadyStateModel.cc
@@ -104,6 +104,57 @@ SteadyStateModel::checkPass(bool ramsey_model, WarningConsolidation &warnings) c
     }
 }
 
+void
+SteadyStateModel::writeLatexSteadyStateFile(const string &basename) const
+{
+  ofstream output, content_output;
+  string filename = basename + "_steady_state.tex";
+  string content_basename = basename + "_steady_state_content";
+  string content_filename = content_basename + ".tex";
+
+  output.open(filename.c_str(), ios::out | ios::binary);
+  if (!output.is_open())
+    {
+      cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  content_output.open(content_filename.c_str(), ios::out | ios::binary);
+  if (!content_output.is_open())
+    {
+      cerr << "ERROR: Can't open file " << content_filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  output << "\\documentclass[10pt,a4paper]{article}" << endl
+         << "\\usepackage[landscape]{geometry}" << endl
+         << "\\usepackage{fullpage}" << endl
+         << "\\usepackage{amsfonts}" << endl
+         << "\\usepackage{breqn}" << endl
+         << "\\begin{document}" << endl
+         << "\\footnotesize" << endl;
+
+  for (vector<pair<vector<int>, expr_t> >::const_iterator it = def_table.begin();
+       it != def_table.end(); it++)
+    for (vector<int>::const_iterator it1 = it->first.begin(); it1 != it->first.end(); it1++)
+      {
+        int id = *it1;
+        expr_t value = it->second;
+        content_output << "\\begin{dmath}" << endl
+                       << symbol_table.getTeXName(id) << " = ";
+        value->writeOutput(content_output, oLatexStaticModel);
+        content_output << endl << "\\end{dmath}" << endl;
+      }
+
+  static_model.writeLatexAuxVarRecursiveDefinitions(content_output);
+
+  output << "\\include{" << content_basename << "}" << endl
+         << "\\end{document}" << endl;
+
+  output.close();
+  content_output.close();
+}
+
 void
 SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_model, bool julia) const
 {
diff --git a/SteadyStateModel.hh b/SteadyStateModel.hh
index a7e0a542..f0782bc1 100644
--- a/SteadyStateModel.hh
+++ b/SteadyStateModel.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Dynare Team
+ * Copyright (C) 2010-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -50,6 +50,8 @@ public:
   */
   void writeSteadyStateFile(const string &basename, bool ramsey_model, bool julia) const;
   void writeSteadyStateFileC(const string &basename, bool ramsey_model) const;
+  //! Writes LaTeX file with the equations of the dynamic model (for the steady state model)
+  void writeLatexSteadyStateFile(const string &basename) const;
 };
 
 #endif
-- 
GitLab