preprocessor: interface for generate_irfs block. Closes #1531

issue#70
Houtan Bastani 2017-10-06 14:49:14 +02:00
parent 51ee883f21
commit 1e40e0a8a1
6 changed files with 174 additions and 4 deletions

View File

@ -4489,3 +4489,73 @@ SMMEstimationStatement::writeJsonOutput(ostream &output) const
}
output << "}";
}
GenerateIRFsStatement::GenerateIRFsStatement(const OptionsList &options_list_arg,
const vector<string> &generate_irf_names_arg,
const generate_irf_elements_t &generate_irf_elements_arg) :
options_list(options_list_arg),
generate_irf_names(generate_irf_names_arg),
generate_irf_elements(generate_irf_elements_arg)
{
}
void
GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
options_list.writeOutput(output);
if (generate_irf_names.empty())
{
output << "options_.irf_opt.irf_shock_graphtitles = {};" << endl
<< "options_.irf_opt.irf_shocks = [];" << endl;
return;
}
output << "options_.irf_opt.irf_shock_graphtitles = { ";
for (vector<string>::const_iterator it = generate_irf_names.begin();
it != generate_irf_names.end(); it++)
output << "'" << *it << "'; ";
output << "};" << endl;
int idx = 1;
output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, " << generate_irf_elements.size() << ");" << endl;
for (generate_irf_elements_t::const_iterator it = generate_irf_elements.begin();
it != generate_irf_elements.end(); it++, idx++)
output << "options_.irf_opt.irf_shocks(M_.exo_names == '" << it->first.first << "', " << idx << ") = "
<< it->first.second << ";" << endl
<< "options_.irf_opt.irf_shocks(M_.exo_names == '" << it->second.first << "', " << idx << ") = "
<< it->second.second << ";" << endl;
}
void
GenerateIRFsStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"generate_irfs\"";
if (options_list.getNumberOfOptions())
{
output << ", ";
options_list.writeJsonOutput(output);
}
if (!generate_irf_elements.empty())
{
size_t n = generate_irf_elements.size();
size_t idx = 1;
output << ", \"irf_elements\": [";
for (generate_irf_elements_t::const_iterator it = generate_irf_elements.begin();
it != generate_irf_elements.end(); it++)
{
output << "{\"name\": \"" << generate_irf_names[idx-1] << "\", "
<< "\"exogenous_variable_1\": \"" << it->first.first << "\", "
<< "\"exogenous_variable_1_value\": \"" << it->first.second << "\", "
<< "\"exogenous_variable_2\": \"" << it->second.first << "\", "
<< "\"exogenous_variable_2_value\": \"" << it->second.second << "\""
<< "}";
if (++idx <= n)
output << ", ";
}
output << "]";
}
output << "}";
}

View File

