diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 287da9ca..7cbf05fa 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -50,6 +50,18 @@ SteadyStatement::writeOutput(ostream &output, const string &basename, bool minim output << "steady;" << endl; } +void +SteadyStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"steady\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + CheckStatement::CheckStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -68,6 +80,18 @@ CheckStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidatio mod_file_struct.check_present = true; } +void +CheckStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"check\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + ModelInfoStatement::ModelInfoStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -86,6 +110,18 @@ ModelInfoStatement::writeOutput(ostream &output, const string &basename, bool mi output << "model_info();" << endl; } +void +ModelInfoStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"model_info\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + SimulStatement::SimulStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -105,6 +141,18 @@ SimulStatement::writeOutput(ostream &output, const string &basename, bool minima << "perfect_foresight_solver;" << endl; } +void +SimulStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"simul\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + PerfectForesightSetupStatement::PerfectForesightSetupStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -117,6 +165,18 @@ PerfectForesightSetupStatement::writeOutput(ostream &output, const string &basen output << "perfect_foresight_setup;" << endl; } +void +PerfectForesightSetupStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"perfect_foresight_setup\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + PerfectForesightSolverStatement::PerfectForesightSolverStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -138,6 +198,18 @@ PerfectForesightSolverStatement::writeOutput(ostream &output, const string &base output << "perfect_foresight_solver;" << endl; } +void +PerfectForesightSolverStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"perfect_foresight_solver\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + PriorPosteriorFunctionStatement::PriorPosteriorFunctionStatement(const bool prior_func_arg, const OptionsList &options_list_arg) : prior_func(prior_func_arg), @@ -171,6 +243,21 @@ PriorPosteriorFunctionStatement::writeOutput(ostream &output, const string &base << "'" << type << "');" << endl; } +void +PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const +{ + string type = "posterior"; + if (prior_func) + type = "prior"; + output << "{\"statementName\": \"prior_posterior_function\", \"type\": \"" << type << "\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + VarModelStatement::VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, const string &name_arg) : @@ -490,6 +577,23 @@ StochSimulStatement::writeOutput(ostream &output, const string &basename, bool m output << "info = stoch_simul(var_list_);" << endl; } +void +StochSimulStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"stoch_simul\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + ForecastStatement::ForecastStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -505,6 +609,23 @@ ForecastStatement::writeOutput(ostream &output, const string &basename, bool min output << "[oo_.forecast,info] = dyn_forecast(var_list_,M_,options_,oo_,'simul');" << endl; } +void +ForecastStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"forecast\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + RamseyModelStatement::RamseyModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -562,7 +683,20 @@ RamseyModelStatement::writeOutput(ostream &output, const string &basename, bool options_list.writeOutput(output); } -RamseyConstraintsStatement::RamseyConstraintsStatement(const constraints_t &constraints_arg) : +void +RamseyModelStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ramsey_model\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + +RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg) : + symbol_table(symbol_table_arg), constraints(constraints_arg) { } @@ -608,6 +742,43 @@ RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename, output << "};" << endl; } +void +RamseyConstraintsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"ramsey_constraints\"" + << ", \"ramsey_model_constraints\": [" << endl; + for (RamseyConstraintsStatement::constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); ++it) + { + if (it != constraints.begin()) + output << ", "; + output << "{\"constraint\": \"" << symbol_table.getName(it->endo) << " "; + switch (it->code) + { + case oLess: + output << '<'; + break; + case oGreater: + output << '>'; + break; + case oLessEqual: + output << "<="; + break; + case oGreaterEqual: + output << ">="; + break; + default: + cerr << "Ramsey constraints: this shouldn't happen." << endl; + exit(1); + } + output << " "; + it->expression->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}" << endl; + } + output << "]" << endl; + output << "}"; +} + // Statement * // RamseyConstraintsStatement::cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) // { @@ -752,6 +923,27 @@ RamseyPolicyStatement::writeOutput(ostream &output, const string &basename, bool << "ramsey_policy(var_list_);" << endl; } +void +RamseyPolicyStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ramsey_policy\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << ", \"ramsey_policy_list\": ["; + for (vector::const_iterator it = ramsey_policy_list.begin(); + it != ramsey_policy_list.end(); ++it) + { + if (it != ramsey_policy_list.begin()) + output << ","; + output << "\"" << *it << "\""; + } + output << "]" + << "}"; +} + DiscretionaryPolicyStatement::DiscretionaryPolicyStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -812,6 +1004,23 @@ DiscretionaryPolicyStatement::writeOutput(ostream &output, const string &basenam output << "discretionary_policy(var_list_);" << endl; } +void +DiscretionaryPolicyStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"discretionary_policy\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + EstimationStatement::EstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -917,6 +1126,23 @@ EstimationStatement::writeOutput(ostream &output, const string &basename, bool m output << "oo_recursive_=dynare_estimation(var_list_);" << endl; } +void +EstimationStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"estimation\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + DynareSensitivityStatement::DynareSensitivityStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -953,6 +1179,18 @@ DynareSensitivityStatement::writeOutput(ostream &output, const string &basename, output << "dynare_sensitivity(options_gsa);" << endl; } +void +DynareSensitivityStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"dynare_sensitivity\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + RplotStatement::RplotStatement(const SymbolList &symbol_list_arg) : symbol_list(symbol_list_arg) { @@ -965,6 +1203,18 @@ RplotStatement::writeOutput(ostream &output, const string &basename, bool minima output << "rplot(var_list_);" << endl; } +void +RplotStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"rplot\""; + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + UnitRootVarsStatement::UnitRootVarsStatement(void) { } @@ -976,6 +1226,14 @@ UnitRootVarsStatement::writeOutput(ostream &output, const string &basename, bool << "options_.steadystate.nocheck = 1;" << endl; } +void +UnitRootVarsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"unit_root_vars\", " + << "\"diffuse_filter\": 1, " + << "\"steady_state.nocheck\": 1}"; +} + PeriodsStatement::PeriodsStatement(int periods_arg) : periods(periods_arg) { } @@ -986,6 +1244,13 @@ PeriodsStatement::writeOutput(ostream &output, const string &basename, bool mini output << "options_.periods = " << periods << ";" << endl; } +void +PeriodsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"periods\", " + << "\"periods\": " << periods << "}"; +} + DsampleStatement::DsampleStatement(int val1_arg) : val1(val1_arg), val2(-1) { } @@ -1003,6 +1268,14 @@ DsampleStatement::writeOutput(ostream &output, const string &basename, bool mini output << "dsample(" << val1 << ", " << val2 << ");" << endl; } +void +DsampleStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"dsample\", " + << "\"value1\": " << val1 << ", " + << "\"value2\": " << val2 << "}"; +} + EstimatedParamsStatement::EstimatedParamsStatement(const vector &estim_params_list_arg, const SymbolTable &symbol_table_arg) : estim_params_list(estim_params_list_arg), @@ -1131,6 +1404,55 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename, b } } +void +EstimatedParamsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"estimated_params\", " + << "\"params\": ["; + for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) + { + if (it != estim_params_list.begin()) + output << ", "; + output << "{"; + switch (it->type) + { + case 1: + output << "\"var\": \"" << it->name << "\""; + break; + case 2: + output << "\"param\": \"" << it->name << "\""; + break; + case 3: + output << "\"var1\": \"" << it->name << "\"," + << "\"var2\": \"" << it->name2 << "\""; + break; + } + + output << ", \"init_val\": \""; + it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"lower_bound\": \""; + it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"upper_bound\": \""; + it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"prior_distribution\": " + << it->prior + << ", \"mean\": \""; + it->mean->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"std\": \""; + it->std->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"p3\": \""; + it->p3->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"p4\": \""; + it->p4->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \"jscale\": \""; + it->jscale->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}" << endl; + } + output << "]" + << "}"; +} + EstimatedParamsInitStatement::EstimatedParamsInitStatement(const vector &estim_params_list_arg, const SymbolTable &symbol_table_arg, const bool use_calibration_arg) : @@ -1204,6 +1526,42 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam } } +void +EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"estimated_params_init\""; + + if (use_calibration) + output << ", \"use_calibration_initialization\": 1"; + + output << ", \"params\": ["; + for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) + { + if (it != estim_params_list.begin()) + output << ", "; + output << "{"; + switch (it->type) + { + case 1: + output << "\"var\": \"" << it->name << "\""; + break; + case 2: + output << "\"param\": \"" << it->name << "\""; + break; + case 3: + output << "\"var1\": \"" << it->name << "\"," + << "\"var2\": \"" << it->name2 << "\""; + break; + } + output << ", \"init_val\": \""; + it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << "}"; +} + EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement(const vector &estim_params_list_arg, const SymbolTable &symbol_table_arg) : estim_params_list(estim_params_list_arg), @@ -1290,6 +1648,40 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen } } +void +EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"estimated_params_bounds\", " + << "\"params\": ["; + + for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) + { + if (it != estim_params_list.begin()) + output << ", "; + output << "{"; + switch (it->type) + { + case 1: + output << "\"var\": \"" << it->name << "\""; + case 2: + output << "\"param\": \"" << it->name << "\""; + break; + case 3: + output << "\"var1\": \"" << it->name << "\"," + << "\"var2\": \"" << it->name2 << "\""; + break; + } + output << ", \"lower_bound\": "; + it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << ", \"upper_bound\": "; + it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "}"; + } + output << "]" + << "}"; +} + ObservationTrendsStatement::ObservationTrendsStatement(const trend_elements_t &trend_elements_arg, const SymbolTable &symbol_table_arg) : trend_elements(trend_elements_arg), @@ -1316,6 +1708,32 @@ ObservationTrendsStatement::writeOutput(ostream &output, const string &basename, } } +void +ObservationTrendsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"observation_trends\", " + << "\"trends\" : {"; + bool printed = false; + for (trend_elements_t::const_iterator it = trend_elements.begin(); + it != trend_elements.end(); it++) + { + if (symbol_table.getType(it->first) == eEndogenous) + { + if (printed) + output << ", "; + output << "\"" << it->first << "\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"" << endl; + printed = true; + } + else + cerr << "Warning : Non-variable symbol used in observation_trends: " << it->first << endl; + } + output << "}" + << "}"; +} + OsrParamsStatement::OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg) : symbol_list(symbol_list_arg), symbol_table(symbol_table_arg) @@ -1342,6 +1760,18 @@ OsrParamsStatement::writeOutput(ostream &output, const string &basename, bool mi output << "M_.osr.param_indices(" << ++i <<") = " << symbol_table.getTypeSpecificID(*it) + 1 << ";" << endl; } +void +OsrParamsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"osr_params\""; + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + OsrStatement::OsrStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -1381,6 +1811,29 @@ OsrParamsBoundsStatement::writeOutput(ostream &output, const string &basename, b } } +void +OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"osr_params_bounds\"" + << ", \"bounds\": ["; + for (vector::const_iterator it = osr_params_list.begin(); + it != osr_params_list.end(); it++) + { + if (it != osr_params_list.begin()) + output << ", "; + output << "{\"parameter\": \"" << it->name << "\"," + << "\"bounds\": [\""; + it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\", \""; + it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"]" + << "}"; + } + output << "]" + << "}"; +} + void OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { @@ -1418,6 +1871,23 @@ OsrStatement::writeOutput(ostream &output, const string &basename, bool minimal_ output << "oo_.osr = osr(var_list_,M_.osr.param_names,M_.osr.variable_indices,M_.osr.variable_weights);" << endl; } +void +OsrStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"osr\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + OptimWeightsStatement::OptimWeightsStatement(const var_weights_t &var_weights_arg, const covar_weights_t &covar_weights_arg, const SymbolTable &symbol_table_arg) : @@ -1469,6 +1939,38 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename, bool } } +void +OptimWeightsStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"optim_weights\", " + << "\"weights\": ["; + for (var_weights_t::const_iterator it = var_weights.begin(); + it != var_weights.end(); it++) + { + if (it != var_weights.begin()) + output << ", "; + output << "{\"name\": \"" << it->first << "\"" + << ", \"value\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + + for (covar_weights_t::const_iterator it = covar_weights.begin(); + it != covar_weights.end(); it++) + { + if (it != covar_weights.begin() || !var_weights.empty()) + output << ", "; + output << "{\"name1\": \"" << it->first.first << "\"" + << ", \"name2\": \"" << it->first.second << "\"" + << ", \"value\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << "}"; +} + DynaSaveStatement::DynaSaveStatement(const SymbolList &symbol_list_arg, const string &filename_arg) : symbol_list(symbol_list_arg), @@ -1484,6 +1986,19 @@ DynaSaveStatement::writeOutput(ostream &output, const string &basename, bool min << "',var_list_);" << endl; } +void +DynaSaveStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"dynasave\", " + << "\"filename\": \"" << filename << "\""; + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + DynaTypeStatement::DynaTypeStatement(const SymbolList &symbol_list_arg, const string &filename_arg) : symbol_list(symbol_list_arg), @@ -1499,6 +2014,19 @@ DynaTypeStatement::writeOutput(ostream &output, const string &basename, bool min << "',var_list_);" << endl; } +void +DynaTypeStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"dynatype\", " + << "\"filename\": \"" << filename << "\""; + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + ModelComparisonStatement::ModelComparisonStatement(const filename_list_t &filename_list_arg, const OptionsList &options_list_arg) : filename_list(filename_list_arg), @@ -1523,8 +2051,37 @@ ModelComparisonStatement::writeOutput(ostream &output, const string &basename, b output << "oo_ = model_comparison(ModelNames_,ModelPriors_,oo_,options_,M_.fname);" << endl; } +void +ModelComparisonStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"model_comparison\""; + if (!filename_list.empty()) + output << ", \"filename_list\": {"; + + for (filename_list_t::const_iterator it = filename_list.begin(); + it != filename_list.end(); it++) + { + if (it != filename_list.begin()) + output << ", "; + output << "\"name\": \"" << it->first << "\"" + << "\"prior\": \"" << it->second << "\""; + } + + if (!filename_list.empty()) + output << "}"; + + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + + output << "}"; +} + PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) : - model_tree(model_tree_arg) + model_tree(model_tree_arg), + computing_pass_called(false) { } @@ -1557,6 +2114,7 @@ void PlannerObjectiveStatement::computingPass() { model_tree->computingPass(eval_context_t(), false, true, true, none, false, false); + computing_pass_called = true; } void @@ -1565,6 +2123,19 @@ PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, model_tree->writeStaticFile(basename + "_objective", false, false, false, false); } +void +PlannerObjectiveStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"planner_objective\"" + << ", "; + if (computing_pass_called) + model_tree->writeJsonComputingPassOutput(output, false); + else + model_tree->writeJsonOutput(output); + + output << "}"; +} + BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg) : maxnlags(maxnlags_arg), options_list(options_list_arg) @@ -1584,6 +2155,18 @@ BVARDensityStatement::writeOutput(ostream &output, const string &basename, bool output << "bvar_density(" << maxnlags << ");" << endl; } +void +BVARDensityStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"bvar_density\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + BVARForecastStatement::BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg) : nlags(nlags_arg), options_list(options_list_arg) @@ -1603,6 +2186,18 @@ BVARForecastStatement::writeOutput(ostream &output, const string &basename, bool output << "bvar_forecast(" << nlags << ");" << endl; } +void +BVARForecastStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"bvar_forecast\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + SBVARStatement::SBVARStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1621,6 +2216,18 @@ SBVARStatement::writeOutput(ostream &output, const string &basename, bool minima output << "sbvar(M_,options_);" << endl; } +void +SBVARStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"sbvar\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVAREstimationStatement::MSSBVAREstimationStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1650,6 +2257,18 @@ MSSBVAREstimationStatement::writeOutput(ostream &output, const string &basename, output << "[options_, oo_] = ms_estimation(M_, options_, oo_);" << endl; } +void +MSSBVAREstimationStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_estimation\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARSimulationStatement::MSSBVARSimulationStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1678,6 +2297,18 @@ MSSBVARSimulationStatement::writeOutput(ostream &output, const string &basename, output << "[options_, oo_] = ms_simulation(M_, options_, oo_);" << endl; } +void +MSSBVARSimulationStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_simulation\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARComputeMDDStatement::MSSBVARComputeMDDStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1697,6 +2328,18 @@ MSSBVARComputeMDDStatement::writeOutput(ostream &output, const string &basename, output << "[options_, oo_] = ms_compute_mdd(M_, options_, oo_);" << endl; } +void +MSSBVARComputeMDDStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_compute_mdd\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARComputeProbabilitiesStatement::MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1724,6 +2367,18 @@ MSSBVARComputeProbabilitiesStatement::writeOutput(ostream &output, const string output << "[options_, oo_] = ms_compute_probabilities(M_, options_, oo_);" << endl; } +void +MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_compute_probabilities\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARIrfStatement::MSSBVARIrfStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -1771,6 +2426,23 @@ MSSBVARIrfStatement::writeOutput(ostream &output, const string &basename, bool m output << "[options_, oo_] = ms_irf(var_list_,M_, options_, oo_);" << endl; } +void +MSSBVARIrfStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_irf\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARForecastStatement::MSSBVARForecastStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1797,6 +2469,18 @@ MSSBVARForecastStatement::writeOutput(ostream &output, const string &basename, b output << "[options_, oo_] = ms_forecast(M_, options_, oo_);" << endl; } +void +MSSBVARForecastStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_forecast\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + MSSBVARVarianceDecompositionStatement::MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1841,6 +2525,18 @@ MSSBVARVarianceDecompositionStatement::writeOutput(ostream &output, const string output << "[options_, oo_] = ms_variance_decomposition(M_, options_, oo_);" << endl; } +void +MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"ms_sbvar_variance_decomposition\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + IdentificationStatement::IdentificationStatement(const OptionsList &options_list_arg) { options_list = options_list_arg; @@ -1880,6 +2576,18 @@ IdentificationStatement::writeOutput(ostream &output, const string &basename, bo output << "dynare_identification(options_ident);" << endl; } +void +IdentificationStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"identification\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg) : dynamic_model(dynamic_model_arg), write_equation_tags(write_equation_tags_arg) @@ -1892,6 +2600,12 @@ WriteLatexDynamicModelStatement::writeOutput(ostream &output, const string &base dynamic_model.writeLatexFile(basename, write_equation_tags); } +void +WriteLatexDynamicModelStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"write_latex_dynamic_model\"}"; +} + WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel &static_model_arg) : static_model(static_model_arg) { @@ -1903,6 +2617,12 @@ WriteLatexStaticModelStatement::writeOutput(ostream &output, const string &basen static_model.writeLatexFile(basename); } +void +WriteLatexStaticModelStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"write_latex_static_model\"}"; +} + WriteLatexOriginalModelStatement::WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg) : original_model(original_model_arg) { @@ -1914,6 +2634,12 @@ WriteLatexOriginalModelStatement::writeOutput(ostream &output, const string &bas original_model.writeLatexOriginalFile(basename); } +void +WriteLatexOriginalModelStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"write_latex_original_model\"}"; +} + ShockDecompositionStatement::ShockDecompositionStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -1926,7 +2652,24 @@ ShockDecompositionStatement::writeOutput(ostream &output, const string &basename { options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "[oo_,M_]= shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; + output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; +} + +void +ShockDecompositionStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"shock_decomposition\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; } RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement(const SymbolList &symbol_list_arg, @@ -1988,6 +2731,18 @@ ConditionalForecastStatement::writeOutput(ostream &output, const string &basenam output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl; } +void +ConditionalForecastStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"conditional_forecast\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + PlotConditionalForecastStatement::PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg) : periods(periods_arg), symbol_list(symbol_list_arg) @@ -2004,6 +2759,19 @@ PlotConditionalForecastStatement::writeOutput(ostream &output, const string &bas output << "plot_icforecast(var_list_, " << periods << ",options_);" << endl; } +void +PlotConditionalForecastStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"plot_conditional_forecast\", " + << "\"periods\": " << periods; + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg, const bool &upper_cholesky_present_arg, const bool &lower_cholesky_present_arg, @@ -2114,6 +2882,42 @@ SvarIdentificationStatement::writeOutput(ostream &output, const string &basename } } +void +SvarIdentificationStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"svar_identification\""; + + if (upper_cholesky_present) + output << ", \"upper_cholesky\": 1"; + + if (lower_cholesky_present) + output << ", \"lower_cholesky\": 1"; + + if (constants_exclusion_present) + output << ", \"constants_exclusion\": 1"; + + if (!upper_cholesky_present && !lower_cholesky_present) + { + output << ", \"nlags\": " << getMaxLag() + << ", \"restrictions\": ["; + + for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++) + { + if (it != restrictions.begin()) + output << ", "; + output << "{" + << "\"equation_number\": " << it->equation << ", " + << "\"restriction_number\": " << it->restriction_nbr << ", " + << "\"variable\": \"" << symbol_table.getName(it->variable) << "\", " + << "\"expression\": \""; + it->value->writeOutput(output); + output << "\"}"; + } + output << "]"; + } + output << "}"; +} + MarkovSwitchingStatement::MarkovSwitchingStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -2353,6 +3157,33 @@ MarkovSwitchingStatement::writeCOutput(ostream &output, const string &basename) << " chain, number_of_regimes, number_of_lags, number_of_lags_was_passed, parameters, duration, restriction_map));" << endl; } +void +MarkovSwitchingStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"markov_switching\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + + if (!restriction_map.empty()) + output << ", {"; + for (map, double >::const_iterator it = restriction_map.begin(); + it != restriction_map.end(); it++) + { + if (it != restriction_map.begin()) + output << ", "; + output << "{\"current_period_regime\": " << it->first.first + << ", \"next_period_regime\": " << it->first.second + << ", \"transition_probability\": "<< it->second + << "}"; + } + if (!restriction_map.empty()) + output << "}"; + output << "}"; +} + SvarStatement::SvarStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -2417,6 +3248,18 @@ SvarStatement::writeOutput(ostream &output, const string &basename, bool minimal output << "'ALL';" << endl; } +void +SvarStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"svar\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + SvarGlobalIdentificationCheckStatement::SvarGlobalIdentificationCheckStatement(void) { } @@ -2427,6 +3270,12 @@ SvarGlobalIdentificationCheckStatement::writeOutput(ostream &output, const strin output << "svar_global_identification_check(options_);" << std::endl; } +void +SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"svar_global_identification\"}"; +} + SetTimeStatement::SetTimeStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -2438,6 +3287,18 @@ SetTimeStatement::writeOutput(ostream &output, const string &basename, bool mini options_list.writeOutput(output); } +void +SetTimeStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"set_time\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + EstimationDataStatement::EstimationDataStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -2477,6 +3338,18 @@ EstimationDataStatement::writeOutput(ostream &output, const string &basename, bo options_list.writeOutput(output, "options_.dataset"); } +void +EstimationDataStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"estimation_data\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + SubsamplesStatement::SubsamplesStatement(const string &name1_arg, const string &name2_arg, const subsample_declaration_map_t subsample_declaration_map_arg, @@ -2550,6 +3423,30 @@ SubsamplesStatement::writeOutput(ostream &output, const string &basename, bool m << endl; } +void +SubsamplesStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"subsamples\"" + << ", \"name1\": \"" << name1 << "\""; + if (!name2.empty()) + output << ", \"name2\": \"" << name2 << "\""; + + output << ", \"declarations\": {"; + for (subsample_declaration_map_t::const_iterator it = subsample_declaration_map.begin(); + it != subsample_declaration_map.end(); it++) + { + if (it != subsample_declaration_map.begin()) + output << ","; + output << "{" + << "\"range_index\": \"" << it->first << "\"" + << ", \"date1\": \"" << it->second.first << "\"" + << ", \"date2\": \"" << it->second.second << "\"" + << "}"; + } + output << "}" + << "}"; +} + SubsamplesEqualStatement::SubsamplesEqualStatement(const string &to_name1_arg, const string &to_name2_arg, const string &from_name1_arg, @@ -2612,6 +3509,19 @@ SubsamplesEqualStatement::writeOutput(ostream &output, const string &basename, b << endl; } +void +SubsamplesEqualStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"subsamples_equal\"" + << ", \"to_name1\": \"" << to_name1 << "\""; + if (!to_name2.empty()) + output << ", \"to_name2\": \"" << to_name2 << "\""; + output << ", \"from_name1\": \"" << from_name1 << "\""; + if (!from_name2.empty()) + output << ", \"from_name2\": \"" << from_name2 << "\""; + output << "}"; +} + JointPriorStatement::JointPriorStatement(const vector joint_parameters_arg, const PriorDistributions &prior_shape_arg, const OptionsList &options_list_arg) : @@ -2718,6 +3628,59 @@ JointPriorStatement::writeOutputHelper(ostream &output, const string &field, con output << "};" << endl; } +void +JointPriorStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"joint_prior\"" + << ", \"key\": ["; + for (vector::const_iterator it = joint_parameters.begin(); it != joint_parameters.end(); it++) + { + if (it != joint_parameters.begin()) + output << ", "; + output << "\"" << *it << "\""; + } + output << "]"; + + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + + output << ", \"shape\": "; + switch (prior_shape) + { + case eBeta: + output << "\"beta\""; + break; + case eGamma: + output << "\"gamma\""; + break; + case eNormal: + output << "\"normal\""; + break; + case eInvGamma: + output << "\"inv_gamma\""; + break; + case eUniform: + output << "\"uniform\""; + break; + case eInvGamma2: + output << "\"inv_gamma2\""; + break; + case eDirichlet: + output << "\"dirichlet\""; + break; + case eWeibull: + output << "\"weibull\""; + break; + case eNoShape: + cerr << "Impossible case." << endl; + exit(EXIT_FAILURE); + } + output << "}"; +} + BasicPriorStatement::~BasicPriorStatement() { } @@ -2838,6 +3801,27 @@ BasicPriorStatement::writePriorOutput(ostream &output, string &lhs_field, const writeCommonOutput(output, lhs_field); } +void +BasicPriorStatement::writeJsonPriorOutput(ostream &output) const +{ + output << ", \"name\": \"" << name << "\"" + << ", \"subsample\": \"" << subsample_name << "\"" + << ", "; + writeJsonShape(output); + if (variance != NULL) + { + deriv_node_temp_terms_t tef_terms; + output << ", \"variance\": \""; + variance->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\""; + } + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } +} + void BasicPriorStatement::writeCVarianceOption(ostream &output) const { @@ -2911,6 +3895,41 @@ BasicPriorStatement::writeCShape(ostream &output) const } } +void +BasicPriorStatement::writeJsonShape(ostream &output) const +{ + output << "\"shape\": "; + switch (prior_shape) + { + case eBeta: + output << "\"beta\""; + break; + case eGamma: + output << "\"gamma\""; + break; + case eNormal: + output << "\"normal\""; + break; + case eInvGamma: + output << "\"inv_gamma\""; + break; + case eUniform: + output << "\"uniform\""; + break; + case eInvGamma2: + output << "\"inv_gamma2\""; + break; + case eDirichlet: + output << "\"dirichlet\""; + break; + case eWeibull: + output << "\"weibull\""; + break; + case eNoShape: + assert(prior_shape != eNoShape); + } +} + PriorStatement::PriorStatement(const string &name_arg, const string &subsample_name_arg, const PriorDistributions &prior_shape_arg, @@ -2930,6 +3949,14 @@ PriorStatement::writeOutput(ostream &output, const string &basename, bool minima writePriorOutput(output, lhs_field, ""); } +void +PriorStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"prior\""; + writeJsonPriorOutput(output); + output << "}"; +} + void PriorStatement::writeCOutput(ostream &output, const string &basename) { @@ -2970,6 +3997,14 @@ StdPriorStatement::writeOutput(ostream &output, const string &basename, bool min writePriorOutput(output, lhs_field, ""); } +void +StdPriorStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"std_prior\""; + writeJsonPriorOutput(output); + output << "}"; +} + void StdPriorStatement::writeCOutput(ostream &output, const string &basename) { @@ -3035,6 +4070,15 @@ CorrPriorStatement::writeOutput(ostream &output, const string &basename, bool mi writePriorOutput(output, lhs_field, name1); } +void +CorrPriorStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"corr_prior\"" + << ", \"name2\": \"" << name1 << "\""; + writeJsonPriorOutput(output); + output << "}"; +} + void CorrPriorStatement::writeCOutput(ostream &output, const string &basename) { @@ -3169,6 +4213,21 @@ PriorEqualStatement::writeOutput(ostream &output, const string &basename, bool m output << lhs_field << " = " << rhs_field << ";" << endl; } +void +PriorEqualStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"prior_equal\"" + << ", \"to_name1\": \"" << to_name1 << "\""; + if (to_declaration_type == "corr") + output << ", \"to_name2\": \"" << to_name2 << "\""; + output << ", \"to_subsample\": \"" << to_subsample_name << "\"" + << ", \"from_name1\": \"" << from_name1 << "\""; + if (to_declaration_type == "corr") + output << ", \"from_name2\": \"" << from_name2 << "\""; + output << ", \"from_subsample\": \"" << from_subsample_name << "\"" + << "}"; +} + BasicOptionsStatement::~BasicOptionsStatement() { } @@ -3246,6 +4305,19 @@ BasicOptionsStatement::writeOptionsOutput(ostream &output, string &lhs_field, co writeCommonOutput(output, lhs_field); } +void +BasicOptionsStatement::writeJsonOptionsOutput(ostream &output) const +{ + output << ", \"name\": \"" << name << "\""; + if (!subsample_name.empty()) + output << ", \"subsample_name\": \"" << subsample_name << "\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } +} + OptionsStatement::OptionsStatement(const string &name_arg, const string &subsample_name_arg, const OptionsList &options_list_arg) : @@ -3263,6 +4335,14 @@ OptionsStatement::writeOutput(ostream &output, const string &basename, bool mini writeOptionsOutput(output, lhs_field, ""); } +void +OptionsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"options\""; + writeJsonOptionsOutput(output); + output << "}"; +} + void OptionsStatement::writeCOutput(ostream &output, const string &basename) { @@ -3294,6 +4374,14 @@ StdOptionsStatement::writeOutput(ostream &output, const string &basename, bool m writeOptionsOutput(output, lhs_field, ""); } +void +StdOptionsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"std_options\""; + writeJsonOptionsOutput(output); + output << "}"; +} + void StdOptionsStatement::writeCOutput(ostream &output, const string &basename) { @@ -3351,6 +4439,15 @@ CorrOptionsStatement::writeOutput(ostream &output, const string &basename, bool writeOptionsOutput(output, lhs_field, name1); } +void +CorrOptionsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"corr_options\"" + << ", \"name2\": \"" << name1 << "\""; + writeJsonOptionsOutput(output); + output << "}"; +} + void CorrOptionsStatement::writeCOutput(ostream &output, const string &basename) { @@ -3410,6 +4507,21 @@ OptionsEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso } } +void +OptionsEqualStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"options_equal\"" + << ", \"to_name1\": \"" << to_name1 << "\""; + if (to_declaration_type == "corr") + output << ", \"to_name2\": \"" << to_name2 << "\""; + output << ", \"to_subsample\": \"" << to_subsample_name << "\"" + << ", \"from_name1\": \"" << from_name1 << "\""; + if (to_declaration_type == "corr") + output << ", \"from_name2\": \"" << from_name2 << "\""; + output << ", \"from_subsample\": \"" << from_subsample_name << "\"" + << "}"; +} + void OptionsEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const { @@ -3502,6 +4614,23 @@ CalibSmootherStatement::writeOutput(ostream &output, const string &basename, boo output << "[oo_,M_,options_,bayestopt_]=evaluate_smoother('calibration',var_list_,M_,oo_,options_,bayestopt_,estim_params_);" << endl; } +void +CalibSmootherStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"calib_smoother\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + if (!symbol_list.empty()) + { + output << ", "; + symbol_list.writeJsonOutput(output); + } + output << "}"; +} + ExtendedPathStatement::ExtendedPathStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -3538,6 +4667,18 @@ ExtendedPathStatement::writeOutput(ostream &output, const string &basename, bool << ", [], options_, M_, oo_);" << endl; } +void +ExtendedPathStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"extended_path\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} + ModelDiagnosticsStatement::ModelDiagnosticsStatement() { } @@ -3548,6 +4689,12 @@ ModelDiagnosticsStatement::writeOutput(ostream &output, const string &basename, output << "model_diagnostics(M_,options_,oo_);" << endl; } +void +ModelDiagnosticsStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"model_diagnostics\"}"; +} + Smoother2histvalStatement::Smoother2histvalStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -3559,3 +4706,15 @@ Smoother2histvalStatement::writeOutput(ostream &output, const string &basename, options_list.writeOutput(output, "options_smoother2histval"); output << "smoother2histval(options_smoother2histval);" << endl; } + +void +Smoother2histvalStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"smoother_2_histval\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + output << "}"; +} diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 0291cc9e..4fdd1256 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -36,6 +36,7 @@ public: SteadyStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class CheckStatement : public Statement @@ -46,6 +47,7 @@ public: CheckStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SimulStatement : public Statement @@ -56,6 +58,7 @@ public: SimulStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class PerfectForesightSetupStatement : public Statement @@ -65,6 +68,7 @@ private: public: PerfectForesightSetupStatement(const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class PerfectForesightSolverStatement : public Statement @@ -75,6 +79,7 @@ public: PerfectForesightSolverStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class PriorPosteriorFunctionStatement : public Statement @@ -86,6 +91,7 @@ public: PriorPosteriorFunctionStatement(const bool prior_func_arg, const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ModelInfoStatement : public Statement @@ -96,6 +102,7 @@ public: ModelInfoStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class StochSimulStatement : public Statement @@ -108,6 +115,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class VarModelStatement : public Statement @@ -172,6 +180,7 @@ public: ForecastStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class RamseyModelStatement : public Statement @@ -184,6 +193,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class RamseyConstraintsStatement : public Statement @@ -197,11 +207,13 @@ public: }; typedef vector constraints_t; private: + const SymbolTable &symbol_table; const constraints_t constraints; public: - RamseyConstraintsStatement(const constraints_t &constraints_arg); + RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; // virtual Statement *cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table); }; @@ -218,6 +230,7 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkRamseyPolicyList(); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class DiscretionaryPolicyStatement : public Statement @@ -230,6 +243,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class RplotStatement : public Statement @@ -239,6 +253,7 @@ private: public: RplotStatement(const SymbolList &symbol_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class UnitRootVarsStatement : public Statement @@ -246,6 +261,7 @@ class UnitRootVarsStatement : public Statement public: UnitRootVarsStatement(void); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class PeriodsStatement : public Statement @@ -255,6 +271,7 @@ private: public: PeriodsStatement(int periods_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class DsampleStatement : public Statement @@ -265,6 +282,7 @@ public: DsampleStatement(int val1_arg); DsampleStatement(int val1_arg, int val2_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class EstimationStatement : public Statement @@ -277,6 +295,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class DynareSensitivityStatement : public Statement @@ -287,6 +306,7 @@ public: DynareSensitivityStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ObservationTrendsStatement : public Statement @@ -300,6 +320,7 @@ public: ObservationTrendsStatement(const trend_elements_t &trend_elements_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class OsrParamsStatement : public Statement @@ -311,6 +332,7 @@ public: OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class OsrStatement : public Statement @@ -323,6 +345,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; //! Temporary structure used when parsing estimation_params* statements @@ -349,6 +372,7 @@ public: OsrParamsBoundsStatement(const vector &osr_params_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class DynaTypeStatement : public Statement @@ -360,6 +384,7 @@ public: DynaTypeStatement(const SymbolList &symbol_list_arg, const string &filename_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class DynaSaveStatement : public Statement @@ -371,6 +396,7 @@ public: DynaSaveStatement(const SymbolList &symbol_list_arg, const string &filename_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ModelComparisonStatement : public Statement @@ -384,6 +410,7 @@ public: ModelComparisonStatement(const filename_list_t &filename_list_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; //! Temporary structure used when parsing estimation_params* statements @@ -423,6 +450,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class EstimatedParamsInitStatement : public Statement @@ -437,6 +465,7 @@ public: const bool use_calibration_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class EstimatedParamsBoundsStatement : public Statement @@ -448,6 +477,7 @@ public: EstimatedParamsBoundsStatement(const vector &estim_params_list_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class OptimWeightsStatement : public Statement @@ -465,6 +495,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; /*! \todo Make model_tree a member instead of a pointer */ @@ -472,6 +503,7 @@ class PlannerObjectiveStatement : public Statement { private: StaticModel *model_tree; + bool computing_pass_called; public: //! Constructor /*! \param model_tree_arg the model tree used to store the objective function. @@ -485,6 +517,7 @@ public: /*! \todo allow for the possibility of disabling temporary terms */ virtual void computingPass(); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; //! Return the Planner Objective StaticModel *getPlannerObjective() const; }; @@ -498,6 +531,7 @@ public: BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class BVARForecastStatement : public Statement @@ -509,6 +543,7 @@ public: BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SBVARStatement : public Statement @@ -519,6 +554,7 @@ public: SBVARStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVAREstimationStatement : public Statement @@ -529,6 +565,7 @@ public: MSSBVAREstimationStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARSimulationStatement : public Statement @@ -539,6 +576,7 @@ public: MSSBVARSimulationStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARComputeMDDStatement : public Statement @@ -549,6 +587,7 @@ public: MSSBVARComputeMDDStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARComputeProbabilitiesStatement : public Statement @@ -559,6 +598,7 @@ public: MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARIrfStatement : public Statement @@ -571,6 +611,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARForecastStatement : public Statement @@ -581,6 +622,7 @@ public: MSSBVARForecastStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MSSBVARVarianceDecompositionStatement : public Statement @@ -591,6 +633,7 @@ public: MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class IdentificationStatement : public Statement @@ -601,6 +644,7 @@ public: IdentificationStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class WriteLatexDynamicModelStatement : public Statement @@ -611,6 +655,7 @@ private: public: WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class WriteLatexStaticModelStatement : public Statement @@ -620,6 +665,7 @@ private: public: WriteLatexStaticModelStatement(const StaticModel &static_model_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class WriteLatexOriginalModelStatement : public Statement @@ -629,6 +675,7 @@ private: public: WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ShockDecompositionStatement : public Statement @@ -640,6 +687,7 @@ public: ShockDecompositionStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class RealtimeShockDecompositionStatement : public Statement @@ -682,6 +730,7 @@ private: public: ConditionalForecastStatement(const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class PlotConditionalForecastStatement : public Statement @@ -693,6 +742,7 @@ private: public: PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class CalibSmootherStatement : public Statement @@ -705,6 +755,7 @@ public: const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ExtendedPathStatement : public Statement @@ -715,6 +766,7 @@ public: ExtendedPathStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SvarIdentificationStatement : public Statement @@ -746,6 +798,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MarkovSwitchingStatement : public Statement @@ -758,6 +811,7 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class SvarStatement : public Statement @@ -768,6 +822,7 @@ public: SvarStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SvarGlobalIdentificationCheckStatement : public Statement @@ -775,6 +830,7 @@ class SvarGlobalIdentificationCheckStatement : public Statement public: SvarGlobalIdentificationCheckStatement(); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SetTimeStatement : public Statement @@ -784,6 +840,7 @@ private: public: SetTimeStatement(const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class EstimationDataStatement : public Statement @@ -794,6 +851,7 @@ public: EstimationDataStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SubsamplesStatement : public Statement @@ -813,6 +871,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SubsamplesEqualStatement : public Statement @@ -830,6 +889,7 @@ public: const string &from_name2_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class JointPriorStatement : public Statement @@ -845,6 +905,7 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; + virtual void writeJsonOutput(ostream &output) const; }; class BasicPriorStatement : public Statement @@ -877,6 +938,8 @@ protected: void writeCShape(ostream &output) const; void writeCVarianceOption(ostream &output) const; void writeCDomain(ostream &output) const; + void writeJsonShape(ostream &output) const; + void writeJsonPriorOutput(ostream &output) const; }; class PriorStatement : public BasicPriorStatement @@ -889,6 +952,7 @@ public: const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class StdPriorStatement : public BasicPriorStatement @@ -904,6 +968,7 @@ public: const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class CorrPriorStatement : public BasicPriorStatement @@ -922,6 +987,7 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class PriorEqualStatement : public Statement @@ -949,6 +1015,7 @@ public: void get_base_name(const SymbolType symb_type, string &lhs_field) const; virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class BasicOptionsStatement : public Statement @@ -972,6 +1039,7 @@ protected: void writeOptionsIndex(ostream &output, const string &lhs_field) const; void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; void writeCOutputHelper(ostream &output, const string &field) const; + void writeJsonOptionsOutput(ostream &output) const; }; class OptionsStatement : public BasicOptionsStatement @@ -980,6 +1048,7 @@ public: OptionsStatement(const string &name_arg, const string &subsample_name_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class StdOptionsStatement : public BasicOptionsStatement @@ -993,6 +1062,7 @@ public: const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class CorrOptionsStatement : public BasicOptionsStatement @@ -1008,6 +1078,7 @@ public: virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class OptionsEqualStatement : public Statement @@ -1035,6 +1106,7 @@ public: void get_base_name(const SymbolType symb_type, string &lhs_field) const; virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ModelDiagnosticsStatement : public Statement @@ -1042,6 +1114,7 @@ class ModelDiagnosticsStatement : public Statement public: ModelDiagnosticsStatement(); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class Smoother2histvalStatement : public Statement @@ -1051,6 +1124,7 @@ private: public: Smoother2histvalStatement(const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; #endif diff --git a/DynamicModel.cc b/DynamicModel.cc index 7bce38a2..a4c0e162 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -5544,3 +5544,470 @@ DynamicModel::writeCCOutput(ostream &output, const string &basename, bool block_ output << "NNZDerivatives.push_back(-1);" << endl << "NNZDerivatives.push_back(-1);" << endl; } + +void +DynamicModel::writeJsonOutput(ostream &output) const +{ + writeJsonModelEquations(output, false); + output << ", "; + writeJsonXrefs(output); +} + +void +DynamicModel::writeJsonXrefs(ostream &output) const +{ + output << "\"xrefs\": {" + << "\"parameters\": ["; + for (map, set >::const_iterator it = xref_param.begin(); + it != xref_param.end(); it++) + { + if (it != xref_param.begin()) + output << ", "; + output << "{\"parameter\": \"" << symbol_table.getName(it->first.first) << "\"" + << ", \"equations\": ["; + for (set::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << ", "; + output << *it1 + 1; + } + output << "]}"; + } + output << "]" + << ", \"endogenous\": ["; + for (map, set >::const_iterator it = xref_endo.begin(); + it != xref_endo.end(); it++) + { + if (it != xref_endo.begin()) + output << ", "; + output << "{\"endogenous\": \"" << symbol_table.getName(it->first.first) << "\"" + << ", \"shift\": " << it->first.second + << ", \"equations\": ["; + for (set::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << ", "; + output << *it1 + 1; + } + output << "]}"; + } + output << "]" + << ", \"exogenous\": ["; + for (map, set >::const_iterator it = xref_exo.begin(); + it != xref_exo.end(); it++) + { + if (it != xref_exo.begin()) + output << ", "; + output << "{\"exogenous\": \"" << symbol_table.getName(it->first.first) << "\"" + << ", \"shift\": " << it->first.second + << ", \"equations\": ["; + for (set::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << ", "; + output << *it1 + 1; + } + output << "]}"; + } + output << "]" + << ", \"exogenous_deterministic\": ["; + for (map, set >::const_iterator it = xref_exo_det.begin(); + it != xref_exo_det.end(); it++) + { + if (it != xref_exo_det.begin()) + output << ", "; + output << "{\"exogenous_det\": \"" << symbol_table.getName(it->first.first) << "\"" + << ", \"shift\": " << it->first.second + << ", \"equations\": ["; + for (set::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << ", "; + output << *it1 + 1; + } + output << "]}"; + } + output << "]}" << endl; +} + +void +DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const +{ + ostringstream model_local_vars_output; // Used for storing model local vars + ostringstream model_output; // Used for storing model temp vars and equations + 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); + model_output << ", "; + 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; + int var = it->first.second; + int col = getDynJacobianCol(var); + expr_t d1 = it->second; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"lag\": " << getLagByDerivID(var); + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"col\": " << col + 1 + << ", \"val\": \""; + d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); + jacobian_output << "\"}" << endl; + } + 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; + int var1 = it->first.second.first; + int var2 = it->first.second.second; + expr_t d2 = it->second; + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); + int col_nb = id1 * dynJacobianColsNbr + id2; + int col_nb_sym = id2 * dynJacobianColsNbr + id1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2); + else + hessian_output << "{\"row\": " << eq + 1; + + hessian_output << ", \"col\": [" << col_nb + 1; + if (id1 != id2) + hessian_output << ", " << col_nb_sym + 1; + hessian_output << "]" + << ", \"val\": \""; + d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); + hessian_output << "\"}" << endl; + } + 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; + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int var3 = it->first.second.second.second; + expr_t d3 = it->second; + + if (writeDetails) + third_derivatives_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2) + << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\"" + << ", \"lag3\": " << getLagByDerivID(var3); + else + third_derivatives_output << "{\"row\": " << eq + 1; + + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); + int id3 = getDynJacobianCol(var3); + set cols; + cols.insert(id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3); + cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); + cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); + cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); + cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); + cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); + + third_derivatives_output << ", \"col\": ["; + for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) + { + if (it2 != cols.begin()) + third_derivatives_output << ", "; + third_derivatives_output << *it2 + 1; + } + third_derivatives_output << "]" + << ", \"val\": \""; + d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); + third_derivatives_output << "\"}" << endl; + } + third_derivatives_output << "]}"; + + if (writeDetails) + output << "\"dynamic_model_derivative_details\": {"; + else + output << "\"dynamic_model_derivatives\": {"; + output << model_local_vars_output.str() + << ", " << model_output.str() + << ", " << jacobian_output.str() + << ", " << hessian_output.str() + << ", " << third_derivatives_output.str() + << "}"; +} + +void +DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) 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; + int param = it->first.second; + expr_t d1 = it->second; + + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"param_col\": " << param_col + 1 + << ", \"val\": \""; + d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); + jacobian_output << "\"}" << endl; + } + 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; + int var = it->first.second.first; + int param = it->first.second.second; + expr_t d2 = it->second; + + int var_col = getDynJacobianCol(var) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"lag\": " << getLagByDerivID(var) + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + hessian_output << ", \"var_col\": " << var_col + 1 + << ", \"param_col\": " << param_col + 1 + << ", \"val\": \""; + d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); + hessian_output << "\"}" << endl; + } + 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; + int param1 = it->first.second.first; + int param2 = it->first.second.second; + expr_t d2 = it->second; + + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + hessian1_output << "{\"eq\": " << eq + 1 + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + hessian1_output << "{\"row\": " << eq + 1; + hessian1_output << ", \"param1_col\": " << param1_col + 1 + << ", \"param2_col\": " << param2_col + 1 + << ", \"val\": \""; + d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); + hessian1_output << "\"}" << endl; + } + 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; + int var = it->first.second.first; + int param1 = it->first.second.second.first; + int param2 = it->first.second.second.second; + expr_t d2 = it->second; + + int var_col = getDynJacobianCol(var) + 1; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + third_derivs_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(var) << "\"" + << ", \"lag\": " << getLagByDerivID(var) + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + third_derivs_output << "{\"row\": " << eq + 1; + third_derivs_output << ", \"var_col\": " << var_col + 1 + << ", \"param1_col\": " << param1_col + 1 + << ", \"param2_col\": " << param2_col + 1 + << ", \"val\": \""; + d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); + third_derivs_output << "\"}" << endl; + } + 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; + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int param = it->first.second.second.second; + expr_t d2 = it->second; + + int var1_col = getDynJacobianCol(var1) + 1; + int var2_col = getDynJacobianCol(var2) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + third_derivs1_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"lag1\": " << getLagByDerivID(var1) + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"lag2\": " << getLagByDerivID(var2) + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + third_derivs1_output << "{\"row\": " << eq + 1; + third_derivs1_output << ", \"var1_col\": " << var1_col + 1 + << ", \"var2_col\": " << var2_col + 1 + << ", \"param_col\": " << param_col + 1 + << ", \"val\": \""; + d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); + third_derivs1_output << "\"}" << endl; + } + third_derivs1_output << "]}" << endl; + + if (writeDetails) + output << "\"dynamic_model_params_derivative_details\": {"; + else + output << "\"dynamic_model_params_derivatives\": {"; + output << model_local_vars_output.str() + << ", " << model_output.str() + << ", " << jacobian_output.str() + << ", " << hessian_output.str() + << ", " << hessian1_output.str() + << ", " << third_derivs_output.str() + << ", " << third_derivs1_output.str() + << "}"; +} diff --git a/DynamicModel.hh b/DynamicModel.hh index 7c742f41..fa7e68c4 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -241,6 +241,18 @@ public: //! Writes model initialization and lead/lag incidence matrix to output void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const; + //! Write JSON Output + void writeJsonOutput(ostream &output) const; + + //! Write JSON Output representation of dynamic model after computing pass + void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; + + //! Write JSON prams derivatives file + void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; + + //! Write cross reference output if the xref maps have been filed + void writeJsonXrefs(ostream &output) const; + //! Return true if the hessian is equal to zero inline bool checkHessianZero() const; diff --git a/DynareBison.yy b/DynareBison.yy index 06b7db9d..d95f77d3 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -3518,7 +3518,7 @@ o_use_shock_groups : USE_SHOCK_GROUPS { driver.option_str("use_shock_groups","de o_psd_use_shock_groups : USE_SHOCK_GROUPS { driver.option_str("plot_shock_decomp.use_shock_groups","default"); } | USE_SHOCK_GROUPS EQUAL symbol { driver.option_str("plot_shock_decomp.use_shock_groups", $3); } ; -o_colormap : COLORMAP EQUAL symbol { driver.option_num("colormap",$3); }; +o_colormap : COLORMAP EQUAL symbol { driver.option_num("plot_shock_decomp.colormap",$3); }; o_psd_colormap : COLORMAP EQUAL symbol { driver.option_num("plot_shock_decomp.colormap",$3); }; range : symbol ':' symbol diff --git a/DynareMain.cc b/DynareMain.cc index 887cf281..14d594c4 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -45,6 +45,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) , bool cygwin, bool msvc, bool mingw #endif + , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail ); void main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file, @@ -61,6 +62,7 @@ usage() #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) << " [cygwin] [msvc] [mingw]" #endif + << "[json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonprintderivdetail]" << endl; exit(EXIT_FAILURE); } @@ -113,6 +115,10 @@ main(int argc, char **argv) map defines; vector path; FileOutputType output_mode = none; + JsonOutputPointType json = nojson; + JsonFileOutputType json_output_mode = file; + bool onlyjson = false; + bool jsonprintderivdetail = false; LanguageOutputType language = matlab; // Parse options @@ -291,6 +297,33 @@ main(int argc, char **argv) } } } + else if (!strcmp(argv[arg], "jsonstdout")) + json_output_mode = standardout; + else if (!strcmp(argv[arg], "onlyjson")) + onlyjson = true; + else if (!strcmp(argv[arg], "jsonprintderivdetail")) + jsonprintderivdetail = true; + else if (strlen(argv[arg]) >= 4 && !strncmp(argv[arg], "json", 4)) + { + if (strlen(argv[arg]) <= 5 || argv[arg][4] != '=') + { + 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; @@ -337,6 +370,7 @@ main(int argc, char **argv) #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) , cygwin, msvc, mingw #endif + , json, json_output_mode, onlyjson, jsonprintderivdetail ); return EXIT_SUCCESS; diff --git a/DynareMain2.cc b/DynareMain2.cc index dc9420ca..758b278f 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -34,24 +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 + , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail ) { ParsingDriver p(warnings, nostrict); // Do parsing and construct internal representation of mod file ModFile *mod_file = p.parse(in, debug); + if (json == parsing) + mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); // Run checking pass mod_file->checkPass(nostrict); + if (json == checkpass) + mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); // Perform transformations on the model (creation of auxiliary vars and equations) - mod_file->transformPass(nostrict, compute_xrefs); + mod_file->transformPass(nostrict, compute_xrefs || json == transformpass); + if (json == transformpass) + mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); // Evaluate parameters initialization, initval, endval and pounds mod_file->evalAllExpressions(warn_uninit); // Do computations mod_file->computingPass(no_tmp_terms, output_mode, params_derivs_order); + if (json == computingpass) + mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonprintderivdetail); // Write outputs if (output_mode != none) diff --git a/ExprNode.cc b/ExprNode.cc index 7fcd58fc..c2d2a518 100644 --- a/ExprNode.cc +++ b/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 &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, @@ -327,6 +342,14 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << datatree.num_constants.get(id); } +void +NumConstNode::writeJsonOutput(ostream &output, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + output << datatree.num_constants.get(id); +} + bool NumConstNode::containsExternalFunction() const { @@ -643,6 +666,23 @@ VariableNode::containsExternalFunction() const return false; } +void +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(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + output << datatree.symbol_table.getName(symb_id); + if (lag != 0) + output << "(" << lag << ")"; +} + void VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1918,6 +1958,147 @@ UnaryOpNode::containsExternalFunction() const return arg->containsExternalFunction(); } +void +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(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + // Always put parenthesis around uminus nodes + if (op_code == oUminus) + output << "("; + + switch (op_code) + { + case oUminus: + output << "-"; + break; + case oExp: + output << "exp"; + break; + case oLog: + output << "log"; + break; + case oLog10: + output << "log10"; + break; + case oCos: + output << "cos"; + break; + case oSin: + output << "sin"; + break; + case oTan: + output << "tan"; + break; + case oAcos: + output << "acos"; + break; + case oAsin: + output << "asin"; + break; + case oAtan: + output << "atan"; + break; + case oCosh: + output << "cosh"; + break; + case oSinh: + output << "sinh"; + break; + case oTanh: + output << "tanh"; + break; + case oAcosh: + output << "acosh"; + break; + case oAsinh: + output << "asinh"; + break; + case oAtanh: + output << "atanh"; + break; + case oSqrt: + output << "sqrt"; + break; + case oAbs: + output << "abs"; + break; + case oSign: + output << "sign"; + break; + case oDiff: + output << "diff"; + break; + case oSteadyState: + output << "("; + arg->writeJsonOutput(output, temporary_terms, tef_terms); + output << ")"; + return; + case oSteadyStateParamDeriv: + { + VariableNode *varg = dynamic_cast(arg); + assert(varg != NULL); + assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); + 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); + output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")"; + } + return; + case oSteadyStateParam2ndDeriv: + { + VariableNode *varg = dynamic_cast(arg); + assert(varg != NULL); + assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); + assert(datatree.symbol_table.getType(param1_symb_id) == eParameter); + assert(datatree.symbol_table.getType(param2_symb_id) == eParameter); + 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); + output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1 + << "," << tsid_param2+1 << ")"; + } + return; + case oExpectation: + output << "EXPECTATION(" << expectation_information_set << ")"; + break; + case oErf: + output << "erf"; + break; + } + + bool close_parenthesis = false; + + /* Enclose argument with parentheses if: + - current opcode is not uminus, or + - current opcode is uminus and argument has lowest precedence + */ + if (op_code != oUminus + || (op_code == oUminus + && arg->precedenceJson(temporary_terms) < precedenceJson(temporary_terms))) + { + output << "("; + close_parenthesis = true; + } + + // Write argument + arg->writeJsonOutput(output, temporary_terms, tef_terms); + + if (close_parenthesis) + output << ")"; + + // Close parenthesis for uminus + if (op_code == oUminus) + output << ")"; +} + void UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -2115,6 +2296,14 @@ UnaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType out arg->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); } +void +UnaryOpNode::writeJsonExternalFunctionOutput(vector &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, @@ -2923,6 +3112,44 @@ 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(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: + case oAdl: + return 100; + } + // Suppress GCC warning + exit(EXIT_FAILURE); +} + int BinaryOpNode::cost(const map &temp_terms_map, bool is_matlab) const { @@ -3194,6 +3421,127 @@ BinaryOpNode::containsExternalFunction() const || arg2->containsExternalFunction(); } +void +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(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + if (op_code == oMax || op_code == oMin) + { + switch (op_code) + { + case oMax: + output << "max("; + break; + case oMin: + output << "min("; + break; + default: + ; + } + arg1->writeJsonOutput(output, temporary_terms, tef_terms); + output << ","; + arg2->writeJsonOutput(output, temporary_terms, tef_terms); + output << ")"; + return; + } + + 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(arg1); + if (arg1->precedenceJson(temporary_terms) < prec + || (op_code == oPower && barg1 != NULL && barg1->op_code == oPower)) + { + output << "("; + close_parenthesis = true; + } + + // Write left argument + arg1->writeJsonOutput(output, temporary_terms, tef_terms); + + if (close_parenthesis) + output << ")"; + + // Write current operator symbol + switch (op_code) + { + case oPlus: + output << "+"; + break; + case oMinus: + output << "-"; + break; + case oTimes: + output << "*"; + break; + case oDivide: + output << "/"; + break; + case oPower: + output << "^"; + break; + case oLess: + output << "<"; + break; + case oGreater: + output << ">"; + break; + case oLessEqual: + output << "<="; + break; + case oGreaterEqual: + output << ">="; + break; + case oEqualEqual: + output << "=="; + break; + case oDifferent: + output << "!="; + break; + case oEqual: + output << "="; + break; + default: + ; + } + + close_parenthesis = false; + + /* Add parenthesis around right argument if: + - its precedence is lower than those of the current node + - it is a power operator and current operator is also a power operator + - 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(arg2); + int arg2_prec = arg2->precedenceJson(temporary_terms); + if (arg2_prec < prec + || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower) + || (op_code == oMinus && arg2_prec == prec) + || (op_code == oDivide && arg2_prec == prec)) + { + output << "("; + close_parenthesis = true; + } + + // Write right argument + arg2->writeJsonOutput(output, temporary_terms, tef_terms); + + if (close_parenthesis) + output << ")"; +} + void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -3383,6 +3731,15 @@ BinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType ou arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); } +void +BinaryOpNode::writeJsonExternalFunctionOutput(vector &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, @@ -4382,6 +4739,37 @@ TrinaryOpNode::containsExternalFunction() const || arg3->containsExternalFunction(); } +void +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(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + switch (op_code) + { + case oNormcdf: + output << "normcdf("; + break; + case oNormpdf: + output << "normpdf("; + break; + } + + arg1->writeJsonOutput(output, temporary_terms, tef_terms); + output << ","; + arg2->writeJsonOutput(output, temporary_terms, tef_terms); + output << ","; + arg3->writeJsonOutput(output, temporary_terms, tef_terms); + output << ")"; +} + void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -4458,6 +4846,16 @@ TrinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType o arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); } +void +TrinaryOpNode::writeJsonExternalFunctionOutput(vector &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, @@ -5126,6 +5524,21 @@ AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, Ex } } +void +AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + if (it != arguments.begin()) + output << ","; + + (*it)->writeJsonOutput(output, temporary_terms, tef_terms); + } +} + void AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -5289,6 +5702,23 @@ ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsign } } +void +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(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + output << datatree.symbol_table.getName(symb_id) << "("; + writeJsonExternalFunctionArguments(output, temporary_terms, tef_terms); + output << ")"; +} + void ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -5398,6 +5828,42 @@ ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutpu } } +void +ExternalFunctionNode::writeJsonExternalFunctionOutput(vector &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::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\": {" + << "\"external_function_term\": \"TEF_" << indx << "\""; + + if (symb_id == first_deriv_symb_id) + ef << ", \"external_function_term_d\": \"TEFD_" << indx << "\""; + + if (symb_id == second_deriv_symb_id) + ef << ", \"external_function_term_dd\": \"TEFDD_" << indx << "\""; + + ef << ", \"value\": \"" << 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 { @@ -5479,6 +5945,34 @@ FirstDerivExternalFunctionNode::composeDerivatives(const vector &dargs) return theDeriv; } +void +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(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 FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -5666,6 +6160,47 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp } } +void +FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &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\": {" + << "\"external_function_term\": \"TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << "\"" + << ", \"analytic_derivative\": false" + << ", \"wrt\": " << inputIndex + << ", \"value\": \"" << 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\": {" + << "\"external_function_term\": \"TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << "\"" + << ", \"analytic_derivative\": true" + << ", \"value\": \"" << 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, @@ -5791,6 +6326,35 @@ SecondDerivExternalFunctionNode::composeDerivatives(const vector &dargs) exit(EXIT_FAILURE); } +void +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(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 SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -5955,6 +6519,48 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex } } +void +SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &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\": {" + << "\"external_function_term\": \"TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << "\"" + << ", \"analytic_derivative\": false" + << ", \"wrt1\": " << inputIndex1 + << ", \"wrt2\": " << inputIndex2 + << ", \"value\": \"" << 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\": {" + << "\"external_function_term\": \"TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << "\"" + << ", \"analytic_derivative\": true" + << ", \"value\": \"" << 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 { @@ -6312,3 +6918,16 @@ VarExpectationNode::substituteStaticAuxiliaryVariable() const { return const_cast(this); } + +void +VarExpectationNode::writeJsonOutput(ostream &output, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + output << "var_expectation(" + << "forecast_horizon = " << forecast_horizon + << ", name = " << datatree.symbol_table.getName(symb_id) + << ", model_name = " << model_name + << ", yindex = " << yidx + << ")"; +} diff --git a/ExprNode.hh b/ExprNode.hh index b4d0ce15..4845e4a6 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -224,11 +224,22 @@ enum ExprNodeOutputType //! Writes output of node, using a Txxx notation for nodes in temporary_terms 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, 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 &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, @@ -497,6 +508,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, 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 > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; @@ -550,6 +562,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, 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 > &result) const; virtual void computeTemporaryTerms(map &reference_count, @@ -633,10 +646,14 @@ public: map &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, 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 &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, @@ -719,15 +736,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 > &reference_count, map &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, 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 &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, @@ -833,10 +855,14 @@ public: map &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, 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 &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, @@ -907,6 +933,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, 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 &arguments_arg); @@ -915,10 +942,14 @@ public: map &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, 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 &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, @@ -985,9 +1016,13 @@ public: map &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, 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 &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, @@ -1025,6 +1060,7 @@ public: vector< vector > &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, 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, @@ -1032,6 +1068,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 &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, @@ -1064,6 +1103,7 @@ public: vector< vector > &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, 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, @@ -1071,6 +1111,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 &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, @@ -1141,6 +1184,7 @@ public: virtual bool isVarModelReferenced(const string &model_info_name) const; virtual void getEndosAndMaxLags(map &model_endos_and_lags) const; virtual expr_t substituteStaticAuxiliaryVariable() const; + virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; }; #endif diff --git a/ExtendedPreprocessorTypes.hh b/ExtendedPreprocessorTypes.hh index bf57a19f..e40c73ee 100644 --- a/ExtendedPreprocessorTypes.hh +++ b/ExtendedPreprocessorTypes.hh @@ -38,4 +38,19 @@ enum LanguageOutputType julia, // outputs files for Julia python, // outputs files for Python (not yet implemented) (not yet implemented) }; + +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/ModFile.cc b/ModFile.cc index 88ef7f92..11e9bc54 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -1288,3 +1288,229 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) jlOutputFile.close(); cout << "done" << endl; } + +void +ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail) +{ + 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, jsonprintderivdetail); + + 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); + } + + if (onlyjson) + exit(EXIT_SUCCESS); +} + +void +ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode) const +{ + ostringstream output; + output << "{" << endl; + + symbol_table.writeJsonOutput(output); + output << ", "; + dynamic_model.writeJsonOutput(output); + + if (!statements.empty()) + { + output << ", \"statements\": ["; + for (vector::const_iterator it = statements.begin(); + it != statements.end(); it++) + { + if (it != statements.begin()) + output << ", " << endl; + (*it)->writeJsonOutput(output); + } + output << "]" << endl; + } + output << "}" << endl; + + if (json_output_mode == standardout) + cout << output.str(); + else + { + ofstream jsonOutputFile; + + if (basename.size()) + { + string fname(basename); + fname += ".json"; + jsonOutputFile.open(fname.c_str(), ios::out | ios::binary); + if (!jsonOutputFile.is_open()) + { + cerr << "ERROR: Can't open file " << fname << " for writing" << endl; + exit(EXIT_FAILURE); + } + } + else + { + cerr << "ERROR: Missing file name" << endl; + exit(EXIT_FAILURE); + } + + jsonOutputFile << output.str(); + jsonOutputFile.close(); + } +} + +void +ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonprintderivdetail) const +{ + ostringstream static_output, static_detail_output; + static_output << "{"; + static_model.writeJsonComputingPassOutput(static_output, false); + static_output << "}" << endl; + + ostringstream dynamic_output, dynamic_detail_output; + dynamic_output << "{"; + dynamic_model.writeJsonComputingPassOutput(dynamic_output, false); + dynamic_output << "}" << endl; + + ostringstream tmp_out, static_paramsd_output, static_paramsd_detail_output; + tmp_out << ""; + static_paramsd_output << ""; + static_paramsd_detail_output << ""; + static_model.writeJsonParamsDerivativesFile(tmp_out, false); + if (!tmp_out.str().empty()) + static_paramsd_output << "{" << tmp_out.str() << "}" << endl; + + ostringstream tmp1_out, dynamic_paramsd_output, dynamic_paramsd_detail_output; + tmp1_out << ""; + dynamic_paramsd_output << ""; + dynamic_paramsd_detail_output << ""; + dynamic_model.writeJsonParamsDerivativesFile(tmp1_out, false); + if (!tmp1_out.str().empty()) + dynamic_paramsd_output << "{" << tmp1_out.str() << "}" << endl; + + if (jsonprintderivdetail) + { + static_detail_output << "{"; + static_model.writeJsonComputingPassOutput(static_detail_output, true); + static_detail_output << "}"; + + dynamic_detail_output << "{"; + dynamic_model.writeJsonComputingPassOutput(dynamic_detail_output, true); + dynamic_detail_output << "}"; + + ostringstream tmpd_out, tmpd1_out; + tmpd_out << ""; + tmpd1_out << ""; + static_model.writeJsonParamsDerivativesFile(tmpd_out, true); + if (!tmpd_out.str().empty()) + static_paramsd_detail_output << "{" << tmpd_out.str() << "}" << endl; + + dynamic_model.writeJsonParamsDerivativesFile(tmpd1_out, true); + if (!tmpd1_out.str().empty()) + dynamic_paramsd_detail_output << "{" << tmpd1_out.str() << "}" << endl; + } + + if (json_output_mode == standardout) + { + cout << static_output.str() << endl + << dynamic_output.str() << endl; + + if (!static_paramsd_output.str().empty()) + cout << static_paramsd_output.str() << endl; + + if (!dynamic_paramsd_output.str().empty()) + cout << dynamic_paramsd_output.str() << endl; + + if (jsonprintderivdetail) + { + cout << static_detail_output.str() << endl + << dynamic_detail_output.str() << endl; + + if (!static_paramsd_detail_output.str().empty()) + cout << static_paramsd_detail_output.str() << endl; + + if (!dynamic_paramsd_detail_output.str().empty()) + cout << dynamic_paramsd_detail_output.str() << endl; + } + } + else + { + 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"; + + writeJsonFileHelper(fname_static, static_output); + writeJsonFileHelper(fname_dynamic, dynamic_output); + + if (jsonprintderivdetail) + { + string fname_static_details, fname_dynamic_details; + fname_static_details = basename + "_static_details.json"; + fname_dynamic_details = basename + "_dynamic_details.json"; + + writeJsonFileHelper(fname_static_details, static_detail_output); + writeJsonFileHelper(fname_dynamic_details, dynamic_detail_output); + } + + if (!static_paramsd_output.str().empty()) + { + string fname_static_params, fname_static_params_details; + fname_static_params = basename + "_static_params_derivs.json"; + fname_static_params_details = basename + "_static_params_derivs_details.json"; + writeJsonFileHelper(fname_static_params, static_paramsd_output); + writeJsonFileHelper(fname_static_params_details, static_paramsd_detail_output); + } + + if (!dynamic_paramsd_output.str().empty()) + { + string fname_dynamic_params, fname_dynamic_params_details; + fname_dynamic_params = basename + "_params_derivs.json"; + fname_dynamic_params_details = basename + "_params_derivs_details.json"; + writeJsonFileHelper(fname_dynamic_params, dynamic_paramsd_output); + writeJsonFileHelper(fname_dynamic_params_details, dynamic_paramsd_detail_output); + } + } +} + +void +ModFile::writeJsonFileHelper(string &fname, ostringstream &output) const +{ + ofstream jsonOutput; + jsonOutput.open(fname.c_str(), ios::out | ios::binary); + if (!jsonOutput.is_open()) + { + cerr << "ERROR: Can't open file " << fname << " for writing" << endl; + exit(EXIT_FAILURE); + } + jsonOutput << output.str(); + jsonOutput.close(); + +} diff --git a/ModFile.hh b/ModFile.hh index a4812471..d8bb587c 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -117,7 +117,10 @@ 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, bool jsonprintderivdetail) const; + void writeJsonFileHelper(string &fname, ostringstream &output) const; public: //! Add a statement void addStatement(Statement *st); @@ -167,6 +170,11 @@ public: void writeModelCC(const string &basename) const; void computeChecksum(); + //! Write JSON representation of ModFile object + //! Initially created to enable Julia to work with .mod files + //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass) + //! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files + void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonprintderivdetail = false); }; #endif // ! MOD_FILE_HH diff --git a/ModelTree.cc b/ModelTree.cc index 9bfb30ea..2282f292 100644 --- a/ModelTree.cc +++ b/ModelTree.cc @@ -232,7 +232,7 @@ ModelTree::computeNonSingularNormalization(jacob_map_t &contemporaneous_jacobian void ModelTree::computeNormalizedEquations(multimap &endo2eqs) const { - for (int i = 0; i < equations.size(); i++) + for (size_t i = 0; i < equations.size(); i++) { VariableNode *lhs = dynamic_cast(equations[i]->get_arg1()); if (lhs == NULL) @@ -247,7 +247,7 @@ ModelTree::computeNormalizedEquations(multimap &endo2eqs) const if (endo.find(make_pair(symbol_table.getTypeSpecificID(symb_id), 0)) != endo.end()) continue; - endo2eqs.insert(make_pair(symbol_table.getTypeSpecificID(symb_id), i)); + endo2eqs.insert(make_pair(symbol_table.getTypeSpecificID(symb_id), (int) i)); cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl; } } @@ -1195,6 +1195,60 @@ 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(*it) != NULL) + { + if (wrote_term) + output << ", "; + vector efout; + (*it)->writeJsonExternalFunctionOutput(efout, tt2, tef_terms); + for (vector::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 << "\"" + << ", \"value\": \""; + (*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 &tmp_paren_vars, bool &message_printed) const { @@ -1384,6 +1438,54 @@ 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 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::const_iterator it = used_local_vars.begin(); + it != used_local_vars.end(); ++it) + { + vector efout; + expr_t value = local_variables_table.find(*it)->second; + value->writeJsonExternalFunctionOutput(efout, tt, tef_terms); + for (vector::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++) + { + if (it1 != efout.begin()) + output << ", "; + output << *it1; + } + } + output << "]" + << ", \"model_local_variables\": ["; + for (set::const_iterator it = used_local_vars.begin(); + it != used_local_vars.end(); ++it) + { + if (it != used_local_vars.begin()) + output << ", "; + 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 << "{\"variable\": \"" << symbol_table.getName(id) << "__\"" + << ", \"value\": \""; + value->writeJsonOutput(output, tt, tef_terms); + output << "\"}" << endl; + } + output << "]"; +} + void ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) const { @@ -1588,7 +1690,7 @@ ModelTree::writeLatexModelFile(const string &basename, ExprNodeOutputType output content_output << iteqt->second.first; - if (!empty(iteqt->second.second)) + if (iteqt->second.second.empty()) content_output << "= `" << iteqt->second.second << "'"; wrote_eq_tag = true; @@ -1667,7 +1769,7 @@ ModelTree::addNonstationaryVariables(vector nonstationary_vars, bool log_de void ModelTree::initializeVariablesAndEquations() { - for (int j = 0; j < equations.size(); j++) + for (size_t j = 0; j < equations.size(); j++) { equation_reordered.push_back(j); variable_reordered.push_back(j); @@ -1845,3 +1947,80 @@ ModelTree::isNonstationary(int symb_id) const return (nonstationary_symbols_map.find(symb_id) != nonstationary_symbols_map.end()); } + +void +ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const +{ + deriv_node_temp_terms_t tef_terms; + vector > eqtags; + 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++) + { + if (eq > 0) + output << ", "; + + BinaryOpNode *eq_node = equations[eq]; + expr_t lhs = eq_node->get_arg1(); + expr_t rhs = eq_node->get_arg2(); + + if (residuals) + { + 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) + { + } + output << "}"; + } + else + { + output << "{\"lhs\": \""; + lhs->writeJsonOutput(output, tt_empty, tef_terms); + output << "\", \"rhs\": \""; + rhs->writeJsonOutput(output, tt_empty, tef_terms); + output << "\"" + << ", \"line\": " << equations_lineno[eq]; + + for (vector > >::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 >::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/ModelTree.hh b/ModelTree.hh index f3c34836..24db008a 100644 --- a/ModelTree.hh +++ b/ModelTree.hh @@ -177,6 +177,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 @@ -190,6 +191,11 @@ protected: void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const; //! Writes model equations void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const; + //! Writes JSON model equations + //! 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/NumericalInitialization.cc b/NumericalInitialization.cc index 7d943976..84302651 100644 --- a/NumericalInitialization.cc +++ b/NumericalInitialization.cc @@ -63,6 +63,15 @@ InitParamStatement::writeJuliaOutput(ostream &output, const string &basename) // output << symbol_table.getName(symb_id) << " = model_.params[ " << id << " ]" << endl; } +void +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, temporary_terms_t(), tef_terms); + output << "\"}"; +} + void InitParamStatement::writeCOutput(ostream &output, const string &basename) { @@ -165,6 +174,21 @@ InitOrEndValStatement::writeInitValues(ostream &output) const } } +void +InitOrEndValStatement::writeJsonInitValues(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + for (init_values_t::const_iterator it = init_values.begin(); + it != init_values.end(); it++) + { + if (it != init_values.begin()) + output << ", "; + output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " << "\"value\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } +} + InitValStatement::InitValStatement(const init_values_t &init_values_arg, const SymbolTable &symbol_table_arg, const bool &all_values_required_arg) : @@ -210,6 +234,14 @@ InitValStatement::writeOutput(ostream &output, const string &basename, bool mini writeInitValues(output); } +void +InitValStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"init_val\", \"vals\": ["; + writeJsonInitValues(output); + output << "]}"; +} + void InitValStatement::writeOutputPostInit(ostream &output) const { @@ -267,6 +299,14 @@ EndValStatement::writeOutput(ostream &output, const string &basename, bool minim writeInitValues(output); } +void +EndValStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"end_val\", \"vals\": ["; + writeJsonInitValues(output); + output << "]}"; +} + HistValStatement::HistValStatement(const hist_values_t &hist_values_arg, const SymbolTable &symbol_table_arg, const bool &all_values_required_arg) : @@ -373,6 +413,25 @@ HistValStatement::writeOutput(ostream &output, const string &basename, bool mini } } +void +HistValStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"hist_val\", \"vals\": ["; + for (hist_values_t::const_iterator it = hist_values.begin(); + it != hist_values.end(); it++) + { + if (it != hist_values.begin()) + output << ", "; + output << "{ \"name\": \"" << symbol_table.getName(it->first.first) << "\"" + << ", \"lag\": " << it->first.second + << ", \"value\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]}"; +} + InitvalFileStatement::InitvalFileStatement(const string &filename_arg) : filename(filename_arg) { @@ -388,6 +447,14 @@ InitvalFileStatement::writeOutput(ostream &output, const string &basename, bool << "initvalf('" << filename << "');" << endl; } +void +InitvalFileStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"init_val_file\"" + << ", \"filename\": \"" << filename << "\"" + << "}"; +} + HistvalFileStatement::HistvalFileStatement(const string &filename_arg) : filename(filename_arg) { @@ -399,6 +466,14 @@ HistvalFileStatement::writeOutput(ostream &output, const string &basename, bool output << "histvalf('" << filename << "');" << endl; } +void +HistvalFileStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"hist_val_file\"" + << ", \"filename\": \"" << filename << "\"" + << "}"; +} + HomotopyStatement::HomotopyStatement(const homotopy_values_t &homotopy_values_arg, const SymbolTable &symbol_table_arg) : homotopy_values(homotopy_values_arg), @@ -435,6 +510,31 @@ HomotopyStatement::writeOutput(ostream &output, const string &basename, bool min } } +void +HomotopyStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"homotopy\", " + << "\"values\": ["; + for (homotopy_values_t::const_iterator it = homotopy_values.begin(); + it != homotopy_values.end(); it++) + { + if (it != homotopy_values.begin()) + output << ", "; + output << "{\"name\": \"" << symbol_table.getName(it->first) << "\"" + << ", \"initial_value\": \""; + if (it->second.first != NULL) + it->second.first->writeJsonOutput(output, temporary_terms_t(), tef_terms); + else + output << "NaN"; + output << "\", \"final_value\": \""; + it->second.second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << "}"; +} + SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(const string &filename_arg) : filename(filename_arg) { @@ -446,6 +546,14 @@ SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba output << "save_params_and_steady_state('" << filename << "');" << endl; } +void +SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"save_params_and_steady_state\"" + << ", \"filename\": \"" << filename << "\"" + << "}"; +} + LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const string &filename, const SymbolTable &symbol_table_arg, WarningConsolidation &warnings) : @@ -511,6 +619,24 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba } } +void +LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"load_params_and_steady_state\"" + << "\"values\": ["; + for (map::const_iterator it = content.begin(); + it != content.end(); it++) + { + if (it != content.begin()) + output << ", "; + output << "{\"name\": \"" << symbol_table.getName(it->first) << "\"" + << ", \"value\": \"" << it->second << "\"}"; + } + output << "]" + << "}"; +} + void LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_t &eval_context) const { diff --git a/NumericalInitialization.hh b/NumericalInitialization.hh index 2e34677b..58a7e6e0 100644 --- a/NumericalInitialization.hh +++ b/NumericalInitialization.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2016 Dynare Team + * Copyright (C) 2003-2017 Dynare Team * * This file is part of Dynare. * @@ -43,6 +43,7 @@ public: virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void writeJuliaOutput(ostream &output, const string &basename); virtual void writeCOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; //! Fill eval context with parameter value void fillEvalContext(eval_context_t &eval_context) const; }; @@ -69,6 +70,7 @@ public: void fillEvalContext(eval_context_t &eval_context) const; protected: void writeInitValues(ostream &output) const; + void writeJsonInitValues(ostream &output) const; }; class InitValStatement : public InitOrEndValStatement @@ -79,6 +81,7 @@ public: const bool &all_values_required_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; //! Writes initializations for oo_.exo_simul and oo_.exo_det_simul void writeOutputPostInit(ostream &output) const; }; @@ -92,6 +95,7 @@ public: //! Workaround for trac ticket #35 virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class HistValStatement : public Statement @@ -114,6 +118,7 @@ public: //! Workaround for trac ticket #157 virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class InitvalFileStatement : public Statement @@ -123,6 +128,7 @@ private: public: InitvalFileStatement(const string &filename_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class HistvalFileStatement : public Statement @@ -132,6 +138,7 @@ private: public: HistvalFileStatement(const string &filename_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class HomotopyStatement : public Statement @@ -147,6 +154,7 @@ public: HomotopyStatement(const homotopy_values_t &homotopy_values_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class SaveParamsAndSteadyStateStatement : public Statement @@ -156,6 +164,7 @@ private: public: SaveParamsAndSteadyStateStatement(const string &filename_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class LoadParamsAndSteadyStateStatement : public Statement @@ -172,6 +181,7 @@ public: virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; //! Fill eval context with parameters/variables values void fillEvalContext(eval_context_t &eval_context) const; + virtual void writeJsonOutput(ostream &output) const; }; #endif diff --git a/ParsingDriver.cc b/ParsingDriver.cc index e71b6321..cb7e82e8 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -3189,7 +3189,7 @@ ParsingDriver::prior_posterior_function(bool prior_func) void ParsingDriver::add_ramsey_constraints_statement() { - mod_file->addStatement(new RamseyConstraintsStatement(ramsey_constraints)); + mod_file->addStatement(new RamseyConstraintsStatement(mod_file->symbol_table, ramsey_constraints)); ramsey_constraints.clear(); } diff --git a/Shocks.cc b/Shocks.cc index 6f95a7a9..5a932061 100644 --- a/Shocks.cc +++ b/Shocks.cc @@ -67,6 +67,34 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const output << "M_.exo_det_length = " << exo_det_length << ";\n"; } +void +AbstractShocksStatement::writeJsonDetShocks(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "\"deterministic_shocks\": ["; + for (det_shocks_t::const_iterator it = det_shocks.begin(); + it != det_shocks.end(); it++) + { + if (it != det_shocks.begin()) + output << ", "; + output << "{\"var\": \"" << symbol_table.getName(it->first) << "\", " + << "\"values\": ["; + for (vector::const_iterator it1 = it->second.begin(); + it1 != it->second.end(); it1++) + { + if (it1 != it->second.begin()) + output << ", "; + output << "{\"period1\": " << it1->period1 << ", " + << "\"period2\": " << it1->period2 << ", " + << "\"value\": \""; + it1->value->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]}"; + } + output << "]"; +} + ShocksStatement::ShocksStatement(bool overwrite_arg, const det_shocks_t &det_shocks_arg, const var_and_std_shocks_t &var_shocks_arg, @@ -123,6 +151,72 @@ ShocksStatement::writeOutput(ostream &output, const string &basename, bool minim output << "M_.sigma_e_is_diagonal = 1;" << endl; } +void +ShocksStatement::writeJsonOutput(ostream &output) const +{ + deriv_node_temp_terms_t tef_terms; + output << "{\"statementName\": \"shocks\"" + << ", \"overwrite\": "; + if (overwrite) + output << "true"; + else + output << "false"; + if (!det_shocks.empty()) + { + output << ", "; + writeJsonDetShocks(output); + } + output<< ", \"variance\": ["; + for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); it != var_shocks.end(); it++) + { + if (it != var_shocks.begin()) + output << ", "; + output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " + << "\"variance\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << ", \"stderr\": ["; + for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); it != std_shocks.end(); it++) + { + if (it != std_shocks.begin()) + output << ", "; + output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " + << "\"stderr\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << ", \"covariance\": ["; + for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); it != covar_shocks.end(); it++) + { + if (it != covar_shocks.begin()) + output << ", "; + output << "{" + << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", " + << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", " + << "\"covariance\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << ", \"correlation\": ["; + for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); it != corr_shocks.end(); it++) + { + if (it != corr_shocks.begin()) + output << ", "; + output << "{" + << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", " + << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", " + << "\"correlation\": \""; + it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); + output << "\"}"; + } + output << "]" + << "}"; +} + void ShocksStatement::writeVarOrStdShock(ostream &output, var_and_std_shocks_t::const_iterator &it, bool stddev) const @@ -430,6 +524,26 @@ MomentCalibration::writeOutput(ostream &output, const string &basename, bool min output << "};" << endl; } +void +MomentCalibration::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"moment_calibration\"" + << ", \"moment_calibration_criteria\": ["; + for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++) + { + if (it != constraints.begin()) + output << ", "; + output << "{\"endogenous1\": \"" << symbol_table.getName(it->endo1) << "\"" + << ", \"endogenous2\": \"" << symbol_table.getName(it->endo2) << "\"" + << ", \"lags\": \"" << it->lags << "\"" + << ", \"lower_bound\": \"" << it->lower_bound << "\"" + << ", \"upper_bound\": \"" << it->upper_bound << "\"" + << "}"; + } + output << "]" + << "}"; +} + IrfCalibration::IrfCalibration(const constraints_t &constraints_arg, const SymbolTable &symbol_table_arg, const OptionsList &options_list_arg) @@ -455,6 +569,32 @@ IrfCalibration::writeOutput(ostream &output, const string &basename, bool minima output << "};" << endl; } +void +IrfCalibration::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"irf_calibration\""; + if (options_list.getNumberOfOptions()) + { + output << ", "; + options_list.writeJsonOutput(output); + } + + output << ", \"irf_restrictions\": ["; + for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++) + { + if (it != constraints.begin()) + output << ", "; + output << "{\"endogenous\": \"" << symbol_table.getName(it->endo) << "\"" + << ", \"exogenous\": \"" << symbol_table.getName(it->exo) << "\"" + << ", \"periods\": \"" << it->periods << "\"" + << ", \"lower_bound\": \"" << it->lower_bound << "\"" + << ", \"upper_bound\": \"" << it->upper_bound << "\"" + << "}"; + } + output << "]" + << "}"; +} + ShockGroupsStatement::ShockGroupsStatement(const group_t &shock_groups_arg, const string &name_arg) : shock_groups(shock_groups_arg), name(name_arg) { diff --git a/Shocks.hh b/Shocks.hh index 0710e663..618bf34b 100644 --- a/Shocks.hh +++ b/Shocks.hh @@ -50,6 +50,7 @@ protected: const det_shocks_t det_shocks; const SymbolTable &symbol_table; void writeDetShocks(ostream &output) const; + void writeJsonDetShocks(ostream &output) const; AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg, const det_shocks_t &det_shocks_arg, @@ -77,8 +78,9 @@ public: const covar_and_corr_shocks_t &covar_shocks_arg, const covar_and_corr_shocks_t &corr_shocks_arg, const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); + virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class MShocksStatement : public AbstractShocksStatement @@ -120,6 +122,7 @@ public: MomentCalibration(const constraints_t &constraints_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class IrfCalibration : public Statement @@ -141,6 +144,7 @@ public: const SymbolTable &symbol_table_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class ShockGroupsStatement : public Statement diff --git a/Statement.cc b/Statement.cc index d1a34bd2..14bffcc3 100644 --- a/Statement.cc +++ b/Statement.cc @@ -82,6 +82,11 @@ Statement::writeJuliaOutput(ostream &output, const string &basename) { } +void +Statement::writeJsonOutput(ostream &output) const +{ +} + void Statement::computingPass() { @@ -105,6 +110,14 @@ NativeStatement::writeOutput(ostream &output, const string &basename, bool minim output << ns << endl; } +void +NativeStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"native\"" + << ", \"string\": \"" << native_statement << "\"" + << "}"; +} + VerbatimStatement::VerbatimStatement(const string &verbatim_statement_arg) : verbatim_statement(verbatim_statement_arg) { @@ -116,6 +129,14 @@ VerbatimStatement::writeOutput(ostream &output, const string &basename, bool min output << verbatim_statement << endl; } +void +VerbatimStatement::writeJsonOutput(ostream &output) const +{ + output << "{\"statementName\": \"verbatim\"" + << ", \"string\": \"" << verbatim_statement << "\"" + << "}"; +} + void OptionsList::writeOutput(ostream &output) const { @@ -209,6 +230,100 @@ OptionsList::writeOutput(ostream &output, const string &option_group) const } } +void +OptionsList::writeJsonOutput(ostream &output) const +{ + if (getNumberOfOptions() == 0) + return; + + output << "\"options\": {"; + for (num_options_t::const_iterator it = num_options.begin(); + it != num_options.end();) + { + output << "\""<< it->first << "\": " << it->second; + it++; + if (it != num_options.end() + || !(paired_num_options.empty() + && string_options.empty() + && date_options.empty() + && symbol_list_options.empty() + && vector_int_options.empty())) + output << ", "; + } + + for (paired_num_options_t::const_iterator it = paired_num_options.begin(); + it != paired_num_options.end();) + { + output << "\""<< it->first << "\": [" << it->second.first << " " << it->second.second << "]"; + it++; + if (it != paired_num_options.end() + || !(string_options.empty() + && date_options.empty() + && symbol_list_options.empty() + && vector_int_options.empty())) + output << ", "; + } + + for (string_options_t::const_iterator it = string_options.begin(); + it != string_options.end();) + { + output << "\""<< it->first << "\": \"" << it->second << "\""; + it++; + if (it != string_options.end() + || !(date_options.empty() + && symbol_list_options.empty() + && vector_int_options.empty())) + output << ", "; + } + + for (date_options_t::const_iterator it = date_options.begin(); + it != date_options.end();) + { + output << "\""<< it->first << "\": \"" << it->second << "\""; + it++; + if (it != date_options.end() + || !(symbol_list_options.empty() + && vector_int_options.empty())) + output << ", "; + } + + for (symbol_list_options_t::const_iterator it = symbol_list_options.begin(); + it != symbol_list_options.end(); it++) + { + output << "\""<< it->first << "\":"; + it->second.writeJsonOutput(output); + it++; + if (it != symbol_list_options.end() + || !vector_int_options.empty()) + output << ", "; + } + + for (vec_int_options_t::const_iterator it = vector_int_options.begin(); + it != vector_int_options.end();) + { + output << "\""<< it->first << "\": ["; + if (it->second.size() > 1) + { + for (vector::const_iterator viit = it->second.begin(); + viit != it->second.end();) + { + output << *viit; + viit++; + if (viit != it->second.end()) + output << ", "; + } + } + else + output << it->second.front() << endl; + output << "]"; + it++; + if (it != vector_int_options.end()) + output << ", "; + } + + output << "}"; +} + void OptionsList::clear() { @@ -219,3 +334,14 @@ OptionsList::clear() symbol_list_options.clear(); vector_int_options.clear(); } + +int +OptionsList::getNumberOfOptions() const +{ + return num_options.size() + + paired_num_options.size() + + string_options.size() + + date_options.size() + + symbol_list_options.size() + + vector_int_options.size(); +} diff --git a/Statement.hh b/Statement.hh index d189f73a..7e77e12e 100644 --- a/Statement.hh +++ b/Statement.hh @@ -141,6 +141,7 @@ public: virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const = 0; virtual void writeCOutput(ostream &output, const string &basename); virtual void writeJuliaOutput(ostream &output, const string &basename); + virtual void writeJsonOutput(ostream &output) const; }; class NativeStatement : public Statement @@ -150,6 +151,7 @@ private: public: NativeStatement(const string &native_statement_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class VerbatimStatement : public Statement @@ -159,6 +161,7 @@ private: public: VerbatimStatement(const string &verbatim_statement_arg); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; + virtual void writeJsonOutput(ostream &output) const; }; class OptionsList @@ -176,8 +179,10 @@ public: date_options_t date_options; symbol_list_options_t symbol_list_options; vec_int_options_t vector_int_options; + int getNumberOfOptions() const; void writeOutput(ostream &output) const; void writeOutput(ostream &output, const string &option_group) const; + void writeJsonOutput(ostream &output) const; void clear(); }; diff --git a/StaticModel.cc b/StaticModel.cc index 1038ac53..ecc50640 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -2412,3 +2412,384 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons paramsDerivsFile.close(); } + +void +StaticModel::writeJsonOutput(ostream &output) const +{ + writeJsonModelEquations(output, false); +} + +void +StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const +{ + ostringstream model_local_vars_output; // Used for storing model local vars + ostringstream model_output; // Used for storing model + 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); + model_output << ", "; + 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; + int var = it->first.second; + int symb_id = getSymbIDByDerivID(var); + int col = symbol_table.getTypeSpecificID(symb_id); + expr_t d1 = it->second; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(symb_id) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"col\": " << col + 1 + << ", \"val\": \""; + d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); + jacobian_output << "\"}" << endl; + } + 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; + int symb_id1 = getSymbIDByDerivID(it->first.second.first); + int symb_id2 = getSymbIDByDerivID(it->first.second.second); + expr_t d2 = it->second; + + int tsid1 = symbol_table.getTypeSpecificID(symb_id1); + int tsid2 = symbol_table.getTypeSpecificID(symb_id2); + + int col = tsid1*symbol_table.endo_nbr()+tsid2; + int col_sym = tsid2*symbol_table.endo_nbr()+tsid1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(symb_id1) << "\"" + << ", \"var2\": \"" << symbol_table.getName(symb_id2) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + + hessian_output << ", \"col\": [" << col + 1; + if (symb_id1 != symb_id2) + hessian_output << ", " << col_sym + 1; + hessian_output << "]" + << ", \"val\": \""; + d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); + hessian_output << "\"}" << endl; + } + 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; + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int var3 = it->first.second.second.second; + expr_t d3 = it->second; + + if (writeDetails) + third_derivatives_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\""; + else + third_derivatives_output << "{\"row\": " << eq + 1; + + int id1 = getSymbIDByDerivID(var1); + int id2 = getSymbIDByDerivID(var2); + int id3 = getSymbIDByDerivID(var3); + set cols; + cols.insert(id1 * hessianColsNbr + id2 * JacobianColsNbr + id3); + cols.insert(id1 * hessianColsNbr + id3 * JacobianColsNbr + id2); + cols.insert(id2 * hessianColsNbr + id1 * JacobianColsNbr + id3); + cols.insert(id2 * hessianColsNbr + id3 * JacobianColsNbr + id1); + cols.insert(id3 * hessianColsNbr + id1 * JacobianColsNbr + id2); + cols.insert(id3 * hessianColsNbr + id2 * JacobianColsNbr + id1); + + third_derivatives_output << ", \"col\": ["; + for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) + { + if (it2 != cols.begin()) + third_derivatives_output << ", "; + third_derivatives_output << *it2 + 1; + } + third_derivatives_output << "]" + << ", \"val\": \""; + d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); + third_derivatives_output << "\"}" << endl; + } + third_derivatives_output << "]}"; + + if (writeDetails) + output << "\"static_model_derivative_details\": {"; + else + output << "\"static_model_derivatives\": {"; + output << model_local_vars_output.str() + << ", " << model_output.str() + << ", " << jacobian_output.str() + << ", " << hessian_output.str() + << ", " << third_derivatives_output.str() + << "}"; +} + +void +StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) 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; + int param = it->first.second; + expr_t d1 = it->second; + + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + jacobian_output << "{\"eq\": " << eq + 1 + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + jacobian_output << "{\"row\": " << eq + 1; + jacobian_output << ", \"param_col\": " << param_col + << ", \"val\": \""; + d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); + jacobian_output << "\"}" << endl; + } + 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; + int var = it->first.second.first; + int param = it->first.second.second; + expr_t d2 = it->second; + + int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + hessian_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" + << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + hessian_output << "{\"row\": " << eq + 1; + hessian_output << ", \"var_col\": " << var_col + << ", \"param_col\": " << param_col + << ", \"val\": \""; + d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); + hessian_output << "\"}" << endl; + } + 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; + int param1 = it->first.second.first; + int param2 = it->first.second.second; + expr_t d2 = it->second; + + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + hessian1_output << "{\"eq\": " << eq + 1 + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + hessian1_output << "{\"row\": " << eq + 1; + hessian1_output << ", \"param1_col\": " << param1_col + << ", \"param2_col\": " << param2_col + << ", \"val\": \""; + d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); + hessian1_output << "\"}" << endl; + } + 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; + int var = it->first.second.first; + int param1 = it->first.second.second.first; + int param2 = it->first.second.second.second; + expr_t d2 = it->second; + + int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; + int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; + int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; + + if (writeDetails) + third_derivs_output << "{\"eq\": " << eq + 1 + << ", \"var\": \"" << symbol_table.getName(var) << "\"" + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" + << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; + else + third_derivs_output << "{\"row\": " << eq + 1; + third_derivs_output << ", \"var_col\": " << var_col + << ", \"param1_col\": " << param1_col + << ", \"param2_col\": " << param2_col + << ", \"val\": \""; + d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); + third_derivs_output << "\"}" << endl; + } + 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; + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int param = it->first.second.second.second; + expr_t d2 = it->second; + + int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1; + int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + + if (writeDetails) + third_derivs1_output << "{\"eq\": " << eq + 1 + << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" + << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" + << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; + else + third_derivs1_output << "{\"row\": " << eq + 1; + third_derivs1_output << ", \"var1_col\": " << var1_col + << ", \"var2_col\": " << var2_col + << ", \"param_col\": " << param_col + << ", \"val\": \""; + d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); + third_derivs1_output << "\"}" << endl; + } + third_derivs1_output << "]}" << endl; + + if (writeDetails) + output << "\"static_model_params_derivative_details\": {"; + else + output << "\"static_model_params_derivatives\": {"; + output << model_local_vars_output.str() + << ", " << model_output.str() + << ", " << jacobian_output.str() + << ", " << hessian_output.str() + << ", " << hessian1_output.str() + << ", " << third_derivs_output.str() + << ", " << third_derivs1_output.str() + << "}"; +} diff --git a/StaticModel.hh b/StaticModel.hh index abf2aa01..2dcc8197 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -170,6 +170,15 @@ public: //! Writes static model file void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const; + //! Write JSON Output (used by PlannerObjectiveStatement) + void writeJsonOutput(ostream &output) const; + + //! Write JSON representation of static model + void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; + + //! Writes file containing static parameters derivatives + void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; + //! Writes file containing static parameters derivatives void writeParamsDerivativesFile(const string &basename, bool julia) const; diff --git a/SymbolList.cc b/SymbolList.cc index 8a8f8c62..6e5251f1 100644 --- a/SymbolList.cc +++ b/SymbolList.cc @@ -59,6 +59,20 @@ SymbolList::getSymbols() const return symbols; } +void +SymbolList::writeJsonOutput(ostream &output) const +{ + output << "\"symbol_list\": ["; + for (vector::const_iterator it = symbols.begin(); + it != symbols.end(); ++it) + { + if (it != symbols.begin()) + output << ","; + output << "\"" << *it << "\""; + } + output << "]"; +} + void SymbolList::clear() { diff --git a/SymbolList.hh b/SymbolList.hh index b29f4596..e0107230 100644 --- a/SymbolList.hh +++ b/SymbolList.hh @@ -41,6 +41,8 @@ public: void writeOutput(const string &varname, ostream &output) const; //! Output content in Matlab format without preceding varname of writeOutput void write(ostream &output) const; + //! Write JSON output + void writeJsonOutput(ostream &output) const; //! Clears all content void clear(); //! Get a copy of the string vector diff --git a/SymbolTable.cc b/SymbolTable.cc index 0657fe2a..27450363 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "SymbolTable.hh" @@ -138,6 +139,17 @@ SymbolTable::freeze() throw (FrozenException) } } +void +SymbolTable::unfreeze() +{ + frozen = false; + endo_ids.clear(); + exo_ids.clear(); + exo_det_ids.clear(); + param_ids.clear(); + type_specific_ids.clear(); +} + void SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException) { @@ -1067,3 +1079,36 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio output << " ]" << endl; } } + +void +SymbolTable::writeJsonOutput(ostream &output) const +{ + output << "\"endogenous\": "; + writeJsonVarVector(output, endo_ids); + + output << ", \"exogenous\":"; + writeJsonVarVector(output, exo_ids); + + output << ", \"exogenous_deterministic\": "; + writeJsonVarVector(output, exo_det_ids); + + output << ", \"parameters\": "; + writeJsonVarVector(output, param_ids); +} + +void +SymbolTable::writeJsonVarVector(ostream &output, const vector &varvec) const +{ + output << "["; + for (size_t i = 0; i < varvec.size(); i++) + { + if (i != 0) + output << ", "; + output << "{" + << "\"name\":\"" << getName(varvec[i]) << "\", " + << "\"texName\":\"" << boost::replace_all_copy(getTeXName(varvec[i]), "\\", "\\\\") << "\", " + << "\"longName\":\"" << boost::replace_all_copy(getLongName(varvec[i]), "\\", "\\\\") << "\"}" + << endl; + } + output << "]" << endl; +} diff --git a/SymbolTable.hh b/SymbolTable.hh index 9dd260ee..a804c908 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -224,7 +224,8 @@ private: int addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t arg) throw (FrozenException); //! Factorized code for adding aux lead variables int addLeadAuxiliaryVarInternal(bool endo, int index, expr_t arg) throw (FrozenException); - + //! Factorized code for Json writing + void writeJsonVarVector(ostream &output, const vector &varvec) const; public: //! Add a symbol /*! Returns the symbol ID */ @@ -317,6 +318,9 @@ public: int getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException); //! Freeze symbol table void freeze() throw (FrozenException); + //! unreeze symbol table + //! Used after having written JSON files + void unfreeze(); //! Change the type of a symbol void changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException); //! Get type specific ID (by symbol ID) @@ -337,6 +341,8 @@ public: inline int orig_endo_nbr() const throw (NotYetFrozenException); //! Write output of this class void writeOutput(ostream &output) const throw (NotYetFrozenException); + //! Write JSON Output + void writeJsonOutput(ostream &output) const; //! Write Julia output of this class void writeJuliaOutput(ostream &output) const throw (NotYetFrozenException); //! Write C output of this class