diff --git a/DynamicModel.cc b/DynamicModel.cc index be0dd601c207898d6d365a4f3eee3378deae1805..49d58ba2d5de9f1ca6754d4682f8100878f92c71 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -1743,21 +1743,38 @@ DynamicModel::reform(const string name1) const } void -DynamicModel::getNonZeroHessianEquations(map<int, string> &eqs) const +DynamicModel::printNonZeroHessianEquations(ostream &output) const +{ + if (nonzero_hessian_eqs.size() != 1) + output << "["; + for (map<int, string>::const_iterator it = nonzero_hessian_eqs.begin(); + it != nonzero_hessian_eqs.end(); it++) + { + if (it != nonzero_hessian_eqs.begin()) + output << " "; + output << it->first; + } + if (nonzero_hessian_eqs.size() != 1) + output << "]"; +} + +void +DynamicModel::setNonZeroHessianEquations(map<int, string> &eqs) { for (second_derivatives_t::const_iterator it = second_derivatives.begin(); it != second_derivatives.end(); it++) - if (eqs.find(it->first.first) == eqs.end()) + if (nonzero_hessian_eqs.find(it->first.first) == nonzero_hessian_eqs.end()) { - eqs[it->first.first] = ""; + nonzero_hessian_eqs[it->first.first] = ""; for (size_t i = 0; i < equation_tags.size(); i++) if (equation_tags[i].first == it->first.first) if (equation_tags[i].second.first == "name") { - eqs[it->first.first] = equation_tags[i].second.second; + nonzero_hessian_eqs[it->first.first] = equation_tags[i].second.second; break; } } + eqs = nonzero_hessian_eqs; } void diff --git a/DynamicModel.hh b/DynamicModel.hh index e5b9be490bd41c7dd4d951fe0d447543025de5c4..3a93a7ced9fe7a603794ee7e743c4b50b0e518d6 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2017 Dynare Team + * Copyright (C) 2003-2018 Dynare Team * * This file is part of Dynare. * @@ -80,6 +80,9 @@ private: map<pair<int, int>, set<int> > xref_exo; map<pair<int, int>, set<int> > xref_exo_det; + //! Nonzero equations in the Hessian + map<int, string> nonzero_hessian_eqs; + //! Number of columns of dynamic jacobian /*! Set by computeDerivID()s and computeDynJacobianCols() */ int dynJacobianColsNbr; @@ -266,11 +269,11 @@ public: void writeJsonXrefs(ostream &output) const; void writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int> > &xrefs) const; - //! Return true if the hessian is equal to zero - inline bool checkHessianZero() const; + //! Print equations that have non-zero second derivatives + void printNonZeroHessianEquations(ostream &output) const; - //! Return equations that have non-zero second derivatives - void getNonZeroHessianEquations(map<int, string> &eqs) const; + //! Set the equations that have non-zero second derivatives + void setNonZeroHessianEquations(map<int, string> &eqs); //! Adds informations for simulation in a binary file void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, @@ -550,12 +553,6 @@ public: bool isChecksumMatching(const string &basename) const; }; -inline bool -DynamicModel::checkHessianZero() const -{ - return second_derivatives.empty(); -} - //! Classes to re-order derivatives for various sparse storage formats class derivative { diff --git a/ModFile.cc b/ModFile.cc index de52a4da78790e055d4bf1b183ba739d030f3390..a103c59577a535fed6642313e8a5901eda370f6b 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2017 Dynare Team + * Copyright (C) 2006-2018 Dynare Team * * This file is part of Dynare. * @@ -596,15 +596,14 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri 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, nopreprocessoroutput); - if ((linear && !mod_file_struct.ramsey_model_present && !dynamic_model.checkHessianZero()) - || (linear && mod_file_struct.ramsey_model_present && !orig_ramsey_dynamic_model.checkHessianZero())) - { - map<int, string> eqs; - if (mod_file_struct.ramsey_model_present) - orig_ramsey_dynamic_model.getNonZeroHessianEquations(eqs); - else - dynamic_model.getNonZeroHessianEquations(eqs); + map<int, string> eqs; + if (mod_file_struct.ramsey_model_present) + orig_ramsey_dynamic_model.setNonZeroHessianEquations(eqs); + else + dynamic_model.setNonZeroHessianEquations(eqs); + if (linear && !eqs.empty()) + { cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl << " The following equations had non-zero second derivatives:" << endl; for (map<int, string >::const_iterator it = eqs.begin(); it != eqs.end(); it++) @@ -751,7 +750,13 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo mOutputFile << "};" << endl; } - mOutputFile << "M_.hessian_eq_zero = " << dynamic_model.checkHessianZero() << ";" << endl; + mOutputFile << "M_.nonzero_hessian_eqs = "; + if (mod_file_struct.ramsey_model_present) + orig_ramsey_dynamic_model.printNonZeroHessianEquations(mOutputFile); + else + dynamic_model.printNonZeroHessianEquations(mOutputFile); + mOutputFile << ";" << endl + << "M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs);" << endl; config_file.writeCluster(mOutputFile);