diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 85037d4dcce09c630db097418a98f47e8582b8f5..1807762fcc02f0513a827e4f9552d67522052d3a 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -953,7 +953,7 @@ DynamicModel::writeDynamicCFile(const string &basename) const exit(EXIT_FAILURE); } output << "/*" << endl - << " * " << filename << " : Computes dynamic model for Dynare" << endl + << " * " << filename << " : Computes " << modelClassName() << " for Dynare" << endl << " *" << endl << " * Warning : this file is generated automatically by Dynare" << endl << " * from model file (.mod)" << endl @@ -3261,7 +3261,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO getJacobianColsNbr() is not yet set.*/ if (log2(getJacobianColsNbr())*derivsOrder >= numeric_limits<int>::digits) { - cerr << "ERROR: The dynamic derivatives matrix is too large. Please decrease the approximation order." << endl; + cerr << "ERROR: The derivatives matrix of the " << modelClassName() << " is too large. Please decrease the approximation order." << endl; exit(EXIT_FAILURE); } @@ -3275,7 +3275,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO } // Launch computations - cout << "Computing dynamic model derivatives (order " << derivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives (order " << derivsOrder << ")." << endl; computeDerivatives(derivsOrder, vars); @@ -3285,7 +3285,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO if (paramsDerivsOrder > 0) { - cout << "Computing dynamic model derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; computeParamsDerivatives(paramsDerivsOrder); } @@ -3307,12 +3307,12 @@ bool DynamicModel::computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) { auto contemporaneous_jacobian = evaluateAndReduceJacobian(eval_context); - if (!computeNonSingularNormalization(contemporaneous_jacobian, true)) + if (!computeNonSingularNormalization(contemporaneous_jacobian)) return false; auto [prologue, epilogue] = computePrologueAndEpilogue(); auto first_order_endo_derivatives = collectFirstOrderDerivativesEndogenous(); equationTypeDetermination(first_order_endo_derivatives, mfs); - cout << "Finding the optimal block decomposition of the dynamic model..." << endl; + cout << "Finding the optimal block decomposition of the " << modelClassName() << "..." << endl; computeBlockDecomposition(prologue, epilogue); reduceBlockDecomposition(); printBlockDecomposition(); @@ -3663,7 +3663,7 @@ DynamicModel::writeSetAuxiliaryVariables(const string &basename, bool julia) con output << "ds = "; output << func_name + "(ds, params)" << endl << comment << endl - << comment << " Status : Computes Auxiliary variables of the dynamic model and returns a dseries" << endl + << comment << " Status : Computes Auxiliary variables of the " << modelClassName() << " and returns a dseries" << endl << comment << endl << comment << " Warning : this file is generated automatically by Dynare" << endl << comment << " from model file (.mod)" << endl << endl; diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 37051525e6b6b90bcd2854b076476a8b7070ddc8..458de8d1e3036aeb208f95ed8ad79ecbad43de32 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -303,6 +303,13 @@ private: (failure can happen in normalization). */ virtual bool computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms); +protected: + string + modelClassName() const override + { + return "dynamic model"; + } + public: DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, diff --git a/src/ModFile.hh b/src/ModFile.hh index 90d73f8990d1fd81705437efb041820d50d2fcb4..02bc8027f6af05480eb07d92b05bb766f32a44ed 100644 --- a/src/ModFile.hh +++ b/src/ModFile.hh @@ -68,7 +68,7 @@ public: //! A copy of Dynamic model, for testing trends declared by user DynamicModel trend_dynamic_model; //! A copy of the original model, used to test model linearity under ramsey problem - DynamicModel orig_ramsey_dynamic_model; + OrigRamseyDynamicModel orig_ramsey_dynamic_model; //! Epilogue model, as declared in the "epilogue" block Epilogue epilogue; //! Static model, as derived from the "model" block when leads and lags have been removed diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc index fe0d649146333b3842a4c4d7ef06b82ada493b87..58db1c8a1aacdc205eae895f47c016a8b44529ab 100644 --- a/src/ModelEquationBlock.cc +++ b/src/ModelEquationBlock.cc @@ -38,6 +38,23 @@ PlannerObjective::computingPassBlock([[maybe_unused]] const eval_context_t &eval return false; } +OrigRamseyDynamicModel::OrigRamseyDynamicModel(SymbolTable &symbol_table_arg, + NumericalConstants &num_constants_arg, + ExternalFunctionsTable &external_functions_table_arg, + TrendComponentModelTable &trend_component_model_table_arg, + VarModelTable &var_model_table_arg) : + DynamicModel {symbol_table_arg, num_constants_arg, external_functions_table_arg, + trend_component_model_table_arg, var_model_table_arg} +{ +} + +OrigRamseyDynamicModel & +OrigRamseyDynamicModel::operator=(const DynamicModel &m) +{ + DynamicModel::operator=(m); + return *this; +} + SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, diff --git a/src/ModelEquationBlock.hh b/src/ModelEquationBlock.hh index eb255e03ef61e6e53152fcb2fb9babb5e4cea6db..a34fb6dcfcf887dab547747823c225de00f210ec 100644 --- a/src/ModelEquationBlock.hh +++ b/src/ModelEquationBlock.hh @@ -32,10 +32,35 @@ public: PlannerObjective(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg); +protected: + string + modelClassName() const override + { + return "planner objective"; + } + private: bool computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) override; }; +class OrigRamseyDynamicModel : public DynamicModel +{ +public: + OrigRamseyDynamicModel(SymbolTable &symbol_table_arg, + NumericalConstants &num_constants_arg, + ExternalFunctionsTable &external_functions_table_arg, + TrendComponentModelTable &trend_component_model_table_arg, + VarModelTable &var_model_table_arg); + OrigRamseyDynamicModel &operator=(const DynamicModel &m); + +protected: + string + modelClassName() const override + { + return "original Ramsey model"; + } +}; + class SteadyStateModel : public DataTree { private: @@ -104,6 +129,14 @@ public: //! Write Output void writeOutput(ostream &output) const; + +protected: + string + modelClassName() const override + { + return "epilogue"; + } + private: //! Helper for public writeEpilogueFile void writeStaticEpilogueFile(const string &basename) const; diff --git a/src/ModelTree.cc b/src/ModelTree.cc index 8da7b1ad8a2ebd67ca8e79e9b3dc299aadc2acf8..1ad98dd65a8ae9e97bfe9fff4894529c7a111620 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -202,7 +202,7 @@ ModelTree::operator=(const ModelTree &m) } bool -ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic, bool verbose) +ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose) { const int n = equations.size(); @@ -242,7 +242,7 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, boo it != mate_map.begin() + n) { if (verbose) - cerr << "Could not normalize the " << (dynamic ? "dynamic" : "static") << " model. Variable " + cerr << "Could not normalize the " << modelClassName() << " . Variable " << symbol_table.getName(symbol_table.getID(SymbolType::endogenous, it - mate_map.begin())) << " is not in the maximum cardinality matching." << endl; check = false; @@ -251,7 +251,7 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, boo } bool -ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic) +ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian) { int n = equations.size(); @@ -259,11 +259,11 @@ ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_ja not have as many equations as variables. */ if (n != symbol_table.endo_nbr()) { - cout << "The " << (dynamic ? "dynamic" : "static") << " model cannot be normalized, since it does not have as many equations as variables." << endl; + cout << "The " << modelClassName() << " cannot be normalized, since it does not have as many equations as variables." << endl; return false; } - cout << "Normalizing the " << (dynamic ? "dynamic" : "static") << " model..." << endl; + cout << "Normalizing the " << modelClassName() << "..." << endl; // Compute the maximum value of each row of the contemporaneous Jacobian matrix vector max_val(n, 0.0); @@ -293,14 +293,14 @@ ModelTree::computeNonSingularNormalization(const jacob_map_t &contemporaneous_ja suppressed++; if (suppressed != last_suppressed) - found_normalization = computeNormalization(normalized_contemporaneous_jacobian_above_cutoff, dynamic, false); + found_normalization = computeNormalization(normalized_contemporaneous_jacobian_above_cutoff, 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, dynamic, false); + found_normalization = computeNormalization(normalized_contemporaneous_jacobian, false); } } @@ -311,7 +311,7 @@ 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, dynamic, true); + found_normalization = computeNormalization(symbolic_jacobian, true); } /* NB: If normalization failed, an explanatory message has been printed by the last call diff --git a/src/ModelTree.hh b/src/ModelTree.hh index ecb49614c135e0dcb464a81039c0e50759b443b7..fdeb5ecaf6fc3ffc79f01d2146a13d4dfefbfc47 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -344,7 +344,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 dynamic, bool verbose); + bool computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose); //! Try to compute the matching between endogenous and variable using a decreasing cutoff /*! @@ -354,7 +354,7 @@ protected: The resulting normalization is stored in endo2eq. Returns a boolean indicating success. */ - bool computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian, bool dynamic); + bool computeNonSingularNormalization(const jacob_map_t &contemporaneous_jacobian); //! 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. */ @@ -453,6 +453,9 @@ protected: “var” is the block-specific endogenous variable index. */ virtual int getBlockJacobianEndoCol(int blk, int var, int lag) const = 0; + // Returns a human-readable string describing the model class (e.g. “dynamic model”…) + virtual string modelClassName() const = 0; + private: //! Internal helper for the copy constructor and assignment operator /*! Copies all the structures that contain ExprNode*, by the converting the diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 8636bd76407a9f908c53d98ddd44c6c84b205a85..13a023f51c77bd2dc3f68779403de8b286a6388e 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -344,7 +344,7 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co with DynamicModel::computingPass(). */ if (log2(symbol_table.endo_nbr())*derivsOrder >= numeric_limits<int>::digits) { - cerr << "ERROR: The static derivatives matrix is too large. Please decrease the approximation order." << endl; + cerr << "ERROR: The derivatives matrix of the " << modelClassName() << " is too large. Please decrease the approximation order." << endl; exit(EXIT_FAILURE); } @@ -357,13 +357,13 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co } // Launch computations - cout << "Computing static model derivatives (order " << derivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives (order " << derivsOrder << ")." << endl; computeDerivatives(derivsOrder, vars); if (paramsDerivsOrder > 0) { - cout << "Computing static model derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; computeParamsDerivatives(paramsDerivsOrder); } @@ -385,12 +385,12 @@ bool StaticModel::computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) { auto contemporaneous_jacobian = evaluateAndReduceJacobian(eval_context); - if (!computeNonSingularNormalization(contemporaneous_jacobian, false)) + if (!computeNonSingularNormalization(contemporaneous_jacobian)) return false; auto [prologue, epilogue] = computePrologueAndEpilogue(); auto first_order_endo_derivatives = collectFirstOrderDerivativesEndogenous(); equationTypeDetermination(first_order_endo_derivatives, mfs); - cout << "Finding the optimal block decomposition of the static model..." << endl; + cout << "Finding the optimal block decomposition of the " << modelClassName() << "..." << endl; computeBlockDecomposition(prologue, epilogue); reduceBlockDecomposition(); printBlockDecomposition(); @@ -637,7 +637,7 @@ StaticModel::writeStaticCFile(const string &basename) const } output << "/*" << endl - << " * " << filename << " : Computes static model for Dynare" << endl + << " * " << filename << " : Computes " << modelClassName() << " for Dynare" << endl << " *" << endl << " * Warning : this file is generated automatically by Dynare" << endl << " * from model file (.mod)" << endl << endl @@ -1325,7 +1325,7 @@ StaticModel::writeSetAuxiliaryVariables(const string &basename, bool julia) cons output << "y = "; output << func_name << "(y, x, params)" << endl << comment << endl - << comment << " Status : Computes static model for Dynare" << endl + << comment << " Status : Computes Auxiliary variables of the " << modelClassName() << endl << comment << endl << comment << " Warning : this file is generated automatically by Dynare" << endl << comment << " from model file (.mod)" << endl << endl; diff --git a/src/StaticModel.hh b/src/StaticModel.hh index da65283905cc5a4069e114d64bbf491744138a5f..127252b1e91b7225cf3abcf3b4355765b735ca54 100644 --- a/src/StaticModel.hh +++ b/src/StaticModel.hh @@ -116,6 +116,13 @@ private: (failure can happen in normalization). */ virtual bool computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms); +protected: + string + modelClassName() const override + { + return "static model"; + } + public: StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants,