preprocessor: output JSON after different steps, write static, dynamic, params derivs files in JSON. #1387

issue#70
Houtan Bastani 2017-02-20 12:18:11 +01:00
parent 58951045d9
commit 915bea91a1
17 changed files with 1328 additions and 116 deletions

View File

@ -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())

View File

@ -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()
<< "}";
}

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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
{

View File

@ -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,

View File

@ -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

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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 (eq > 0)
output << ", ";
if (!eqtags.empty())
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;
}

View File

@ -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;

View File

@ -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 << "]"

View File

@ -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 << "]"

View File

@ -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()
<< "}";
}

View File

@ -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;

View File

@ -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]) << "\", "