@ -1107,4 +1107,20 @@ public:
virtual void writeJsonOutput(ostream &output) const;
};
class GenerateIRFsStatement : public Statement
{
public:
typedef vector<pair<pair<string, double>, pair<string, double> > > generate_irf_elements_t;
private:
const OptionsList options_list;
const vector<string> generate_irf_names;
const generate_irf_elements_t generate_irf_elements;
public:
GenerateIRFsStatement(const OptionsList &options_list_arg,
const vector<string> & generate_irf_names_arg,
const generate_irf_elements_t &generate_irf_elements_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
};
#endif

View File

@ -113,9 +113,9 @@ class ParsingDriver;
%token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS
%token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION
%token <string_val> NAME
%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE
%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS
%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY
%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS
%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS STDERR_MULTIPLES DIAGONAL_ONLY
%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE
%token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE
%token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION
@ -276,6 +276,7 @@ statement : parameters
| external_function
| steady_state_model
| trend_var
| generate_irfs
| log_trend_var
| ms_estimation
| ms_simulation
@ -2722,6 +2723,32 @@ calib_smoother_option : o_filtered_vars
| o_parameter_set
;
generate_irfs : GENERATE_IRFS ';' END ';'
{ driver.end_generate_irfs(); }
| GENERATE_IRFS ';' generate_irfs_element_list END ';'
{ driver.end_generate_irfs(); }
| GENERATE_IRFS '(' generate_irfs_options_list ')' ';' END ';'
{ driver.end_generate_irfs(); }
| GENERATE_IRFS '(' generate_irfs_options_list ')' ';' generate_irfs_element_list END ';'
{ driver.end_generate_irfs(); }
;
generate_irfs_options_list : generate_irfs_option COMMA generate_irfs_options_list
| generate_irfs_option
;
generate_irfs_option : o_stderr_multiples
| o_diagonal_only
;
generate_irfs_element_list : generate_irfs_element_list generate_irfs_element
| generate_irfs_element
;
generate_irfs_element : NAME COMMA symbol EQUAL signed_number COMMA symbol EQUAL signed_number ';'
{ driver.add_generate_irfs_element($1, $3, $5, $7, $9); }
;
extended_path : EXTENDED_PATH ';'
{ driver.extended_path(); }
| EXTENDED_PATH '(' extended_path_options_list ')' ';'
@ -3113,7 +3140,8 @@ o_bvar_prior_omega : BVAR_PRIOR_OMEGA EQUAL INT_NUMBER { driver.option_num("bvar
o_bvar_prior_flat : BVAR_PRIOR_FLAT { driver.option_num("bvar_prior_flat", "1"); };
o_bvar_prior_train : BVAR_PRIOR_TRAIN EQUAL INT_NUMBER { driver.option_num("bvar_prior_train", $3); };
o_bvar_replic : BVAR_REPLIC EQUAL INT_NUMBER { driver.option_num("bvar_replic", $3); };
o_stderr_multiples : STDERR_MULTIPLES { driver.option_num("irf_opt.stderr_multiples", "1"); };
o_diagonal_only : DIAGONAL_ONLY { driver.option_num("irf_opt.diagonal_only", "1"); };
o_number_of_particles : NUMBER_OF_PARTICLES EQUAL INT_NUMBER { driver.option_num("particle.number_of_particles", $3); };
o_resampling : RESAMPLING EQUAL SYSTEMATIC
| RESAMPLING EQUAL NONE {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.none", "1"); }

View File

@ -210,6 +210,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>moment_calibration {BEGIN DYNARE_BLOCK; return token::MOMENT_CALIBRATION;}
<INITIAL>irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;}
<INITIAL>ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;}
<INITIAL>generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;}
/* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
@ -707,6 +708,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;}
<DYNARE_STATEMENT>no_homotopy {return token::NO_HOMOTOPY;}
<DYNARE_BLOCK>stderr_multiples {return token::STDERR_MULTIPLES;}
<DYNARE_BLOCK>diagonal_only {return token::DIAGONAL_ONLY;}
<DYNARE_BLOCK>equation {return token::EQUATION;}
<DYNARE_BLOCK>exclusion {return token::EXCLUSION;}
<DYNARE_BLOCK>lag {return token::LAG;}

View File

@ -580,6 +580,36 @@ ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2)
delete name;
}
void
ParsingDriver::end_generate_irfs()
{
mod_file->addStatement(new GenerateIRFsStatement(options_list, generate_irf_names, generate_irf_elements));
generate_irf_elements.clear();
generate_irf_names.clear();
options_list.clear();
}
void
ParsingDriver::add_generate_irfs_element(const string *name, string *exo1, string *value1, string *exo2, string *value2)
{
check_symbol_is_exogenous(exo1);
check_symbol_is_exogenous(exo2);
for (vector<string>::const_iterator it = generate_irf_names.begin();
it != generate_irf_names.end(); it++)
if (*it == *name)
error("Names in the generate_irfs block must be unique but you entered '" + *name + "' more than once.");
generate_irf_names.push_back(*name);
generate_irf_elements.push_back(make_pair(make_pair(*exo1, atof(value1->c_str())),
make_pair(*exo2, atof(value2->c_str()))));
delete name;
delete exo1;
delete exo2;
delete value1;
delete value2;
}
void
ParsingDriver::forecast()
{
@ -1630,6 +1660,21 @@ ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name)
}
}
void
ParsingDriver::check_symbol_is_exogenous(string *name)
{
check_symbol_existence(*name);
int symb_id = mod_file->symbol_table.getID(*name);
switch (mod_file->symbol_table.getType(symb_id))
{
case eExogenous:
case eExogenousDet:
break;
default:
error(*name + " is not exogenous.");
}
}
void
ParsingDriver::set_std_prior(string *name, string *subsample_name)
{

View File

@ -93,6 +93,9 @@ private:
//! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
void check_symbol_is_endogenous_or_exogenous(string *name);
//! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't
void check_symbol_is_exogenous(string *name);
//! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at
//! the end of the model block
void check_symbol_existence_in_model_block(const string &name);
@ -196,7 +199,9 @@ private:
Ri_TYPE
};
SvarRestrictionType svar_restriction_type;
//! Temporary storage for generate_irf_elements
GenerateIRFsStatement::generate_irf_elements_t generate_irf_elements;
vector<string> generate_irf_names;
//! Temporary storage for argument list of external function
stack<vector<expr_t> > stack_external_function_args;
//! Temporary storage for parameters in joint prior statement
@ -525,6 +530,9 @@ public:
void add_lower_cholesky();
//! Svar_Global_Identification_Check Statement
void add_svar_global_identification_check();
//! generate_irfs Block
void end_generate_irfs();
void add_generate_irfs_element(const string *name, string *exo1, string *value1, string *exo2, string *value2);
//! Forecast Statement
void forecast();
void set_trends();