preprocessor: add prior statement

issue#70
Houtan Bastani 2011-12-11 15:35:26 +01:00
parent 1c733dd55f
commit 29d8028fc4
8 changed files with 441 additions and 31 deletions

View File

@ -1499,3 +1499,187 @@ EstimationDataStatement::writeOutput(ostream &output, const string &basename) co
if (options_list.date_options.find("first_obs") == options_list.date_options.end())
output << "options_.dataset.firstobs = options_.initial_period;" << endl;
}
BasicPriorStatement::~BasicPriorStatement()
{
}
BasicPriorStatement::BasicPriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg) :
name(name_arg),
variance(variance_arg),
options_list(options_list_arg),
first_statement_encountered(false)
{
}
void
BasicPriorStatement::checkPass(ModFileStructure &mod_file_struct)
{
if (options_list.num_options.find("shape") == options_list.num_options.end())
{
cerr << "ERROR: You must pass the shape option to the prior statement." << endl;
exit(EXIT_FAILURE);
}
}
void
BasicPriorStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const
{
if (symb_type == eExogenous || symb_type == eExogenousDet)
lhs_field = "structural_innovation";
else
lhs_field = "measurement_error";
}
void
BasicPriorStatement::writePriorIndex(ostream &output, const string &lhs_field) const
{
if (first_statement_encountered)
output << "prior_indx = 1;" << endl;
else
output << "prior_indx = size(estimation_info" << lhs_field << "_index, 2) + 1;" << endl;
}
void
BasicPriorStatement::writeVarianceOption(ostream &output, const string &lhs_field) const
{
if (variance)
{
output << "estimation_info" << lhs_field << "(prior_indx).variance = ";
variance->writeOutput(output);
output << ";" << endl;
}
}
void
BasicPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const
{
OptionsList::num_options_t::const_iterator it = options_list.num_options.find(field);
if (it != options_list.num_options.end())
output << "estimation_info" << lhs_field << "(prior_indx)." << field
<< " = " << it->second << ";" << endl;
}
PriorStatement::PriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg) :
BasicPriorStatement(name_arg, variance_arg, options_list_arg)
{
}
void
PriorStatement::checkPass(ModFileStructure &mod_file_struct)
{
BasicPriorStatement::checkPass(mod_file_struct);
if (!mod_file_struct.prior_statement_present)
first_statement_encountered = true;
mod_file_struct.prior_statement_present = true;
}
void
PriorStatement::writeOutput(ostream &output, const string &basename) const
{
string lhs_field = ".prior";
BasicPriorStatement::writePriorIndex(output, lhs_field);
output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "'};" << endl
<< "estimation_info" << lhs_field <<"(prior_indx).name = '" << name << "';" << endl;
writeOutputHelper(output, "mean", lhs_field);
writeOutputHelper(output, "mode", lhs_field);
writeOutputHelper(output, "stdev", lhs_field);
writeOutputHelper(output, "shape", lhs_field);
writeOutputHelper(output, "shift", lhs_field);
writeOutputHelper(output, "domain", lhs_field);
writeOutputHelper(output, "interval", lhs_field);
BasicPriorStatement::writeVarianceOption(output, lhs_field);
}
StdPriorStatement::StdPriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg,
const SymbolTable &symbol_table_arg ) :
BasicPriorStatement(name_arg, variance_arg, options_list_arg),
symbol_table(symbol_table_arg)
{
}
void
StdPriorStatement::checkPass(ModFileStructure &mod_file_struct)
{
BasicPriorStatement::checkPass(mod_file_struct);
if (!mod_file_struct.std_prior_statement_present)
first_statement_encountered = true;
mod_file_struct.std_prior_statement_present = true;
}
void
StdPriorStatement::writeOutput(ostream &output, const string &basename) const
{
string lhs_field;
get_base_name(symbol_table.getType(name), lhs_field);
lhs_field = "." + lhs_field + ".prior";
BasicPriorStatement::writePriorIndex(output, lhs_field);
output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "'};" << endl;
output << "estimation_info" << lhs_field << "(prior_indx).name = '" << name << "';" << endl;
writeOutputHelper(output, "mean", lhs_field);
writeOutputHelper(output, "mode", lhs_field);
writeOutputHelper(output, "stdev", lhs_field);
writeOutputHelper(output, "shape", lhs_field);
writeOutputHelper(output, "shift", lhs_field);
writeOutputHelper(output, "domain", lhs_field);
writeOutputHelper(output, "interval", lhs_field);
BasicPriorStatement::writeVarianceOption(output, lhs_field);
}
CorrPriorStatement::CorrPriorStatement(const string &name_arg1, const string &name_arg2,
const expr_t &variance_arg,
const OptionsList &options_list_arg,
const SymbolTable &symbol_table_arg ) :
BasicPriorStatement(name_arg1, variance_arg, options_list_arg),
name1(name_arg2),
symbol_table(symbol_table_arg)
{
}
void
CorrPriorStatement::checkPass(ModFileStructure &mod_file_struct)
{
BasicPriorStatement::checkPass(mod_file_struct);
if (symbol_table.getType(name) != symbol_table.getType(name1))
{
cerr << "ERROR: In the corr(A,B).prior statement, A and B must be of the same type. "
<< "In your case, " << name << " and " << name1 << " are of different "
<< "types." << endl;
exit(EXIT_FAILURE);
}
if (!mod_file_struct.corr_prior_statement_present)
first_statement_encountered = true;
mod_file_struct.corr_prior_statement_present = true;
}
void
CorrPriorStatement::writeOutput(ostream &output, const string &basename) const
{
string lhs_field;
get_base_name(symbol_table.getType(name), lhs_field);
lhs_field = "." + lhs_field + "_corr.prior";
BasicPriorStatement::writePriorIndex(output, lhs_field);
output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "_" << name1 << "'};" << endl;
output << "estimation_info" << lhs_field << "(prior_indx).name1 = '" << name << "';" << endl;
output << "estimation_info" << lhs_field << "(prior_indx).name2 = '" << name1 << "';" << endl;
writeOutputHelper(output, "mean", lhs_field);
writeOutputHelper(output, "mode", lhs_field);
writeOutputHelper(output, "stdev", lhs_field);
writeOutputHelper(output, "shape", lhs_field);
writeOutputHelper(output, "shift", lhs_field);
writeOutputHelper(output, "domain", lhs_field);
writeOutputHelper(output, "interval", lhs_field);
BasicPriorStatement::writeVarianceOption(output, lhs_field);
}

