* Preprocessor: implemented interface to conditional forecast, with three new statements: "conditional_forecast", "conditional_forecast_paths" and "plot_conditional_forecast"

* Reference manual: created a section on forecasting (with "forecast" option), and added the three new statements to that section


git-svn-id: https://www.dynare.org/svn/dynare/trunk@3049 ac1d8469-bf42-47a9-8791-bf33cf982152
issue#70
sebastien 2009-10-16 17:23:57 +00:00
parent c752ca6122
commit 337bde2589
8 changed files with 231 additions and 11 deletions

View File

@ -1016,4 +1016,27 @@ ShockDecompositionStatement::writeOutput(ostream &output, const string &basename
output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_);\n";
}
ConditionalForecastStatement::ConditionalForecastStatement(const OptionsList &options_list_arg) :
options_list(options_list_arg)
{
}
void
ConditionalForecastStatement::writeOutput(ostream &output, const string &basename) const
{
options_list.writeOutput(output, "options_cond_fcst_");
output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl;
}
PlotConditionalForecastStatement::PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg) :
periods(periods_arg),
symbol_list(symbol_list_arg)
{
}
void
PlotConditionalForecastStatement::writeOutput(ostream &output, const string &basename) const
{
symbol_list.writeOutput("var_list_", output);
output << "plot_icforecast(var_list_);" << endl;
}

View File

