From a87cac34ca9865eece2eaa47ba8668943e1ac0c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien.villemot@ens.fr>
Date: Fri, 8 Jun 2012 17:36:32 +0200
Subject: [PATCH] Preprocessor iface to extended_path

---
 preprocessor/ComputingTasks.cc | 29 ++++++++++++
 preprocessor/ComputingTasks.hh | 10 +++++
 preprocessor/DynareBison.yy    | 20 ++++++++-
 preprocessor/DynareFlex.ll     |  2 +
 preprocessor/ParsingDriver.cc  |  7 +++
 preprocessor/ParsingDriver.hh  |  2 +
 tests/Makefile.am              |  1 +
 tests/ep/rbc2.mod              | 80 ++++++++++++++++++++++++++++++++++
 8 files changed, 149 insertions(+), 2 deletions(-)
 create mode 100644 tests/ep/rbc2.mod

diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc
index 5e18a11295..6714319335 100644
--- a/preprocessor/ComputingTasks.cc
+++ b/preprocessor/ComputingTasks.cc
@@ -2340,3 +2340,32 @@ CalibSmootherStatement::writeOutput(ostream &output, const string &basename) con
          << "options_.order = 1;" << endl
          << "dynare_estimation(var_list_);" << endl;
 }
+
+ExtendedPathStatement::ExtendedPathStatement(const OptionsList &options_list_arg)
+  : options_list(options_list_arg)
+{
+}
+
+void
+ExtendedPathStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  if (options_list.num_options.find("periods") == options_list.num_options.end())
+    {
+      cerr << "ERROR: the 'periods' option of 'extended_path' is mandatory" << endl;
+      exit(EXIT_FAILURE);
+    }
+}
+
+void
+ExtendedPathStatement::writeOutput(ostream &output, const string &basename) const
+{
+  // Beware: options do not have the same name in the interface and in the M code...
+
+  OptionsList::num_options_t::const_iterator it = options_list.num_options.find("solver_periods");
+  if (it != options_list.num_options.end())
+    output << "options_.ep.periods = " << it->second << ";" << endl;
+
+  output << "oo_.endo_simul = [ oo_.steady_state, extended_path([], " << options_list.num_options.find("periods")->second
+         << ") ];" << endl
+         << "oo_.exo_simul = oo_.ep.shocks;" << endl;
+}
diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh
index 0c210ce603..5a75ea55bc 100644
--- a/preprocessor/ComputingTasks.hh
+++ b/preprocessor/ComputingTasks.hh
@@ -519,6 +519,16 @@ public:
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
 
+class ExtendedPathStatement : public Statement
+{
+private:
+  const OptionsList options_list;
+public:
+  ExtendedPathStatement(const OptionsList &options_list_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
 class SvarIdentificationStatement : public Statement
 {
 public:
diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy
index 5ea384959b..e1d2a60412 100644
--- a/preprocessor/DynareBison.yy
+++ b/preprocessor/DynareBison.yy
@@ -97,7 +97,7 @@ class ParsingDriver;
 %token BVAR_REPLIC BYTECODE
 %token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF
 %token DATAFILE FILE DOUBLING DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION
-%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT
+%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH
 %token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
 %token <string_val> FLOAT_NUMBER
 %token DEFAULT FIXED_POINT
@@ -123,7 +123,7 @@ class ParsingDriver;
 %token <string_val> QUOTED_STRING
 %token QZ_CRITERIUM FULL DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT TRUNCATE
 %token RELATIVE_IRF REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY
-%token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO
+%token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS
 %token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME
 %token TEX RAMSEY_POLICY PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
 %token <string_val> TEX_NAME
@@ -269,6 +269,7 @@ statement : parameters
           | ms_irf
           | ms_variance_decomposition
           | calib_smoother
+          | extended_path
           ;
 
 dsample : DSAMPLE INT_NUMBER ';'
@@ -2142,6 +2143,20 @@ calib_smoother_option : o_filtered_vars
                       | o_datafile
                       ;
 
+extended_path : EXTENDED_PATH ';'
+                { driver.extended_path(); }
+              | EXTENDED_PATH '(' extended_path_options_list ')' ';'            
+                { driver.extended_path(); }
+              ;
+
+extended_path_options_list : extended_path_option COMMA extended_path_options_list
+                           | extended_path_option
+                           ;
+
+extended_path_option : o_periods
+                     | o_solver_periods
+                     ;
+
 o_dr_algo : DR_ALGO EQUAL INT_NUMBER {
                                        if (*$3 == string("0"))
                                          driver.warning("dr_algo option is now deprecated, and may be removed in a future version of Dynare");
@@ -2169,6 +2184,7 @@ o_irf_shocks : IRF_SHOCKS EQUAL '(' symbol_list ')' { driver.option_symbol_list(
 o_hp_filter : HP_FILTER EQUAL non_negative_number { driver.option_num("hp_filter", $3); };
 o_hp_ngrid : HP_NGRID EQUAL INT_NUMBER { driver.option_num("hp_ngrid", $3); };
 o_periods : PERIODS EQUAL INT_NUMBER { driver.option_num("periods", $3); };
+o_solver_periods : SOLVER_PERIODS EQUAL INT_NUMBER { driver.option_num("solver_periods", $3); };
 o_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("maxit_", $3); };
 o_cutoff : CUTOFF EQUAL non_negative_number { driver.cutoff($3); };
 o_markowitz : MARKOWITZ EQUAL non_negative_number { driver.option_num("markowitz", $3); };
diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll
index af2af5c0af..43d8d35da1 100644
--- a/preprocessor/DynareFlex.ll
+++ b/preprocessor/DynareFlex.ll
@@ -183,6 +183,7 @@ string eofbuff;
 <INITIAL>homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;}
 <INITIAL>conditional_forecast_paths {BEGIN DYNARE_BLOCK; return token::CONDITIONAL_FORECAST_PATHS;}
 <INITIAL>svar_identification {BEGIN DYNARE_BLOCK; return token::SVAR_IDENTIFICATION;}
+<INITIAL>extended_path {BEGIN DYNARE_BLOCK; return token::EXTENDED_PATH;}
 
  /* For the semicolon after an "end" keyword */
 <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
@@ -463,6 +464,7 @@ string eofbuff;
 <DYNARE_STATEMENT>cova_compute {return token::COVA_COMPUTE;}
 <DYNARE_STATEMENT>discretionary_tol {return token::DISCRETIONARY_TOL;}
 <DYNARE_STATEMENT>analytic_derivation {return token::ANALYTIC_DERIVATION;}
+<DYNARE_STATEMENT>solver_periods {return token::SOLVER_PERIODS;}
 
 <DYNARE_STATEMENT>[\$][^$]*[\$] {
   strtok(yytext+1, "$");
diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc
index 30e474462e..a307855439 100644
--- a/preprocessor/ParsingDriver.cc
+++ b/preprocessor/ParsingDriver.cc
@@ -1940,6 +1940,13 @@ ParsingDriver::calib_smoother()
   options_list.clear();
 }
 
+void
+ParsingDriver::extended_path()
+{
+  mod_file->addStatement(new ExtendedPathStatement(options_list));
+  options_list.clear();
+}
+
 expr_t
 ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2)
 {
diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh
index d3f6107dbf..e6bbeba397 100644
--- a/preprocessor/ParsingDriver.hh
+++ b/preprocessor/ParsingDriver.hh
@@ -516,6 +516,8 @@ public:
   void plot_conditional_forecast(string *periods = NULL);
   //! Smoother on calibrated models
   void calib_smoother();
+  //! Extended path
+  void extended_path();
   //! Writes token "arg1=arg2" to model tree
   expr_t add_model_equal(expr_t arg1, expr_t arg2);
   //! Writes token "arg=0" to model tree
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cdd6945c03..90c6b77365 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -127,6 +127,7 @@ MODFILES = \
 	second_order/ds1.mod \
 	second_order/ds2.mod \
 	ep/rbc.mod \
+	ep/rbc2.mod \
 	ep/rbcii.mod \
 	ep/linear.mod \
 	deterministic_simulations/deterministic_model_purely_forward.mod \
diff --git a/tests/ep/rbc2.mod b/tests/ep/rbc2.mod
new file mode 100644
index 0000000000..6384afadcf
--- /dev/null
+++ b/tests/ep/rbc2.mod
@@ -0,0 +1,80 @@
+// Test preprocessor interface for extended path
+
+var Capital, Output, Labour, Consumption, Efficiency, efficiency, ExpectedTerm;
+
+varexo EfficiencyInnovation;
+
+parameters beta, theta, tau, alpha, psi, delta, rho, effstar, sigma2;
+
+/*
+** Calibration
+*/
+
+
+beta    =  0.990;
+theta   =  0.357;
+tau     =  30.000;
+alpha   =  0.450;
+psi     =  -5.000;
+delta   =  0.020;
+rho     =  0.950;
+effstar =  1.000;
+sigma2  =  0.0001;
+
+external_function(name=mean_preserving_spread,nargs=2);
+
+model(use_dll);
+
+  // Eq. n°1:
+  efficiency = rho*efficiency(-1) + EfficiencyInnovation;
+
+  // Eq. n°2:
+  Efficiency = effstar*exp(efficiency-mean_preserving_spread(rho,sigma2));
+
+  // Eq. n°3:
+  Output = Efficiency*(alpha*(Capital(-1)^psi)+(1-alpha)*(Labour^psi))^(1/psi);
+
+  // Eq. n°4:
+  Consumption + Capital - Output - (1-delta)*Capital(-1);
+
+  // Eq. n°5:
+  ((1-theta)/theta)*(Consumption/(1-Labour)) - (1-alpha)*(Output/Labour)^(1-psi);
+
+  // Eq. n°6:
+  (((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption - ExpectedTerm(1);
+
+  // Eq. n°7:
+  ExpectedTerm = beta*((((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption)*(alpha*((Output/Capital(-1))^(1-psi))+1-delta);
+
+end;
+
+steady_state_model;
+efficiency = 0;
+Efficiency = effstar*exp(efficiency-mean_preserving_spread(rho,sigma2));
+// Compute steady state ratios.
+Output_per_unit_of_Capital=((1/beta-1+delta)/alpha)^(1/(1-psi));
+Consumption_per_unit_of_Capital=Output_per_unit_of_Capital-delta;
+Labour_per_unit_of_Capital=(((Output_per_unit_of_Capital/Efficiency)^psi-alpha)/(1-alpha))^(1/psi);
+Output_per_unit_of_Labour=Output_per_unit_of_Capital/Labour_per_unit_of_Capital;
+Consumption_per_unit_of_Labour=Consumption_per_unit_of_Capital/Labour_per_unit_of_Capital;
+
+// Compute steady state share of capital.
+ShareOfCapital=alpha/(alpha+(1-alpha)*Labour_per_unit_of_Capital^psi);
+
+/// Compute steady state of the endogenous variables.
+Labour=1/(1+Consumption_per_unit_of_Labour/((1-alpha)*theta/(1-theta)*Output_per_unit_of_Labour^(1-psi)));
+Consumption = Consumption_per_unit_of_Labour*Labour;
+Capital = Labour/Labour_per_unit_of_Capital;
+Output = Output_per_unit_of_Capital*Capital;
+ExpectedTerm = beta*((((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption)*(alpha*((Output/Capital)^(1-psi))+1-delta);
+end;
+
+
+shocks;
+var EfficiencyInnovation = sigma2;
+end;
+
+steady;
+
+extended_path(periods=100);
+
-- 
GitLab