Commit 0ccc8230 authored by Houtan Bastani's avatar Houtan Bastani

preprocessor: write equation cross references in JSON. #1387

parent defe06d5
......@@ -5342,6 +5342,127 @@ void
DynamicModel::writeJsonOutput(ostream &output) const
{
writeJsonModelEquations(output, false);
output << ", ";
writeJsonXrefs(output);
}
void
DynamicModel::writeJsonXrefs(ostream &output) const
{
output << "\"xrefs\": {"
<< "\"parameters\": [";
for (map<pair<int, int>, set<int> >::const_iterator it = json_xref_param.begin();
it != json_xref_param.end(); it++)
{
if (it != json_xref_param.begin())
output << ", ";
output << "{\"parameter\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"equations\": [";
for (set<int>::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<pair<int, int>, set<int> >::const_iterator it = json_xref_endo.begin();
it != json_xref_endo.end(); it++)
{
if (it != json_xref_endo.begin())
output << ", ";
output << "{\"endogenous\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"shift\": " << it->first.second
<< ", \"equations\": [";
for (set<int>::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<pair<int, int>, set<int> >::const_iterator it = json_xref_exo.begin();
it != json_xref_exo.end(); it++)
{
if (it != json_xref_exo.begin())
output << ", ";
output << "{\"exogenous\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"shift\": " << it->first.second
<< ", \"equations\": [";
for (set<int>::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<pair<int, int>, set<int> >::const_iterator it = json_xref_exo_det.begin();
it != json_xref_exo_det.end(); it++)
{
if (it != json_xref_exo_det.begin())
output << ", ";
output << "{\"exogenous_det\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"shift\": " << it->first.second
<< ", \"equations\": [";
for (set<int>::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::computeJsonXrefs()
{
map<int, ExprNode::JsonEquationInfo> xrefs;
int i = 0;
for (vector<BinaryOpNode *>::iterator it = equations.begin();
it != equations.end(); it++)
{
ExprNode::JsonEquationInfo ei;
(*it)->computeJsonXrefs(ei);
xrefs[i++] = ei;
}
i = 0;
for (map<int, ExprNode::JsonEquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++, i++)
{
computeJsonRevXref(json_xref_param, it->second.param, i);
computeJsonRevXref(json_xref_endo, it->second.endo, i);
computeJsonRevXref(json_xref_exo, it->second.exo, i);
computeJsonRevXref(json_xref_exo_det, it->second.exo_det, i);
}
}
void
DynamicModel::computeJsonRevXref(map<pair<int, int>, set<int> > &xrefset, const set<pair<int, int> > &eiref, int eqn)
{
for (set<pair<int, int> >::const_iterator it = eiref.begin();
it != eiref.end(); it++)
{
set<int> eq;
if (xrefset.find(*it) != xrefset.end())
eq = xrefset[*it];
eq.insert(eqn);
xrefset[*it] = eq;
}
}
void
......@@ -5721,3 +5842,4 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
<< ", " << third_derivs1_output.str()
<< "}";
}
......@@ -62,6 +62,12 @@ private:
/*! Set by computeDerivIDs() */
int max_exo_det_lag, max_exo_det_lead;
//! Cross references WITH lags (for #1387, potentially combine with cross references above upon decision by @michel)
map<pair<int, int>, set<int> > json_xref_param;
map<pair<int, int>, set<int> > json_xref_endo;
map<pair<int, int>, set<int> > json_xref_exo;
map<pair<int, int>, set<int> > json_xref_exo_det;
//! Number of columns of dynamic jacobian
/*! Set by computeDerivID()s and computeDynJacobianCols() */
int dynJacobianColsNbr;
......@@ -189,6 +195,9 @@ private:
/*! pair< pair<static, forward>, pair<backward,mixed> > */
vector<pair< pair<int, int>, pair<int, int> > > block_col_type;
//! Related to public function computeJsonXref
void computeJsonRevXref(map<pair<int, int>, set<int> > &xrefset, const set<pair<int, int> > &eiref, int eqn);
//! List for each variable its block number and its maximum lag and lead inside the block
vector<pair<int, pair<int, int> > > variable_block_lead_lag;
//! List for each equation its block number
......@@ -202,7 +211,10 @@ public:
//! Adds a variable node
/*! This implementation allows for non-zero lag */
virtual VariableNode *AddVariable(int symb_id, int lag = 0);
//! For computing cross references for json output (i.e. that contains lag information) #1387
void computeJsonXrefs();
//! Execute computations (variable sorting + derivation)
/*!
\param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
......@@ -220,6 +232,9 @@ public:
//! Write JSON Output
void writeJsonOutput(ostream &output) const;
//! Write cross reference output if the xref maps have been filed
void writeJsonXrefs(ostream &output) const;
//! Write JSON Output representation of dynamic model after computing pass
void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const;
......
......@@ -396,6 +396,11 @@ NumConstNode::computeXrefs(EquationInfo &ei) const
{
}
void
NumConstNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
}
expr_t
NumConstNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -1131,6 +1136,34 @@ VariableNode::computeXrefs(EquationInfo &ei) const
}
}
void
VariableNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
switch (type)
{
case eEndogenous:
ei.endo.insert(make_pair(symb_id, lag));
break;
case eExogenous:
ei.exo.insert(make_pair(symb_id, lag));
break;
case eExogenousDet:
ei.exo_det.insert(make_pair(symb_id, lag));
break;
case eParameter:
ei.param.insert(make_pair(symb_id, 0));
break;
case eTrend:
case eLogTrend:
case eModelLocalVariable:
case eModFileLocalVariable:
case eStatementDeclaredVariable:
case eUnusedEndogenous:
case eExternalFunction:
break;
}
}
expr_t
VariableNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -2558,6 +2591,12 @@ UnaryOpNode::computeXrefs(EquationInfo &ei) const
arg->computeXrefs(ei);
}
void
UnaryOpNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
arg->computeJsonXrefs(ei);
}
expr_t
UnaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -3994,6 +4033,13 @@ BinaryOpNode::computeXrefs(EquationInfo &ei) const
arg2->computeXrefs(ei);
}
void
BinaryOpNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
arg1->computeJsonXrefs(ei);
arg2->computeJsonXrefs(ei);
}
expr_t
BinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -4761,6 +4807,14 @@ TrinaryOpNode::computeXrefs(EquationInfo &ei) const
arg3->computeXrefs(ei);
}
void
TrinaryOpNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
arg1->computeJsonXrefs(ei);
arg2->computeJsonXrefs(ei);
arg3->computeJsonXrefs(ei);
}
expr_t
TrinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -5644,6 +5698,15 @@ ExternalFunctionNode::computeXrefs(EquationInfo &ei) const
(*it)->computeXrefs(ei);
}
void
ExternalFunctionNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeJsonXrefs(ei);
}
expr_t
ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
{
......@@ -6044,6 +6107,15 @@ FirstDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const
(*it)->computeXrefs(ei);
}
void
FirstDerivExternalFunctionNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeJsonXrefs(ei);
}
SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg,
int top_level_symb_id_arg,
const vector<expr_t> &arguments_arg,
......@@ -6359,6 +6431,15 @@ SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const
(*it)->computeXrefs(ei);
}
void
SecondDerivExternalFunctionNode::computeJsonXrefs(JsonEquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeJsonXrefs(ei);
}
void
SecondDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
......
......@@ -171,6 +171,14 @@ protected:
set<int> exo_det;
};
struct JsonEquationInfo
{
set<pair<int, int> > param;
set<pair<int, int> > endo;
set<pair<int, int> > exo;
set<pair<int, int> > exo_det;
};
public:
ExprNode(DataTree &datatree_arg);
virtual ~ExprNode();
......@@ -310,6 +318,7 @@ public:
*/
// virtual void computeXrefs(set<int> &param, set<int> &endo, set<int> &exo, set<int> &exo_det) const = 0;
virtual void computeXrefs(EquationInfo &ei) const = 0;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const = 0;
//! Try to normalize an equation linear in its endogenous variable
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const = 0;
......@@ -497,6 +506,7 @@ public:
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, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -553,6 +563,7 @@ public:
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, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
SymbolType
get_type() const
{
......@@ -652,6 +663,7 @@ public:
};
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -756,6 +768,7 @@ public:
}
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -841,6 +854,7 @@ public:
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, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -928,6 +942,7 @@ public:
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, deriv_node_temp_terms_t &tef_terms) const = 0;
virtual expr_t toStatic(DataTree &static_datatree) const = 0;
virtual void computeXrefs(EquationInfo &ei) const = 0;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const = 0;
virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const;
virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -989,6 +1004,7 @@ public:
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, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};
......@@ -1030,6 +1046,7 @@ public:
deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};
......@@ -1073,6 +1090,7 @@ public:
deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual void computeJsonXrefs(JsonEquationInfo &ei) const;
virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};
......
......@@ -414,6 +414,9 @@ ModFile::transformPass(bool nostrict)
// Freeze the symbol table
symbol_table.freeze();
//! Need access to this info after transform pass so calculate it here
dynamic_model.computeJsonXrefs();
/*
Enforce the same number of equations and endogenous, except in three cases:
- ramsey_model, ramsey_policy or discretionary_policy is used
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment