Refactor parsing of deterministic shocks

This will simplify the implementation of heteroskedastic_shocks.
issue#70
Sébastien Villemot 2021-05-26 17:00:07 +02:00
parent c35f160e3f
commit e552bfc4b3
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
3 changed files with 71 additions and 65 deletions

View File

@ -199,7 +199,8 @@ class ParsingDriver;
%type <pair<string,string>> named_var_elem subsamples_eq_opt integer_range_w_inf
%type <vector<pair<string,string>>> named_var named_var_1
%type <tuple<string,string,string,string>> prior_eq_opt options_eq_opt
%type <vector<expr_t>> matched_moments_list
%type <vector<pair<int, int>>> period_list
%type <vector<expr_t>> matched_moments_list value_list
%%
%start statement_list;
@ -1038,7 +1039,7 @@ shock_elem : det_shock_elem
;
det_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';'
{ driver.add_det_shock($2, false); }
{ driver.add_det_shock($2, $5, $8, false); }
;
svar_identification : SVAR_IDENTIFICATION {driver.begin_svar_identification();} ';' svar_identification_list END ';'
@ -1137,33 +1138,81 @@ mshock_list : mshock_list det_shock_elem
;
period_list : period_list COMMA INT_NUMBER
{ driver.add_period($3); }
{
$$ = $1;
int p = stoi($3);
$$.push_back({ p, p });
}
| period_list INT_NUMBER
{ driver.add_period($2); }
{
$$ = $1;
int p = stoi($2);
$$.push_back({ p, p });
}
| period_list COMMA INT_NUMBER ':' INT_NUMBER
{ driver.add_period($3, $5); }
{
$$ = $1;
int p1 = stoi($3), p2 = stoi($5);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.push_back({ p1, p2 });
}
| period_list INT_NUMBER ':' INT_NUMBER
{ driver.add_period($2, $4); }
{
$$ = $1;
int p1 = stoi($2), p2 = stoi($4);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.push_back({ p1, p2 });
}
| INT_NUMBER ':' INT_NUMBER
{ driver.add_period($1, $3); }
{
int p1 = stoi($1), p2 = stoi($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$ = { { p1, p2 } };
}
| INT_NUMBER
{ driver.add_period($1); }
{
int p = stoi($1);
$$ = { { p, p } };
}
;
sigma_e : SIGMA_E EQUAL '[' triangular_matrix ']' ';' { driver.do_sigma_e(); };
value_list : value_list COMMA '(' expression ')'
{ driver.add_value($4); }
{
$$ = $1;
$$.push_back($4);
}
| value_list '(' expression ')'
{ driver.add_value($3); }
{
$$ = $1;
$$.push_back($3);
}
| '(' expression ')'
{ driver.add_value($2); }
{ $$ = { $2 }; }
| value_list COMMA signed_number
{ driver.add_value($3); }
{
$$ = $1;
$$.push_back($3.at(0) == '-' ?
driver.add_uminus(driver.add_non_negative_constant($3.substr(1))) :
driver.add_non_negative_constant($3));
}
| value_list signed_number
{ driver.add_value($2); }
{
$$ = $1;
$$.push_back($2.at(0) == '-' ?
driver.add_uminus(driver.add_non_negative_constant($2.substr(1))) :
driver.add_non_negative_constant($2));
}
| signed_number
{ driver.add_value($1); }
{
$$ = { $1.at(0) == '-' ?
driver.add_uminus(driver.add_non_negative_constant($1.substr(1))) :
driver.add_non_negative_constant($1) };
}
;
triangular_matrix : triangular_matrix ';' triangular_row
@ -2898,7 +2947,7 @@ 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); }
{ driver.add_det_shock($2, $5, $8, true); }
;
steady_state_model : STEADY_STATE_MODEL ';' { driver.begin_steady_state_model(); }

View File

@ -810,7 +810,7 @@ ParsingDriver::end_mshocks(bool overwrite)
}
void
ParsingDriver::add_det_shock(const string &var, bool conditional_forecast)
ParsingDriver::add_det_shock(const string &var, const vector<pair<int, int>> &periods, const vector<expr_t> &values, bool conditional_forecast)
{
if (conditional_forecast)
check_symbol_is_endogenous(var);
@ -822,24 +822,21 @@ ParsingDriver::add_det_shock(const string &var, bool conditional_forecast)
if (det_shocks.find(symb_id) != det_shocks.end())
error("shocks/conditional_forecast_paths: variable " + var + " declared twice");
if (det_shocks_periods.size() != det_shocks_values.size())
if (periods.size() != values.size())
error("shocks/conditional_forecast_paths: variable " + var + ": number of periods is different from number of shock values");
vector<ShocksStatement::DetShockElement> v;
for (size_t i = 0; i < det_shocks_periods.size(); i++)
for (size_t i = 0; i < periods.size(); i++)
{
ShocksStatement::DetShockElement dse;
dse.period1 = det_shocks_periods[i].first;
dse.period2 = det_shocks_periods[i].second;
dse.value = det_shocks_values[i];
dse.period1 = periods[i].first;
dse.period2 = periods[i].second;
dse.value = values[i];
v.push_back(dse);
}
det_shocks[symb_id] = v;
det_shocks_periods.clear();
det_shocks_values.clear();
}
void
@ -936,42 +933,6 @@ ParsingDriver::add_correl_shock(const string &var1, const string &var2, expr_t v
corr_shocks[key] = value;
}
void
ParsingDriver::add_period(const string &p1, const string &p2)
{
int p1_val = stoi(p1);
int p2_val = stoi(p2);
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.emplace_back(p1_val, p2_val);
}
void
ParsingDriver::add_period(const string &p1)
{
int p1_val = stoi(p1);
det_shocks_periods.emplace_back(p1_val, p1_val);
}
void
ParsingDriver::add_value(expr_t value)
{
det_shocks_values.push_back(value);
}
void
ParsingDriver::add_value(const string &v)
{
expr_t id;
if (v.at(0) == '-')
id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v.substr(1, string::npos)));
else
id = data_tree->AddNonNegativeConstant(v);
det_shocks_values.push_back(id);
}
void
ParsingDriver::begin_svar_identification()
{

View File

@ -151,10 +151,6 @@ private:
OptimWeightsStatement::covar_weights_t covar_weights;
//! Temporary storage for deterministic shocks
ShocksStatement::det_shocks_t det_shocks;
//! Temporary storage for periods of deterministic shocks
vector<pair<int, int>> det_shocks_periods;
//! Temporary storage for values of deterministic shocks
vector<expr_t> det_shocks_values;
//! Temporary storage for variances of shocks
ShocksStatement::var_and_std_shocks_t var_shocks;
//! Temporary storage for standard errors of shocks
@ -439,7 +435,7 @@ public:
//! Writes a mshocks statement
void end_mshocks(bool overwrite);
//! Adds a deterministic shock or a path element inside a conditional_forecast_paths block
void add_det_shock(const string &var, bool conditional_forecast);
void add_det_shock(const string &var, const vector<pair<int, int>> &periods, const vector<expr_t> &values, bool conditional_forecast);
//! Adds a std error shock
void add_stderr_shock(const string &var, expr_t value);
//! Adds a variance shock