View File

@ -575,5 +575,61 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const;
};
class BasicPriorStatement : public Statement
{
public:
virtual ~BasicPriorStatement();
protected:
const string name;
const expr_t variance;
const OptionsList options_list;
bool first_statement_encountered;
BasicPriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct);
void get_base_name(const SymbolType symb_type, string &lhs_field) const;
void writePriorIndex(ostream &output, const string &lhs_field) const;
void writeVarianceOption(ostream &output, const string &lhs_field) const;
void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const;
};
class PriorStatement : public BasicPriorStatement
{
public:
PriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class StdPriorStatement : public BasicPriorStatement
{
private:
const SymbolTable symbol_table;
public:
StdPriorStatement(const string &name_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg,
const SymbolTable &symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class CorrPriorStatement : public BasicPriorStatement
{
private:
const string name1;
const SymbolTable symbol_table;
public:
CorrPriorStatement(const string &name_arg1,
const string &name_arg2,
const expr_t &variance_arg,
const OptionsList &options_list_arg,
const SymbolTable &symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct);
virtual void writeOutput(ostream &output, const string &basename) const;
};
#endif

View File

@ -98,8 +98,8 @@ class ParsingDriver;
%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT
%token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
%token <string_val> FLOAT_NUMBER
%token FORECAST K_ORDER_SOLVER INSTRUMENTS
%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK
%token FORECAST K_ORDER_SOLVER INSTRUMENTS PRIOR SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD
%token HISTVAL HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HP_FILTER HP_NGRID
%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE
%token <string_val> INT_NUMBER
@ -147,7 +147,7 @@ class ParsingDriver;
%token VLISTLOG VLISTPER
%token RESTRICTION RESTRICTIONS RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST
%token NONE DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM
%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM
%token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD
%token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
%token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION
@ -175,9 +175,9 @@ class ParsingDriver;
%type <node_val> expression expression_or_empty
%type <node_val> equation hand_side
%type <string_val> non_negative_number signed_number signed_integer date_number
%type <string_val> filename symbol
%type <string_val> filename symbol prior_distribution
%type <string_val> vec_value_1 vec_value
%type <string_val> range prior
%type <string_val> range prior_pdf_string
%type <symbol_type_val> change_type_arg
%type <vector_string_val> change_type_var_list
%type <vector_int_val> vec_int_elem vec_int_1 vec_int vec_int_number
@ -216,6 +216,7 @@ statement : parameters
| estimated_params_init
| set_time
| data
| prior
| varobs
| observation_trends
| unit_root_vars
@ -1014,18 +1015,18 @@ estimated_elem1 : STDERR symbol
}
;
estimated_elem2 : prior COMMA estimated_elem3
estimated_elem2 : prior_pdf_string COMMA estimated_elem3
{
driver.estim_params.prior = *$1;
delete $1;
}
| expression_or_empty COMMA prior COMMA estimated_elem3
| expression_or_empty COMMA prior_pdf_string COMMA estimated_elem3
{
driver.estim_params.init_val = $1;
driver.estim_params.prior = *$3;
delete $3;
}
| expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA prior COMMA estimated_elem3
| expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA prior_pdf_string COMMA estimated_elem3
{
driver.estim_params.init_val = $1;
driver.estim_params.low_bound = $3;
@ -1144,21 +1145,37 @@ estimated_bounds_elem : STDERR symbol COMMA expression COMMA expression ';'
}
;
prior : BETA_PDF
{ $$ = new string("1"); }
| GAMMA_PDF
{ $$ = new string("2"); }
| NORMAL_PDF
{ $$ = new string("3"); }
| INV_GAMMA_PDF
{ $$ = new string("4"); }
| INV_GAMMA1_PDF
{ $$ = new string("4"); }
| UNIFORM_PDF
{ $$ = new string("5"); }
| INV_GAMMA2_PDF
{ $$ = new string("6"); }
;
prior_distribution : BETA
{ $$ = new string("1"); }
| GAMMA
{ $$ = new string("2"); }
| NORMAL
{ $$ = new string("3"); }
| INV_GAMMA
{ $$ = new string("4"); }
| INV_GAMMA1
{ $$ = new string("4"); }
| UNIFORM
{ $$ = new string("5"); }
| INV_GAMMA2
{ $$ = new string("6"); }
;
prior_pdf_string : BETA_PDF
{ $$ = new string("1"); }
| GAMMA_PDF
{ $$ = new string("2"); }
| NORMAL_PDF
{ $$ = new string("3"); }
| INV_GAMMA_PDF
{ $$ = new string("4"); }
| INV_GAMMA1_PDF
{ $$ = new string("4"); }
| UNIFORM_PDF
{ $$ = new string("5"); }
| INV_GAMMA2_PDF
{ $$ = new string("6"); }
;
set_time : SET_TIME '(' date_number ')' ';'
{ driver.set_time($3); }
@ -1180,6 +1197,28 @@ data_options : o_file
| o_xls_range
;
prior : symbol '.' PRIOR '(' prior_options_list ')' ';'
{ driver.set_prior($1); }
| STD '(' symbol ')' '.' PRIOR '(' prior_options_list ')' ';'
{ driver.set_std_prior($3); }
| CORR '(' symbol COMMA symbol')' '.' PRIOR '(' prior_options_list ')' ';'
{ driver.set_corr_prior($3, $5); }
;
prior_options_list : prior_options_list COMMA prior_options
| prior_options
;
prior_options : o_shift
| o_mean
| o_stdev
| o_variance
| o_mode
| o_interval
| o_shape
| o_domain
;
estimation : ESTIMATION ';'
{ driver.run_estimation(); }
| ESTIMATION '(' estimation_options_list ')' ';'
@ -1898,8 +1937,15 @@ o_new_estimation_data_first_obs : FIRST_OBS EQUAL date_number
o_last_obs : LAST_OBS EQUAL date_number
{ driver.option_date("last_obs", $3); }
;
o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); };
o_shape : SHAPE EQUAL prior_distribution { driver.option_num("shape", $3); };
o_mode : MODE EQUAL signed_number { driver.option_num("mode", $3); };
o_mean : MEAN EQUAL signed_number { driver.option_num("mean", $3); };
o_stdev : STDEV EQUAL non_negative_number { driver.option_num("stdev", $3); };
o_domain : DOMAINN EQUAL vec_value { driver.option_num("domain", $3); };
o_interval : INTERVAL EQUAL vec_value { driver.option_num("interval", $3); };
o_variance : VARIANCE EQUAL expression { driver.add_expression_to_prior_statement($3); }
o_new_estimation_data_nobs : NOBS EQUAL INT_NUMBER { driver.option_num("nobs", $3); };
o_prefilter : PREFILTER EQUAL INT_NUMBER { driver.option_num("prefilter", $3); };
o_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("presample", $3); };
o_lik_algo : LIK_ALGO EQUAL INT_NUMBER { driver.option_num("lik_algo", $3); };
@ -2276,6 +2322,12 @@ symbol : NAME
| CMS
| NCMS
| CNUM
| GAMMA
| INV_GAMMA
| INV_GAMMA1
| INV_GAMMA2
| NORMAL
| UNIFORM
;
%%

