From 23a72d7aaa2c4613cf87718f83ae524585d346ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ry=C3=BBk=29?=
 <stepan@adjemian.eu>
Date: Sun, 10 Apr 2022 09:39:28 +0200
Subject: [PATCH] Use dynare_solve to simulate purely forward deterministic
 models.

---
 matlab/dynamic_forward_model_for_simulation.m | 27 +++++++++++++++++++
 .../dynamic_static_model_for_simulation.m     |  0
 .../sim1_purely_backward.m                    |  2 +-
 .../sim1_purely_forward.m                     | 22 ++++++++-------
 .../sim1_purely_static.m                      |  2 +-
 5 files changed, 42 insertions(+), 11 deletions(-)
 create mode 100644 matlab/dynamic_forward_model_for_simulation.m
 rename matlab/{backward => }/dynamic_static_model_for_simulation.m (100%)

diff --git a/matlab/dynamic_forward_model_for_simulation.m b/matlab/dynamic_forward_model_for_simulation.m
new file mode 100644
index 0000000000..b3e6c65621
--- /dev/null
+++ b/matlab/dynamic_forward_model_for_simulation.m
@@ -0,0 +1,27 @@
+function [r, J] = dynamic_forward_model_for_simulation(z, dynamicmodel, ylead, x, params, steady_state, it_)
+
+% Copyright © 2022 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+if nargout>1
+        % Compute residuals and jacobian of the full dynamic model.
+    [r, J] = feval(dynamicmodel, [z; ylead], x, params, steady_state, it_);
+    J = J(:,1:length(z)); % Remove derivatives with respect to shocks.
+else
+    % Compute residuals.
+    r = feval(dynamicmodel, [z; ylead], x, params, steady_state, it_);
+end
\ No newline at end of file
diff --git a/matlab/backward/dynamic_static_model_for_simulation.m b/matlab/dynamic_static_model_for_simulation.m
similarity index 100%
rename from matlab/backward/dynamic_static_model_for_simulation.m
rename to matlab/dynamic_static_model_for_simulation.m
diff --git a/matlab/perfect-foresight-models/sim1_purely_backward.m b/matlab/perfect-foresight-models/sim1_purely_backward.m
index 81c5e9edc3..c545806f60 100644
--- a/matlab/perfect-foresight-models/sim1_purely_backward.m
+++ b/matlab/perfect-foresight-models/sim1_purely_backward.m
@@ -30,7 +30,7 @@ if ismember(options.solve_algo, [12,14]) && ~M.possible_to_use_solve_algo_12_14
     error(M.message_solve_algo_12_14)
 end
 
-dynamicmodel = str2func([M.fname,'.dynamic']);
+dynamicmodel = str2func(sprintf('%s.%s', M.fname, 'dynamic'));
 dynamicmodel_s = str2func('dynamic_backward_model_for_simulation');
 
 info.status = true;
diff --git a/matlab/perfect-foresight-models/sim1_purely_forward.m b/matlab/perfect-foresight-models/sim1_purely_forward.m
index ff893bd4e1..20215e6478 100644
--- a/matlab/perfect-foresight-models/sim1_purely_forward.m
+++ b/matlab/perfect-foresight-models/sim1_purely_forward.m
@@ -1,7 +1,7 @@
 function [endogenousvariables, info] = sim1_purely_forward(endogenousvariables, exogenousvariables, steadystate, M, options)
 % Performs deterministic simulation of a purely forward model
 
-% Copyright (C) 2012-2017 Dynare Team
+% Copyright © 2012-2022 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -25,21 +25,25 @@ if ny0 ~= M.endo_nbr
     error('All endogenous variables must appear at the current period!')
 end
 
-dynamicmodel = str2func([M.fname,'.dynamic']);
+dynamicmodel = str2func(sprintf('%s.%s', M.fname, 'dynamic'));
+dynamicmodel_s = str2func('dynamic_forward_model_for_simulation');
 
 info.status = 1;
 
 for it = options.periods:-1:1
     yf = endogenousvariables(:,it+1); % Values at next period, also used as guess value for current period
-    yf1 = yf(iyf);
-    % TODO Call dynare_solve instead.
-    [tmp, check] = solve1(dynamicmodel, [yf; yf1], 1:M.endo_nbr, 1:M.endo_nbr, ...
-                          1, options.gstep, options.dynatol.f, ...
-                          options.dynatol.x, options.simul.maxit, [], ...
-                          options.debug, exogenousvariables, M.params, steadystate, ...
-                          it+M.maximum_lag);
+    if ismember(options.solve_algo, [12,14])
+        [tmp, check, ~, ~, errorcode] = dynare_solve(dynamicmodel_s, yf, options, M.isloggedlhs, M.isauxdiffloggedrhs, M.endo_names, M.lhs, ...
+                                                     dynamicmodel, yf(iyf), exogenousvariables, M.params, steadystate, it);
+    else
+        [tmp, check, ~, ~, errorcode] = dynare_solve(dynamicmodel_s, yf, options, ...
+                                                     dynamicmodel, yf(iyf), exogenousvariables, M.params, steadystate, it);
+    end
     if check
         info.status = 0;
+        if option.debug
+            dprintf('sim1_purely_forward: Nonlinear solver routine failed with errorcode=%i in period %i.', errorcode, it)
+        end
     end
     endogenousvariables(:,it) = tmp(1:M.endo_nbr);
 end
diff --git a/matlab/perfect-foresight-models/sim1_purely_static.m b/matlab/perfect-foresight-models/sim1_purely_static.m
index 373896cff9..74de6ecb83 100644
--- a/matlab/perfect-foresight-models/sim1_purely_static.m
+++ b/matlab/perfect-foresight-models/sim1_purely_static.m
@@ -27,7 +27,7 @@ if ismember(options.solve_algo, [12,14]) && ~M.possible_to_use_solve_algo_12_14
     error(M.message_solve_algo_12_14)
 end
 
-dynamicmodel = str2func([M.fname,'.dynamic']);
+dynamicmodel = str2func(sprintf('%s.%s', M.fname, 'dynamic'));
 dynamicmodel_s = str2func('dynamic_static_model_for_simulation');
 
 info.status = true;
-- 
GitLab