From 82c2682bb2da5ef3ae0358c3de203b6e2469c816 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 20 Dec 2019 11:10:32 +0100
Subject: [PATCH] =?UTF-8?q?New=20=E2=80=9Cwith=5Fepilogue=E2=80=9D=20optio?=
 =?UTF-8?q?n=20of=20=E2=80=9Cshock=5Fdecomposition=E2=80=9D,=20=E2=80=9Cre?=
 =?UTF-8?q?altime=5Fshock=5Fdecomposition=E2=80=9D=20and=20=E2=80=9Cinitia?=
 =?UTF-8?q?l=5Fcondition=5Fdecomposition=E2=80=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Ref. dynare!1688
---
 src/ComputingTasks.cc     | 24 ++++++++++++++++++++++++
 src/ComputingTasks.hh     |  3 +++
 src/DynareBison.yy        |  7 ++++++-
 src/DynareFlex.ll         |  1 +
 src/ModFile.cc            |  2 +-
 src/ModelEquationBlock.cc | 11 +++++++++--
 src/ModelEquationBlock.hh |  4 ++--
 src/Statement.hh          |  3 +++
 8 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 3522f192..e08b60b0 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -2761,6 +2761,14 @@ ShockDecompositionStatement::ShockDecompositionStatement(SymbolList symbol_list_
 {
 }
 
+void
+ShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  if (auto it = options_list.num_options.find("shock_decomp.with_epilogue");
+      it != options_list.num_options.end() && it->second == "true")
+    mod_file_struct.with_epilogue_option = true;
+}
+
 void
 ShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
@@ -2793,6 +2801,14 @@ RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement(SymbolL
 {
 }
 
+void
+RealtimeShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  if (auto it = options_list.num_options.find("shock_decomp.with_epilogue");
+      it != options_list.num_options.end() && it->second == "true")
+    mod_file_struct.with_epilogue_option = true;
+}
+
 void
 RealtimeShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
@@ -2858,6 +2874,14 @@ InitialConditionDecompositionStatement::InitialConditionDecompositionStatement(S
 {
 }
 
+void
+InitialConditionDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  if (auto it = options_list.num_options.find("initial_condition_decomp.with_epilogue");
+      it != options_list.num_options.end() && it->second == "true")
+    mod_file_struct.with_epilogue_option = true;
+}
+
 void
 InitialConditionDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh
index e8e2a7ca..82c77210 100644
--- a/src/ComputingTasks.hh
+++ b/src/ComputingTasks.hh
@@ -720,6 +720,7 @@ private:
 public:
   ShockDecompositionStatement(SymbolList symbol_list_arg,
                               OptionsList options_list_arg);
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
   void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
   void writeJsonOutput(ostream &output) const override;
 };
@@ -732,6 +733,7 @@ private:
 public:
   RealtimeShockDecompositionStatement(SymbolList symbol_list_arg,
                                       OptionsList options_list_arg);
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
   void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
   void writeJsonOutput(ostream &output) const override;
 };
@@ -756,6 +758,7 @@ private:
 public:
   InitialConditionDecompositionStatement(SymbolList symbol_list_arg,
                                          OptionsList options_list_arg);
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
   void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
   void writeJsonOutput(ostream &output) const override;
 };
diff --git a/src/DynareBison.yy b/src/DynareBison.yy
index ad8fd04e..047f81ac 100644
--- a/src/DynareBison.yy
+++ b/src/DynareBison.yy
@@ -169,7 +169,7 @@ class ParsingDriver;
 %token NO_IDENTIFICATION_STRENGTH NO_IDENTIFICATION_REDUCEDFORM NO_IDENTIFICATION_MOMENTS
 %token NO_IDENTIFICATION_MINIMAL NO_IDENTIFICATION_SPECTRUM NORMALIZE_JACOBIANS GRID_NBR
 %token TOL_RANK TOL_DERIV TOL_SV CHECKS_VIA_SUBSETS MAX_DIM_SUBSETS_GROUPS
-%token MAX_NROWS SQUEEZE_SHOCK_DECOMPOSITION
+%token MAX_NROWS SQUEEZE_SHOCK_DECOMPOSITION WITH_EPILOGUE
 
 %token <vector<string>> SYMBOL_VEC
 
@@ -2830,6 +2830,7 @@ shock_decomposition_option : o_parameter_set
                            | o_nobs
                            | o_init_state
 			   | o_forecast_type
+                           | o_shock_decomposition_with_epilogue
                            ;
 
 realtime_shock_decomposition_options_list : realtime_shock_decomposition_option COMMA realtime_shock_decomposition_options_list
