From 5a5817b4fe26c40c113a2d9c62497e69a71d4b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Thu, 14 Nov 2019 17:51:16 +0100 Subject: [PATCH] Improvements to the test for balanced growth path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Raise the default tolerance for cross-derivatives to 1e-6, to reduce the number of false positives — New option “balanced_growth_test_tol” to the “model” block for changing that tolerance — Turn back test failures into errors. Since there is now an option for controlling the tolerance, the user always has the possibility of making the test pass. Closes: dynare#1389 --- src/DynamicModel.cc | 11 +++++++---- src/DynamicModel.hh | 8 ++++++++ src/DynareBison.yy | 3 ++- src/DynareFlex.ll | 1 + src/ParsingDriver.cc | 6 ++++++ src/ParsingDriver.hh | 2 ++ 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 32110a3b..e6cd7e91 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -100,6 +100,7 @@ DynamicModel::DynamicModel(const DynamicModel &m) : ModelTree {m}, trend_component_model_table {m.trend_component_model_table}, var_model_table {m.var_model_table}, + balanced_growth_test_tol {m.balanced_growth_test_tol}, static_only_equations_lineno {m.static_only_equations_lineno}, static_only_equations_equation_tags {m.static_only_equations_equation_tags}, deriv_id_table {m.deriv_id_table}, @@ -160,6 +161,7 @@ DynamicModel::operator=(const DynamicModel &m) assert(&trend_component_model_table == &m.trend_component_model_table); assert(&var_model_table == &m.var_model_table); + balanced_growth_test_tol = m.balanced_growth_test_tol; static_only_equations_lineno = m.static_only_equations_lineno; static_only_equations_equation_tags = m.static_only_equations_equation_tags; @@ -5800,13 +5802,14 @@ DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context if (symbol_table.getType(endogit->first.first) == SymbolType::endogenous) { double nearZero = testeq->getDerivative(endogit->second)->eval(eval_context); // eval d F / d Trend d Endog - if (fabs(nearZero) > zero_band) + if (fabs(nearZero) > balanced_growth_test_tol) { - cerr << "WARNING: trends not compatible with balanced growth path; the second-order cross partial of equation " << eq + 1 << " (line " + cerr << "ERROR: trends not compatible with balanced growth path; the second-order cross partial of equation " << eq + 1 << " (line " << equations_lineno[eq] << ") w.r.t. trend variable " << symbol_table.getName(it->first.first) << " and endogenous variable " - << symbol_table.getName(endogit->first.first) << " is not null. " << endl; - // Changed to warning. See discussion in #1389 + << symbol_table.getName(endogit->first.first) << " is not null (abs. value = " + << fabs(nearZero) << "). If you are confident that your trends are correctly specified, you can raise the value of option 'balanced_growth_test_tol' in the 'model' block." << endl; + exit(EXIT_FAILURE); } } } diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 67ca4019..865d22d7 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -35,7 +35,15 @@ public: TrendComponentModelTable &trend_component_model_table; //! A reference to the VAR model table VarModelTable &var_model_table; + /* Used in the balanced growth test, for determining whether the + cross-derivative of a given equation, w.r.t. an endogenous and a trend + variable is zero. Controlled by option “balanced_growth_test_tol” of the + “model” block. The default should not be too small (see dynare#1389). */ + double balanced_growth_test_tol{1e-6}; private: + /* Used in the balanced growth test, for skipping equations where the test + cannot be performed (i.e. when LHS=RHS at the initial values). Should not + be too large, otherwise the test becomes less powerful. */ constexpr static double zero_band{1e-8}; //! Stores equations declared as [static] diff --git a/src/DynareBison.yy b/src/DynareBison.yy index ca6ce508..f1a24547 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -73,7 +73,7 @@ class ParsingDriver; } %token AIM_SOLVER ANALYTIC_DERIVATION ANALYTIC_DERIVATION_MODE AR POSTERIOR_SAMPLING_METHOD -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION SILENT_OPTIMIZER +%token BALANCED_GROWTH_TEST_TOL BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION SILENT_OPTIMIZER %token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER FIG_NAME WRITE_XLS %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA INTERACTIVE SCREEN_SHOCKS STEADYSTATE %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN DETAIL_PLOT TYPE @@ -900,6 +900,7 @@ model_options : BLOCK { driver.block(); } | o_linear | PARALLEL_LOCAL_FILES EQUAL '(' parallel_local_filename_list ')' | LINEAR_DECOMPOSITION { driver.linear_decomposition(); } + | BALANCED_GROWTH_TEST_TOL EQUAL non_negative_number { driver.balanced_growth_test_tol($3); } ; model_options_list : model_options_list COMMA model_options diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll index 111d07cb..b24d6a2f 100644 --- a/src/DynareFlex.ll +++ b/src/DynareFlex.ll @@ -706,6 +706,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2])) <DYNARE_BLOCK>periods {return token::PERIODS;} <DYNARE_BLOCK>cutoff {return token::CUTOFF;} <DYNARE_BLOCK>mfs {return token::MFS;} +<DYNARE_BLOCK>balanced_growth_test_tol {return token::BALANCED_GROWTH_TEST_TOL;} <DYNARE_BLOCK>gamma_pdf {return token::GAMMA_PDF;} <DYNARE_BLOCK>beta_pdf {return token::BETA_PDF;} <DYNARE_BLOCK>normal_pdf {return token::NORMAL_PDF;} diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 2ecac4d6..0aea25ad 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -793,6 +793,12 @@ ParsingDriver::mfs(const string &value) mod_file->static_model.mfs = val; } +void +ParsingDriver::balanced_growth_test_tol(const string &value) +{ + mod_file->dynamic_model.balanced_growth_test_tol = stod(value); +} + void ParsingDriver::end_initval(bool all_values_required) { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 42572adf..c944dc2c 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -356,6 +356,8 @@ public: void cutoff(const string &value); //! mfs option of model block void mfs(const string &value); + //! balanced_growth_test_tol option of model block + void balanced_growth_test_tol(const string &value); //! Sets the FILENAME for the initial value in initval void initval_file(const string &filename); //! Declares an endogenous variable -- GitLab