diff --git a/doc/dynare.texi b/doc/dynare.texi index 9f1910093..1329587b3 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -780,9 +780,12 @@ line numbering directives. Instructs Dynare to no create a logfile of this run in @file{@var{FILENAME}.log}. The default is to create the logfile. -@item no_2nd_order_params_derivs -Instructs Dynare not to compute the second order derivative of the jacobian or -the derivative of the hessian with respect to the parameters. +@item params_derivs_order=0|1|2 +When @ref{identification}, @ref{dynare_sensitivity} (with identification), or +@ref{estimation_cmd} are present, this option is used to limit the order of the +derivatives with respect to the parameters that are calculated by the +preprocessor. @code{0} means no derivatives, @code{1} means first derivatives, +and @code{2} means second derivatives. Default: @code{2} @item nowarn Suppresses all warnings. @@ -7514,6 +7517,7 @@ estimation environment is set up. @node Performing sensitivity analysis @subsection Performing sensitivity analysis +@anchor{dynare_sensitivity} @deffn Command dynare_sensitivity ; @deffnx Command dynare_sensitivity (@var{OPTIONS}@dots{}); @@ -7828,6 +7832,7 @@ end; @node Performing identification analysis @subsection Performing identification analysis +@anchor{identification} @deffn Command identification ; @deffnx Command identification (@var{OPTIONS}@dots{}); diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index 56dcc0704..c56f15ec5 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -3113,11 +3113,11 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context) } void -DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, FileOutputType paramsDerivatives, +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, bool bytecode, bool compute_xrefs) { - assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivatives)); + assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivsOrder)); initializeVariablesAndEquations(); @@ -3148,10 +3148,10 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative computeHessian(vars); } - if (paramsDerivatives != none) + if (paramsDerivsOrder > 0) { cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl; - computeParamsDerivatives(paramsDerivatives); + computeParamsDerivatives(paramsDerivsOrder); if (!no_tmp_terms) computeParamsDerivativesTemporaryTerms(); diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index 88f883cbb..9cef4cb02 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -208,11 +208,11 @@ public: \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 hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true) \param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true) - \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed (implies jacobianExo = true) + \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) \param eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files */ - void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, FileOutputType paramsDerivatives, + 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); //! 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; diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc index 4d6336f8d..6975ba0e9 100644 --- a/preprocessor/DynareMain.cc +++ b/preprocessor/DynareMain.cc @@ -41,7 +41,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file, WarningConsolidation &warnings_arg, bool nostrict, bool check_model_changes, bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode, - LanguageOutputType lang, bool sec_order_param_deriv + LanguageOutputType lang, int params_derivs_order #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -57,7 +57,7 @@ usage() cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]" << " [-D[=]] [-I/path] [nostrict] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=C|C++|julia]" - << " [no_2nd_order_params_derivs]" + << " [params_derivs_order=0|1|2]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -91,7 +91,7 @@ main(int argc, char **argv) bool no_line_macro = false; bool no_log = false; bool no_warn = false; - bool sec_order_param_deriv = true; + int params_derivs_order = 2; bool warn_uninit = false; bool console = false; bool nograph = false; @@ -121,8 +121,16 @@ main(int argc, char **argv) debug = true; else if (!strcmp(argv[arg], "noclearall")) clear_all = false; - else if (!strcmp(argv[arg], "no_2nd_order_params_derivs")) - sec_order_param_deriv = false; + else if (strlen(argv[arg]) >= 19 && !strncmp(argv[arg], "params_derivs_order", 19)) + { + if (strlen(argv[arg]) >= 22 || argv[arg][19] != '=' || + !(argv[arg][20] == '0' || argv[arg][20] == '1' || argv[arg][20] == '2')) + { + cerr << "Incorrect syntax for params_derivs_order option" << endl; + usage(); + } + params_derivs_order = stoi(string(argv[arg] + 20)); + } else if (!strcmp(argv[arg], "onlyclearglobals")) { clear_all = false; @@ -322,7 +330,7 @@ main(int argc, char **argv) main2(macro_output, basename, debug, clear_all, clear_global, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, parallel, config_file, warnings, nostrict, check_model_changes, minimal_workspace, - compute_xrefs, output_mode, language, sec_order_param_deriv + compute_xrefs, output_mode, language, params_derivs_order #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/preprocessor/DynareMain2.cc b/preprocessor/DynareMain2.cc index 386f939cd..a023328e4 100644 --- a/preprocessor/DynareMain2.cc +++ b/preprocessor/DynareMain2.cc @@ -30,7 +30,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file, WarningConsolidation &warnings, bool nostrict, bool check_model_changes, bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode, - LanguageOutputType language, bool sec_order_param_deriv + LanguageOutputType language, int params_derivs_order #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -51,7 +51,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear mod_file->evalAllExpressions(warn_uninit); // Do computations - mod_file->computingPass(no_tmp_terms, output_mode, compute_xrefs, sec_order_param_deriv); + mod_file->computingPass(no_tmp_terms, output_mode, compute_xrefs, params_derivs_order); // Write outputs if (output_mode != none) diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index 1a62e8004..c09f49ea1 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -469,7 +469,7 @@ ModFile::transformPass(bool nostrict) } void -ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xrefs, bool sec_order_param_deriv) +ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xrefs, int params_derivs_order) { // Mod file may have no equation (for example in a standalone BVAR estimation) if (dynamic_model.equation_number() > 0) @@ -489,13 +489,11 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xr const bool static_hessian = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; - FileOutputType paramsDerivatives = none; - if (mod_file_struct.estimation_analytic_derivation) - paramsDerivatives = third; - if (mod_file_struct.identification_present || !sec_order_param_deriv) - paramsDerivatives = first; + int paramsDerivsOrder = 0; + if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) + paramsDerivsOrder = params_derivs_order; static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, - false, paramsDerivatives, block, byte_code); + false, paramsDerivsOrder, block, byte_code); } // Set things to compute for dynamic model if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present @@ -526,12 +524,10 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xr bool thirdDerivatives = mod_file_struct.order_option == 3 || mod_file_struct.estimation_analytic_derivation || output == third; - FileOutputType paramsDerivatives = none; - if (mod_file_struct.estimation_analytic_derivation) - paramsDerivatives = third; - if (mod_file_struct.identification_present || !sec_order_param_deriv) - paramsDerivatives = first; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); + int paramsDerivsOrder = 0; + if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) + paramsDerivsOrder = params_derivs_order; + dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, compute_xrefs); } } else // No computing task requested, compute derivatives up to 2nd order by default diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh index 8dcb91409..4635ac1c2 100644 --- a/preprocessor/ModFile.hh +++ b/preprocessor/ModFile.hh @@ -132,8 +132,8 @@ public: //! Execute computations /*! \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 sec_order_param_deriv if true, compute second order param derivatives*/ - void computingPass(bool no_tmp_terms, FileOutputType output, bool compute_xrefs, bool sec_order_param_deriv); + /*! \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); //! 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 diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc index 518bd3fde..1fa26332b 100644 --- a/preprocessor/ModelTree.cc +++ b/preprocessor/ModelTree.cc @@ -1657,9 +1657,9 @@ ModelTree::sparseHelper(int order, ostream &output, int row_nb, int col_nb, Expr } void -ModelTree::computeParamsDerivatives(FileOutputType paramsDerivatives) +ModelTree::computeParamsDerivatives(int paramsDerivsOrder) { - if (!(paramsDerivatives == first || paramsDerivatives == second || paramsDerivatives == third)) + if (!(paramsDerivsOrder == 1 || paramsDerivsOrder == 2)) return; set deriv_id_set; addAllParamDerivId(deriv_id_set); @@ -1677,7 +1677,7 @@ ModelTree::computeParamsDerivatives(FileOutputType paramsDerivatives) residuals_params_derivatives[make_pair(eq, param)] = d1; } - if (paramsDerivatives == second || paramsDerivatives == third) + if (paramsDerivsOrder == 2) for (first_derivatives_t::const_iterator it2 = residuals_params_derivatives.begin(); it2 != residuals_params_derivatives.end(); it2++) { @@ -1704,35 +1704,36 @@ ModelTree::computeParamsDerivatives(FileOutputType paramsDerivatives) jacobian_params_derivatives[make_pair(eq, make_pair(var, param))] = d2; } - if (paramsDerivatives == second || paramsDerivatives == third) - for (second_derivatives_t::const_iterator it2 = jacobian_params_derivatives.begin(); - it2 != jacobian_params_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var = it2->first.second.first; - int param1 = it2->first.second.second; - expr_t d1 = it2->second; + if (paramsDerivsOrder == 2) + { + for (second_derivatives_t::const_iterator it2 = jacobian_params_derivatives.begin(); + it2 != jacobian_params_derivatives.end(); it2++) + { + int eq = it2->first.first; + int var = it2->first.second.first; + int param1 = it2->first.second.second; + expr_t d1 = it2->second; - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - jacobian_params_second_derivatives[make_pair(eq, make_pair(var, make_pair(param1, param)))] = d2; - } + expr_t d2 = d1->getDerivative(param); + if (d2 == Zero) + continue; + jacobian_params_second_derivatives[make_pair(eq, make_pair(var, make_pair(param1, param)))] = d2; + } - if (paramsDerivatives == third) - for (second_derivatives_t::const_iterator it2 = second_derivatives.begin(); - it2 != second_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var1 = it2->first.second.first; - int var2 = it2->first.second.second; - expr_t d1 = it2->second; + for (second_derivatives_t::const_iterator it2 = second_derivatives.begin(); + it2 != second_derivatives.end(); it2++) + { + int eq = it2->first.first; + int var1 = it2->first.second.first; + int var2 = it2->first.second.second; + expr_t d1 = it2->second; - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - hessian_params_derivatives[make_pair(eq, make_pair(var1, make_pair(var2, param)))] = d2; - } + expr_t d2 = d1->getDerivative(param); + if (d2 == Zero) + continue; + hessian_params_derivatives[make_pair(eq, make_pair(var1, make_pair(var2, param)))] = d2; + } + } } } diff --git a/preprocessor/ModelTree.hh b/preprocessor/ModelTree.hh index 41f30d3b3..4db8fb867 100644 --- a/preprocessor/ModelTree.hh +++ b/preprocessor/ModelTree.hh @@ -177,7 +177,7 @@ protected: /*! \param vars the derivation IDs w.r. to which derive the 2nd derivatives */ void computeThirdDerivatives(const set &vars); //! Computes derivatives of the Jacobian and Hessian w.r. to parameters - void computeParamsDerivatives(FileOutputType paramsDerivatives); + void computeParamsDerivatives(int paramsDerivsOrder); //! Write derivative of an equation w.r. to a variable void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; //! Computes temporary terms (for all equations and derivatives) diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc index a3b42f562..3f1ec6805 100644 --- a/preprocessor/StaticModel.cc +++ b/preprocessor/StaticModel.cc @@ -1047,7 +1047,7 @@ StaticModel::collect_first_order_derivatives_endogenous() } void -StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, FileOutputType paramsDerivatives, bool block, bool bytecode) +StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, bool block, bool bytecode) { initializeVariablesAndEquations(); @@ -1095,10 +1095,10 @@ StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms computeThirdDerivatives(vars); } - if (paramsDerivatives != none) + if (paramsDerivsOrder > 0) { cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl; - computeParamsDerivatives(paramsDerivatives); + computeParamsDerivatives(paramsDerivsOrder); if (!no_tmp_terms) computeParamsDerivativesTemporaryTerms(); diff --git a/preprocessor/StaticModel.hh b/preprocessor/StaticModel.hh index d8ec97900..21609adab 100644 --- a/preprocessor/StaticModel.hh +++ b/preprocessor/StaticModel.hh @@ -162,9 +162,9 @@ public: \param eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary terms will be computed in the static files \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed - \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed + \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed */ - void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, FileOutputType paramsDerivatives, bool block, bool bytecode); + void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, int paramsDerivsOrder, bool block, bool bytecode); //! Adds informations for simulation in a binary file for a block decomposed model void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,