Merge branch 'master' into json

issue#70
Houtan Bastani 2017-03-10 17:20:15 +01:00
commit bab5d9bea1
9 changed files with 150 additions and 136 deletions

View File

@ -3164,7 +3164,7 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context)
void void
DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder,
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll,
bool bytecode, bool compute_xrefs) bool bytecode)
{ {
assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivsOrder)); assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivsOrder));
@ -3272,9 +3272,113 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
if (bytecode) if (bytecode)
computeTemporaryTermsMapping(); computeTemporaryTermsMapping();
} }
}
if (compute_xrefs) void
computeXrefs(); DynamicModel::computeXrefs()
{
int i = 0;
for (vector<BinaryOpNode *>::iterator it = equations.begin();
it != equations.end(); it++)
{
ExprNode::EquationInfo ei;
(*it)->computeXrefs(ei);
xrefs[i++] = ei;
}
i = 0;
for (map<int, ExprNode::EquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++, i++)
{
computeRevXref(xref_param, it->second.param, i);
computeRevXref(xref_endo, it->second.endo, i);
computeRevXref(xref_exo, it->second.exo, i);
computeRevXref(xref_exo_det, it->second.exo_det, i);
}
}
void
DynamicModel::computeRevXref(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
DynamicModel::writeXrefs(ostream &output) const
{
output << "M_.xref1.param = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.endo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.exo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.exo_det = cell(1, M_.eq_nbr);" << endl;
int i = 1;
for (map<int, ExprNode::EquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++, i++)
{
output << "M_.xref1.param{" << i << "} = [ ";
for (set<pair<int, int> >::const_iterator it1 = it->second.param.begin();
it1 != it->second.param.end(); it1++)
output << symbol_table.getTypeSpecificID(it1->first) + 1 << " ";
output << "];" << endl;
output << "M_.xref1.endo{" << i << "} = [ ";
for (set<pair<int, int> >::const_iterator it1 = it->second.endo.begin();
it1 != it->second.endo.end(); it1++)
output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");";
output << "];" << endl;
output << "M_.xref1.exo{" << i << "} = [ ";
for (set<pair<int, int> >::const_iterator it1 = it->second.exo.begin();
it1 != it->second.exo.end(); it1++)
output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");";
output << "];" << endl;
output << "M_.xref1.exo_det{" << i << "} = [ ";
for (set<pair<int, int> >::const_iterator it1 = it->second.exo_det.begin();
it1 != it->second.exo_det.end(); it1++)
output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");";
output << "];" << endl;
}
output << "M_.xref2.param = cell(1, M_.param_nbr);" << endl
<< "M_.xref2.endo = cell(1, M_.endo_nbr);" << endl
<< "M_.xref2.exo = cell(1, M_.exo_nbr);" << endl
<< "M_.xref2.exo_det = cell(1, M_.exo_det_nbr);" << endl;
writeRevXrefs(output, xref_param, "param");
writeRevXrefs(output, xref_endo, "endo");
writeRevXrefs(output, xref_exo, "exo");
writeRevXrefs(output, xref_exo_det, "exo_det");
}
void
DynamicModel::writeRevXrefs(ostream &output, const map<pair<int, int>, set<int> > &xrefmap, const string &type) const
{
int last_tsid = -1;
for (map<pair<int, int>, set<int> >::const_iterator it = xrefmap.begin();
it != xrefmap.end(); it++)
{
int tsid = symbol_table.getTypeSpecificID(it->first.first) + 1;
output << "M_.xref2." << type << "{" << tsid << "} = [ ";
if (last_tsid == tsid)
output << "M_.xref2." << type << "{" << tsid << "}; ";
else
last_tsid = tsid;
for (set<int>::const_iterator it1 = it->second.begin();
it1 != it->second.end(); it1++)
if (type == "param")
output << *it1 + 1 << " ";
else
output << "struct('shift', " << it->first.second << ", 'eq', " << *it1+1 << ");";
output << "];" << endl;
}
} }
map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>

View File

