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