From 8bfcefe7fb4ffd69fe2231255eb401ffe20432bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=B3ra=20Kocsis?= <dora@dynare.org>
Date: Fri, 22 Nov 2019 18:58:31 +0100
Subject: [PATCH] Add interface for forecast_shock_decomposition.
 Dynare/dynare#1657

---
 src/ComputingTasks.cc | 32 ++++++++++++++++++++++++++++++++
 src/ComputingTasks.hh | 12 ++++++++++++
 src/DynareBison.yy    | 33 ++++++++++++++++++++++++++++++++-
 src/DynareFlex.ll     |  1 +
 src/ParsingDriver.cc  |  8 ++++++++
 src/ParsingDriver.hh  |  2 ++
 6 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 7a3f51b0..548e7c88 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -2784,6 +2784,38 @@ ShockDecompositionStatement::writeJsonOutput(ostream &output) const
   output << "}";
 }
 
+ForecastShockDecompositionStatement::ForecastShockDecompositionStatement(SymbolList symbol_list_arg,
+                                                                         OptionsList options_list_arg) :
+  symbol_list{move(symbol_list_arg)},
+  options_list{move(options_list_arg)}
+{
+}
+
+void
+ForecastShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  options_list.writeOutput(output);
+  symbol_list.writeOutput("var_list_", output);
+  output << "oo_ = forecast_shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl;
+}
+
+void
+ForecastShockDecompositionStatement::writeJsonOutput(ostream &output) const
+{
+  output << R"({"statementName": "forecast_shock_decomposition")";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement(SymbolList symbol_list_arg,
                                                                          OptionsList options_list_arg) :
   symbol_list{move(symbol_list_arg)},
diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh
index abfb95ed..5d156e24 100644
--- a/src/ComputingTasks.hh
+++ b/src/ComputingTasks.hh
@@ -717,6 +717,18 @@ public:
   void writeJsonOutput(ostream &output) const override;
 };
 
+class ForecastShockDecompositionStatement : public Statement
+{
+private:
+  const SymbolList symbol_list;
+  const OptionsList options_list;
+public:
+  ForecastShockDecompositionStatement(SymbolList symbol_list_arg,
+                                      OptionsList options_list_arg);
+  void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
+  void writeJsonOutput(ostream &output) const override;
+};
+
 class RealtimeShockDecompositionStatement : public Statement
 {
 private:
diff --git a/src/DynareBison.yy b/src/DynareBison.yy
index f1a24547..c5b4d6da 100644
--- a/src/DynareBison.yy
+++ b/src/DynareBison.yy
@@ -113,7 +113,7 @@ class ParsingDriver;
 %token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY TARGETS
 %token SHOCKS SHOCK_DECOMPOSITION SHOCK_GROUPS USE_SHOCK_GROUPS SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD
 %token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS ROBUST_LIN_SOLVE
-%token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION
+%token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION FORECAST_SHOCK_DECOMPOSITION UNCONDITIONAL CONDITIONAL
 %token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
 %token <string> TEX_NAME
 %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
@@ -269,6 +269,7 @@ statement : parameters
           | write_latex_original_model
           | write_latex_steady_state_model
           | shock_decomposition
+          | forecast_shock_decomposition
           | realtime_shock_decomposition
           | plot_shock_decomposition
           | initial_condition_decomposition
@@ -2396,6 +2397,16 @@ shock_decomposition : SHOCK_DECOMPOSITION ';'
                       { driver.shock_decomposition(); }
                     ;
 
+forecast_shock_decomposition : FORECAST_SHOCK_DECOMPOSITION ';'
+                               {driver.forecast_shock_decomposition(); }
+                             | FORECAST_SHOCK_DECOMPOSITION '(' forecast_shock_decomposition_options_list ')' ';'
+                               { driver.forecast_shock_decomposition(); }
+                             | FORECAST_SHOCK_DECOMPOSITION symbol_list ';'
+                               { driver.forecast_shock_decomposition(); }
+                             | FORECAST_SHOCK_DECOMPOSITION '(' forecast_shock_decomposition_options_list ')' symbol_list ';'
+                               { driver.forecast_shock_decomposition(); }
+                             ;
+
 realtime_shock_decomposition : REALTIME_SHOCK_DECOMPOSITION ';'
                                {driver.realtime_shock_decomposition(); }
                              | REALTIME_SHOCK_DECOMPOSITION '(' realtime_shock_decomposition_options_list ')' ';'
@@ -2795,6 +2806,21 @@ shock_decomposition_option : o_parameter_set
                            | o_init_state
                            ;
 
+forecast_shock_decomposition_options_list : forecast_shock_decomposition_option COMMA forecast_shock_decomposition_options_list
+                                          | forecast_shock_decomposition_option
+                                          ;
+
+forecast_shock_decomposition_option : o_parameter_set
+                                    | o_datafile
+                                    | o_use_shock_groups
+                                    | o_colormap
+                                    | o_shock_decomposition_nograph
+                                    | o_first_obs
+                                    | o_nobs
+                                    | o_init_state
+                                    | o_fsd_type
+                                    ;
+
 realtime_shock_decomposition_options_list : realtime_shock_decomposition_option COMMA realtime_shock_decomposition_options_list
                                          | realtime_shock_decomposition_option
                                          ;
@@ -3220,6 +3246,11 @@ o_posterior_nograph : POSTERIOR_NOGRAPH
           ;
 o_shock_decomposition_nograph : NOGRAPH { driver.option_num("no_graph.shock_decomposition", "true"); }
 o_init_state : INIT_STATE EQUAL INT_NUMBER { driver.option_num("shock_decomp.init_state", $3); };
+o_fsd_type : TYPE EQUAL UNCONDITIONAL
+             { driver.option_str("forecast_shock_decomp.type", "unconditional"); }
+           | TYPE EQUAL CONDITIONAL
+             { driver.option_str("forecast_shock_decomp.type", "conditional"); }
+           ;
 o_shock_decomposition_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("shock_decomp.presample", $3); };
 o_shock_decomposition_forecast : FORECAST EQUAL INT_NUMBER { driver.option_num("shock_decomp.forecast", $3); };
 o_save_realtime : SAVE_REALTIME EQUAL vec_int { driver.option_vec_int("shock_decomp.save_realtime", $3); };
diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll
index b24d6a2f..9292d35f 100644
--- a/src/DynareFlex.ll
+++ b/src/DynareFlex.ll
@@ -158,6 +158,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]))
 <INITIAL>histval_file {BEGIN DYNARE_STATEMENT; return token::HISTVAL_FILE;}
 <INITIAL>forecast {BEGIN DYNARE_STATEMENT; return token::FORECAST;}
 <INITIAL>shock_decomposition {BEGIN DYNARE_STATEMENT; return token::SHOCK_DECOMPOSITION;}
+<INITIAL>forecast_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::FORECAST_SHOCK_DECOMPOSITION;}
 <INITIAL>realtime_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::REALTIME_SHOCK_DECOMPOSITION;}
 <INITIAL>plot_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::PLOT_SHOCK_DECOMPOSITION;}
 <INITIAL>initial_condition_decomposition {BEGIN DYNARE_STATEMENT; return token::INITIAL_CONDITION_DECOMPOSITION;}
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 0aea25ad..5dc29472 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -2348,6 +2348,14 @@ ParsingDriver::shock_decomposition()
   options_list.clear();
 }
 
+void
+ParsingDriver::forecast_shock_decomposition()
+{
+  mod_file->addStatement(make_unique<ForecastShockDecompositionStatement>(symbol_list, options_list));
+  symbol_list.clear();
+  options_list.clear();
+}
+
 void
 ParsingDriver::realtime_shock_decomposition()
 {
diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh
index c944dc2c..172e3a5c 100644
--- a/src/ParsingDriver.hh
+++ b/src/ParsingDriver.hh
@@ -682,6 +682,8 @@ public:
   void markov_switching();
   //! Shock decomposition
   void shock_decomposition();
+  //! Forecast Shock decomposition
+  void forecast_shock_decomposition();
   //! Realtime Shock decomposition
   void realtime_shock_decomposition();
   //! Plot Shock decomposition
-- 
GitLab