@ -62,6 +62,13 @@ private:
/*! Set by computeDerivIDs() */ /*! Set by computeDerivIDs() */
int max_exo_det_lag, max_exo_det_lead; int max_exo_det_lag, max_exo_det_lead;
//! Cross reference information
map<int, ExprNode::EquationInfo> xrefs;
map<pair<int, int>, set<int> > xref_param;
map<pair<int, int>, set<int> > xref_endo;
map<pair<int, int>, set<int> > xref_exo;
map<pair<int, int>, set<int> > xref_exo_det;
//! Number of columns of dynamic jacobian //! Number of columns of dynamic jacobian
/*! Set by computeDerivID()s and computeDynJacobianCols() */ /*! Set by computeDerivID()s and computeDynJacobianCols() */
int dynJacobianColsNbr; int dynJacobianColsNbr;
@ -189,6 +196,12 @@ private:
/*! pair< pair<static, forward>, pair<backward,mixed> > */ /*! pair< pair<static, forward>, pair<backward,mixed> > */
vector<pair< pair<int, int>, pair<int, int> > > block_col_type; vector<pair< pair<int, int>, pair<int, int> > > block_col_type;
//! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc)
void computeRevXref(map<pair<int, int>, set<int> > &xrefset, const set<pair<int, int> > &eiref, int eqn);
//! Write reverse cross references
void writeRevXrefs(ostream &output, const map<pair<int, int>, set<int> > &xrefmap, const string &type) const;
//! List for each variable its block number and its maximum lag and lead inside the block //! 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; vector<pair<int, pair<int, int> > > variable_block_lead_lag;
//! List for each equation its block number //! List for each equation its block number
@ -202,7 +215,13 @@ public:
//! Adds a variable node //! Adds a variable node
/*! This implementation allows for non-zero lag */ /*! This implementation allows for non-zero lag */
virtual VariableNode *AddVariable(int symb_id, int lag = 0); virtual VariableNode *AddVariable(int symb_id, int lag = 0);
//! Compute cross references
void computeXrefs();
//! Write cross references
void writeXrefs(ostream &output) const;
//! Execute computations (variable sorting + derivation) //! 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) \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
@ -213,7 +232,7 @@ public:
\param no_tmp_terms if true, no temporary terms will be computed in the dynamic files \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files
*/ */
void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder,
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, bool compute_xrefs); const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode);
//! Writes model initialization and lead/lag incidence matrix to output //! 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; 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;

View File

@ -50,7 +50,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
// Perform transformations on the model (creation of auxiliary vars and equations) // Perform transformations on the model (creation of auxiliary vars and equations)
mod_file->transformPass(nostrict); mod_file->transformPass(nostrict, compute_xrefs);
if (json == transformpass) if (json == transformpass)
mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
@ -58,7 +58,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
mod_file->evalAllExpressions(warn_uninit); mod_file->evalAllExpressions(warn_uninit);
// Do computations // Do computations
mod_file->computingPass(no_tmp_terms, output_mode, compute_xrefs, params_derivs_order); mod_file->computingPass(no_tmp_terms, output_mode, params_derivs_order);
if (json == computingpass) if (json == computingpass)
mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonprintderivdetail); mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonprintderivdetail);

View File

