Ensure that dynamic model files contains all the derivatives that have been computed

Previously, there could be a discrepancy if the order mandated by
“identification” was less that the one mandated by “stoch_simul”.

Ref. #40
issue#70
Sébastien Villemot 2020-01-20 17:22:32 +01:00
parent 1c44baea05
commit 23a08a3662
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
5 changed files with 26 additions and 25 deletions

View File

@ -1691,7 +1691,7 @@ DynamicModel::writeDynamicJuliaFile(const string &basename) const
} }
void void
DynamicModel::writeDynamicCFile(const string &basename, int order) const DynamicModel::writeDynamicCFile(const string &basename) const
{ {
filesystem::create_directories(basename + "/model/src"); filesystem::create_directories(basename + "/model/src");
string filename = basename + "/model/src/dynamic.c"; string filename = basename + "/model/src/dynamic.c";
@ -1780,7 +1780,7 @@ DynamicModel::writeDynamicCFile(const string &basename, int order) const
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
<< "{" << endl << "{" << endl
<< " /* Check that no derivatives of higher order than computed are being requested */" << endl << " /* Check that no derivatives of higher order than computed are being requested */" << endl
<< " if (nlhs > " << order + 1 << ")" << endl << " if (nlhs > " << computed_derivs_order << ")" << endl
<< R"( mexErrMsgTxt("Derivatives of higher order than computed have been requested");)" << endl << R"( mexErrMsgTxt("Derivatives of higher order than computed have been requested");)" << endl
<< " /* Create a pointer to the input matrix y. */" << endl << " /* Create a pointer to the input matrix y. */" << endl
<< " double *y = mxGetPr(prhs[0]);" << endl << " double *y = mxGetPr(prhs[0]);" << endl
@ -3080,7 +3080,7 @@ DynamicModel::includeExcludeEquations(const string &eqs, bool exclude_eqs)
} }
void void
DynamicModel::writeOutput(ostream &output, const string &basename, bool block_decomposition, bool linear_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const DynamicModel::writeOutput(ostream &output, const string &basename, bool block_decomposition, bool linear_decomposition, bool byte_code, bool use_dll, bool estimation_present, bool compute_xrefs, bool julia) const
{ {
/* Writing initialisation for M_.lead_lag_incidence matrix /* Writing initialisation for M_.lead_lag_incidence matrix
M_.lead_lag_incidence is a matrix with as many columns as there are M_.lead_lag_incidence is a matrix with as many columns as there are
@ -3689,7 +3689,7 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
// Use -1 if the derivatives have not been computed // Use -1 if the derivatives have not been computed
output << modstruct << (julia ? "nnzderivatives" : "NNZDerivatives") << " = ["; output << modstruct << (julia ? "nnzderivatives" : "NNZDerivatives") << " = [";
for (int i = 1; i < static_cast<int>(NNZDerivatives.size()); i++) for (int i = 1; i < static_cast<int>(NNZDerivatives.size()); i++)
output << (i > order ? -1 : NNZDerivatives[i]) << "; "; output << (i > computed_derivs_order ? -1 : NNZDerivatives[i]) << "; ";
output << "];" << endl; output << "];" << endl;
// Write Pac Model Consistent Expectation parameter info // Write Pac Model Consistent Expectation parameter info
@ -4959,11 +4959,8 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
computeDerivatives(derivsOrder, vars); computeDerivatives(derivsOrder, vars);
if (derivsOrder > 1) if (derivsOrder > 1)
{ for (const auto &[indices, d2] : derivatives[2])
hessian_computed = true; nonzero_hessian_eqs.insert(indices[0]);
for (const auto &[indices, d2] : derivatives[2])
nonzero_hessian_eqs.insert(indices[0]);
}
if (paramsDerivsOrder > 0) if (paramsDerivsOrder > 0)
{ {
@ -5442,7 +5439,7 @@ DynamicModel::collectBlockVariables()
} }
void void
DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, int order, bool julia) const DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const
{ {
if (block && bytecode) if (block && bytecode)
writeModelEquationsCode_Block(basename, map_idx, linear_decomposition); writeModelEquationsCode_Block(basename, map_idx, linear_decomposition);
@ -5456,7 +5453,7 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_d
writeSparseDynamicMFile(basename); writeSparseDynamicMFile(basename);
else if (use_dll) else if (use_dll)
{ {
writeDynamicCFile(basename, order); writeDynamicCFile(basename);
compileDll(basename, "dynamic", mexext, matlabroot, dynareroot); compileDll(basename, "dynamic", mexext, matlabroot, dynareroot);
} }
else if (julia) else if (julia)

View File

@ -99,8 +99,6 @@ private:
//! Nonzero equations in the Hessian //! Nonzero equations in the Hessian
set<int> nonzero_hessian_eqs; set<int> nonzero_hessian_eqs;
//! Whether the hessian has actually been computed
bool hessian_computed{false};
//! Number of columns of dynamic jacobian //! Number of columns of dynamic jacobian
/*! Set by computeDerivID()s and computeDynJacobianCols() */ /*! Set by computeDerivID()s and computeDynJacobianCols() */
@ -123,7 +121,7 @@ private:
void writeDynamicJuliaFile(const string &dynamic_basename) const; void writeDynamicJuliaFile(const string &dynamic_basename) const;
//! Writes dynamic model file (C version) //! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */ /*! \todo add third derivatives handling */
void writeDynamicCFile(const string &basename, int order) const; void writeDynamicCFile(const string &basename) const;
//! Writes dynamic model file when SparseDLL option is on //! Writes dynamic model file when SparseDLL option is on
void writeSparseDynamicMFile(const string &basename) const; void writeSparseDynamicMFile(const string &basename) const;
//! Writes the dynamic model equations and its derivatives //! Writes the dynamic model equations and its derivatives
@ -327,7 +325,7 @@ public:
void computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsOrder, void computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsOrder,
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, bool linear_decomposition); const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, bool linear_decomposition);
//! 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 linear_decomposition, 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 linear_decomposition, bool byte_code, bool use_dll, bool estimation_present, bool compute_xrefs, bool julia) const;
//! Write JSON AST //! Write JSON AST
void writeJsonAST(ostream &output) const; void writeJsonAST(ostream &output) const;
@ -363,7 +361,7 @@ public:
inline bool inline bool
isHessianComputed() const isHessianComputed() const
{ {
return hessian_computed; return computed_derivs_order >= 2;
} }
//! Returns equations that have non-zero second derivatives //! Returns equations that have non-zero second derivatives
inline set<int> inline set<int>
@ -415,7 +413,7 @@ public:
void Write_Inf_To_Bin_File_Block(const string &basename, void Write_Inf_To_Bin_File_Block(const string &basename,
int num, int &u_count_int, bool &file_open, bool is_two_boundaries, bool linear_decomposition) const; int num, int &u_count_int, bool &file_open, bool is_two_boundaries, bool linear_decomposition) const;
//! Writes dynamic model file //! Writes dynamic model file
void writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, int order, bool julia) const; void writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const;
//! Writes file containing parameters derivatives //! Writes file containing parameters derivatives
void writeParamsDerivativesFile(const string &basename, bool julia) const; void writeParamsDerivativesFile(const string &basename, bool julia) const;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2006-2019 Dynare Team * Copyright © 2006-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -1018,8 +1018,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
if (dynamic_model.equation_number() > 0) if (dynamic_model.equation_number() > 0)
{ {
if (linear_decomposition) if (linear_decomposition)
non_linear_equations_dynamic_model.writeOutput(mOutputFile, basename, block, true, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present, compute_xrefs, false); non_linear_equations_dynamic_model.writeOutput(mOutputFile, basename, block, true, byte_code, use_dll, mod_file_struct.estimation_present, compute_xrefs, false);
dynamic_model.writeOutput(mOutputFile, basename, block, false, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present, compute_xrefs, false); dynamic_model.writeOutput(mOutputFile, basename, block, false, byte_code, use_dll, mod_file_struct.estimation_present, compute_xrefs, false);
if (!no_static) if (!no_static)
static_model.writeOutput(mOutputFile, block); static_model.writeOutput(mOutputFile, block);
} }
@ -1126,11 +1126,11 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
if (linear_decomposition) if (linear_decomposition)
{ {
non_linear_equations_dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll, mexext, matlabroot, dynareroot, mod_file_struct.order_option, false); non_linear_equations_dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll, mexext, matlabroot, dynareroot, false);
non_linear_equations_dynamic_model.writeParamsDerivativesFile(basename, false); non_linear_equations_dynamic_model.writeParamsDerivativesFile(basename, false);
} }
dynamic_model.writeDynamicFile(basename, block, false, byte_code, use_dll, mexext, matlabroot, dynareroot, mod_file_struct.order_option, false); dynamic_model.writeDynamicFile(basename, block, false, byte_code, use_dll, mexext, matlabroot, dynareroot, false);
dynamic_model.writeParamsDerivativesFile(basename, false); dynamic_model.writeParamsDerivativesFile(basename, false);
@ -1245,7 +1245,6 @@ ModFile::writeExternalFilesJulia(const string &basename) const
if (dynamic_model.equation_number() > 0) if (dynamic_model.equation_number() > 0)
{ {
dynamic_model.writeOutput(jlOutputFile, basename, false, false, false, false, dynamic_model.writeOutput(jlOutputFile, basename, false, false, false, false,
mod_file_struct.order_option,
mod_file_struct.estimation_present, false, true); mod_file_struct.estimation_present, false, true);
if (!no_static) if (!no_static)
{ {
@ -1253,7 +1252,7 @@ ModFile::writeExternalFilesJulia(const string &basename) const
static_model.writeParamsDerivativesFile(basename, true); static_model.writeParamsDerivativesFile(basename, true);
} }
dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll, dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll,
"", {}, {}, mod_file_struct.order_option, true); "", {}, {}, true);
dynamic_model.writeParamsDerivativesFile(basename, true); dynamic_model.writeParamsDerivativesFile(basename, true);
} }
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, true); steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, true);