@@ -2847,6 +2848,7 @@ realtime_shock_decomposition_option : o_parameter_set
                                     | o_shock_decomposition_forecast
                                     | o_save_realtime
                                     | o_fast_realtime
+                                    | o_shock_decomposition_with_epilogue
                                     ;
 
 plot_shock_decomposition_options_list : plot_shock_decomposition_option COMMA plot_shock_decomposition_options_list
@@ -2892,6 +2894,7 @@ initial_condition_decomposition_option : o_icd_type
                                        | o_icd_flip
                                        | o_icd_colormap
                                        | o_icd_max_nrows
+                                       | o_icd_with_epilogue
                                        ;
 
 homotopy_setup: HOMOTOPY_SETUP ';' homotopy_list END ';'
@@ -3308,6 +3311,8 @@ o_psd_graph_format : GRAPH_FORMAT EQUAL allowed_graph_formats
                    | GRAPH_FORMAT EQUAL '(' list_allowed_graph_formats ')'
                      { driver.plot_shock_decomp_process_graph_format_option(); }
                    ;
+o_shock_decomposition_with_epilogue : WITH_EPILOGUE { driver.option_num("shock_decomp.with_epilogue", "true"); };
+o_icd_with_epilogue : WITH_EPILOGUE { driver.option_num("initial_condition_decomp.with_epilogue", "true"); };
 allowed_graph_formats : EPS
                         { driver.add_graph_format("eps"); }
                       | FIG
diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll
index 005610f9..eb291391 100644
--- a/src/DynareFlex.ll
+++ b/src/DynareFlex.ll
@@ -704,6 +704,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2]))
 <DYNARE_STATEMENT>checks_via_subsets {return token::CHECKS_VIA_SUBSETS;}
 <DYNARE_STATEMENT>max_dim_subsets_groups {return token::MAX_DIM_SUBSETS_GROUPS;}
 <DYNARE_STATEMENT>max_nrows {return token::MAX_NROWS;}
+<DYNARE_STATEMENT>with_epilogue {return token::WITH_EPILOGUE;}
 
 <DYNARE_STATEMENT>\$[^$]*\$ {
   strtok(yytext+1, "$");
diff --git a/src/ModFile.cc b/src/ModFile.cc
index dd43b496..2e26a507 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -114,7 +114,7 @@ ModFile::checkPass(bool nostrict, bool stochastic)
   steady_state_model.checkPass(mod_file_struct, warnings);
 
   // Check epilogue block
-  epilogue.checkPass(warnings);
+  epilogue.checkPass(mod_file_struct, warnings);
 
   if (mod_file_struct.write_latex_steady_state_model_present &&
       !mod_file_struct.steady_state_model_present)
diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc
index c7027bfa..e901b88a 100644
--- a/src/ModelEquationBlock.cc
+++ b/src/ModelEquationBlock.cc
@@ -321,10 +321,17 @@ Epilogue::addDefinition(int symb_id, expr_t expr)
 }
 
 void
-Epilogue::checkPass(WarningConsolidation &warnings) const
+Epilogue::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const
 {
   if (dynamic_def_table.size() == 0)
-    return;
+    {
+      if (mod_file_struct.with_epilogue_option)
+        {
+          cerr << "ERROR: the 'with_epilogue' option cannot be specified when there is no 'epilogue' block" << endl;
+          exit(EXIT_FAILURE);
+        }
+      return;
+    }
 
   vector<int> so_far_defined;
   for (const auto & it : dynamic_def_table)
diff --git a/src/ModelEquationBlock.hh b/src/ModelEquationBlock.hh
index 19871b59..c51a6f2e 100644
--- a/src/ModelEquationBlock.hh
+++ b/src/ModelEquationBlock.hh
@@ -86,8 +86,8 @@ public:
   //! Add an expression of the form "var = expr;"
   void addDefinition(int symb_id, expr_t expr);
 
-  //! Checks that no variable is declared twice
-  void checkPass(WarningConsolidation &warnings) const;
+  //! Checks that no variable is declared twice, and that “with_epilogue” is not misused
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const;
 
   //! Creates static epilogue equations
   void toStatic();
diff --git a/src/Statement.hh b/src/Statement.hh
index b6d6eab3..cf439425 100644
--- a/src/Statement.hh
+++ b/src/Statement.hh
@@ -131,6 +131,9 @@ public:
   set<int> pac_params;
   //! Instruments if ramsey_model, ramsey_policy or discretionary_policy is present
   SymbolList instruments;
+  /* Whether any of shock_decomposition, realtime_shock_decomposition and
+     initial_condition_decomposition has the “with_epilogue” option */
+  bool with_epilogue_option{false};
 };
 
 class Statement
-- 
GitLab