From 7a78593df4af2277d2b1e788853256a6b169a453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3ra=20Kocsis?= Date: Wed, 16 Oct 2019 17:34:27 +0200 Subject: [PATCH] introduce variableMapping, default equation name tags in M_ and JSON output --- src/DynamicModel.cc | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/DynamicModel.hh | 12 +++++++ src/ModFile.cc | 2 ++ 3 files changed, 91 insertions(+) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index b406b20b..2213fbdd 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3050,6 +3050,15 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de output << "};" << endl; } + // Write mapping for variables and equations they are present in + for (const auto & variable : variableMapping) + { + output << modstruct << "mapping." << symbol_table.getName(variable.first) << ".eqidx = ["; + for (auto equation : variable.second) + output << equation + 1 << " "; + output << "];" << endl; + } + /* Say if static and dynamic models differ (because of [static] and [dynamic] equation tags) */ output << modstruct << "static_and_dynamic_models_differ = " @@ -5483,6 +5492,52 @@ DynamicModel::ParamUsedWithLeadLag() const return ParamUsedWithLeadLagInternal(); } +void +DynamicModel::createVariableMapping(int orig_eq_nbr) +{ + for (int ii = 0; ii < orig_eq_nbr; ii++) + { + set eqvars; + equations[ii]->collectVariables(SymbolType::endogenous, eqvars); + equations[ii]->collectVariables(SymbolType::exogenous, eqvars); + for (auto eqvar : eqvars) + { + while (symbol_table.isAuxiliaryVariable(eqvar)) + eqvar = symbol_table.getOrigSymbIdForAuxVar(eqvar); + variableMapping[eqvar].emplace(ii); + } + } +} + +void +DynamicModel::expandEqTags() +{ + set existing_tags; + for (const auto & eqn : equation_tags) + if (eqn.second.first == "name") + existing_tags.insert(eqn.first); + + for (int eq = 0; eq < static_cast(equations.size()); eq++) + if (existing_tags.find(eq) == existing_tags.end()) + if (auto lhs_expr = dynamic_cast(equations[eq]->arg1); lhs_expr && equation_tags_xref.find(pair("name", symbol_table.getName(lhs_expr->symb_id))) == equation_tags_xref.end()) + { + equation_tags.push_back(pair(eq, pair("name", symbol_table.getName(lhs_expr->symb_id)))); + equation_tags_xref.emplace(pair("name", symbol_table.getName(lhs_expr->symb_id)), eq); + } + else if (equation_tags_xref.find(pair("name",to_string(eq+1))) == equation_tags_xref.end()) + { + equation_tags.push_back(pair(eq, pair("name", to_string(eq+1)))); + equation_tags_xref.emplace(pair("name", to_string(eq+1)), eq); + } + else + { + cerr << "Error creating default equation tag: cannot assign default tag to equation number " << eq+1 << " because it is already in use" << endl; + exit(EXIT_FAILURE); + } + + sort(equation_tags.begin(), equation_tags.end()); +} + set DynamicModel::findUnusedEndogenous() { @@ -6642,6 +6697,8 @@ DynamicModel::writeJsonOutput(ostream &output) const writeJsonXrefs(output); output << ", "; writeJsonAST(output); + output << ", "; + writeJsonVariableMapping(output); } void @@ -6682,6 +6739,26 @@ DynamicModel::writeJsonAST(ostream &output) const output << "]"; } +void +DynamicModel::writeJsonVariableMapping(ostream &output) const +{ + output << R"("variable_mapping":[)" << endl; + int ii = 0; + int end_idx_map = static_cast(variableMapping.size()-1); + for (const auto & variable : variableMapping) + { + output << R"({"name": ")" << symbol_table.getName(variable.first) << R"(", "equations":[)"; + int it = 0; + int end_idx_eq = static_cast(variable.second.size())-1; + for (const auto & equation : variable.second) + for (const auto & equation_tag : equation_tags) + if (equation_tag.first == equation && equation_tag.second.first == "name") + output << R"(")" << equation_tag.second.second << (it++ == end_idx_eq ? R"("])":R"(", )"); + output << (ii++ == end_idx_map ? R"(})":R"(},)") << endl; + } + output << "]"; +} + void DynamicModel::writeJsonXrefsHelper(ostream &output, const map, set> &xrefs) const { diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index b8bc1495..67ca4019 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -97,6 +97,9 @@ private: vector v_temporary_terms_inuse; + //! Creates mapping for variables and equations they are present in + map> variableMapping; + //! Store the derivatives or the chainrule derivatives:map, expr_t> using first_chain_rule_derivatives_t = map, expr_t>; first_chain_rule_derivatives_t first_chain_rule_derivatives; @@ -289,6 +292,9 @@ public: //! Write JSON AST void writeJsonAST(ostream &output) const; + //! Write JSON variable mapping + void writeJsonVariableMapping(ostream &output) const; + //! Write JSON Output void writeJsonOutput(ostream &output) const; @@ -369,6 +375,12 @@ public: /*! It assumes that the nonlinear model given in argument has just been allocated */ void toNonlinearPart(DynamicModel &non_linear_equations_dynamic_model) const; + //! Creates mapping for variables and equations they are present in + void createVariableMapping(int orig_eq_nbr); + + //! Expands equation tags with default equation names (available "name" tag or LHS variable or equation ID) + void expandEqTags(); + //! Find endogenous variables not used in model set findUnusedEndogenous(); //! Find exogenous variables not used in model diff --git a/src/ModFile.cc b/src/ModFile.cc index eb283507..bb55a0c0 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -394,6 +394,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const dynamic_model.substituteAdl(); dynamic_model.setLeadsLagsOrig(); original_model = dynamic_model; + dynamic_model.expandEqTags(); // Check that all declared endogenous are used in equations set unusedEndogs = dynamic_model.findUnusedEndogenous(); @@ -602,6 +603,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const } // And finally perform the substitutions dynamic_model.substituteVarExpectation(var_expectation_subst_table); + dynamic_model.createVariableMapping(original_model.equation_number()); if (mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present