View File

@ -189,12 +189,24 @@ string eofbuff;
/* End of a Dynare block */
<DYNARE_BLOCK>end {BEGIN INITIAL; return token::END;}
<DYNARE_STATEMENT>prior {return token::PRIOR;}
<INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;}
<INITIAL>corr {BEGIN DYNARE_STATEMENT; return token::CORR;}
/* Inside of a Dynare statement */
<DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>nobs {return token::NOBS;}
<DYNARE_STATEMENT>last_obs {return token::LAST_OBS;}
<DYNARE_STATEMENT>first_obs {return token::FIRST_OBS;}
<DYNARE_STATEMENT>mean {return token::MEAN;}
<DYNARE_STATEMENT>stdev {return token::STDEV;}
<DYNARE_STATEMENT>domain {return token::DOMAINN;}
<DYNARE_STATEMENT>variance {return token::VARIANCE;}
<DYNARE_STATEMENT>mode {return token::MODE;}
<DYNARE_STATEMENT>interval {return token::INTERVAL;}
<DYNARE_STATEMENT>shape {return token::SHAPE;}
<DYNARE_STATEMENT>shift {return token::SHIFT;}
<DYNARE_STATEMENT>prefilter {return token::PREFILTER;}
<DYNARE_STATEMENT>presample {return token::PRESAMPLE;}
<DYNARE_STATEMENT>lik_algo {return token::LIK_ALGO;}
@ -253,7 +265,6 @@ string eofbuff;
<DYNARE_STATEMENT>nargs {return token::EXT_FUNC_NARGS;}
<DYNARE_STATEMENT>first_deriv_provided {return token::FIRST_DERIV_PROVIDED;}
<DYNARE_STATEMENT>second_deriv_provided {return token::SECOND_DERIV_PROVIDED;}
<DYNARE_STATEMENT>freq {return token::FREQ;}
<DYNARE_STATEMENT>monthly {return token::MONTHLY; }
<DYNARE_STATEMENT>quarterly {return token::QUARTERLY; }
@ -281,6 +292,30 @@ string eofbuff;
yylval->string_val = new string(yytext);
return token::BETA;
}
<DYNARE_STATEMENT>gamma {
yylval->string_val = new string(yytext);
return token::GAMMA;
}
<DYNARE_STATEMENT>inv_gamma {
yylval->string_val = new string(yytext);
return token::INV_GAMMA;
}
<DYNARE_STATEMENT>inv_gamma1 {
yylval->string_val = new string(yytext);
return token::INV_GAMMA1;
}
<DYNARE_STATEMENT>inv_gamma2 {
yylval->string_val = new string(yytext);
return token::INV_GAMMA2;
}
<DYNARE_STATEMENT>normal {
yylval->string_val = new string(yytext);
return token::NORMAL;
}
<DYNARE_STATEMENT>uniform {
yylval->string_val = new string(yytext);
return token::UNIFORM;
}
<DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;}
<DYNARE_STATEMENT>specification {return token::SPECIFICATION;}
<DYNARE_STATEMENT>sims_zha {return token::SIMS_ZHA;}

