From 746f88eb6eb321e76b8dac8de4764c0a049c4823 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 2 Mar 2017 18:34:18 +0100 Subject: [PATCH] preprocessor: create two different static and dynamic files with the option jsonprintderivdetail. #1387 --- ComputingTasks.cc | 2 +- DynamicModel.cc | 216 +++++++++++++++++++++++++++++++--------------- DynamicModel.hh | 4 +- DynareMain.cc | 9 +- DynareMain2.cc | 4 +- ModFile.cc | 138 +++++++++++++++++------------ ModFile.hh | 6 +- StaticModel.cc | 189 +++++++++++++++++++++++++++++----------- StaticModel.hh | 4 +- 9 files changed, 388 insertions(+), 184 deletions(-) diff --git a/ComputingTasks.cc b/ComputingTasks.cc index bc9aa02a..7eccf256 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -1866,7 +1866,7 @@ PlannerObjectiveStatement::writeJsonOutput(ostream &output) const output << "{\"statementName\": \"planner_objective\"" << ", "; if (computing_pass_called) - model_tree->writeJsonComputingPassOutput(output); + model_tree->writeJsonComputingPassOutput(output, false); else model_tree->writeJsonOutput(output); diff --git a/DynamicModel.cc b/DynamicModel.cc index 213ead14..10db3a8b 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -5345,7 +5345,7 @@ DynamicModel::writeJsonOutput(ostream &output) const } void -DynamicModel::writeJsonComputingPassOutput(ostream &output) const +DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const { ostringstream model_local_vars_output; // Used for storing model local vars ostringstream model_output; // Used for storing model temp vars and equations @@ -5383,13 +5383,17 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output) const jacobian_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(getSymbIDByDerivID(it->first.second)); - int lag = getLagByDerivID(it->first.second); + int var = it->first.second; + int col = getDynJacobianCol(var); expr_t d1 = it->second; - jacobian_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" - << ", \"lag\": " << lag + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"lag\": " << getLagByDerivID(var); + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"col\": " << col + 1 << ", \"val\": \""; d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); jacobian_output << "\"}" << endl; @@ -5412,17 +5416,27 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output) const hessian_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - int lag1 = getLagByDerivID(it->first.second.first); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); - int lag2 = getLagByDerivID(it->first.second.second); + int var1 = it->first.second.first; + int var2 = it->first.second.second; expr_t d2 = it->second; + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); + int col_nb = id1 * dynJacobianColsNbr + id2; + int col_nb_sym = id2 * dynJacobianColsNbr + id1; - hessian_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"lag1\": " << lag1 - << ", \"var2\": \"" << var2 << "\"" - << ", \"lag2\": " << lag2 + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2); + else + hessian_output << "{\"row\": " << eq + 1; + + hessian_output << ", \"col\": [" << col_nb + 1; + if (id1 != id2) + hessian_output << ", " << col_nb_sym + 1; + hessian_output << "]" << ", \"val\": \""; d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); hessian_output << "\"}" << endl; @@ -5445,29 +5459,52 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output) const third_derivatives_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - int lag1 = getLagByDerivID(it->first.second.first); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - int lag2 = getLagByDerivID(it->first.second.second.first); - string var3 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); - int lag3 = getLagByDerivID(it->first.second.second.second); + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int var3 = it->first.second.second.second; expr_t d3 = it->second; - third_derivatives_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"lag1\": " << lag1 - << ", \"var2\": \"" << var2 << "\"" - << ", \"lag2\": " << lag2 - << ", \"var3\": \"" << var3 << "\"" - << ", \"lag3\": " << lag3 + if (writeDetails) + third_derivatives_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2) + << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\"" + << ", \"lag3\": " << getLagByDerivID(var3); + else + third_derivatives_output << "{\"row\": " << eq + 1; + + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); + int id3 = getDynJacobianCol(var3); + set cols; + cols.insert(id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3); + cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); + cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); + cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); + cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); + cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); + + third_derivatives_output << ", \"col\": ["; + for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) + { + if (it2 != cols.begin()) + third_derivatives_output << ", "; + third_derivatives_output << *it2 + 1; + } + third_derivatives_output << "]" << ", \"val\": \""; d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); third_derivatives_output << "\"}" << endl; } third_derivatives_output << "]}"; - output << "\"dynamic_model_derivatives\": {" - << model_local_vars_output.str() + if (writeDetails) + output << "\"dynamic_model_derivative_details\": {"; + else + output << "\"dynamic_model_derivatives\": {"; + output << model_local_vars_output.str() << ", " << model_output.str() << ", " << jacobian_output.str() << ", " << hessian_output.str() @@ -5476,7 +5513,7 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output) const } void -DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const +DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const { if (!residuals_params_derivatives.size() && !residuals_params_second_derivatives.size() @@ -5510,11 +5547,17 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const jacobian_output << ", "; int eq = it->first.first; - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second)); + int param = it->first.second; expr_t d1 = it->second; - jacobian_output << "{\"eq\": " << eq + 1 - << ", \"param\": \"" << param << "\"" + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"param_col\": " << param_col + 1 << ", \"val\": \""; d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); jacobian_output << "\"}" << endl; @@ -5532,15 +5575,22 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const hessian_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - int lag = getLagByDerivID(it->first.second.first); - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); + int var = it->first.second.first; + int param = it->first.second.second; expr_t d2 = it->second; - hessian_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" - << ", \"lag\": " << lag - << ", \"param\": \"" << param << "\"" + int var_col = getDynJacobianCol(var) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"lag\": " << getLagByDerivID(var) + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + hessian_output << ", \"var_col\": " << var_col + 1 + << ", \"param_col\": " << param_col + 1 << ", \"val\": \""; d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); hessian_output << "\"}" << endl; @@ -5559,14 +5609,22 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const hessian1_output << ", "; int eq = it->first.first; - string param1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string param2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); + int param1 = it->first.second.first; + int param2 = it->first.second.second; expr_t d2 = it->second; - hessian1_output << "{\"eq\": " << eq + 1 - << ", \"param1\": \"" << param1 << "\"" - << ", \"param2\": \"" << param2 << "\"" - << ", \"val\": \""; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + hessian1_output << "{\"eq\": " << eq + 1 + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + hessian1_output << "{\"row\": " << eq + 1; + hessian1_output << ", \"param1_col\": " << param1_col + 1 + << ", \"param2_col\": " << param2_col + 1 + << ", \"val\": \""; d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); hessian1_output << "\"}" << endl; } @@ -5584,17 +5642,26 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const third_derivs_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(it->first.second.first); - int lag = getLagByDerivID(it->first.second.first); - string param1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - string param2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); + int var = it->first.second.first; + int param1 = it->first.second.second.first; + int param2 = it->first.second.second.second; expr_t d2 = it->second; - third_derivs_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" - << ", \"lag\": " << lag - << ", \"param1\": \"" << param1 << "\"" - << ", \"param2\": \"" << param2 << "\"" + int var_col = getDynJacobianCol(var) + 1; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + third_derivs_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(var) << "\"" + << ", \"lag\": " << getLagByDerivID(var) + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + third_derivs_output << "{\"row\": " << eq + 1; + third_derivs_output << ", \"var_col\": " << var_col + 1 + << ", \"param1_col\": " << param1_col + 1 + << ", \"param2_col\": " << param2_col + 1 << ", \"val\": \""; d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); third_derivs_output << "\"}" << endl; @@ -5614,27 +5681,38 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const third_derivs1_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - int lag1 = getLagByDerivID(it->first.second.first); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - int lag2 = getLagByDerivID(it->first.second.second.first); - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int param = it->first.second.second.second; expr_t d2 = it->second; - third_derivs1_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"lag1\": " << lag1 - << ", \"var2\": \"" << var2 << "\"" - << ", \"lag2\": " << lag2 - << ", \"param1\": \"" << param << "\"" + int var1_col = getDynJacobianCol(var1) + 1; + int var2_col = getDynJacobianCol(var2) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + third_derivs1_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2) + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + third_derivs1_output << "{\"row\": " << eq + 1; + third_derivs1_output << ", \"var1_col\": " << var1_col + 1 + << ", \"var2_col\": " << var2_col + 1 + << ", \"param_col\": " << param_col + 1 << ", \"val\": \""; d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); third_derivs1_output << "\"}" << endl; } third_derivs1_output << "]}" << endl; - output << "\"dynamic_model_params_derivatives\": {" - << model_local_vars_output.str() + if (writeDetails) + output << "\"dynamic_model_params_derivative_details\": {"; + else + output << "\"dynamic_model_params_derivatives\": {"; + output << model_local_vars_output.str() << ", " << model_output.str() << ", " << jacobian_output.str() << ", " << hessian_output.str() diff --git a/DynamicModel.hh b/DynamicModel.hh index 87e41e38..b0828a2b 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -221,10 +221,10 @@ public: void writeJsonOutput(ostream &output) const; //! Write JSON Output representation of dynamic model after computing pass - void writeJsonComputingPassOutput(ostream &output) const; + void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; //! Write JSON prams derivatives file - void writeJsonParamsDerivativesFile(ostream &output) const; + void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; //! Return true if the hessian is equal to zero inline bool checkHessianZero() const; diff --git a/DynareMain.cc b/DynareMain.cc index 3aa0aa3f..03c74ec6 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -45,7 +45,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) , bool cygwin, bool msvc, bool mingw #endif - , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson + , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail ); void main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file, @@ -62,7 +62,7 @@ usage() #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) << " [cygwin] [msvc] [mingw]" #endif - << "[json=parse|check|transform|compute] [jsonstdout] [onlyjson]" + << "[json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonprintderivdetail]" << endl; exit(EXIT_FAILURE); } @@ -118,6 +118,7 @@ main(int argc, char **argv) JsonOutputPointType json = nojson; JsonFileOutputType json_output_mode = file; bool onlyjson = false; + bool jsonprintderivdetail = false; LanguageOutputType language = matlab; // Parse options @@ -300,6 +301,8 @@ main(int argc, char **argv) json_output_mode = standardout; else if (!strcmp(argv[arg], "onlyjson")) onlyjson = true; + else if (!strcmp(argv[arg], "jsonprintderivdetail")) + jsonprintderivdetail = true; else if (strlen(argv[arg]) >= 4 && !strncmp(argv[arg], "json", 4)) { if (strlen(argv[arg]) <= 5 || argv[arg][4] != '=') @@ -367,7 +370,7 @@ main(int argc, char **argv) #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) , cygwin, msvc, mingw #endif - , json, json_output_mode, onlyjson + , json, json_output_mode, onlyjson, jsonprintderivdetail ); return EXIT_SUCCESS; diff --git a/DynareMain2.cc b/DynareMain2.cc index 5139cd3d..c3a24936 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -34,7 +34,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) , bool cygwin, bool msvc, bool mingw #endif - , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson + , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail ) { ParsingDriver p(warnings, nostrict); @@ -60,7 +60,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear // Do computations mod_file->computingPass(no_tmp_terms, output_mode, compute_xrefs, params_derivs_order); if (json == computingpass) - mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); + mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonprintderivdetail); // Write outputs if (output_mode != none) diff --git a/ModFile.cc b/ModFile.cc index 32cb70bf..7ee204ad 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -1248,7 +1248,7 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) } void -ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson) +ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail) { if (json == nojson) return; @@ -1262,7 +1262,7 @@ ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonF symbol_table.unfreeze(); if (json == computingpass) - writeJsonComputingPassOutput(basename, json_output_mode); + writeJsonComputingPassOutput(basename, json_output_mode, jsonprintderivdetail); switch (json) { @@ -1340,40 +1340,78 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType } void -ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode) const +ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonprintderivdetail) const { - ostringstream static_output; + ostringstream static_output, static_detail_output; static_output << "{"; - static_model.writeJsonComputingPassOutput(static_output); + static_model.writeJsonComputingPassOutput(static_output, false); static_output << "}" << endl; - ostringstream dynamic_output; + ostringstream dynamic_output, dynamic_detail_output; dynamic_output << "{"; - dynamic_model.writeJsonComputingPassOutput(dynamic_output); + dynamic_model.writeJsonComputingPassOutput(dynamic_output, false); dynamic_output << "}" << endl; - ostringstream tmp_out, static_paramsd_output; + ostringstream tmp_out, static_paramsd_output, static_paramsd_detail_output; tmp_out << ""; static_paramsd_output << ""; - static_model.writeJsonParamsDerivativesFile(tmp_out); + static_paramsd_detail_output << ""; + static_model.writeJsonParamsDerivativesFile(tmp_out, false); if (!tmp_out.str().empty()) static_paramsd_output << "{" << tmp_out.str() << "}" << endl; - ostringstream tmp1_out, dynamic_paramsd_output; + ostringstream tmp1_out, dynamic_paramsd_output, dynamic_paramsd_detail_output; tmp1_out << ""; dynamic_paramsd_output << ""; - dynamic_model.writeJsonParamsDerivativesFile(tmp1_out); + dynamic_paramsd_detail_output << ""; + dynamic_model.writeJsonParamsDerivativesFile(tmp1_out, false); if (!tmp1_out.str().empty()) dynamic_paramsd_output << "{" << tmp1_out.str() << "}" << endl; + if (jsonprintderivdetail) + { + static_detail_output << "{"; + static_model.writeJsonComputingPassOutput(static_detail_output, true); + static_detail_output << "}"; + + dynamic_detail_output << "{"; + dynamic_model.writeJsonComputingPassOutput(dynamic_detail_output, true); + dynamic_detail_output << "}"; + + ostringstream tmpd_out, tmpd1_out; + tmpd_out << ""; + tmpd1_out << ""; + static_model.writeJsonParamsDerivativesFile(tmpd_out, true); + if (!tmpd_out.str().empty()) + static_paramsd_detail_output << "{" << tmpd_out.str() << "}" << endl; + + dynamic_model.writeJsonParamsDerivativesFile(tmpd1_out, true); + if (!tmpd1_out.str().empty()) + dynamic_paramsd_detail_output << "{" << tmpd1_out.str() << "}" << endl; + } + if (json_output_mode == standardout) { - cout << static_output.str() << endl; - cout << dynamic_output.str() << endl; - if (!dynamic_paramsd_output.str().empty()) - cout << dynamic_paramsd_output.str() << endl; + cout << static_output.str() << endl + << dynamic_output.str() << endl; + if (!static_paramsd_output.str().empty()) cout << static_paramsd_output.str() << endl; + + if (!dynamic_paramsd_output.str().empty()) + cout << dynamic_paramsd_output.str() << endl; + + if (jsonprintderivdetail) + { + cout << static_detail_output.str() << endl + << dynamic_detail_output.str() << endl; + + if (!static_paramsd_detail_output.str().empty()) + cout << static_paramsd_detail_output.str() << endl; + + if (!dynamic_paramsd_detail_output.str().empty()) + cout << dynamic_paramsd_detail_output.str() << endl; + } } else { @@ -1387,56 +1425,50 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType fname_static = basename + "_static.json"; fname_dynamic = basename + "_dynamic.json"; - ofstream jsonOutputFileStatic, jsonOutputFileDynamic; - jsonOutputFileStatic.open(fname_static.c_str(), ios::out | ios::binary); - if (!jsonOutputFileStatic.is_open()) - { - cerr << "ERROR: Can't open file " << fname_static << " for writing" << endl; - exit(EXIT_FAILURE); - } + writeJsonFileHelper(fname_static, static_output); + writeJsonFileHelper(fname_dynamic, dynamic_output); - jsonOutputFileDynamic.open(fname_dynamic.c_str(), ios::out | ios::binary); - if (!jsonOutputFileDynamic.is_open()) + if (jsonprintderivdetail) { - cerr << "ERROR: Can't open file " << fname_dynamic << " for writing" << endl; - exit(EXIT_FAILURE); - } + string fname_static_details, fname_dynamic_details; + fname_static_details = basename + "_static_details.json"; + fname_dynamic_details = basename + "_dynamic_details.json"; - jsonOutputFileStatic << static_output.str(); - jsonOutputFileStatic.close(); - jsonOutputFileDynamic << dynamic_output.str(); - jsonOutputFileDynamic.close(); + writeJsonFileHelper(fname_static_details, static_detail_output); + writeJsonFileHelper(fname_dynamic_details, dynamic_detail_output); + } if (!static_paramsd_output.str().empty()) { - string fname_static_params; + string fname_static_params, fname_static_params_details; fname_static_params = basename + "_static_params_derivs.json"; - ofstream jsonOutputFileStaticParamsDerivs; - jsonOutputFileStaticParamsDerivs.open(fname_static_params.c_str(), ios::out | ios::binary); - if (!jsonOutputFileStaticParamsDerivs.is_open()) - { - cerr << "ERROR: Can't open file " << fname_static_params << " for writing" << endl; - exit(EXIT_FAILURE); - } - - jsonOutputFileStaticParamsDerivs << static_paramsd_output.str(); - jsonOutputFileStaticParamsDerivs.close(); + fname_static_params_details = basename + "_static_params_derivs_details.json"; + writeJsonFileHelper(fname_static_params, static_paramsd_output); + writeJsonFileHelper(fname_static_params_details, static_paramsd_detail_output); } if (!dynamic_paramsd_output.str().empty()) { - string fname_dynamic_params; + string fname_dynamic_params, fname_dynamic_params_details; fname_dynamic_params = basename + "_params_derivs.json"; - ofstream jsonOutputFileDynamicParamsDerivs; - jsonOutputFileDynamicParamsDerivs.open(fname_dynamic_params.c_str(), ios::out | ios::binary); - if (!jsonOutputFileDynamicParamsDerivs.is_open()) - { - cerr << "ERROR: Can't open file " << fname_dynamic_params << " for writing" << endl; - exit(EXIT_FAILURE); - } - - jsonOutputFileDynamicParamsDerivs << dynamic_paramsd_output.str(); - jsonOutputFileDynamicParamsDerivs.close(); + fname_dynamic_params_details = basename + "_params_derivs_details.json"; + writeJsonFileHelper(fname_dynamic_params, dynamic_paramsd_output); + writeJsonFileHelper(fname_dynamic_params_details, dynamic_paramsd_detail_output); } } } + +void +ModFile::writeJsonFileHelper(string &fname, ostringstream &output) const +{ + ofstream jsonOutput; + jsonOutput.open(fname.c_str(), ios::out | ios::binary); + if (!jsonOutput.is_open()) + { + cerr << "ERROR: Can't open file " << fname << " for writing" << endl; + exit(EXIT_FAILURE); + } + jsonOutput << output.str(); + jsonOutput.close(); + +} diff --git a/ModFile.hh b/ModFile.hh index 385e97b6..c04f4de5 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -119,8 +119,8 @@ private: WarningConsolidation &warnings; //! Functions used in writing of JSON outut. See writeJsonOutput void writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode) const; - void writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode) const; - + void writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonprintderivdetail) const; + void writeJsonFileHelper(string &fname, ostringstream &output) const; public: //! Add a statement void addStatement(Statement *st); @@ -174,7 +174,7 @@ public: //! Initially created to enable Julia to work with .mod files //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass) //! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files - void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson); + void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail = false); }; #endif // ! MOD_FILE_HH diff --git a/StaticModel.cc b/StaticModel.cc index 35c9f516..65d4d632 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -2422,7 +2422,7 @@ StaticModel::writeJsonOutput(ostream &output) const } void -StaticModel::writeJsonComputingPassOutput(ostream &output) const +StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const { ostringstream model_local_vars_output; // Used for storing model local vars ostringstream model_output; // Used for storing model @@ -2463,11 +2463,17 @@ StaticModel::writeJsonComputingPassOutput(ostream &output) const jacobian_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(getSymbIDByDerivID(it->first.second)); + int var = it->first.second; + int symb_id = getSymbIDByDerivID(var); + int col = symbol_table.getTypeSpecificID(symb_id); expr_t d1 = it->second; - jacobian_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(symb_id) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"col\": " << col + 1 << ", \"val\": \""; d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); jacobian_output << "\"}" << endl; @@ -2491,13 +2497,27 @@ StaticModel::writeJsonComputingPassOutput(ostream &output) const hessian_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); + int symb_id1 = getSymbIDByDerivID(it->first.second.first); + int symb_id2 = getSymbIDByDerivID(it->first.second.second); expr_t d2 = it->second; - hessian_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"var2\": \"" << var2 << "\"" + int tsid1 = symbol_table.getTypeSpecificID(symb_id1); + int tsid2 = symbol_table.getTypeSpecificID(symb_id2); + + int col = tsid1*symbol_table.endo_nbr()+tsid2; + int col_sym = tsid2*symbol_table.endo_nbr()+tsid1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(symb_id1) << "\"" + << ", \"var2\": \"" << symbol_table.getName(symb_id2) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + + hessian_output << ", \"col\": [" << col + 1; + if (symb_id1 != symb_id2) + hessian_output << ", " << col_sym + 1; + hessian_output << "]" << ", \"val\": \""; d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); hessian_output << "\"}" << endl; @@ -2520,23 +2540,49 @@ StaticModel::writeJsonComputingPassOutput(ostream &output) const third_derivatives_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - string var3 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int var3 = it->first.second.second.second; expr_t d3 = it->second; - third_derivatives_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"var2\": \"" << var2 << "\"" - << ", \"var3\": \"" << var3 << "\"" + if (writeDetails) + third_derivatives_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\""; + else + third_derivatives_output << "{\"row\": " << eq + 1; + + int id1 = getSymbIDByDerivID(var1); + int id2 = getSymbIDByDerivID(var2); + int id3 = getSymbIDByDerivID(var3); + set cols; + cols.insert(id1 * hessianColsNbr + id2 * JacobianColsNbr + id3); + cols.insert(id1 * hessianColsNbr + id3 * JacobianColsNbr + id2); + cols.insert(id2 * hessianColsNbr + id1 * JacobianColsNbr + id3); + cols.insert(id2 * hessianColsNbr + id3 * JacobianColsNbr + id1); + cols.insert(id3 * hessianColsNbr + id1 * JacobianColsNbr + id2); + cols.insert(id3 * hessianColsNbr + id2 * JacobianColsNbr + id1); + + third_derivatives_output << ", \"col\": ["; + for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) + { + if (it2 != cols.begin()) + third_derivatives_output << ", "; + third_derivatives_output << *it2 + 1; + } + third_derivatives_output << "]" << ", \"val\": \""; d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); third_derivatives_output << "\"}" << endl; } third_derivatives_output << "]}"; - output << "\"static_model_derivatives\": {" - << model_local_vars_output.str() + if (writeDetails) + output << "\"static_model_derivative_details\": {"; + else + output << "\"static_model_derivatives\": {"; + output << model_local_vars_output.str() << ", " << model_output.str() << ", " << jacobian_output.str() << ", " << hessian_output.str() @@ -2545,7 +2591,7 @@ StaticModel::writeJsonComputingPassOutput(ostream &output) const } void -StaticModel::writeJsonParamsDerivativesFile(ostream &output) const +StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const { if (!residuals_params_derivatives.size() && !residuals_params_second_derivatives.size() @@ -2579,11 +2625,17 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output) const jacobian_output << ", "; int eq = it->first.first; - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second)); + int param = it->first.second; expr_t d1 = it->second; - jacobian_output << "{\"eq\": " << eq + 1 - << ", \"param\": \"" << param << "\"" + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"param_col\": " << param_col << ", \"val\": \""; d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); jacobian_output << "\"}" << endl; @@ -2601,13 +2653,21 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output) const hessian_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); + int var = it->first.second.first; + int param = it->first.second.second; expr_t d2 = it->second; - hessian_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" - << ", \"param\": \"" << param << "\"" + int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + hessian_output << ", \"var_col\": " << var_col + << ", \"param_col\": " << param_col << ", \"val\": \""; d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); hessian_output << "\"}" << endl; @@ -2626,14 +2686,22 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output) const hessian1_output << ", "; int eq = it->first.first; - string param1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string param2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second)); + int param1 = it->first.second.first; + int param2 = it->first.second.second; expr_t d2 = it->second; - hessian1_output << "{\"eq\": " << eq + 1 - << ", \"param1\": \"" << param1 << "\"" - << ", \"param2\": \"" << param2 << "\"" - << ", \"val\": \""; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + hessian1_output << "{\"eq\": " << eq + 1 + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + hessian1_output << "{\"row\": " << eq + 1; + hessian1_output << ", \"param1_col\": " << param1_col + << ", \"param2_col\": " << param2_col + << ", \"val\": \""; d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); hessian1_output << "\"}" << endl; } @@ -2651,15 +2719,25 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output) const third_derivs_output << ", "; int eq = it->first.first; - string var = symbol_table.getName(it->first.second.first); - string param1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - string param2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); + int var = it->first.second.first; + int param1 = it->first.second.second.first; + int param2 = it->first.second.second.second; expr_t d2 = it->second; - third_derivs_output << "{\"eq\": " << eq + 1 - << ", \"var\": \"" << var << "\"" - << ", \"param1\": \"" << param1 << "\"" - << ", \"param2\": \"" << param2 << "\"" + int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + third_derivs_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(var) << "\"" + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + third_derivs_output << "{\"row\": " << eq + 1; + third_derivs_output << ", \"var_col\": " << var_col + << ", \"param1_col\": " << param1_col + << ", \"param2_col\": " << param2_col << ", \"val\": \""; d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); third_derivs_output << "\"}" << endl; @@ -2679,23 +2757,36 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output) const third_derivs1_output << ", "; int eq = it->first.first; - string var1 = symbol_table.getName(getSymbIDByDerivID(it->first.second.first)); - string var2 = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.first)); - string param = symbol_table.getName(getSymbIDByDerivID(it->first.second.second.second)); + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int param = it->first.second.second.second; expr_t d2 = it->second; - third_derivs1_output << "{\"eq\": " << eq + 1 - << ", \"var1\": \"" << var1 << "\"" - << ", \"var2\": \"" << var2 << "\"" - << ", \"param1\": \"" << param << "\"" + int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1; + int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + third_derivs1_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + third_derivs1_output << "{\"row\": " << eq + 1; + third_derivs1_output << ", \"var1_col\": " << var1_col + << ", \"var2_col\": " << var2_col + << ", \"param_col\": " << param_col << ", \"val\": \""; d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); third_derivs1_output << "\"}" << endl; } third_derivs1_output << "]}" << endl; - output << "\"static_model_params_derivatives\": {" - << model_local_vars_output.str() + if (writeDetails) + output << "\"static_model_params_derivative_details\": {"; + else + output << "\"static_model_params_derivatives\": {"; + output << model_local_vars_output.str() << ", " << model_output.str() << ", " << jacobian_output.str() << ", " << hessian_output.str() diff --git a/StaticModel.hh b/StaticModel.hh index d770896e..f1a7d36a 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -174,10 +174,10 @@ public: void writeJsonOutput(ostream &output) const; //! Write JSON representation of static model - void writeJsonComputingPassOutput(ostream &output) const; + void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; //! Writes file containing static parameters derivatives - void writeJsonParamsDerivativesFile(ostream &output) const; + void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; //! Writes file containing static parameters derivatives void writeParamsDerivativesFile(const string &basename, bool julia) const;