From a4171ad4ab2e4b0455b99f62ac7ef287773c4439 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Mon, 20 Feb 2017 12:18:11 +0100
Subject: [PATCH] preprocessor: output JSON after different steps, write
static, dynamic, params derivs files in JSON. #1387
---
preprocessor/ComputingTasks.cc | 36 +--
preprocessor/DynamicModel.cc | 302 ++++++++++++++++++-
preprocessor/DynamicModel.hh | 6 +
preprocessor/DynareMain.cc | 29 +-
preprocessor/DynareMain2.cc | 17 +-
preprocessor/ExprNode.cc | 350 +++++++++++++++++++---
preprocessor/ExprNode.hh | 52 +++-
preprocessor/ExtendedPreprocessorTypes.hh | 9 +
preprocessor/ModFile.cc | 141 ++++++++-
preprocessor/ModFile.hh | 5 +-
preprocessor/ModelTree.cc | 179 +++++++++--
preprocessor/ModelTree.hh | 6 +-
preprocessor/NumericalInitialization.cc | 10 +-
preprocessor/Shocks.cc | 10 +-
preprocessor/StaticModel.cc | 284 ++++++++++++++++++
preprocessor/StaticModel.hh | 8 +-
preprocessor/SymbolTable.cc | 2 +-
17 files changed, 1329 insertions(+), 117 deletions(-)
diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc
index db2ac6249..f750b9b6f 100644
--- a/preprocessor/ComputingTasks.cc
+++ b/preprocessor/ComputingTasks.cc
@@ -509,7 +509,7 @@ RamseyConstraintsStatement::writeJsonOutput(ostream &output) const
exit(1);
}
output << " ";
- it->expression->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->expression->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}" << endl;
}
output << "]" << endl;
@@ -1170,23 +1170,23 @@ EstimatedParamsStatement::writeJsonOutput(ostream &output) const
}
output << ", \"init_val\": \"";
- it->init_val->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"lower_bound\": \"";
- it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"upper_bound\": \"";
- it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"prior_distribution\": "
<< it->prior
<< ", \"mean\": \"";
- it->mean->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->mean->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"std\": \"";
- it->std->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->std->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"p3\": \"";
- it->p3->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->p3->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"p4\": \"";
- it->p4->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->p4->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"jscale\": \"";
- it->jscale->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->jscale->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}" << endl;
}
output << "]"
@@ -1297,7 +1297,7 @@ EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const
break;
}
output << ", \"init_val\": \"";
- it->init_val->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
@@ -1417,9 +1417,9 @@ EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const
break;
}
output << ", \"lower_bound\": ";
- it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << ", \"upper_bound\": ";
- it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "}";
}
output << "]"
@@ -1470,7 +1470,7 @@ ObservationTrendsStatement::writeJsonOutput(ostream &output) const
if (printed)
output << ", ";
output << "\"" << it->first << "\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"" << endl;
printed = true;
}
@@ -1571,9 +1571,9 @@ OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const
output << ", ";
output << "{\"parameter\": \"" << it->name << "\","
<< "\"bounds\": [\"";
- it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\", \"";
- it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"]"
<< "}";
}
@@ -1699,7 +1699,7 @@ OptimWeightsStatement::writeJsonOutput(ostream &output) const
output << ", ";
output << "{\"name\": \"" << it->first << "\""
<< ", \"value\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
@@ -1711,7 +1711,7 @@ OptimWeightsStatement::writeJsonOutput(ostream &output) const
output << "{\"name1\": \"" << it->first.first << "\""
<< ", \"name2\": \"" << it->first.second << "\""
<< ", \"value\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
@@ -3504,7 +3504,7 @@ BasicPriorStatement::writeJsonPriorOutput(ostream &output) const
{
deriv_node_temp_terms_t tef_terms;
output << ", \"variance\": \"";
- variance->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ variance->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"";
}
if (options_list.getNumberOfOptions())
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index 704592dab..edcc5f3ac 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -5341,5 +5341,305 @@ DynamicModel::writeCCOutput(ostream &output, const string &basename, bool block_
void
DynamicModel::writeJsonOutput(ostream &output) const
{
- writeJsonModelEquations(output);
+ writeJsonModelEquations(output, false);
+}
+
+void
+DynamicModel::writeJsonComputingPassOutput(ostream &output) const
+{
+ ostringstream model_local_vars_output; // Used for storing model local vars
+ ostringstream model_output; // Used for storing model temp vars and equations
+ ostringstream jacobian_output; // Used for storing jacobian equations
+ ostringstream hessian_output; // Used for storing Hessian equations
+ ostringstream third_derivatives_output; // Used for storing third order derivatives equations
+
+ deriv_node_temp_terms_t tef_terms;
+ temporary_terms_t temp_term_empty;
+ temporary_terms_t temp_term_union = temporary_terms_res;
+ temporary_terms_t temp_term_union_m_1;
+
+ string concat = "";
+ int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr;
+
+ writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
+
+ writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat);
+
+ writeJsonModelEquations(model_output, true);
+
+ // Writing Jacobian
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end());
+ concat = "jacobian";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, tef_terms, concat);
+ jacobian_output << ", \"jacobian\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"ncols\": " << dynJacobianColsNbr
+ << ", \"entries\": [";
+ for (first_derivatives_t::const_iterator it = first_derivatives.begin();
+ it != first_derivatives.end(); it++)
+ {
+ if (it != first_derivatives.begin())
+ jacobian_output << ", ";
+
+ int eq = it->first.first;
+ string var = symbol_table.getName(getSymbIDByDerivID(it->first.second));
+ int lag = getLagByDerivID(it->first.second);
+ expr_t d1 = it->second;
+
+ jacobian_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"lag\": " << lag
+ << ", \"val\": \"";
+ d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms);
+ jacobian_output << "\"}" << endl;
+ }
+ jacobian_output << "]}";
+
+ // Writing Hessian
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end());
+ concat = "hessian";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, tef_terms, concat);
+ hessian_output << ", \"hessian\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"ncols\": " << hessianColsNbr
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = second_derivatives.begin();
+ it != second_derivatives.end(); it++)
+ {
+ if (it != second_derivatives.begin())
+ 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);
+ expr_t d2 = it->second;
+
+ hessian_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"lag1\": " << lag1
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"lag2\": " << lag2
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms);
+ hessian_output << "\"}" << endl;
+ }
+ hessian_output << "]}";
+
+ // Writing third derivatives
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end());
+ concat = "third_derivatives";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, tef_terms, concat);
+ third_derivatives_output << ", \"third_derivative\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"ncols\": " << hessianColsNbr * dynJacobianColsNbr
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = third_derivatives.begin();
+ it != third_derivatives.end(); it++)
+ {
+ if (it != third_derivatives.begin())
+ 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);
+ expr_t d3 = it->second;
+
+ third_derivatives_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"lag1\": " << lag1
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"lag2\": " << lag2
+ << ", \"var3\": \"" << var3 << "\""
+ << ", \"lag3\": " << lag3
+ << ", \"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()
+ << ", " << model_output.str()
+ << ", " << jacobian_output.str()
+ << ", " << hessian_output.str()
+ << ", " << third_derivatives_output.str()
+ << "}";
+}
+
+void
+DynamicModel::writeJsonParamsDerivativesFile(ostream &output) const
+{
+ if (!residuals_params_derivatives.size()
+ && !residuals_params_second_derivatives.size()
+ && !jacobian_params_derivatives.size()
+ && !jacobian_params_second_derivatives.size()
+ && !hessian_params_derivatives.size())
+ return;
+
+ ostringstream model_local_vars_output; // Used for storing model local vars
+ ostringstream model_output; // Used for storing model temp vars and equations
+ ostringstream jacobian_output; // Used for storing jacobian equations
+ ostringstream hessian_output; // Used for storing Hessian equations
+ ostringstream hessian1_output; // Used for storing Hessian equations
+ ostringstream third_derivs_output; // Used for storing third order derivatives equations
+ ostringstream third_derivs1_output; // Used for storing third order derivatives equations
+
+ deriv_node_temp_terms_t tef_terms;
+ writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
+
+ temporary_terms_t temp_terms_empty;
+ string concat = "all";
+ writeJsonTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, tef_terms, concat);
+ jacobian_output << "\"deriv_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
+ it != residuals_params_derivatives.end(); it++)
+ {
+ if (it != residuals_params_derivatives.begin())
+ jacobian_output << ", ";
+
+ int eq = it->first.first;
+ string param = symbol_table.getName(getSymbIDByDerivID(it->first.second));
+ expr_t d1 = it->second;
+
+ jacobian_output << "{\"eq\": " << eq
+ << ", \"param\": \"" << param << "\""
+ << ", \"val\": \"";
+ d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms);
+ jacobian_output << "\"}" << endl;
+ }
+ jacobian_output << "]}";
+ hessian_output << "\"deriv_jacobian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvarcols\": " << dynJacobianColsNbr
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
+ it != jacobian_params_derivatives.end(); it++)
+ {
+ if (it != jacobian_params_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ hessian_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"lag\": " << lag
+ << ", \"param\": \"" << param << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms);
+ hessian_output << "\"}" << endl;
+ }
+ hessian_output << "]}";
+
+ hessian1_output << "\"second_deriv_residuals_wrt_params\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"nparam1cols\": " << symbol_table.param_nbr()
+ << ", \"nparam2cols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
+ it != residuals_params_second_derivatives.end(); ++it)
+ {
+ if (it != residuals_params_second_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ hessian1_output << "{\"eq\": " << eq
+ << ", \"param1\": \"" << param1 << "\""
+ << ", \"param2\": \"" << param2 << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms);
+ hessian1_output << "\"}" << endl;
+ }
+ hessian1_output << "]}";
+ third_derivs_output << "\"second_deriv_jacobian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvarcols\": " << dynJacobianColsNbr
+ << ", \"nparam1cols\": " << symbol_table.param_nbr()
+ << ", \"nparam2cols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
+ it != jacobian_params_second_derivatives.end(); ++it)
+ {
+ if (it != jacobian_params_second_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ third_derivs_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"lag\": " << lag
+ << ", \"param1\": \"" << param1 << "\""
+ << ", \"param2\": \"" << param2 << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms);
+ third_derivs_output << "\"}" << endl;
+ }
+ third_derivs_output << "]}" << endl;
+
+ third_derivs1_output << "\"derivative_hessian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvar1cols\": " << dynJacobianColsNbr
+ << ", \"nvar2cols\": " << dynJacobianColsNbr
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
+ it != hessian_params_derivatives.end(); ++it)
+ {
+ if (it != hessian_params_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ third_derivs1_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"lag1\": " << lag1
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"lag2\": " << lag2
+ << ", \"param1\": \"" << param << "\""
+ << ", \"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()
+ << ", " << model_output.str()
+ << ", " << jacobian_output.str()
+ << ", " << hessian_output.str()
+ << ", " << hessian1_output.str()
+ << ", " << third_derivs_output.str()
+ << ", " << third_derivs1_output.str()
+ << "}";
}
diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh
index e79ac7f42..87e41e386 100644
--- a/preprocessor/DynamicModel.hh
+++ b/preprocessor/DynamicModel.hh
@@ -220,6 +220,12 @@ public:
//! Write JSON Output
void writeJsonOutput(ostream &output) const;
+ //! Write JSON Output representation of dynamic model after computing pass
+ void writeJsonComputingPassOutput(ostream &output) const;
+
+ //! Write JSON prams derivatives file
+ void writeJsonParamsDerivativesFile(ostream &output) const;
+
//! Return true if the hessian is equal to zero
inline bool checkHessianZero() const;
diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc
index c56509262..cd62325c9 100644
--- a/preprocessor/DynareMain.cc
+++ b/preprocessor/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
- , bool json, JsonFileOutputType json_output_mode
+ , JsonOutputPointType json, JsonFileOutputType json_output_mode
);
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] [jsonstdout]"
+ << "[json=parse|check|transform|compute] [jsonstdout]"
<< endl;
exit(EXIT_FAILURE);
}
@@ -115,7 +115,7 @@ main(int argc, char **argv)
map<string, string> defines;
vector<string> path;
FileOutputType output_mode = none;
- bool json = false;
+ JsonOutputPointType json = nojson;
JsonFileOutputType json_output_mode = file;
LanguageOutputType language = matlab;
@@ -297,8 +297,27 @@ main(int argc, char **argv)
}
else if (!strcmp(argv[arg], "jsonstdout"))
json_output_mode = standardout;
- else if (!strcmp(argv[arg], "json"))
- json = true;
+ else if (strlen(argv[arg]) >= 4 && !strncmp(argv[arg], "json", 4))
+ {
+ if (strlen(argv[arg]) <= 5 || argv[arg][4] != '=')
+ {
+ cerr << "Incorrect syntax for json option" << endl;
+ usage();
+ }
+ if (strlen(argv[arg]) == 10 && !strncmp(argv[arg] + 5, "parse", 5))
+ json = parsing;
+ else if (strlen(argv[arg]) == 10 && !strncmp(argv[arg] + 5, "check", 5))
+ json = checkpass;
+ else if (strlen(argv[arg]) == 14 && !strncmp(argv[arg] + 5, "transform", 9))
+ json = transformpass;
+ else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 5, "compute", 7))
+ json = computingpass;
+ else
+ {
+ cerr << "Incorrect syntax for json option" << endl;
+ usage();
+ }
+ }
else
{
cerr << "Unknown option: " << argv[arg] << endl;
diff --git a/preprocessor/DynareMain2.cc b/preprocessor/DynareMain2.cc
index 3bbc4b4fd..bc2d34ffc 100644
--- a/preprocessor/DynareMain2.cc
+++ b/preprocessor/DynareMain2.cc
@@ -34,32 +34,33 @@ 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
- , bool json, JsonFileOutputType json_output_mode
+ , JsonOutputPointType json, JsonFileOutputType json_output_mode
)
{
ParsingDriver p(warnings, nostrict);
// Do parsing and construct internal representation of mod file
ModFile *mod_file = p.parse(in, debug);
- if (json)
- {
- mod_file->symbol_table.freeze();
- mod_file->writeJsonOutput(basename, json_output_mode);
- mod_file->symbol_table.unfreeze();
- cout << "JSON file written after Parsing step." << endl;
- }
+ if (json == parsing)
+ mod_file->writeJsonOutput(basename, json, json_output_mode);
// Run checking pass
mod_file->checkPass(nostrict);
+ if (json == checkpass)
+ mod_file->writeJsonOutput(basename, json, json_output_mode);
// Perform transformations on the model (creation of auxiliary vars and equations)
mod_file->transformPass(nostrict);
+ if (json == transformpass)
+ mod_file->writeJsonOutput(basename, json, json_output_mode);
// Evaluate parameters initialization, initval, endval and pounds
mod_file->evalAllExpressions(warn_uninit);
// 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);
// Write outputs
if (output_mode != none)
diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc
index ccba75c28..b5b9d4dd2 100644
--- a/preprocessor/ExprNode.cc
+++ b/preprocessor/ExprNode.cc
@@ -73,6 +73,13 @@ ExprNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t &te
return 100;
}
+int
+ExprNode::precedenceJson(const temporary_terms_t &temporary_terms) const
+{
+ // For a constant, a variable, or a unary op, the precedence is maximal
+ return 100;
+}
+
int
ExprNode::cost(int cost, bool is_matlab) const
{
@@ -185,6 +192,14 @@ ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output
// Nothing to do
}
+void
+ExprNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ // Nothing to do
+}
+
void
ExprNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@@ -323,7 +338,7 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
}
void
-NumConstNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+NumConstNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
@@ -624,10 +639,17 @@ VariableNode::containsExternalFunction() const
}
void
-VariableNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+VariableNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
output << datatree.symbol_table.getName(symb_id);
if (lag != 0)
output << "(" << lag << ")";
@@ -1869,13 +1891,20 @@ UnaryOpNode::containsExternalFunction() const
}
void
-UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+UnaryOpNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
// Always put parenthesis around uminus nodes
if (op_code == oUminus)
- output << LEFT_PAR(output_type);
+ output << "(";
switch (op_code)
{
@@ -1938,7 +1967,7 @@ UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
break;
case oSteadyState:
output << "(";
- arg->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg->writeJsonOutput(output, temporary_terms, tef_terms);
output << ")";
return;
case oSteadyStateParamDeriv:
@@ -1949,7 +1978,6 @@ UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
assert(datatree.symbol_table.getType(param1_symb_id) == eParameter);
int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id);
int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id);
- assert(IS_MATLAB(output_type));
output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")";
}
return;
@@ -1963,7 +1991,6 @@ UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id);
int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id);
int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id);
- assert(IS_MATLAB(output_type));
output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1
<< "," << tsid_param2+1 << ")";
}
@@ -1984,23 +2011,21 @@ UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
*/
if (op_code != oUminus
|| (op_code == oUminus
- && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
+ && arg->precedenceJson(temporary_terms) < precedenceJson(temporary_terms)))
{
- output << LEFT_PAR(output_type);
- if (op_code == oSign && (output_type == oCDynamicModel || output_type == oCStaticModel))
- output << "1.0,";
+ output << "(";
close_parenthesis = true;
}
// Write argument
- arg->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg->writeJsonOutput(output, temporary_terms, tef_terms);
if (close_parenthesis)
- output << RIGHT_PAR(output_type);
+ output << ")";
// Close parenthesis for uminus
if (op_code == oUminus)
- output << RIGHT_PAR(output_type);
+ output << ")";
}
void
@@ -2197,6 +2222,14 @@ UnaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType out
arg->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
+void
+UnaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ arg->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+}
+
void
UnaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@@ -2963,6 +2996,43 @@ BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t
exit(EXIT_FAILURE);
}
+int
+BinaryOpNode::precedenceJson(const temporary_terms_t &temporary_terms) const
+{
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
+ // A temporary term behaves as a variable
+ if (it != temporary_terms.end())
+ return 100;
+
+ switch (op_code)
+ {
+ case oEqual:
+ return 0;
+ case oEqualEqual:
+ case oDifferent:
+ return 1;
+ case oLessEqual:
+ case oGreaterEqual:
+ case oLess:
+ case oGreater:
+ return 2;
+ case oPlus:
+ case oMinus:
+ return 3;
+ case oTimes:
+ case oDivide:
+ return 4;
+ case oPower:
+ case oPowerDeriv:
+ return 5;
+ case oMin:
+ case oMax:
+ return 100;
+ }
+ // Suppress GCC warning
+ exit(EXIT_FAILURE);
+}
+
int
BinaryOpNode::cost(const map<NodeTreeReference, temporary_terms_t> &temp_terms_map, bool is_matlab) const
{
@@ -3226,10 +3296,18 @@ BinaryOpNode::containsExternalFunction() const
}
void
-BinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+BinaryOpNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ // If current node is a temporary term
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
if (op_code == oMax || op_code == oMin)
{
switch (op_code)
@@ -3243,32 +3321,32 @@ BinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
default:
;
}
- arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg1->writeJsonOutput(output, temporary_terms, tef_terms);
output << ",";
- arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg2->writeJsonOutput(output, temporary_terms, tef_terms);
output << ")";
return;
}
- int prec = precedence(output_type, temporary_terms);
+ int prec = precedenceJson(temporary_terms);
bool close_parenthesis = false;
// If left argument has a lower precedence, or if current and left argument are both power operators,
// add parenthesis around left argument
BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1);
- if (arg1->precedence(output_type, temporary_terms) < prec
+ if (arg1->precedenceJson(temporary_terms) < prec
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
{
- output << LEFT_PAR(output_type);
+ output << "(";
close_parenthesis = true;
}
// Write left argument
- arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg1->writeJsonOutput(output, temporary_terms, tef_terms);
if (close_parenthesis)
- output << RIGHT_PAR(output_type);
+ output << ")";
// Write current operator symbol
switch (op_code)
@@ -3321,21 +3399,21 @@ BinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
- it is a minus operator with same precedence than current operator
- it is a divide operator with same precedence than current operator */
BinaryOpNode *barg2 = dynamic_cast<BinaryOpNode *>(arg2);
- int arg2_prec = arg2->precedence(output_type, temporary_terms);
+ int arg2_prec = arg2->precedenceJson(temporary_terms);
if (arg2_prec < prec
- || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type))
+ || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower)
|| (op_code == oMinus && arg2_prec == prec)
- || (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type)))
+ || (op_code == oDivide && arg2_prec == prec))
{
- output << LEFT_PAR(output_type);
+ output << "(";
close_parenthesis = true;
}
// Write right argument
- arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg2->writeJsonOutput(output, temporary_terms, tef_terms);
if (close_parenthesis)
- output << RIGHT_PAR(output_type);
+ output << ")";
}
void
@@ -3527,6 +3605,15 @@ BinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType ou
arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
+void
+BinaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+ arg2->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+}
+
void
BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@@ -4478,10 +4565,18 @@ TrinaryOpNode::containsExternalFunction() const
}
void
-TrinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+TrinaryOpNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ // If current node is a temporary term
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
switch (op_code)
{
case oNormcdf:
@@ -4492,11 +4587,11 @@ TrinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
break;
}
- arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg1->writeJsonOutput(output, temporary_terms, tef_terms);
output << ",";
- arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg2->writeJsonOutput(output, temporary_terms, tef_terms);
output << ",";
- arg3->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ arg3->writeJsonOutput(output, temporary_terms, tef_terms);
output << ")";
}
@@ -4576,6 +4671,16 @@ TrinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType o
arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
}
+void
+TrinaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+ arg2->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+ arg3->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+}
+
void
TrinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@@ -5181,7 +5286,7 @@ AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, Ex
}
void
-AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type,
+AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
@@ -5191,7 +5296,7 @@ AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output
if (it != arguments.begin())
output << ",";
- (*it)->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
+ (*it)->writeJsonOutput(output, temporary_terms, tef_terms);
}
}
@@ -5359,12 +5464,19 @@ ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsign
}
void
-ExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+ExternalFunctionNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
output << datatree.symbol_table.getName(symb_id) << "(";
- writeJsonExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
+ writeJsonExternalFunctionArguments(output, temporary_terms, tef_terms);
output << ")";
}
@@ -5477,6 +5589,42 @@ ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutpu
}
}
+void
+ExternalFunctionNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
+ assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ for (vector<expr_t>::const_iterator it = arguments.begin();
+ it != arguments.end(); it++)
+ (*it)->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+
+ if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
+ {
+ tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
+ int indx = getIndxInTefTerms(symb_id, tef_terms);
+ int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
+ assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ stringstream ef;
+ ef << "{\"external_function\": {"
+ << "\"output\": \"TEF_" << indx << "\"";
+
+ if (symb_id == first_deriv_symb_id)
+ ef << ", \"output_d\": \"TEFD_" << indx << "\"";
+
+ if (symb_id == second_deriv_symb_id)
+ ef << ", \"output_dd\": \"TEFDD_" << indx << "\"";
+
+ ef << ", \"function\": \"" << datatree.symbol_table.getName(symb_id) << "(";
+ writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms);
+ ef << ")\"}}";
+ efout.push_back(ef.str());
+ }
+}
+
expr_t
ExternalFunctionNode::toStatic(DataTree &static_datatree) const
{
@@ -5559,10 +5707,31 @@ FirstDerivExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
}
void
-FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ // If current node is a temporary term
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<FirstDerivExternalFunctionNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
+ const int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
+ assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ const int tmpIndx = inputIndex - 1;
+
+ if (first_deriv_symb_id == symb_id)
+ output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms)
+ << "[" << tmpIndx << "]";
+ else if (first_deriv_symb_id == eExtFunNotSet)
+ output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex;
+ else
+ output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms)
+ << "[" << tmpIndx << "]";
}
void
@@ -5752,6 +5921,47 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp
}
}
+void
+FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
+ assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ /* For a node with derivs provided by the user function, call the method
+ on the non-derived node */
+ if (first_deriv_symb_id == symb_id)
+ {
+ expr_t parent = datatree.AddExternalFunction(symb_id, arguments);
+ parent->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+ return;
+ }
+
+ if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms))
+ return;
+
+ stringstream ef;
+ if (first_deriv_symb_id == eExtFunNotSet)
+ ef << "{\"first_deriv_external_function\": {"
+ << "\"output\": \"TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << "\""
+ << ", \"analytic_derivative\": false"
+ << ", \"wrt\": " << inputIndex
+ << ", \"function\": \"" << datatree.symbol_table.getName(symb_id) << "(";
+ else
+ {
+ tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size();
+ ef << "{\"first_deriv_external_function\": {"
+ << "\"output\": \"TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms)
+ << ", \"analytic_derivative\": true"
+ << ", \"function\": \"" << datatree.symbol_table.getName(first_deriv_symb_id) << "(";
+ }
+
+ writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms);
+ ef << ")\"}}";
+ efout.push_back(ef.str());
+}
+
void
FirstDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@@ -5878,10 +6088,32 @@ SecondDerivExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
}
void
-SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
+SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
+ // If current node is a temporary term
+ temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<SecondDerivExternalFunctionNode *>(this));
+ if (it != temporary_terms.end())
+ {
+ output << "T" << idx;
+ return;
+ }
+
+ const int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
+ assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ const int tmpIndex1 = inputIndex1 - 1;
+ const int tmpIndex2 = inputIndex2 - 1;
+
+ if (second_deriv_symb_id == symb_id)
+ output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms)
+ << "[" << tmpIndex1 << "," << tmpIndex2 << "]";
+ else if (second_deriv_symb_id == eExtFunNotSet)
+ output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2;
+ else
+ output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms)
+ << "[" << tmpIndex1 << "," << tmpIndex2 << "]";
}
void
@@ -6048,6 +6280,48 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex
}
}
+void
+SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const
+{
+ int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
+ assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
+
+ /* For a node with derivs provided by the user function, call the method
+ on the non-derived node */
+ if (second_deriv_symb_id == symb_id)
+ {
+ expr_t parent = datatree.AddExternalFunction(symb_id, arguments);
+ parent->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms);
+ return;
+ }
+
+ if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms))
+ return;
+
+ stringstream ef;
+ if (second_deriv_symb_id == eExtFunNotSet)
+ ef << "{\"second_deriv_external_function\": {"
+ << "\"output\": \"TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << "\""
+ << ", \"analytic_derivative\": false"
+ << ", \"wrt1\": " << inputIndex1
+ << ", \"wrt2\": " << inputIndex2
+ << ", \"function\": \"" << datatree.symbol_table.getName(symb_id) << "(";
+ else
+ {
+ tef_terms[make_pair(second_deriv_symb_id, arguments)] = (int) tef_terms.size();
+ ef << "{\"second_deriv_external_function\": {"
+ << "\"output\": \"TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms)
+ << ", \"analytic_derivative\": true"
+ << ", \"function\": \"" << datatree.symbol_table.getName(second_deriv_symb_id) << "(";
+ }
+
+ writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms);
+ ef << ")\"}}" << endl;
+ efout.push_back(ef.str());
+}
+
expr_t
SecondDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
{
diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh
index 326540719..e4e5d9bcd 100644
--- a/preprocessor/ExprNode.hh
+++ b/preprocessor/ExprNode.hh
@@ -222,13 +222,21 @@ public:
void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
//! Writes output of node in JSON syntax
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
+
+ virtual int precedenceJson(const temporary_terms_t &temporary_terms) const;
//! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ //! Write the JSON output of an external function in a string vector
+ //! Allows the insertion of commas if necessary
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
+
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -481,7 +489,7 @@ public:
};
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
@@ -531,7 +539,7 @@ public:
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg);
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void computeTemporaryTerms(map<expr_t, int > &reference_count,
@@ -607,11 +615,14 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -690,16 +701,20 @@ public:
BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder);
virtual void prepareForDerivation();
+ virtual int precedenceJson(const temporary_terms_t &temporary_terms) const;
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -801,11 +816,14 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -872,7 +890,7 @@ protected:
int getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs);
//! Helper function to write output arguments of any given external function
void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- void writeJsonExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ void writeJsonExternalFunctionArguments(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
public:
AbstractExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg,
const vector<expr_t> &arguments_arg);
@@ -881,11 +899,14 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const = 0;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const = 0;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const = 0;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -948,10 +969,13 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -989,7 +1013,7 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -997,6 +1021,9 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -1029,7 +1056,7 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
- virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@@ -1037,6 +1064,9 @@ public:
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
+ virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
+ const temporary_terms_t &temporary_terms,
+ deriv_node_temp_terms_t &tef_terms) const;
virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
diff --git a/preprocessor/ExtendedPreprocessorTypes.hh b/preprocessor/ExtendedPreprocessorTypes.hh
index 1388cafc3..26c8ac19e 100644
--- a/preprocessor/ExtendedPreprocessorTypes.hh
+++ b/preprocessor/ExtendedPreprocessorTypes.hh
@@ -44,4 +44,13 @@ enum JsonFileOutputType
file, // output JSON files to file
standardout, // output JSON files to stdout
};
+
+enum JsonOutputPointType
+ {
+ nojson, // don't output JSON
+ parsing, // output JSON after the parsing step
+ checkpass, // output JSON after the check pass
+ transformpass, // output JSON after the transform pass
+ computingpass // output JSON after the computing pass
+ };
#endif
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 78ae952ac..4cf0ba1ba 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -1248,7 +1248,44 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output)
}
void
-ModFile::writeJsonOutput(const string &basename, JsonFileOutputType json_output_mode) const
+ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode)
+{
+ if (json == nojson)
+ return;
+
+ if (json == parsing || json == checkpass)
+ symbol_table.freeze();
+
+ writeJsonOutputParsingCheck(basename, json_output_mode);
+
+ if (json == parsing || json == checkpass)
+ symbol_table.unfreeze();
+
+ if (json == computingpass)
+ writeJsonComputingPassOutput(basename, json_output_mode);
+
+ switch (json)
+ {
+ case parsing:
+ cout << "JSON written after Parsing step." << endl;
+ break;
+ case checkpass:
+ cout << "JSON written after Check step." << endl;
+ break;
+ case transformpass:
+ cout << "JSON written after Transform step." << endl;
+ break;
+ case computingpass:
+ cout << "JSON written after Computing step." << endl;
+ break;
+ case nojson:
+ cerr << "ModFile::writeJsonOutput: should not arrive here." << endl;
+ exit(EXIT_FAILURE);
+ }
+}
+
+void
+ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode) const
{
ostringstream output;
output << "{" << endl;
@@ -1298,3 +1335,105 @@ ModFile::writeJsonOutput(const string &basename, JsonFileOutputType json_output_
jsonOutputFile.close();
}
}
+
+void
+ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode) const
+{
+ ostringstream static_output;
+ static_output << "{";
+ static_model.writeJsonComputingPassOutput(static_output);
+ static_output << "}" << endl;
+
+ ostringstream dynamic_output;
+ dynamic_output << "{";
+ dynamic_model.writeJsonComputingPassOutput(dynamic_output);
+ dynamic_output << "}" << endl;
+
+ ostringstream tmp_out, static_paramsd_output;
+ tmp_out << "";
+ static_paramsd_output << "";
+ static_model.writeJsonParamsDerivativesFile(tmp_out);
+ if (!tmp_out.str().empty())
+ static_paramsd_output << "{" << tmp_out.str() << "}" << endl;
+
+ ostringstream tmp1_out, dynamic_paramsd_output;
+ tmp1_out << "";
+ dynamic_paramsd_output << "";
+ dynamic_model.writeJsonParamsDerivativesFile(tmp1_out);
+ if (!tmp1_out.str().empty())
+ dynamic_paramsd_output << "{" << tmp1_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;
+ if (!static_paramsd_output.str().empty())
+ cout << static_paramsd_output.str() << endl;
+ }
+ else
+ {
+ if (basename.empty())
+ {
+ cerr << "ERROR: Missing file name" << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ string fname_static, fname_dynamic;
+ 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);
+ }
+
+ jsonOutputFileDynamic.open(fname_dynamic.c_str(), ios::out | ios::binary);
+ if (!jsonOutputFileDynamic.is_open())
+ {
+ cerr << "ERROR: Can't open file " << fname_dynamic << " for writing" << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ jsonOutputFileStatic << static_output.str();
+ jsonOutputFileStatic.close();
+ jsonOutputFileDynamic << dynamic_output.str();
+ jsonOutputFileDynamic.close();
+
+ if (!static_paramsd_output.str().empty())
+ {
+ string fname_static_params;
+ 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();
+ }
+
+ if (!dynamic_paramsd_output.str().empty())
+ {
+ string fname_dynamic_params;
+ 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();
+ }
+ }
+}
diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh
index b83f984da..684d592ee 100644
--- a/preprocessor/ModFile.hh
+++ b/preprocessor/ModFile.hh
@@ -117,6 +117,9 @@ private:
ModFileStructure mod_file_struct;
//! Warnings Encountered
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;
public:
//! Add a statement
@@ -171,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, JsonFileOutputType json_output_mode) const;
+ void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode);
};
#endif // ! MOD_FILE_HH
diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc
index 444aec2b3..3e2b73958 100644
--- a/preprocessor/ModelTree.cc
+++ b/preprocessor/ModelTree.cc
@@ -1292,6 +1292,59 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_term
}
}
+void
+ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output,
+ deriv_node_temp_terms_t &tef_terms, string &concat) const
+{
+ // Local var used to keep track of temp nodes already written
+ bool wrote_term = false;
+ temporary_terms_t tt2 = ttm1;
+
+ output << "\"external_functions_temporary_terms_" << concat << "\": [";
+ for (temporary_terms_t::const_iterator it = tt.begin();
+ it != tt.end(); it++)
+ if (ttm1.find(*it) == ttm1.end())
+ {
+ if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL)
+ {
+ if (wrote_term)
+ output << ", ";
+ vector<string> efout;
+ (*it)->writeJsonExternalFunctionOutput(efout, tt2, tef_terms);
+ for (vector<string>::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++)
+ {
+ if (it1 != efout.begin())
+ output << ", ";
+ output << *it1;
+ }
+ wrote_term = true;
+ }
+ tt2.insert(*it);
+ }
+
+ tt2 = ttm1;
+ wrote_term = false;
+ output << "]"
+ << ", \"temporary_terms_" << concat << "\": [";
+ for (temporary_terms_t::const_iterator it = tt.begin();
+ it != tt.end(); it++)
+ if (ttm1.find(*it) == ttm1.end())
+ {
+ if (wrote_term)
+ output << ", ";
+ output << "{\"temporary_term\": \"";
+ (*it)->writeJsonOutput(output, tt, tef_terms);
+ output << " = ";
+ (*it)->writeJsonOutput(output, tt2, tef_terms);
+ output << "\"}" << endl;
+ wrote_term = true;
+
+ // Insert current node into tt2
+ tt2.insert(*it);
+ }
+ output << "]";
+}
+
void
ModelTree::fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars, bool &message_printed) const
{
@@ -1481,6 +1534,51 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
}
}
+void
+ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const
+{
+ /* Collect all model local variables appearing in equations, and print only
+ them. Printing unused model local variables can lead to a crash (see
+ ticket #101). */
+ set<int> used_local_vars;
+
+ // Use an empty set for the temporary terms
+ const temporary_terms_t tt;
+
+ for (size_t i = 0; i < equations.size(); i++)
+ equations[i]->collectVariables(eModelLocalVariable, used_local_vars);
+
+ output << "\"external_functions_model_local_variables\": [";
+ for (set<int>::const_iterator it = used_local_vars.begin();
+ it != used_local_vars.end(); ++it)
+ {
+ vector<string> efout;
+ expr_t value = local_variables_table.find(*it)->second;
+ value->writeJsonExternalFunctionOutput(efout, tt, tef_terms);
+ for (vector<string>::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++)
+ {
+ if (it1 != efout.begin())
+ output << ", ";
+ output << *it1;
+ }
+ }
+ output << "]"
+ << ", \"model_local_variables\": [";
+ for (set<int>::const_iterator it = used_local_vars.begin();
+ it != used_local_vars.end(); ++it)
+ {
+ int id = *it;
+ expr_t value = local_variables_table.find(id)->second;
+
+ /* We append underscores to avoid name clashes with "g1" or "oo_" (see
+ also VariableNode::writeOutput) */
+ output << "{\"" << symbol_table.getName(id) << "__ = ";
+ value->writeJsonOutput(output, tt, tef_terms);
+ output << "\"}" << endl;
+ }
+ output << "]";
+}
+
void
ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) const
{
@@ -1920,37 +2018,76 @@ bool ModelTree::isNonstationary(int symb_id) const
}
void
-ModelTree::writeJsonModelEquations(ostream &output) const
+ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
{
deriv_node_temp_terms_t tef_terms;
vector<pair<string,string> > eqtags;
- output << endl << ",\"model\":[" << endl;
+ temporary_terms_t tt_empty;
+ if (residuals)
+ output << endl << ",\"residuals\":[" << endl;
+ else
+ output << endl << ",\"model\":[" << endl;
for (int eq = 0; eq < (int) equations.size(); eq++)
{
- output << "{ \"equation\": \"";
- equations[eq]->writeJsonOutput(output, oMatlabDynamicModel, temporary_terms, tef_terms);
- output << "\", \"line\": " << equations_lineno[eq];
- for (vector<pair<int, pair<string, string> > >::const_iterator it = equation_tags.begin();
- it != equation_tags.end(); it++)
- if (it->first == eq)
- eqtags.push_back(it->second);
-
- if (!eqtags.empty())
+ if (eq > 0)
+ output << ", ";
+
+ if (residuals)
{
- output << ", \"tags\": {";
- int i = 0;
- for (vector<pair<string, string> >:: const_iterator it = eqtags.begin(); it != eqtags.end(); it++, i++)
+ BinaryOpNode *eq_node = equations[eq];
+ expr_t lhs = eq_node->get_arg1();
+ expr_t rhs = eq_node->get_arg2();
+
+ output << "{\"residual\": {"
+ << "\"lhs\": \"";
+ lhs->writeJsonOutput(output, temporary_terms, tef_terms);
+ output << "\"";
+
+ output << ", \"rhs\": \"";
+ rhs->writeJsonOutput(output, temporary_terms, tef_terms);
+ output << "\"";
+ try
+ {
+ // Test if the right hand side of the equation is empty.
+ if (rhs->eval(eval_context_t()) != 0)
+ {
+ output << ", \"rhs\": \"";
+ rhs->writeJsonOutput(output, temporary_terms, tef_terms);
+ output << "\"";
+ }
+ }
+ catch (ExprNode::EvalException &e)
{
- if (i != 0)
- output << ", ";
- output << "\"" << it->first << "\": \"" << it->second << "\"";
}
output << "}";
- eqtags.clear();
}
- output << "}";
- if (eq < (int) equations.size() - 1)
- output << "," << endl;
+ else
+ {
+ output << "{\"equation\": \"";
+ equations[eq]->writeJsonOutput(output, tt_empty, tef_terms);
+ output << "\""
+ << ", \"line\": " << equations_lineno[eq];
+
+ for (vector<pair<int, pair<string, string> > >::const_iterator it = equation_tags.begin();
+ it != equation_tags.end(); it++)
+ if (it->first == eq)
+ eqtags.push_back(it->second);
+
+ if (!eqtags.empty())
+ {
+ output << ", \"tags\": {";
+ int i = 0;
+ for (vector<pair<string, string> >:: const_iterator it = eqtags.begin(); it != eqtags.end(); it++, i++)
+ {
+ if (i != 0)
+ output << ", ";
+ output << "\"" << it->first << "\": \"" << it->second << "\"";
+ }
+ output << "}";
+ eqtags.clear();
+ }
+ }
+ output << "}" << endl;
}
output << endl << "]" << endl;
}
diff --git a/preprocessor/ModelTree.hh b/preprocessor/ModelTree.hh
index d74598d89..ac6bfca8e 100644
--- a/preprocessor/ModelTree.hh
+++ b/preprocessor/ModelTree.hh
@@ -186,6 +186,7 @@ protected:
void computeParamsDerivativesTemporaryTerms();
//! Writes temporary terms
void writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
+ void writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, deriv_node_temp_terms_t &tef_terms, string &concat) const;
//! Compiles temporary terms
void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const;
//! Adds informations for simulation in a binary file
@@ -200,7 +201,10 @@ protected:
//! Writes model equations
void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
//! Writes JSON model equations
- void writeJsonModelEquations(ostream &output) const;
+ //! if residuals = true, we are writing the dynamic/static model.
+ //! Otherwise, just the model equations (with line numbers, no tmp terms)
+ void writeJsonModelEquations(ostream &output, bool residuals) const;
+ void writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const;
//! Compiles model equations
void compileModelEquations(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
diff --git a/preprocessor/NumericalInitialization.cc b/preprocessor/NumericalInitialization.cc
index 22c013b3d..59ef96ad7 100644
--- a/preprocessor/NumericalInitialization.cc
+++ b/preprocessor/NumericalInitialization.cc
@@ -68,7 +68,7 @@ InitParamStatement::writeJsonOutput(ostream &output) const
{
deriv_node_temp_terms_t tef_terms;
output << "{\"statementName\": \"param_init\", \"name\": \"" << symbol_table.getName(symb_id) << "\", " << "\"value\": \"";
- param_value->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ param_value->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
@@ -184,7 +184,7 @@ InitOrEndValStatement::writeJsonInitValues(ostream &output) const
if (it != init_values.begin())
output << ", ";
output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " << "\"value\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
}
@@ -428,7 +428,7 @@ HistValStatement::writeJsonOutput(ostream &output) const
output << "{ \"name\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"lag\": " << it->first.second
<< ", \"value\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]}";
@@ -526,11 +526,11 @@ HomotopyStatement::writeJsonOutput(ostream &output) const
output << "{\"name\": \"" << symbol_table.getName(it->first) << "\""
<< ", \"initial_value\": \"";
if (it->second.first != NULL)
- it->second.first->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second.first->writeJsonOutput(output, temporary_terms_t(), tef_terms);
else
output << "NaN";
output << "\", \"final_value\": \"";
- it->second.second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second.second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
diff --git a/preprocessor/Shocks.cc b/preprocessor/Shocks.cc
index 95391092b..4835b3705 100644
--- a/preprocessor/Shocks.cc
+++ b/preprocessor/Shocks.cc
@@ -87,7 +87,7 @@ AbstractShocksStatement::writeJsonDetShocks(ostream &output) const
output << "{\"period1\": " << it1->period1 << ", "
<< "\"period2\": " << it1->period2 << ", "
<< "\"value\": \"";
- it1->value->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it1->value->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]}";
@@ -174,7 +174,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const
output << ", ";
output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", "
<< "\"variance\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
@@ -185,7 +185,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const
output << ", ";
output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", "
<< "\"stderr\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
@@ -198,7 +198,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const
<< "\"name\": \"" << symbol_table.getName(it->first.first) << "\", "
<< "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", "
<< "\"covariance\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
@@ -211,7 +211,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const
<< "\"name\": \"" << symbol_table.getName(it->first.first) << "\", "
<< "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", "
<< "\"correlation\": \"";
- it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+ it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms);
output << "\"}";
}
output << "]"
diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc
index a7652f9b8..4516a8868 100644
--- a/preprocessor/StaticModel.cc
+++ b/preprocessor/StaticModel.cc
@@ -2414,3 +2414,287 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
paramsDerivsFile.close();
}
+
+void
+StaticModel::writeJsonComputingPassOutput(ostream &output) const
+{
+ ostringstream model_local_vars_output; // Used for storing model local vars
+ ostringstream model_output; // Used for storing model
+ ostringstream jacobian_output; // Used for storing jacobian equations
+ ostringstream hessian_output; // Used for storing Hessian equations
+ ostringstream third_derivatives_output; // Used for storing third order derivatives equations
+
+ deriv_node_temp_terms_t tef_terms;
+ temporary_terms_t temp_term_empty;
+ temporary_terms_t temp_term_union = temporary_terms_res;
+ temporary_terms_t temp_term_union_m_1;
+
+ string concat = "";
+
+ writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
+
+ writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat);
+
+ writeJsonModelEquations(model_output, true);
+
+ int nrows = equations.size();
+ int JacobianColsNbr = symbol_table.endo_nbr();
+ int hessianColsNbr = JacobianColsNbr*JacobianColsNbr;
+
+ // Write Jacobian w.r. to endogenous only
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end());
+ concat = "jacobian";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, tef_terms, concat);
+ jacobian_output << ", \"jacobian\": {"
+ << " \"nrows\": " << nrows
+ << ", \"ncols\": " << JacobianColsNbr
+ << ", \"entries\": [";
+ for (first_derivatives_t::const_iterator it = first_derivatives.begin();
+ it != first_derivatives.end(); it++)
+ {
+ if (it != first_derivatives.begin())
+ jacobian_output << ", ";
+
+ int eq = it->first.first;
+ string var = symbol_table.getName(getSymbIDByDerivID(it->first.second));
+ expr_t d1 = it->second;
+
+ jacobian_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"val\": \"";
+ d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms);
+ jacobian_output << "\"}" << endl;
+ }
+ jacobian_output << "]}";
+
+ int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr();
+ // Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed)
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end());
+ concat = "hessian";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, tef_terms, concat);
+ hessian_output << ", \"hessian\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"ncols\": " << g2ncols
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = second_derivatives.begin();
+ it != second_derivatives.end(); it++)
+ {
+ if (it != second_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ hessian_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms);
+ hessian_output << "\"}" << endl;
+ }
+ hessian_output << "]}";
+
+ // Writing third derivatives
+ temp_term_union_m_1 = temp_term_union;
+ temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end());
+ concat = "third_derivatives";
+ writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, tef_terms, concat);
+ third_derivatives_output << ", \"third_derivative\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"ncols\": " << hessianColsNbr * JacobianColsNbr
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = third_derivatives.begin();
+ it != third_derivatives.end(); it++)
+ {
+ if (it != third_derivatives.begin())
+ 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));
+ expr_t d3 = it->second;
+
+ third_derivatives_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"var3\": \"" << var3 << "\""
+ << ", \"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()
+ << ", " << model_output.str()
+ << ", " << jacobian_output.str()
+ << ", " << hessian_output.str()
+ << ", " << third_derivatives_output.str()
+ << "}";
+}
+
+void
+StaticModel::writeJsonParamsDerivativesFile(ostream &output) const
+{
+ if (!residuals_params_derivatives.size()
+ && !residuals_params_second_derivatives.size()
+ && !jacobian_params_derivatives.size()
+ && !jacobian_params_second_derivatives.size()
+ && !hessian_params_derivatives.size())
+ return;
+
+ ostringstream model_local_vars_output; // Used for storing model local vars
+ ostringstream model_output; // Used for storing model temp vars and equations
+ ostringstream jacobian_output; // Used for storing jacobian equations
+ ostringstream hessian_output; // Used for storing Hessian equations
+ ostringstream hessian1_output; // Used for storing Hessian equations
+ ostringstream third_derivs_output; // Used for storing third order derivatives equations
+ ostringstream third_derivs1_output; // Used for storing third order derivatives equations
+
+ deriv_node_temp_terms_t tef_terms;
+ writeJsonModelLocalVariables(model_local_vars_output, tef_terms);
+
+ temporary_terms_t temp_terms_empty;
+ string concat = "all";
+ writeJsonTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, tef_terms, concat);
+ jacobian_output << "\"deriv_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin();
+ it != residuals_params_derivatives.end(); it++)
+ {
+ if (it != residuals_params_derivatives.begin())
+ jacobian_output << ", ";
+
+ int eq = it->first.first;
+ string param = symbol_table.getName(getSymbIDByDerivID(it->first.second));
+ expr_t d1 = it->second;
+
+ jacobian_output << "{\"eq\": " << eq
+ << ", \"param\": \"" << param << "\""
+ << ", \"val\": \"";
+ d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms);
+ jacobian_output << "\"}" << endl;
+ }
+ jacobian_output << "]}";
+ hessian_output << "\"deriv_jacobian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvarcols\": " << symbol_table.endo_nbr()
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin();
+ it != jacobian_params_derivatives.end(); it++)
+ {
+ if (it != jacobian_params_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ hessian_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"param\": \"" << param << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms);
+ hessian_output << "\"}" << endl;
+ }
+ hessian_output << "]}";
+
+ hessian1_output << "\"second_deriv_residuals_wrt_params\": {"
+ << " \"nrows\": " << equations.size()
+ << ", \"nparam1cols\": " << symbol_table.param_nbr()
+ << ", \"nparam2cols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin();
+ it != residuals_params_second_derivatives.end(); ++it)
+ {
+ if (it != residuals_params_second_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ hessian1_output << "{\"eq\": " << eq
+ << ", \"param1\": \"" << param1 << "\""
+ << ", \"param2\": \"" << param2 << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms);
+ hessian1_output << "\"}" << endl;
+ }
+ hessian1_output << "]}";
+ third_derivs_output << "\"second_deriv_jacobian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvarcols\": " << symbol_table.endo_nbr()
+ << ", \"nparam1cols\": " << symbol_table.param_nbr()
+ << ", \"nparam2cols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin();
+ it != jacobian_params_second_derivatives.end(); ++it)
+ {
+ if (it != jacobian_params_second_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ third_derivs_output << "{\"eq\": " << eq
+ << ", \"var\": \"" << var << "\""
+ << ", \"param1\": \"" << param1 << "\""
+ << ", \"param2\": \"" << param2 << "\""
+ << ", \"val\": \"";
+ d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms);
+ third_derivs_output << "\"}" << endl;
+ }
+ third_derivs_output << "]}" << endl;
+
+ third_derivs1_output << "\"derivative_hessian_wrt_params\": {"
+ << " \"neqs\": " << equations.size()
+ << ", \"nvar1cols\": " << symbol_table.endo_nbr()
+ << ", \"nvar2cols\": " << symbol_table.endo_nbr()
+ << ", \"nparamcols\": " << symbol_table.param_nbr()
+ << ", \"entries\": [";
+ for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin();
+ it != hessian_params_derivatives.end(); ++it)
+ {
+ if (it != hessian_params_derivatives.begin())
+ 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));
+ expr_t d2 = it->second;
+
+ third_derivs1_output << "{\"eq\": " << eq
+ << ", \"var1\": \"" << var1 << "\""
+ << ", \"var2\": \"" << var2 << "\""
+ << ", \"param1\": \"" << param << "\""
+ << ", \"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()
+ << ", " << model_output.str()
+ << ", " << jacobian_output.str()
+ << ", " << hessian_output.str()
+ << ", " << hessian1_output.str()
+ << ", " << third_derivs_output.str()
+ << ", " << third_derivs1_output.str()
+ << "}";
+}
diff --git a/preprocessor/StaticModel.hh b/preprocessor/StaticModel.hh
index bf6cad6f3..04d41e14a 100644
--- a/preprocessor/StaticModel.hh
+++ b/preprocessor/StaticModel.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2016 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@@ -173,6 +173,12 @@ public:
//! Writes static model file
void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const;
+ //! Write JSON representation of static model
+ void writeJsonComputingPassOutput(ostream &output) const;
+
+ //! Writes file containing static parameters derivatives
+ void writeJsonParamsDerivativesFile(ostream &output) const;
+
//! Writes file containing static parameters derivatives
void writeParamsDerivativesFile(const string &basename, bool julia) const;
diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc
index 04b46de01..d6150183c 100644
--- a/preprocessor/SymbolTable.cc
+++ b/preprocessor/SymbolTable.cc
@@ -1022,7 +1022,7 @@ void
SymbolTable::writeJsonVarVector(ostream &output, const vector<int> &varvec) const
{
output << "[";
- for (int i = 0; i < varvec.size(); i++)
+ for (size_t i = 0; i < varvec.size(); i++)
{
output << endl << "{"
<< "\"name\":\"" << getName(varvec[i]) << "\", "
--
GitLab