View File

@ -449,7 +449,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool console,
}
mOutputFile << "tic;" << endl
<< "global M_ oo_ options_ ys0_ ex0_" << endl
<< "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl
<< "options_ = [];" << endl
<< "M_.fname = '" << basename << "';" << endl
<< "%" << endl

View File

@ -46,6 +46,15 @@ ParsingDriver::check_symbol_existence(const string &name)
error("Unknown symbol: " + name);
}
void
ParsingDriver::check_symbol_is_parameter(string *name)
{
check_symbol_existence(*name);
int symb_id = mod_file->symbol_table.getID(*name);
if (mod_file->symbol_table.getType(symb_id) != eParameter)
error(*name + " is not a parameter");
}
void
ParsingDriver::set_current_data_tree(DataTree *data_tree_arg)
{
@ -372,13 +381,9 @@ ParsingDriver::dsample(string *arg1, string *arg2)
void
ParsingDriver::init_param(string *name, expr_t rhs)
{
check_symbol_existence(*name);
check_symbol_is_parameter(name);
int symb_id = mod_file->symbol_table.getID(*name);
if (mod_file->symbol_table.getType(symb_id) != eParameter)
error(*name + " is not a parameter");
mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
delete name;
}
@ -1219,6 +1224,60 @@ ParsingDriver::estimation_data()
options_list.clear();
}
void
ParsingDriver::set_prior(string *name)
{
check_symbol_is_parameter(name);
mod_file->addStatement(new PriorStatement(*name, prior_variance, options_list));
options_list.clear();
prior_variance = NULL;
delete name;
}
void
ParsingDriver::add_expression_to_prior_statement(expr_t variance)
{
prior_variance = variance;
}
void
ParsingDriver::check_symbol_is_endogenous_or_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 eEndogenous:
case eExogenous:
case eExogenousDet:
break;
default:
error(*name + " is neither endogenous or exogenous.");
}
}
void
ParsingDriver::set_std_prior(string *name)
{
check_symbol_is_endogenous_or_exogenous(name);
mod_file->addStatement(new StdPriorStatement(*name, prior_variance, options_list, mod_file->symbol_table));
options_list.clear();
prior_variance = NULL;
delete name;
}
void
ParsingDriver::set_corr_prior(string *name1, string *name2)
{
check_symbol_is_endogenous_or_exogenous(name1);
check_symbol_is_endogenous_or_exogenous(name2);
mod_file->addStatement(new CorrPriorStatement(*name1, *name2, prior_variance, options_list, mod_file->symbol_table));
options_list.clear();
prior_variance = NULL;
delete name1;
delete name2;
}
void
ParsingDriver::run_estimation()
{

View File

@ -81,6 +81,12 @@ private:
//! Checks that a given symbol exists, and stops with an error message if it doesn't
void check_symbol_existence(const string &name);
//! Checks that a given symbol exists and is a parameter, and stops with an error message if it isn't
void check_symbol_is_parameter(string *name);
//! 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);
//! Helper to add a symbol declaration
void declare_symbol(const string *name, SymbolType type, const string *tex_name);
@ -178,6 +184,8 @@ private:
vector<int> declared_trend_vars;
//! Temporary storage for declaring nonstationary variables
vector<int> declared_nonstationary_vars;
//! Temporary storage for a variance declared in the prior statement
expr_t prior_variance;
//! reset the values for temporary storage
void reset_current_external_function_options();
//! Adds a model lagged variable to ModelTree and VariableTable
@ -359,6 +367,16 @@ public:
void set_time(string *arg);
//! Estimation Data
void estimation_data();
//! Sets the prior for a parameter
void set_prior(string *arg);
//! Adds the variance option to its temporary holding place
void add_expression_to_prior_statement(expr_t variance);
//! Sets the prior for estimated std dev
void set_std_prior(string *arg);
//! Sets the prior for estimated correlation
void set_corr_prior(string *arg1, string *arg2);
//! Sets the subsamples for a parameter
void set_subsamples(string *arg);
//! Runs estimation process
void run_estimation();
//! Runs dynare_sensitivy()

View File

@ -88,6 +88,12 @@ public:
bool bayesian_irf_present;
//! Whether there is a data statement present
bool estimation_data_statement_present;
//! Whether there is a prior statement present
bool prior_statement_present;
//! Whether there is a std prior statement present
bool std_prior_statement_present;
//! Whether there is a corr prior statement present
bool corr_prior_statement_present;
};
class Statement