@ -470,4 +470,24 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const;
};
class ConditionalForecastStatement : public Statement
{
private:
const OptionsList options_list;
public:
ConditionalForecastStatement(const OptionsList &options_list_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class PlotConditionalForecastStatement : public Statement
{
private:
//! A value of -1 indicates that the length of the constrained path should be used
const int periods;
const SymbolList symbol_list;
public:
PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
#endif

View File

@ -92,7 +92,7 @@ class ParsingDriver;
%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA
%token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN
%token BVAR_REPLIC BYTECODE
%token CALIB CALIB_VAR CHANGE_TYPE CHECK CONF_SIG CONSTANT CORR COVAR CUTOFF
%token CALIB CALIB_VAR CALIBRATION CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF
%token DATAFILE DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE
%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT
%token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS
@ -113,8 +113,8 @@ class ParsingDriver;
%token NAN_CONSTANT NOBS NOCONSTANT NOCORR NODIAGNOSTIC NOFUNCTIONS
%token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF
%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS
%token PARAMETERS PERIODS PLANNER_OBJECTIVE PLOT_PRIORS PREFILTER PRESAMPLE
%token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_ANALYSIS POSTERIOR_ANALYSIS
%token PARAMETERS PARAMETER_SET PERIODS PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE
%token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_ANALYSIS PRIOR_MODE PRIOR_MEAN POSTERIOR_ANALYSIS POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN
%token <string_val> QUOTED_STRING
%token QZ_CRITERIUM
%token RELATIVE_IRF REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE
@ -227,6 +227,9 @@ statement : parameters
| write_latex_dynamic_model
| write_latex_static_model
| shock_decomposition
| conditional_forecast
| conditional_forecast_paths
| plot_conditional_forecast
;
dsample : DSAMPLE INT_NUMBER ';'
@ -565,7 +568,7 @@ shock_list : shock_list shock_elem
;
shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';'
{ driver.add_det_shock($2); }
{ driver.add_det_shock($2, false); }
| VAR symbol ';' STDERR expression ';'
{ driver.add_stderr_shock($2, $5); }
| VAR symbol EQUAL expression ';'
@ -1502,6 +1505,39 @@ number : INT_NUMBER
| FLOAT_NUMBER
;
conditional_forecast : CONDITIONAL_FORECAST '(' conditional_forecast_options ')' ';'
{ driver.conditional_forecast(); }
;
conditional_forecast_options : conditional_forecast_option
| conditional_forecast_options COMMA conditional_forecast_option
;
conditional_forecast_option : o_periods
| o_replic
| o_conf_sig
| o_controlled_varexo
| o_parameter_set
;
plot_conditional_forecast : PLOT_CONDITIONAL_FORECAST symbol_list ';'
{ driver.plot_conditional_forecast(); }
| PLOT_CONDITIONAL_FORECAST '(' PERIODS EQUAL INT_NUMBER ')' symbol_list ';'
{ driver.plot_conditional_forecast($5); }
;
conditional_forecast_paths : CONDITIONAL_FORECAST_PATHS ';' conditional_forecast_paths_shock_list END
{ driver.conditional_forecast_paths(); }
;
conditional_forecast_paths_shock_list : conditional_forecast_paths_shock_elem
| conditional_forecast_paths_shock_list conditional_forecast_paths_shock_elem
;
conditional_forecast_paths_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';'
{ driver.add_det_shock($2, true); }
;
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");
@ -1638,6 +1674,20 @@ o_prior_mc : PRIOR_MC EQUAL INT_NUMBER { driver.option_num("prior_mc", $3); }
o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER {driver.option_num("homotopy_mode",$3); };
o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER {driver.option_num("homotopy_steps",$3); };
o_controlled_varexo : CONTROLLED_VAREXO EQUAL '(' symbol_list ')' { driver.option_symbol_list("controlled_varexo"); };
o_parameter_set : PARAMETER_SET EQUAL PRIOR_MODE
{ driver.option_str("parameter_set", "prior_mode"); }
| PARAMETER_SET EQUAL PRIOR_MEAN
{ driver.option_str("parameter_set", "prior_mean"); }
| PARAMETER_SET EQUAL POSTERIOR_MEAN
{ driver.option_str("parameter_set", "posterior_mean"); }
| PARAMETER_SET EQUAL POSTERIOR_MODE
{ driver.option_str("parameter_set", "posterior_mode"); }
| PARAMETER_SET EQUAL POSTERIOR_MEDIAN
{ driver.option_str("parameter_set", "posterior_median"); }
| PARAMETER_SET EQUAL CALIBRATION
{ driver.option_str("parameter_set", "calibration"); }
;
o_parameters : PARAMETERS EQUAL symbol {driver.option_str("parameters",$3);};
o_shocks : SHOCKS EQUAL '(' list_of_symbol_lists ')' { driver.option_symbol_list("shocks"); };

View File

@ -137,6 +137,8 @@ int sigma_e = 0;
<INITIAL>shock_decomposition {BEGIN DYNARE_STATEMENT; return token::SHOCK_DECOMPOSITION;}
<INITIAL>sbvar {BEGIN DYNARE_STATEMENT; return token::SBVAR;}
<INITIAL>ms_sbvar {BEGIN DYNARE_STATEMENT; return token::MS_SBVAR;}
<INITIAL>conditional_forecast {BEGIN DYNARE_STATEMENT; return token::CONDITIONAL_FORECAST;}
<INITIAL>plot_conditional_forecast {BEGIN DYNARE_STATEMENT; return token::PLOT_CONDITIONAL_FORECAST;}
/* End of a Dynare statement */
<DYNARE_STATEMENT>; {
@ -162,6 +164,7 @@ int sigma_e = 0;
<INITIAL>optim_weights {BEGIN DYNARE_BLOCK; return token::OPTIM_WEIGHTS;}
<INITIAL>calib_var {BEGIN DYNARE_BLOCK; return token::CALIB_VAR;}
<INITIAL>homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;}
<INITIAL>conditional_forecast_paths {BEGIN DYNARE_BLOCK; return token::CONDITIONAL_FORECAST_PATHS;}
/* End of a Dynare block */
<DYNARE_BLOCK>end[ \t\n]*; {BEGIN INITIAL; return token::END;}
@ -323,6 +326,16 @@ int sigma_e = 0;
<DYNARE_STATEMENT>homotopy_mode {return token::HOMOTOPY_MODE; }
<DYNARE_STATEMENT>homotopy_steps {return token::HOMOTOPY_STEPS; }
<DYNARE_STATEMENT>controlled_varexo {return token::CONTROLLED_VAREXO; }
<DYNARE_STATEMENT>parameter_set {return token::PARAMETER_SET; }
<DYNARE_STATEMENT>prior_mode {return token::PRIOR_MODE; }
<DYNARE_STATEMENT>prior_mean {return token::PRIOR_MEAN; }
<DYNARE_STATEMENT>posterior_mode {return token::POSTERIOR_MODE; }
<DYNARE_STATEMENT>posterior_mean {return token::POSTERIOR_MEAN; }
<DYNARE_STATEMENT>posterior_median {return token::POSTERIOR_MEDIAN; }
<DYNARE_STATEMENT>calibration {return token::CALIBRATION; }
<DYNARE_STATEMENT>[\$][^$]*[\$] {
strtok(yytext+1, "$");
yylval->string_val = new string(yytext + 1);

View File

@ -429,18 +429,27 @@ ParsingDriver::end_mshocks()
}
void
ParsingDriver::add_det_shock(string *var)
ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
{
check_symbol_existence(*var);
SymbolType type = mod_file->symbol_table.getType(*var);
if (type != eExogenous && type != eExogenousDet)
error("shocks: shocks can only be applied to exogenous variables");
if (conditional_forecast)
{
if (type != eEndogenous)
error("conditional_forecast_paths: shocks can only be applied to exogenous variables");
}
else
{
if (type != eExogenous && type != eExogenousDet)
error("shocks: shocks can only be applied to exogenous variables");
}
if (det_shocks.find(*var) != det_shocks.end())
error("shocks: variable " + *var + " declared twice");
error("shocks/conditional_forecast_paths: variable " + *var + " declared twice");
if (det_shocks_periods.size() != det_shocks_values.size())
error("shocks: variable " + *var + ": number of periods is different from number of shock values");
error("shocks/conditional_forecast_paths: variable " + *var + ": number of periods is different from number of shock values");
vector<ShocksStatement::DetShockElement> v;
@ -533,6 +542,8 @@ ParsingDriver::add_period(string *p1, string *p2)
{
int p1_val = atoi(p1->c_str());
int p2_val = atoi(p2->c_str());
if (p1_val > p2_val)
error("shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification");
det_shocks_periods.push_back(make_pair(p1_val, p2_val));
delete p1;
delete p2;
@ -1100,6 +1111,35 @@ ParsingDriver::shock_decomposition()
options_list.clear();
}
void
ParsingDriver::conditional_forecast()
{
mod_file->addStatement(new ConditionalForecastStatement(options_list));
options_list.clear();
}
void
ParsingDriver::plot_conditional_forecast(string *periods)
{
int nperiods;
if (periods == NULL)
nperiods = -1;
else
{
nperiods = atoi(periods->c_str());
delete periods;
}
mod_file->addStatement(new PlotConditionalForecastStatement(nperiods, symbol_list));
symbol_list.clear();
}
void
ParsingDriver::conditional_forecast_paths()
{
mod_file->addStatement(new ConditionalForecastPathsStatement(det_shocks, mod_file->symbol_table));
det_shocks.clear();
}
NodeID
ParsingDriver::add_model_equal(NodeID arg1, NodeID arg2)
{

View File

@ -240,8 +240,8 @@ public:
void end_shocks();
//! Writes a mshocks statement
void end_mshocks();
//! Adds a deterministic chock
void add_det_shock(string *var);
//! Adds a deterministic chock or a path element inside a conditional_forecast_paths block
void add_det_shock(string *var, bool conditional_forecast);
//! Adds a std error chock
void add_stderr_shock(string *var, NodeID value);
//! Adds a variance chock
@ -358,6 +358,12 @@ public:
void ms_sbvar();
//! Shock decomposition
void shock_decomposition();
//! Conditional forecast statement
void conditional_forecast();
//! Conditional forecast paths block
void conditional_forecast_paths();
//! Plot conditional forecast statement
void plot_conditional_forecast(string *periods = NULL);
//! Writes token "arg1=arg2" to model tree
NodeID add_model_equal(NodeID arg1, NodeID arg2);
//! Writes token "arg=0" to model tree

View File

@ -19,6 +19,8 @@
using namespace std;
#include <cassert>
#include <cstdlib>
#include <iostream>
#include "Shocks.hh"
@ -185,3 +187,56 @@ MShocksStatement::writeOutput(ostream &output, const string &basename) const
writeVarAndStdShocks(output);
writeCovarAndCorrShocks(output);
}
ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_type &paths_arg, const SymbolTable &symbol_table_arg) :
paths(paths_arg),
symbol_table(symbol_table_arg),
path_length(-1)
{
}
void
ConditionalForecastPathsStatement::checkPass(ModFileStructure &mod_file_struct)
{
for(AbstractShocksStatement::det_shocks_type::const_iterator it = paths.begin();
it != paths.end(); it++)
{
int this_path_length = 0;
const vector<AbstractShocksStatement::DetShockElement> &elems = it->second;
for(int i = 0; i < (int) elems.size(); i++)
// Period1 < Period2, as enforced in ParsingDriver::add_period()
this_path_length = max(this_path_length, elems[i].period2);
if (path_length == -1)
path_length = this_path_length;
else if (path_length != this_path_length)
{
cerr << "conditional_forecast_paths: all constrained paths must have the same length!" << endl;
exit(EXIT_FAILURE);
}
}
}
void
ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &basename) const
{
assert(path_length > 0);
output << "constrained_vars_ = [];" << endl
<< "constrained_paths_ = zeros(" << paths.size() << ", " << path_length << ");" << endl;
int k = 1;
for(AbstractShocksStatement::det_shocks_type::const_iterator it = paths.begin();
it != paths.end(); it++)
{
output << "constrained_vars_ = strvcat(constrained_vars_, '" << it->first << "');" << endl;
const vector<AbstractShocksStatement::DetShockElement> &elems = it->second;
for(int i = 0; i < (int) elems.size(); i++)
for(int j = elems[i].period1; j <= elems[i].period2; j++)
{
output << "constrained_paths_(" << k << "," << j << ")=";
elems[i].value->writeOutput(output);
output << ";" << endl;
}
k++;
}
}

View File

@ -86,4 +86,17 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const;
};
class ConditionalForecastPathsStatement : public Statement
{
private:
const AbstractShocksStatement::det_shocks_type paths;
const SymbolTable &symbol_table;
int path_length;
public:
ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_type &paths_arg,
const SymbolTable &symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct);
virtual void writeOutput(ostream &output, const string &basename) const;
};
#endif