preprocessor: add equation cross references

issue#70
Houtan Bastani 2015-12-18 15:17:32 +01:00
parent 091e80b35b
commit de0ce35ee3
5 changed files with 160 additions and 1 deletions

View File

@ -3049,6 +3049,8 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
output << modstruct << "params = " << (julia ? "fill(NaN, " : "NaN(")
<< symbol_table.param_nbr() << ", 1);" << endl;
writeXrefs(output);
// Write number of non-zero derivatives
// Use -1 if the derivatives have not been computed
output << modstruct << (julia ? "nnzderivatives" : "NNZDerivatives")
@ -3200,6 +3202,8 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
if (bytecode)
computeTemporaryTermsMapping();
}
computeXrefs();
}
map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>

View File

@ -354,6 +354,11 @@ NumConstNode::toStatic(DataTree &static_datatree) const
return static_datatree.AddNonNegativeConstant(datatree.num_constants.get(id));
}
void
NumConstNode::computeXrefs(EquationInfo &ei) const
{
}
expr_t
NumConstNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -1015,6 +1020,34 @@ VariableNode::toStatic(DataTree &static_datatree) const
return static_datatree.AddVariable(symb_id);
}
void
VariableNode::computeXrefs(EquationInfo &ei) const
{
switch (type)
{
case eEndogenous:
ei.endo.insert(symb_id);
break;
case eExogenous:
ei.exo.insert(symb_id);
break;
case eExogenousDet:
ei.exo_det.insert(symb_id);
break;
case eParameter:
ei.param.insert(symb_id);
break;
case eTrend:
case eLogTrend:
case eModelLocalVariable:
case eModFileLocalVariable:
case eStatementDeclaredVariable:
case eUnusedEndogenous:
case eExternalFunction:
break;
}
}
expr_t
VariableNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -2269,6 +2302,12 @@ UnaryOpNode::toStatic(DataTree &static_datatree) const
return buildSimilarUnaryOpNode(sarg, static_datatree);
}
void
UnaryOpNode::computeXrefs(EquationInfo &ei) const
{
arg->computeXrefs(ei);
}
expr_t
UnaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -3496,6 +3535,13 @@ BinaryOpNode::toStatic(DataTree &static_datatree) const
return buildSimilarBinaryOpNode(sarg1, sarg2, static_datatree);
}
void
BinaryOpNode::computeXrefs(EquationInfo &ei) const
{
arg1->computeXrefs(ei);
arg2->computeXrefs(ei);
}
expr_t
BinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -4172,6 +4218,14 @@ TrinaryOpNode::toStatic(DataTree &static_datatree) const
return buildSimilarTrinaryOpNode(sarg1, sarg2, sarg3, static_datatree);
}
void
TrinaryOpNode::computeXrefs(EquationInfo &ei) const
{
arg1->computeXrefs(ei);
arg2->computeXrefs(ei);
arg3->computeXrefs(ei);
}
expr_t
TrinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -4944,6 +4998,15 @@ ExternalFunctionNode::toStatic(DataTree &static_datatree) const
return static_datatree.AddExternalFunction(symb_id, static_arguments);
}
void
ExternalFunctionNode::computeXrefs(EquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeXrefs(ei);
}
expr_t
ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
{
@ -5266,6 +5329,15 @@ FirstDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const
inputIndex);
}
void
FirstDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeXrefs(ei);
}
SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg,
int top_level_symb_id_arg,
const vector<expr_t> &arguments_arg,
@ -5501,6 +5573,15 @@ SecondDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const
inputIndex1, inputIndex2);
}
void
SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->computeXrefs(ei);
}
void
SecondDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,

View File

