From ca1879fe7dfef081b49f6f2b9fa1e4b73f01ea11 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Tue, 10 May 2016 18:01:00 +0200
Subject: [PATCH] preprocessor: interface for osr_params_bounds. #948

---
 ComputingTasks.cc | 28 ++++++++++++++++++++++++++++
 ComputingTasks.hh | 29 ++++++++++++++++++++++++++++-
 DynareBison.yy    | 21 ++++++++++++++++++++-
 DynareFlex.ll     |  1 +
 ParsingDriver.cc  | 19 +++++++++++++++++++
 ParsingDriver.hh  |  9 +++++++++
 6 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index cffa5862..a9427bbb 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -1057,6 +1057,34 @@ OsrStatement::OsrStatement(const SymbolList &symbol_list_arg,
 {
 }
 
+OsrParamsBoundsStatement::OsrParamsBoundsStatement(const vector<OsrParams> &osr_params_list_arg,
+                                                   const SymbolTable &symbol_table_arg) :
+  osr_params_list(osr_params_list_arg),
+  symbol_table(symbol_table_arg)
+{
+}
+
+void
+OsrParamsBoundsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  int nbnds = osr_params_list.size();
+  output << "M_.osr.param_names = cell(" << nbnds << ", 1);" << endl
+         << "M_.osr.param_indices = zeros(" << nbnds << ", 1);" << endl
+         << "M_.osr.bounds = zeros(" << nbnds << ", 2);" << endl;
+  int i = 1;
+  for (vector<OsrParams>::const_iterator it = osr_params_list.begin();
+       it != osr_params_list.end(); it++, i++)
+    {
+      output << "M_.osr.param_names{" << i << "} = '" << it->name << "';" << endl
+             << "M_.osr.param_indices(" << i <<") = " << symbol_table.getTypeSpecificID(it->name) + 1 << ";" << endl
+             << "M_.osr.bounds(" << i << ", :) = [";
+      it->low_bound->writeOutput(output);
+      output << ", ";
+      it->up_bound->writeOutput(output);
+      output << "];" << endl;
+    }
+}
+
 void
 OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
 {
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index a0fd1202..7698a83f 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2015 Dynare Team
+ * Copyright (C) 2003-2016 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -267,6 +267,33 @@ public:
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
 };
 
+//! Temporary structure used when parsing estimation_params* statements
+class OsrParams
+{
+public:
+  string name;
+  expr_t low_bound, up_bound;
+
+  void
+  init(const DataTree &datatree)
+  {
+    name = "";
+    low_bound = datatree.MinusInfinity;
+    up_bound = datatree.Infinity;
+  }
+};
+
+class OsrParamsBoundsStatement : public Statement
+{
+private:
+  const vector<OsrParams> osr_params_list;
+  const SymbolTable &symbol_table;
+public:
+  OsrParamsBoundsStatement(const vector<OsrParams> &osr_params_list_arg,
+                           const SymbolTable &symbol_table_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+};
+
 class DynaTypeStatement : public Statement
 {
 private:
diff --git a/DynareBison.yy b/DynareBison.yy
index 0c6e7fa8..76311ea6 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -93,7 +93,7 @@ class ParsingDriver;
 %token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED STUDENT_DEGREES_OF_FREEDOM
 %token DATAFILE FILE SERIES DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS
 %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR
-%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
+%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME OSR_PARAMS_BOUNDS
 %token <string_val> FLOAT_NUMBER DATES
 %token DEFAULT FIXED_POINT OPT_ALGO
 %token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
@@ -233,6 +233,7 @@ statement : parameters
           | rplot
           | optim_weights
           | osr_params
+          | osr_params_bounds
           | osr
           | dynatype
           | dynasave
@@ -1356,6 +1357,24 @@ estimated_bounds_elem : STDERR symbol COMMA expression COMMA expression ';'
                         }
                       ;
 
+osr_params_bounds : OSR_PARAMS_BOUNDS ';' osr_bounds_list END ';'
+                    { driver.osr_params_bounds(); };
+
+osr_bounds_list : osr_bounds_list osr_bounds_elem
+                  { driver.add_osr_params_element(); }
+                | osr_bounds_elem
+                  { driver.add_osr_params_element(); }
+                ;
+
+osr_bounds_elem : symbol COMMA expression COMMA expression ';'
+                  {
+                    driver.osr_params.name = *$1;
+                    driver.osr_params.low_bound = $3;
+                    driver.osr_params.up_bound = $5;
+                    delete $1;
+                  }
+                ;
+
 prior_distribution : BETA
                      { $$ = eBeta; }
                    | GAMMA
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 37d88361..18b9b225 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -194,6 +194,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>priors {BEGIN DYNARE_BLOCK;return token::ESTIMATED_PARAMS;}
 <INITIAL>estimated_params_init 		{BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_INIT;}
 <INITIAL>estimated_params_bounds 	{BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_BOUNDS;}
+<INITIAL>osr_params_bounds              {BEGIN DYNARE_BLOCK; return token::OSR_PARAMS_BOUNDS;}
 <INITIAL>observation_trends {BEGIN DYNARE_BLOCK; return token::OBSERVATION_TRENDS;}
 <INITIAL>optim_weights {BEGIN DYNARE_BLOCK; return token::OPTIM_WEIGHTS;}
 <INITIAL>homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;}
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 8a06fd45..467bf114 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -88,6 +88,7 @@ ParsingDriver::parse(istream &in, bool debug)
 
   reset_data_tree();
   estim_params.init(*data_tree);
+  osr_params.init(*data_tree);
   reset_current_external_function_options();
 
   lexer = new DynareFlex(&in);
@@ -1284,6 +1285,24 @@ ParsingDriver::estimated_params_bounds()
   estim_params_list.clear();
 }
 
+void
+ParsingDriver::add_osr_params_element()
+{
+  check_symbol_existence(osr_params.name);
+  SymbolType type = mod_file->symbol_table.getType(osr_params.name);
+  if (type != eParameter)
+    error(osr_params.name + " must be a parameter to be used in the osr_bounds block");
+  osr_params_list.push_back(osr_params);
+  osr_params.init(*data_tree);
+}
+
+void
+ParsingDriver::osr_params_bounds()
+{
+  mod_file->addStatement(new OsrParamsBoundsStatement(osr_params_list, mod_file->symbol_table));
+  osr_params_list.clear();
+}
+
 void
 ParsingDriver::set_unit_root_vars()
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index 32096308..d3ad577c 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -125,6 +125,8 @@ private:
   ModelComparisonStatement::filename_list_t filename_list;
   //! Temporary storage for list of EstimationParams (from estimated_params* statements)
   vector<EstimationParams> estim_params_list;
+  //! Temporary storage for list of OsrParams (from osr_params_block statements)
+  vector<OsrParams> osr_params_list;
   //! Temporary storage of variances from optim_weights
   OptimWeightsStatement::var_weights_t var_weights;
   //! Temporary storage of covariances from optim_weights
@@ -241,6 +243,9 @@ public:
   //! Estimation parameters
   EstimationParams estim_params;
 
+  //! OSR parameters
+  OsrParams osr_params;
+
   //! Temporary storage for the prior shape
   PriorDistributions prior_shape;
 
@@ -414,6 +419,10 @@ public:
   void external_function_option(const string &name_option, const string &opt);
   //! Add a line in an estimated params block
   void add_estimated_params_element();
+  //! Writes osr params bounds command
+  void osr_params_bounds();
+  //! Add a line in an osr params block
+  void add_osr_params_element();
   //! Sets the frequency of the data
   void set_time(string *arg);
   //! Estimation Data
-- 
GitLab