preprocessor: fix generate_irfs syntax. closes #1531

issue#70
Houtan Bastani 2017-10-09 11:18:42 +02:00
parent 8c3cafb183
commit badd9069cc
5 changed files with 66 additions and 47 deletions

View File

@ -4490,11 +4490,9 @@ 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) :
const vector<map<string, double> > &generate_irf_elements_arg) :
options_list(options_list_arg),
generate_irf_names(generate_irf_names_arg),
generate_irf_elements(generate_irf_elements_arg)
@ -4507,11 +4505,7 @@ GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool
options_list.writeOutput(output);
if (generate_irf_names.empty())
{
output << "options_.irf_opt.irf_shock_graphtitles = {};" << endl
<< "options_.irf_opt.irf_shocks = [];" << endl;
return;
}
return;
output << "options_.irf_opt.irf_shock_graphtitles = { ";
for (vector<string>::const_iterator it = generate_irf_names.begin();
@ -4519,14 +4513,18 @@ GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool
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;
output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, "
<< generate_irf_names.size() << ");" << endl;
for (size_t i = 0; i < generate_irf_names.size(); i++)
{
map<string, double> m = generate_irf_elements[i];
for (map<string, double>::const_iterator it = m.begin();
it != m.end(); it++)
output << "options_.irf_opt.irf_shocks(M_.exo_names == '"
<< it->first << "', " << i + 1 << ") = "
<< it->second << ";" << endl;
}
}
void
@ -4538,21 +4536,25 @@ GenerateIRFsStatement::writeJsonOutput(ostream &output) const
output << ", ";
options_list.writeJsonOutput(output);
}
if (!generate_irf_elements.empty())
if (!generate_irf_names.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++)
for (size_t i = 0; i < generate_irf_names.size(); i++)
{
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 << "{\"name\": \"" << generate_irf_names[i] << "\", \"shocks\": [";
map<string, double> m = generate_irf_elements[i];
size_t idx = 0;
for (map<string, double>::const_iterator it = m.begin();
it != m.end(); it++, idx++)
{
output << "{\"exogenous_variable\": \"" << it->first << "\", "
<< "\"exogenous_variable_value\": \"" << it->second << "\"}";
if (idx + 1 < m.size())
output << ", ";
}
output << "]}";
if (i + 1 < generate_irf_names.size())
output << ", ";
}
output << "]";

View File

@ -1110,15 +1110,14 @@ public:
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;
const vector<map<string, double> > 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);
const vector<string> &generate_irf_names_arg,
const vector<map<string, double> > &generate_irf_elements_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
};

View File

@ -2847,10 +2847,16 @@ 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); }
generate_irfs_element : NAME COMMA generate_irfs_exog_element_list ';'
{ driver.add_generate_irfs_element($1); }
;
generate_irfs_exog_element_list : generate_irfs_exog_element_list COMMA symbol EQUAL signed_number
{ driver.add_generate_irfs_exog_element($3, $5); }
| symbol EQUAL signed_number
{ driver.add_generate_irfs_exog_element($1, $3); }
;
extended_path : EXTENDED_PATH ';'
{ driver.extended_path(); }
| EXTENDED_PATH '(' extended_path_options_list ')' ';'

View File

@ -584,30 +584,40 @@ 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)
ParsingDriver::add_generate_irfs_element(string *name)
{
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.");
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()))));
generate_irf_elements.push_back(generate_irf_exos);
generate_irf_exos.clear();
delete name;
delete exo1;
delete exo2;
delete value1;
delete value2;
}
void
ParsingDriver::add_generate_irfs_exog_element(string *exo, string *value)
{
check_symbol_is_exogenous(exo);
if (generate_irf_exos.find(*exo) != generate_irf_exos.end())
error("You have set the exogenous variable " + *exo + " twice.");
generate_irf_exos[*exo] = atof(value->c_str());
delete exo;
delete value;
}
void

View File

@ -199,9 +199,10 @@ private:
Ri_TYPE
};
SvarRestrictionType svar_restriction_type;
//! Temporary storage for generate_irf_elements
GenerateIRFsStatement::generate_irf_elements_t generate_irf_elements;
//! Temporary storage for generate_irfs
vector<string> generate_irf_names;
vector<map<string, double> > generate_irf_elements;
map<string, double> generate_irf_exos;
//! Temporary storage for argument list of external function
stack<vector<expr_t> > stack_external_function_args;
//! Temporary storage for parameters in joint prior statement
@ -532,7 +533,8 @@ public:
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);
void add_generate_irfs_element(string *name);
void add_generate_irfs_exog_element(string *exo, string *value);
//! Forecast Statement
void forecast();
void set_trends();