From 23ba760c3b36d2293fa85b9f3cab40e98c8edd9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Thu, 28 Oct 2010 12:07:33 +0200 Subject: [PATCH] Implement solve_algo=0 for Octave (closes #144) --- doc/manual.xml | 2 +- matlab/dynare_solve.m | 16 +++++++++++----- tests/block_bytecode/run_block_bytecode_tests.m | 8 ++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/manual.xml b/doc/manual.xml index 522b21752..d54672f9e 100644 --- a/doc/manual.xml +++ b/doc/manual.xml @@ -1788,7 +1788,7 @@ periods 100; = INTEGER Determines the non-linear solver to use. Possible values for the option are: - 0: uses MATLAB Optimization Toolbox FSOLVE (not available under Octave) + 0: uses fsolve (under MATLAB, only available if you have the Optimization Toolbox; always available under Octave) 1: uses Dynare's own nonlinear equation solver 2: splits the model into recursive blocks and solves each block in turn 3: Chris Sims' solver diff --git a/matlab/dynare_solve.m b/matlab/dynare_solve.m index 34a410eeb..024855362 100644 --- a/matlab/dynare_solve.m +++ b/matlab/dynare_solve.m @@ -38,10 +38,8 @@ global options_ options_ = set_default_option(options_,'solve_algo',2); info = 0; if options_.solve_algo == 0 - if exist('OCTAVE_VERSION') || isempty(ver('optim')) - % Note that fsolve() exists under Octave, but has a different syntax - % So we fail for the moment under Octave, until we add the corresponding code - error('DYNARE_SOLVE: you can''t use solve_algo=0 since you don''t have Matlab''s Optimization Toolbox') + if ~exist('OCTAVE_VERSION') && isempty(ver('optim')) + error('You can''t use solve_algo=0 since you don''t have MATLAB''s Optimization Toolbox') end options=optimset('fsolve'); options.MaxFunEvals = 50000; @@ -53,7 +51,15 @@ if options_.solve_algo == 0 else options.Jacobian = 'off'; end - [x,fval,exitval,output] = fsolve(func,x,options,varargin{:}); + if ~exist('OCTAVE_VERSION') + [x,fval,exitval,output] = fsolve(func,x,options,varargin{:}); + else + % Under Octave, use a wrapper, since fsolve() does not have a 4th arg + func2 = str2func(func); + func = @(x) func2(x, varargin{:}); + [x,fval,exitval,output] = fsolve(func,x,options); + end + if exitval > 0 info = 0; else diff --git a/tests/block_bytecode/run_block_bytecode_tests.m b/tests/block_bytecode/run_block_bytecode_tests.m index 00c02af5e..86d317589 100644 --- a/tests/block_bytecode/run_block_bytecode_tests.m +++ b/tests/block_bytecode/run_block_bytecode_tests.m @@ -28,18 +28,18 @@ putenv("GNUTERM", "dumb") for block = 0:1 for bytecode = 0:1 - ## Recall that solve_algo={0,7} and stack_solve_algo=2 are not supported + ## Recall that solve_algo=7 and stack_solve_algo=2 are not supported ## under Octave default_solve_algo = 2; default_stack_solve_algo = 0; if !block && !bytecode - solve_algos = 1:4; + solve_algos = 0:4; stack_solve_algos = 0; elseif block && !bytecode - solve_algos = [1:4 6 8]; + solve_algos = [0:4 6 8]; stack_solve_algos = [0 1 3 4]; else - solve_algos = [1:6 8]; + solve_algos = [0:6 8]; stack_solve_algos = [0 1 3:5]; endif