diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 4a0fac8392e9e18f080eecdf410230108754156d..5e8c9b63f81f02ef83b81e38ff7092b7a82c29bc 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -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 << "]"; diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 9d16f3063ba357d9e3363b88eab03c710e1bac8a..195475d0087b618b717caa7cb47cc8da32765779 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -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; }; diff --git a/DynareBison.yy b/DynareBison.yy index 9c9fe8f5e7c859b96b653dedd05e796ae8b06b97..dac5db110310885f792c4732c02289bfa8b43d45 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -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 ')' ';' diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 79d07572f563d7a44246f7badb7b61a30cd4fdd9..93f763be0265be0e711ffc3970d5b979fe846606 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -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 diff --git a/ParsingDriver.hh b/ParsingDriver.hh index b136e21c2d686f10f3bdcf463f21f776d65500ff..4386bbcdf463af2a2d7383d9c08d0fef4a10e862 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -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();