From 54ca5d9cc08f6f2a3bec9ff57a3808f988e9b397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 19 Apr 2022 17:06:37 +0200 Subject: [PATCH] Improve messages during model normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit – Indicate whether we are trying to normalize the static or dynamic model – If failed to normalize the static model, suggest to use the “no_static” option – Remove a superfluous error message --- src/DynamicModel.cc | 2 +- src/ModelTree.cc | 23 +++++++++++++++-------- src/ModelTree.hh | 4 ++-- src/StaticModel.cc | 4 ++-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 478e9df8..247bbad0 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -4245,7 +4245,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO { auto contemporaneous_jacobian = evaluateAndReduceJacobian(eval_context); - computeNonSingularNormalization(contemporaneous_jacobian); + computeNonSingularNormalization(contemporaneous_jacobian, true); auto [prologue, epilogue] = computePrologueAndEpilogue(); diff --git a/src/ModelTree.cc b/src/ModelTree.cc index 37319bac..a78a57b7 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -201,7 +201,7 @@ ModelTree::operator=(const ModelTree &m) } bool -ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose) +ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic, bool verbose) { const int n = equations.size(); @@ -241,7 +241,7 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, boo it != mate_map.begin() + n) { if (verbose) - cerr << "ERROR: Could not normalize the model. Variable " + cerr << "ERROR: Could not normalize the " << (dynamic ? "dynamic" : "static") << " model. Variable " << symbol_table.getName(symbol_table.getID(SymbolType::endogenous, it - mate_map.begin())) << " is not in the maximum cardinality matching." << endl; check = false; @@ -250,9 +250,9 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, boo } void -ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian) +ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic) { - cout << "Normalizing the model..." << endl; + cout << "Normalizing the " << (dynamic ? "dynamic" : "static") << " model..." << endl; int n = equations.size(); @@ -284,14 +284,14 @@ ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_ja suppressed++; if (suppressed != last_suppressed) - found_normalization = computeNormalization(normalized_contemporaneous_jacobian_above_cutoff, false); + found_normalization = computeNormalization(normalized_contemporaneous_jacobian_above_cutoff, dynamic, false); last_suppressed = suppressed; if (!found_normalization) { current_cutoff /= 2; // In this last case try to normalize with the complete jacobian if (current_cutoff <= cutoff_lower_limit) - found_normalization = computeNormalization(normalized_contemporaneous_jacobian, false); + found_normalization = computeNormalization(normalized_contemporaneous_jacobian, dynamic, false); } } @@ -302,12 +302,19 @@ ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_ja normalization even with a potential singularity. TODO: Explain why symbolic_jacobian is not contemporaneous. */ auto symbolic_jacobian = computeSymbolicJacobian(); - found_normalization = computeNormalization(symbolic_jacobian, true); + found_normalization = computeNormalization(symbolic_jacobian, dynamic, true); } if (!found_normalization) { - cerr << "No normalization could be computed. Aborting." << endl; + /* Some models don’t have a steady state, and this can cause the + normalization to fail (e.g. if some variable only appears in a diff(), + it will disappear from the static model). Suggest the “no_static” + option as a possible solution. */ + if (!dynamic) + cerr << "If your model does not have a steady state, you may want to try the 'no_static' option of the 'model' block." << endl; + /* The last call to computeNormalization(), which was verbose, already + printed an error message, so we can immediately exit. */ exit(EXIT_FAILURE); } } diff --git a/src/ModelTree.hh b/src/ModelTree.hh index 4c5b1810..c7f17aea 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -283,7 +283,7 @@ protected: \param contemporaneous_jacobian Jacobian used as an incidence matrix: all elements declared in the map (even if they are zero), are used as vertices of the incidence matrix \return True if a complete normalization has been achieved */ - bool computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose); + bool computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic, bool verbose); //! Try to compute the matching between endogenous and variable using a decreasing cutoff /*! @@ -292,7 +292,7 @@ protected: If no matching is found with a zero cutoff, an error message is printed. The resulting normalization is stored in endo2eq. */ - void computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian); + void computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic); //! Evaluate the jacobian (w.r.t. endogenous) and suppress all the elements below the cutoff /*! Returns the contemporaneous_jacobian. Elements below the cutoff are discarded. External functions are evaluated to 1. */ diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 906bdca0..3123b088 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2003-2021 Dynare Team + * Copyright © 2003-2022 Dynare Team * * This file is part of Dynare. * @@ -1040,7 +1040,7 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co { auto contemporaneous_jacobian = evaluateAndReduceJacobian(eval_context); - computeNonSingularNormalization(contemporaneous_jacobian); + computeNonSingularNormalization(contemporaneous_jacobian, false); auto [prologue, epilogue] = computePrologueAndEpilogue(); -- GitLab