@ -1109,16 +1109,16 @@ VariableNode::computeXrefs(EquationInfo &ei) const
switch (type) switch (type)
{ {
case eEndogenous: case eEndogenous:
ei.endo.insert(symb_id); ei.endo.insert(make_pair(symb_id, lag));
break; break;
case eExogenous: case eExogenous:
ei.exo.insert(symb_id); ei.exo.insert(make_pair(symb_id, lag));
break; break;
case eExogenousDet: case eExogenousDet:
ei.exo_det.insert(symb_id); ei.exo_det.insert(make_pair(symb_id, lag));
break; break;
case eParameter: case eParameter:
ei.param.insert(symb_id); ei.param.insert(make_pair(symb_id, 0));
break; break;
case eTrend: case eTrend:
case eLogTrend: case eLogTrend:

View File

@ -165,10 +165,10 @@ protected:
//! For creating equation cross references //! For creating equation cross references
struct EquationInfo struct EquationInfo
{ {
set<int> param; set<pair<int, int> > param;
set<int> endo; set<pair<int, int> > endo;
set<int> exo; set<pair<int, int> > exo;
set<int> exo_det; set<pair<int, int> > exo_det;
}; };
public: public:

View File

@ -319,7 +319,7 @@ ModFile::checkPass(bool nostrict)
} }
void void
ModFile::transformPass(bool nostrict) ModFile::transformPass(bool nostrict, bool compute_xrefs)
{ {
// Save the original model (must be done before any model transformations by preprocessor) // Save the original model (must be done before any model transformations by preprocessor)
dynamic_model.cloneDynamic(original_model); dynamic_model.cloneDynamic(original_model);
@ -414,6 +414,9 @@ ModFile::transformPass(bool nostrict)
// Freeze the symbol table // Freeze the symbol table
symbol_table.freeze(); symbol_table.freeze();
if (compute_xrefs)
dynamic_model.computeXrefs();
/* /*
Enforce the same number of equations and endogenous, except in three cases: Enforce the same number of equations and endogenous, except in three cases:
- ramsey_model, ramsey_policy or discretionary_policy is used - ramsey_model, ramsey_policy or discretionary_policy is used
@ -483,7 +486,7 @@ ModFile::transformPass(bool nostrict)
} }
void void
ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xrefs, int params_derivs_order) ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order)
{ {
// Mod file may have no equation (for example in a standalone BVAR estimation) // Mod file may have no equation (for example in a standalone BVAR estimation)
if (dynamic_model.equation_number() > 0) if (dynamic_model.equation_number() > 0)
@ -517,7 +520,7 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xr
|| mod_file_struct.calib_smoother_present) || mod_file_struct.calib_smoother_present)
{ {
if (mod_file_struct.perfect_foresight_solver_present) if (mod_file_struct.perfect_foresight_solver_present)
dynamic_model.computingPass(true, false, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); dynamic_model.computingPass(true, false, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
else else
{ {
if (mod_file_struct.stoch_simul_present if (mod_file_struct.stoch_simul_present
@ -542,13 +545,13 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xr
int paramsDerivsOrder = 0; int paramsDerivsOrder = 0;
if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation)
paramsDerivsOrder = params_derivs_order; paramsDerivsOrder = params_derivs_order;
dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
if (linear && mod_file_struct.ramsey_model_present) if (linear && mod_file_struct.ramsey_model_present)
orig_ramsey_dynamic_model.computingPass(true, true, false, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); orig_ramsey_dynamic_model.computingPass(true, true, false, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
} }
} }
else // No computing task requested, compute derivatives up to 2nd order by default else // No computing task requested, compute derivatives up to 2nd order by default
dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
if ((linear && !mod_file_struct.ramsey_model_present && !dynamic_model.checkHessianZero()) || if ((linear && !mod_file_struct.ramsey_model_present && !dynamic_model.checkHessianZero()) ||
(linear && mod_file_struct.ramsey_model_present && !orig_ramsey_dynamic_model.checkHessianZero())) (linear && mod_file_struct.ramsey_model_present && !orig_ramsey_dynamic_model.checkHessianZero()))

View File

@ -133,12 +133,12 @@ public:
/*! \todo add check for number of equations and endogenous if ramsey_policy is present */ /*! \todo add check for number of equations and endogenous if ramsey_policy is present */
void checkPass(bool nostrict); void checkPass(bool nostrict);
//! Perform some transformations on the model (creation of auxiliary vars and equations) //! Perform some transformations on the model (creation of auxiliary vars and equations)
void transformPass(bool nostrict); /*! \param compute_xrefs if true, equation cross references will be computed */
void transformPass(bool nostrict, bool compute_xrefs);
//! Execute computations //! Execute computations
/*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */ /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */
/*! \param compute_xrefs if true, equation cross references will be computed */
/*! \param params_derivs_order compute this order of derivs wrt parameters */ /*! \param params_derivs_order compute this order of derivs wrt parameters */
void computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xrefs, int params_derivs_order); void computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order);
//! Writes Matlab/Octave output files //! Writes Matlab/Octave output files
/*! /*!
\param basename The base name used for writing output files. Should be the name of the mod file without its extension \param basename The base name used for writing output files. Should be the name of the mod file without its extension

View File

@ -229,103 +229,6 @@ 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;
}
i = 0;
for (map<int, ExprNode::EquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++, i++)
{
computeRevXref(xref_param, it->second.param, i);
computeRevXref(xref_endo, it->second.endo, i);
computeRevXref(xref_exo, it->second.exo, i);
computeRevXref(xref_exo_det, it->second.exo_det, i);
}
}
void
ModelTree::computeRevXref(map<int, set<int> > &xrefset, const set<int> &eiref, int eqn)
{
for (set<int>::const_iterator it1 = eiref.begin();
it1 != eiref.end(); it1++)
{
set<int> eq;
if (xrefset.find(symbol_table.getTypeSpecificID(*it1)) != xrefset.end())
eq = xrefset[symbol_table.getTypeSpecificID(*it1)];
eq.insert(eqn);
xrefset[symbol_table.getTypeSpecificID(*it1)] = eq;
}
}
void
ModelTree::writeXrefs(ostream &output) const
{
output << "M_.xref1.param = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.endo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.exo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref1.exo_det = cell(1, M_.eq_nbr);" << endl
<< "M_.xref2.param = cell(1, M_.eq_nbr);" << endl
<< "M_.xref2.endo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref2.exo = cell(1, M_.eq_nbr);" << endl
<< "M_.xref2.exo_det = cell(1, M_.eq_nbr);" << endl;
int i = 1;
for (map<int, ExprNode::EquationInfo>::const_iterator it = xrefs.begin();
it != xrefs.end(); it++, i++)
{
output << "M_.xref1.param{" << i << "} = [ ";
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{" << i << "} = [ ";
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{" << i << "} = [ ";
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{" << i << "} = [ ";
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;
}
writeRevXrefs(output, xref_param, "param");
writeRevXrefs(output, xref_endo, "endo");
writeRevXrefs(output, xref_exo, "exo");
writeRevXrefs(output, xref_exo_det, "exo_det");
}
void
ModelTree::writeRevXrefs(ostream &output, const map<int, set<int> > &xrefmap, const string &type) const
{
for (map<int, set<int> >::const_iterator it = xrefmap.begin();
it != xrefmap.end(); it++)
{
output << "M_.xref2." << type << "{" << it->first + 1 << "} = [ ";
for (set<int>::const_iterator it1 = it->second.begin();
it1 != it->second.end(); it1++)
output << *it1 + 1 << " ";
output << "];" << endl;
}
}
void void
ModelTree::computeNormalizedEquations(multimap<int, int> &endo2eqs) const ModelTree::computeNormalizedEquations(multimap<int, int> &endo2eqs) const
{ {

View File

@ -100,13 +100,6 @@ protected:
*/ */
first_derivatives_t residuals_params_derivatives; first_derivatives_t residuals_params_derivatives;
//! Cross reference information
map<int, ExprNode::EquationInfo> xrefs;
map<int, set<int> > xref_param;
map<int, set<int> > xref_endo;
map<int, set<int> > xref_exo;
map<int, set<int> > xref_exo_det;
//! Second derivatives of the residuals w.r. to parameters //! Second derivatives of the residuals w.r. to parameters
/*! First index is equation number, second and third indeces are parameters. /*! First index is equation number, second and third indeces are parameters.
Only non-null derivatives are stored in the map. Only non-null derivatives are stored in the map.
@ -246,14 +239,6 @@ protected:
//! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS) //! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS)
void computeNormalizedEquations(multimap<int, int> &endo2eqs) const; void computeNormalizedEquations(multimap<int, int> &endo2eqs) const;
//! Compute cross references
void computeXrefs();
//! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc)
void computeRevXref(map<int, set<int> > &xrefset, const set<int> &eiref, int eqn);
//! Write cross references
void writeXrefs(ostream &output) const;
//! Write reverse cross references
void writeRevXrefs(ostream &output, const map<int, set<int> > &xrefmap, const string &type) const;
//! Evaluate the jacobian and suppress all the elements below the cutoff //! 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); 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 //! Search the equations and variables belonging to the prologue and the epilogue of the model