View File

@ -112,6 +112,7 @@ ModelTree::ModelTree(const ModelTree &m) :
equations_lineno{m.equations_lineno}, equations_lineno{m.equations_lineno},
equation_tags{m.equation_tags}, equation_tags{m.equation_tags},
equation_tags_xref{m.equation_tags_xref}, equation_tags_xref{m.equation_tags_xref},
computed_derivs_order{m.computed_derivs_order},
NNZDerivatives{m.NNZDerivatives}, NNZDerivatives{m.NNZDerivatives},
equation_reordered{m.equation_reordered}, equation_reordered{m.equation_reordered},
variable_reordered{m.variable_reordered}, variable_reordered{m.variable_reordered},
@ -138,6 +139,7 @@ ModelTree::operator=(const ModelTree &m)
aux_equations.clear(); aux_equations.clear();
equation_tags = m.equation_tags; equation_tags = m.equation_tags;
equation_tags_xref = m.equation_tags_xref; equation_tags_xref = m.equation_tags_xref;
computed_derivs_order = m.computed_derivs_order;
NNZDerivatives = m.NNZDerivatives; NNZDerivatives = m.NNZDerivatives;
derivatives.clear(); derivatives.clear();
@ -1245,6 +1247,8 @@ ModelTree::computeDerivatives(int order, const set<int> &vars)
{ {
assert(order >= 1); assert(order >= 1);
computed_derivs_order = order;
// Do not shrink the vectors, since they have a minimal size of 4 (see constructor) // Do not shrink the vectors, since they have a minimal size of 4 (see constructor)
derivatives.resize(max(static_cast<size_t>(order+1), derivatives.size())); derivatives.resize(max(static_cast<size_t>(order+1), derivatives.size()));
NNZDerivatives.resize(max(static_cast<size_t>(order+1), NNZDerivatives.size()), 0); NNZDerivatives.resize(max(static_cast<size_t>(order+1), NNZDerivatives.size()), 0);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2003-2019 Dynare Team * Copyright © 2003-2020 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -106,6 +106,9 @@ protected:
tests/optimal_policy/nk_ramsey_expectation.mod */ tests/optimal_policy/nk_ramsey_expectation.mod */
vector<BinaryOpNode *> aux_equations; vector<BinaryOpNode *> aux_equations;
//! Maximum order at which (endogenous) derivatives have been computed
int computed_derivs_order{0};
//! Stores derivatives //! Stores derivatives
/*! Index 0 is not used, index 1 contains first derivatives, ... /*! Index 0 is not used, index 1 contains first derivatives, ...
For each derivation order, stores a map whose key is a vector of integer: the For each derivation order, stores a map whose key is a vector of integer: the