@ -159,6 +159,15 @@ protected:
/*! Nodes included in temporary_terms are considered having a null cost */
virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
//! For creating equation cross references
struct EquationInfo
{
set<int> param;
set<int> endo;
set<int> exo;
set<int> exo_det;
};
public:
ExprNode(DataTree &datatree_arg);
virtual ~ExprNode();
@ -279,6 +288,12 @@ public:
adds the result in the static_datatree argument (and not in the original datatree), and returns it.
*/
virtual expr_t toStatic(DataTree &static_datatree) const = 0;
/*!
Compute cross references for equations
*/
// 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;
//! 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;
@ -458,6 +473,7 @@ public:
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
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 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;
@ -510,6 +526,7 @@ public:
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
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;
SymbolType
get_type() const
{
@ -597,6 +614,7 @@ public:
return (op_code);
};
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &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;
@ -688,6 +706,7 @@ public:
return powerDerivOrder;
}
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &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;
@ -759,6 +778,7 @@ public:
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
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 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;
@ -835,6 +855,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 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;
@ -886,6 +907,7 @@ public:
int equation) 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, deriv_node_temp_terms_t &tef_terms) const;
virtual expr_t toStatic(DataTree &static_datatree) const;
virtual void computeXrefs(EquationInfo &ei) const;
virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};
@ -920,6 +942,7 @@ public:
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 expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};
@ -956,6 +979,7 @@ public:
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 expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
};

View File

@ -229,6 +229,51 @@ ModelTree::computeNonSingularNormalization(jacob_map_t &contemporaneous_jacobian
}
}
void
ModelTree::computeXrefs()
{
int i = 0;
for (vector<BinaryOpNode *>::iterator it = equations.begin();
it != equations.end(); it++)
{
ExprNode::EquationInfo ei;
(*it)->computeXrefs(ei);
xrefs[i++] = ei;
}
}
void
ModelTree::writeXrefs(ostream &output) const
{
for (map<int, ExprNode::EquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++)
{
output << "M_.xref1.params{end+1} = [ ";
for (set<int>::const_iterator it1 = it->second.param.begin();
it1 != it->second.param.end(); it1++)
output << symbol_table.getTypeSpecificID(*it1) + 1 << " ";
output << "];" << endl;
output << "M_.xref1.endo{end+1} = [ ";
for (set<int>::const_iterator it1 = it->second.endo.begin();
it1 != it->second.endo.end(); it1++)
output << symbol_table.getTypeSpecificID(*it1) + 1 << " ";
output << "];" << endl;
output << "M_.xref1.exo{end+1} = [ ";
for (set<int>::const_iterator it1 = it->second.exo.begin();
it1 != it->second.exo.end(); it1++)
output << symbol_table.getTypeSpecificID(*it1) + 1 << " ";
output << "];" << endl;
output << "M_.xref1.exo_det{end+1} = [ ";
for (set<int>::const_iterator it1 = it->second.exo_det.begin();
it1 != it->second.exo_det.end(); it1++)
output << symbol_table.getTypeSpecificID(*it1) + 1 << " ";
output << "];" << endl;
}
}
void
ModelTree::computeNormalizedEquations(multimap<int, int> &endo2eqs) const
{

View File

@ -99,6 +99,8 @@ protected:
*/
first_derivatives_t residuals_params_derivatives;
map<int, ExprNode::EquationInfo> xrefs;
//! Second derivatives of the residuals w.r. to parameters
/*! First index is equation number, second and third indeces are parameters.
Only non-null derivatives are stored in the map.
@ -220,6 +222,10 @@ protected:
//! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS)
void computeNormalizedEquations(multimap<int, int> &endo2eqs) const;
//! Compute cross references
void computeXrefs();
//! Write cross references
void writeXrefs(ostream &output) const;
//! Evaluate the jacobian and suppress all the elements below the cutoff
void evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_map_t &contemporaneous_jacobian, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian, double cutoff, bool verbose);
//! Search the equations and variables belonging to the prologue and the epilogue of the model
@ -319,7 +325,6 @@ public:
/*! If order=2, writes either v2(i+1,j+1) or v2[i+j*NNZDerivatives[1]]
If order=3, writes either v3(i+1,j+1) or v3[i+j*NNZDerivatives[2]] */
void sparseHelper(int order, ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const;
inline static std::string
c_Equation_Type(int type)
{