From 221daeab6ffdc18e2ebf026162e92b06ab1c61b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Thu, 1 Jul 2021 17:56:07 +0200
Subject: [PATCH] New time_shift option to var_expectation_model

Ref. dynare#1787
---
 src/ComputingTasks.cc | 6 ++++--
 src/ComputingTasks.hh | 4 +++-
 src/DynareBison.yy    | 4 +++-
 src/DynareFlex.ll     | 1 +
 src/ModFile.cc        | 2 +-
 src/ParsingDriver.cc  | 8 +++++++-
 6 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index a0839c1d..a12702f0 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -4896,10 +4896,11 @@ VarExpectationModelStatement::VarExpectationModelStatement(string model_name_arg
                                                            string aux_model_name_arg,
                                                            string horizon_arg,
                                                            expr_t discount_arg,
+                                                           int time_shift_arg,
                                                            const SymbolTable &symbol_table_arg) :
   model_name{move(model_name_arg)}, expression{expression_arg},
   aux_model_name{move(aux_model_name_arg)}, horizon{move(horizon_arg)},
-  discount{discount_arg}, symbol_table{symbol_table_arg}
+  discount{discount_arg}, time_shift{time_shift_arg}, symbol_table{symbol_table_arg}
 {
 }
 
@@ -4954,7 +4955,8 @@ VarExpectationModelStatement::writeOutput(ostream &output, const string &basenam
 {
   string mstruct = "M_.var_expectation." + model_name;
   output << mstruct << ".auxiliary_model_name = '" << aux_model_name << "';" << endl
-         << mstruct << ".horizon = " << horizon << ';' << endl;
+         << mstruct << ".horizon = " << horizon << ';' << endl
+         << mstruct << ".time_shift = " << time_shift << ';' << endl;
 
   if (!vars_params_constants.size())
     {
diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh
index f507f577..80cec542 100644
--- a/src/ComputingTasks.hh
+++ b/src/ComputingTasks.hh
@@ -1157,6 +1157,7 @@ private:
 public:
   const string aux_model_name, horizon;
   const expr_t discount;
+  const int time_shift;
   const SymbolTable &symbol_table;
   // List of generated auxiliary param ids, in variable-major order
   vector<int> aux_params_ids; // TODO: move this to some new VarModelTable object
@@ -1164,7 +1165,8 @@ private:
   vector<tuple<int, int, double>> vars_params_constants;
 public:
   VarExpectationModelStatement(string model_name_arg, expr_t expression_arg, string aux_model_name_arg,
-                               string horizon_arg, expr_t discount_arg, const SymbolTable &symbol_table_arg);
+                               string horizon_arg, expr_t discount_arg, int time_shift_arg,
+                               const SymbolTable &symbol_table_arg);
   void substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table);
   void substituteDiff(const lag_equivalence_table_t &diff_table, ExprNode::subst_table_t &subst_table);
   // Analyzes the linear combination contained in the 'expression' option
diff --git a/src/DynareBison.yy b/src/DynareBison.yy
index 05f6d59e..78ba1a46 100644
--- a/src/DynareBison.yy
+++ b/src/DynareBison.yy
@@ -166,7 +166,7 @@ class ParsingDriver;
 %token PARAMETER_CONVERGENCE_CRITERION NUMBER_OF_LARGE_PERTURBATIONS NUMBER_OF_SMALL_PERTURBATIONS
 %token NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION MAX_NUMBER_OF_STAGES
 %token RANDOM_FUNCTION_CONVERGENCE_CRITERION RANDOM_PARAMETER_CONVERGENCE_CRITERION NO_INIT_ESTIMATION_CHECK_FIRST_OBS
-%token HETEROSKEDASTIC_FILTER
+%token HETEROSKEDASTIC_FILTER TIME_SHIFT
 /* Method of Moments */
 %token METHOD_OF_MOMENTS MOM_METHOD
 %token BARTLETT_KERNEL_LAG WEIGHTING_MATRIX WEIGHTING_MATRIX_SCALING_FACTOR ANALYTIC_STANDARD_ERRORS ANALYTIC_JACOBIAN PENALIZED_ESTIMATOR VERBOSE 
@@ -449,6 +449,8 @@ var_expectation_model_option : VARIABLE EQUAL symbol
                                { driver.option_str("model_name", $3); }
                              | DISCOUNT EQUAL expression
                                { driver.var_expectation_model_discount = $3; }
+                             | TIME_SHIFT EQUAL signed_integer
+                               { driver.option_num("time_shift", $3); }
                              ;
 
 nonstationary_var_list : nonstationary_var_list symbol
diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll
index 4b553668..4347d994 100644
--- a/src/DynareFlex.ll
+++ b/src/DynareFlex.ll
@@ -814,6 +814,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
 <DYNARE_STATEMENT>coefficients {return token::COEFFICIENTS;}
 <DYNARE_STATEMENT>variances {return token::VARIANCES;}
 <DYNARE_STATEMENT>equations {return token::EQUATIONS;}
+<DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;}
 <DYNARE_STATEMENT>true {
   yylval->build<string>(yytext);
   return token::TRUE;
diff --git a/src/ModFile.cc b/src/ModFile.cc
index 78b6f882..530bc38c 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -590,7 +590,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
 
             subst_expr = dynamic_model.AddPlus(subst_expr,
                                                dynamic_model.AddTimes(dynamic_model.AddVariable(new_param_id),
-                                                                      dynamic_model.AddVariable(variable, -lag)));
+                                                                      dynamic_model.AddVariable(variable, -lag + vems->time_shift)));
           }
 
       if (var_expectation_subst_table.find(model_name) != var_expectation_subst_table.end())
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 3448e2a2..df1ffa58 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -3364,9 +3364,15 @@ ParsingDriver::var_expectation_model()
   else
     var_expectation_model_discount = data_tree->One;
 
+  int time_shift = 0;
+  it = options_list.num_options.find("time_shift");
+  if (it != options_list.num_options.end())
+    time_shift = stoi(it->second);
+
   mod_file->addStatement(make_unique<VarExpectationModelStatement>(model_name, var_expectation_model_expression,
                                                                    var_model_name, horizon,
-                                                                   var_expectation_model_discount, mod_file->symbol_table));
+                                                                   var_expectation_model_discount, time_shift,
+                                                                   mod_file->symbol_table));
 
   options_list.clear();
   var_expectation_model_discount = nullptr;
-- 
GitLab