From b0358b99395b6ec7253576baf5890c60328a4d6b Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer <jpfeifer@gmx.de> Date: Sun, 27 Aug 2023 13:32:45 +0200 Subject: [PATCH] dynare_solve.m: add option to disable randomization of starting value --- matlab/default_option_values.m | 1 + matlab/dynare_solve.m | 63 +++++++++++++++++----------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/matlab/default_option_values.m b/matlab/default_option_values.m index 712fd6ef18..ca98027a22 100644 --- a/matlab/default_option_values.m +++ b/matlab/default_option_values.m @@ -52,6 +52,7 @@ options_.lyapunov_complex_threshold = 1e-15; options_.solve_algo = 4; options_.solve_tolf = eps^(1/3); options_.solve_tolx = eps^(2/3); +options_.solve_randomize_initial_guess = true; options_.trust_region_initial_step_bound_factor = 1; options_.dr_display_tol=1e-6; options_.minimal_workspace = false; diff --git a/matlab/dynare_solve.m b/matlab/dynare_solve.m index c0a3fd41ff..944a3806c4 100644 --- a/matlab/dynare_solve.m +++ b/matlab/dynare_solve.m @@ -59,7 +59,6 @@ else end % checking initial values -% TODO We should have an option to deactivate the randomization. if jacobian_flag [fvec, fjac] = feval(f, x, varargin{:}); wrong_initial_guess_flag = false; @@ -70,36 +69,38 @@ if jacobian_flag errorcode = -11; return; end - if any(~isreal(fvec)) || any(~isreal(fjac(:))) - disp_verbose('dynare_solve: starting value results in complex values. Randomize initial guess...', options.verbosity) - else - disp_verbose('dynare_solve: starting value results in nonfinite/NaN value. Randomize initial guess...', options.verbosity) - end - % Let's try random numbers for the variables initialized with the default value. - wrong_initial_guess_flag = true; - % First try with positive numbers. - tentative_number = 0; - while wrong_initial_guess_flag && tentative_number<=in0*10 - tentative_number = tentative_number+1; - x(idx) = rand(in0, 1)*10; - [fvec, fjac] = feval(f, x, varargin{:}); - wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); - end - % If all previous attempts failed, try with real numbers. - tentative_number = 0; - while wrong_initial_guess_flag && tentative_number<=in0*10 - tentative_number = tentative_number+1; - x(idx) = randn(in0, 1)*10; - [fvec, fjac] = feval(f, x, varargin{:}); - wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); - end - % Last tentative, ff all previous attempts failed, try with negative numbers. - tentative_number = 0; - while wrong_initial_guess_flag && tentative_number<=in0*10 - tentative_number = tentative_number+1; - x(idx) = -rand(in0, 1)*10; - [fvec, fjac] = feval(f, x, varargin{:}); - wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); + if options.solve_randomize_initial_guess + if any(~isreal(fvec)) || any(~isreal(fjac(:))) + disp_verbose('dynare_solve: starting value results in complex values. Randomize initial guess...', options.verbosity) + else + disp_verbose('dynare_solve: starting value results in nonfinite/NaN value. Randomize initial guess...', options.verbosity) + end + % Let's try random numbers for the variables initialized with the default value. + wrong_initial_guess_flag = true; + % First try with positive numbers. + tentative_number = 0; + while wrong_initial_guess_flag && tentative_number<=in0*10 + tentative_number = tentative_number+1; + x(idx) = rand(in0, 1)*10; + [fvec, fjac] = feval(f, x, varargin{:}); + wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); + end + % If all previous attempts failed, try with real numbers. + tentative_number = 0; + while wrong_initial_guess_flag && tentative_number<=in0*10 + tentative_number = tentative_number+1; + x(idx) = randn(in0, 1)*10; + [fvec, fjac] = feval(f, x, varargin{:}); + wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); + end + % Last tentative, ff all previous attempts failed, try with negative numbers. + tentative_number = 0; + while wrong_initial_guess_flag && tentative_number<=in0*10 + tentative_number = tentative_number+1; + x(idx) = -rand(in0, 1)*10; + [fvec, fjac] = feval(f, x, varargin{:}); + wrong_initial_guess_flag = ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))); + end end end else -- GitLab