From 771627eacb9b47e107f0b31c4dc9fdc7a29c8244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 19 Mar 2024 16:19:22 +0100 Subject: [PATCH] =?UTF-8?q?dynare=5Fsolve:=20use=20=E2=80=9Coptions=5F?= =?UTF-8?q?=E2=80=9D=20instead=20of=20=E2=80=9Coptions=E2=80=9D=20as=20arg?= =?UTF-8?q?ument?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- matlab/optimization/dynare_solve.m | 82 +++++++++++++++--------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/matlab/optimization/dynare_solve.m b/matlab/optimization/dynare_solve.m index b41f82e73e..1278055b21 100644 --- a/matlab/optimization/dynare_solve.m +++ b/matlab/optimization/dynare_solve.m @@ -1,4 +1,4 @@ -function [x, errorflag, fvec, fjac, errorcode] = dynare_solve(f, x, maxit, tolf, tolx, options, varargin) +function [x, errorflag, fvec, fjac, errorcode] = dynare_solve(f, x, maxit, tolf, tolx, options_, varargin) % Solves a nonlinear system of equations, f(x) = 0 with n unknowns % and n equations. @@ -6,7 +6,7 @@ function [x, errorflag, fvec, fjac, errorcode] = dynare_solve(f, x, maxit, tolf, % INPUTS % - f [char, fhandle] function to be solved % - x [double] n×1 vector, initial guess. -% - options [struct] Dynare options, aka options_. +% - options_ [struct] Dynare options % - varargin list of additional arguments to be passed to func. % % OUTPUTS @@ -22,7 +22,7 @@ function [x, errorflag, fvec, fjac, errorcode] = dynare_solve(f, x, maxit, tolf, % -10 -> System of equation ill-behaved at the initial guess (Inf, Nans or complex numbers). % -11 -> Initial guess is a solution of the system of equations. -% Copyright © 2001-2023 Dynare Team +% Copyright © 2001-2024 Dynare Team % % This file is part of Dynare. % @@ -39,7 +39,7 @@ function [x, errorflag, fvec, fjac, errorcode] = dynare_solve(f, x, maxit, tolf, % You should have received a copy of the GNU General Public License % along with Dynare. If not, see <https://www.gnu.org/licenses/>. -jacobian_flag = options.jacobian_flag; % true iff Jacobian is returned by f routine (as a second output argument). +jacobian_flag = options_.jacobian_flag; % true iff Jacobian is returned by f routine (as a second output argument). errorflag = false; % Let's be optimistic! nn = size(x,1); @@ -63,17 +63,17 @@ if jacobian_flag [fvec, fjac] = feval(f, x, varargin{:}); wrong_initial_guess_flag = false; if ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))) || any(~isreal(fvec)) || any(~isreal(fjac(:))) - if ~ismember(options.solve_algo,[10,11]) && ~any(isnan(fvec)) && max(abs(fvec))< tolf + if ~ismember(options_.solve_algo,[10,11]) && ~any(isnan(fvec)) && max(abs(fvec))< tolf % return if initial value solves the problem except if a mixed complementarity problem is to be solved (complementarity conditions may not be satisfied) % max([NaN, 0])=0, so explicitly exclude the case where fvec contains a NaN errorcode = -11; return; end - if options.solve_randomize_initial_guess + 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) + 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) + 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; @@ -106,7 +106,7 @@ if jacobian_flag else fvec = feval(f, x, varargin{:}); fjac = zeros(nn, nn); - if ~ismember(options.solve_algo,[10,11]) && ~any(isnan(fvec)) && max(abs(fvec)) < tolf + if ~ismember(options_.solve_algo,[10,11]) && ~any(isnan(fvec)) && max(abs(fvec)) < tolf % return if initial value solves the problem except if a mixed complementarity problem is to be solved (complementarity conditions may not be satisfied) % max([NaN, 0])=0, so explicitly exclude the case where fvec contains a NaN errorcode = -11; @@ -151,7 +151,7 @@ if wrong_initial_guess_flag return end -if options.solve_algo == 0 +if options_.solve_algo == 0 if ~isoctave if ~user_has_matlab_license('optimization_toolbox') error('You can''t use solve_algo=0 since you don''t have MATLAB''s Optimization Toolbox') @@ -180,17 +180,17 @@ if options.solve_algo == 0 options4fsolve.SpecifyObjectiveGradient = jacobian_flag; end %% NB: The Display option is accepted but not honoured under Octave (as of version 7) - if options.debug + if options_.debug options4fsolve.Display = 'final'; else options4fsolve.Display = 'off'; end %% This one comes last, so that the user can override Dynare - if ~isempty(options.fsolve_options) + if ~isempty(options_.fsolve_options) if isoctave - eval(['options4fsolve = optimset(options4fsolve,' options.fsolve_options ');']); + eval(['options4fsolve = optimset(options4fsolve,' options_.fsolve_options ');']); else - eval(['options4fsolve = optimoptions(options4fsolve,' options.fsolve_options ');']); + eval(['options4fsolve = optimoptions(options4fsolve,' options_.fsolve_options ');']); end end @@ -216,22 +216,22 @@ if options.solve_algo == 0 else errorflag = true; end -elseif ismember(options.solve_algo, [1, 12]) +elseif ismember(options_.solve_algo, [1, 12]) %% NB: It is the responsibility of the caller to deal with the block decomposition if solve_algo=12 - [x, errorflag, errorcode] = solve1(f, x, 1:nn, 1:nn, jacobian_flag, options.gstep, tolf, tolx, maxit, [], options.debug, varargin{:}); + [x, errorflag, errorcode] = solve1(f, x, 1:nn, 1:nn, jacobian_flag, options_.gstep, tolf, tolx, maxit, [], options_.debug, varargin{:}); [fvec, fjac] = feval(f, x, varargin{:}); -elseif options.solve_algo==9 - [x, errorflag, errorcode] = trust_region(f, x, 1:nn, 1:nn, jacobian_flag, options.gstep, tolf, tolx, maxit, options.trust_region_initial_step_bound_factor, options.debug, varargin{:}); +elseif options_.solve_algo==9 + [x, errorflag, errorcode] = trust_region(f, x, 1:nn, 1:nn, jacobian_flag, options_.gstep, tolf, tolx, maxit, options_.trust_region_initial_step_bound_factor, options_.debug, varargin{:}); [fvec, fjac] = feval(f, x, varargin{:}); -elseif ismember(options.solve_algo, [2, 4]) - if options.solve_algo == 2 +elseif ismember(options_.solve_algo, [2, 4]) + if options_.solve_algo == 2 solver = @solve1; else solver = @trust_region; end if ~jacobian_flag fjac = zeros(nn,nn) ; - dh = max(abs(x), options.gstep(1)*ones(nn,1))*eps^(1/3); + dh = max(abs(x), options_.gstep(1)*ones(nn,1))*eps^(1/3); for j = 1:nn xdh = x ; xdh(j) = xdh(j)+dh(j) ; @@ -239,7 +239,7 @@ elseif ismember(options.solve_algo, [2, 4]) end end [j1,j2,r,s] = dmperm(fjac); - if options.debug + if options_.debug disp(['DYNARE_SOLVE (solve_algo=2|4): number of blocks = ' num2str(length(r)-1)]); end for i=length(r)-1:-1:1 @@ -258,10 +258,10 @@ elseif ismember(options.solve_algo, [2, 4]) if blockcolumns>=blocklength %(under-)determined block [x, errorflag, errorcode] = solver(f, x, j1(j), j2(j), jacobian_flag, ... - options.gstep, ... - tolf, options.solve_tolx, maxit, ... - options.trust_region_initial_step_bound_factor, ... - options.debug, varargin{:}); + options_.gstep, ... + tolf, options_.solve_tolx, maxit, ... + options_.trust_region_initial_step_bound_factor, ... + options_.debug, varargin{:}); else fprintf('\nDYNARE_SOLVE (solve_algo=2|4): the Dulmage-Mendelsohn decomposition returned a non-square block. This means that the Jacobian is singular. You may want to try another value for solve_algo.\n') %overdetermined block @@ -274,14 +274,14 @@ elseif ismember(options.solve_algo, [2, 4]) end fvec = feval(f, x, varargin{:}); if max(abs(fvec))>tolf - disp_verbose('Call solver on the full nonlinear problem.',options.verbosity) + disp_verbose('Call solver on the full nonlinear problem.',options_.verbosity) [x, errorflag, errorcode] = solver(f, x, 1:nn, 1:nn, jacobian_flag, ... - options.gstep, tolf, options.solve_tolx, maxit, ... - options.trust_region_initial_step_bound_factor, ... - options.debug, varargin{:}); + options_.gstep, tolf, options_.solve_tolx, maxit, ... + options_.trust_region_initial_step_bound_factor, ... + options_.debug, varargin{:}); end [fvec, fjac] = feval(f, x, varargin{:}); -elseif options.solve_algo==3 +elseif options_.solve_algo==3 if jacobian_flag [x, errorcode] = csolve(f, x, f, tolf, maxit, varargin{:}); else @@ -293,9 +293,9 @@ elseif options.solve_algo==3 errorflag = true; end [fvec, fjac] = feval(f, x, varargin{:}); -elseif options.solve_algo==10 +elseif options_.solve_algo==10 % LMMCP - olmmcp = options.lmmcp; + olmmcp = options_.lmmcp; [x, fvec, errorcode, ~, fjac] = lmmcp(f, x, olmmcp.lb, olmmcp.ub, olmmcp, varargin{:}); eq_to_check=find(isfinite(olmmcp.lb) | isfinite(olmmcp.ub)); eq_to_ignore=eq_to_check(x(eq_to_check,:)<=olmmcp.lb(eq_to_check)+eps | x(eq_to_check,:)>=olmmcp.ub(eq_to_check)-eps); @@ -305,7 +305,7 @@ elseif options.solve_algo==10 else errorflag = true; end -elseif options.solve_algo == 11 +elseif options_.solve_algo == 11 % PATH mixed complementary problem % PATH linear mixed complementary problem if ~exist('mcppath') @@ -313,7 +313,7 @@ elseif options.solve_algo == 11 'yourself and add its location to Matlab/Octave path before ' ... 'running Dynare']) end - omcppath = options.mcppath; + omcppath = options_.mcppath; global mcp_data mcp_data.func = f; mcp_data.args = varargin; @@ -326,16 +326,16 @@ elseif options.solve_algo == 11 eq_to_check=find(isfinite(omcppath.lb) | isfinite(omcppath.ub)); eq_to_ignore=eq_to_check(x(eq_to_check,:)<=omcppath.lb(eq_to_check)+eps | x(eq_to_check,:)>=omcppath.ub(eq_to_check)-eps); fvec(eq_to_ignore)=0; -elseif ismember(options.solve_algo, [13, 14]) +elseif ismember(options_.solve_algo, [13, 14]) %% NB: It is the responsibility of the caller to deal with the block decomposition if solve_algo=14 if ~jacobian_flag error('DYNARE_SOLVE: option solve_algo=13 needs computed Jacobian') end - [x, errorflag, errorcode] = block_trust_region(f, x, tolf, options.solve_tolx, maxit, ... - options.trust_region_initial_step_bound_factor, ... - options.solve_algo == 13, ... % Only block-decompose with Dulmage-Mendelsohn for 13, not for 14 - options.debug, varargin{:}); + [x, errorflag, errorcode] = block_trust_region(f, x, tolf, options_.solve_tolx, maxit, ... + options_.trust_region_initial_step_bound_factor, ... + options_.solve_algo == 13, ... % Only block-decompose with Dulmage-Mendelsohn for 13, not for 14 + options_.debug, varargin{:}); [fvec, fjac] = feval(f, x, varargin{:}); else - error('DYNARE_SOLVE: option solve_algo must be one of [0,1,2,3,4,9,10,11,12,13,14]') + error('DYNARE_SOLVE: option solve_algo must be one of [0,1,2,3,4,7,8,9,10,11,12,13,14]') end -- GitLab