From 8aabdaee9c88c0ae3af265a49cd45be46ff093e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Tue, 17 Jan 2023 15:25:47 +0100
Subject: [PATCH] Consolidate functions for solving steady state with block
 and/or bytecode

---
 matlab/block_bytecode_mfs_steadystate.m |  24 ------
 matlab/block_mfs_steadystate.m          |  26 ------
 matlab/dynare_solve_block_or_bytecode.m | 105 ------------------------
 matlab/evaluate_steady_state.m          |  95 ++++++++++++++++++++-
 4 files changed, 92 insertions(+), 158 deletions(-)
 delete mode 100644 matlab/block_bytecode_mfs_steadystate.m
 delete mode 100644 matlab/block_mfs_steadystate.m
 delete mode 100644 matlab/dynare_solve_block_or_bytecode.m

diff --git a/matlab/block_bytecode_mfs_steadystate.m b/matlab/block_bytecode_mfs_steadystate.m
deleted file mode 100644
index c4b5a7095f..0000000000
--- a/matlab/block_bytecode_mfs_steadystate.m
+++ /dev/null
@@ -1,24 +0,0 @@
-function [r, g1] = block_bytecode_mfs_steadystate(y, b, y_all, exo, params, T, M)
-% Wrapper around the *_static.m file, for use with dynare_solve,
-% when block_mfs option is given to steady.
-
-% Copyright © 2009-2023 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/>.
-
-indx = M.block_structure_stat.block(b).variable;
-y_all(indx) = y;
-[r, g1] = bytecode(y_all, exo, params, y_all, 1, y_all, T, 'evaluate', 'static', 'block_decomposed', ['block = ' int2str(b) ]);
diff --git a/matlab/block_mfs_steadystate.m b/matlab/block_mfs_steadystate.m
deleted file mode 100644
index b58ef24042..0000000000
--- a/matlab/block_mfs_steadystate.m
+++ /dev/null
@@ -1,26 +0,0 @@
-function [r, g1] = block_mfs_steadystate(y, fh_static, b, y_all, exo, params, T, M)
-% Wrapper around the static files, for use with dynare_solve,
-% when block option is given to steady.
-
-% Copyright © 2009-2023 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/>.
-
-y_all(M.block_structure_stat.block(b).variable) = y;
-
-[~,~,r,g1] = fh_static(y_all, exo, params, M.block_structure_stat.block(b).g1_sparse_rowval, ...
-                       M.block_structure_stat.block(b).g1_sparse_colval, ...
-                       M.block_structure_stat.block(b).g1_sparse_colptr, T);
diff --git a/matlab/dynare_solve_block_or_bytecode.m b/matlab/dynare_solve_block_or_bytecode.m
deleted file mode 100644
index b5b55561e7..0000000000
--- a/matlab/dynare_solve_block_or_bytecode.m
+++ /dev/null
@@ -1,105 +0,0 @@
-function [x,info] = dynare_solve_block_or_bytecode(y, exo, params, options, M)
-
-% Copyright © 2010-2023 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/>.
-
-info = 0;
-x = y;
-if options.block && ~options.bytecode
-    T = NaN(M.block_structure_stat.tmp_nbr, 1);
-    for b = 1:length(M.block_structure_stat.block)
-        fh_static = str2func(sprintf('%s.sparse.block.static_%d', M.fname, b));
-        ss = x;
-        if M.block_structure_stat.block(b).Simulation_Type ~= 1 && ...
-                M.block_structure_stat.block(b).Simulation_Type ~= 2
-            if options.solve_algo <= 4 || options.solve_algo >= 9
-                [y, errorflag] = dynare_solve('block_mfs_steadystate', ...
-                                              ss(M.block_structure_stat.block(b).variable), ...
-                                              options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
-                                              options, fh_static, b, ss, exo, params, T, M);
-                if errorflag
-                    info = 1;
-                    return
-                end
-                ss(M.block_structure_stat.block(b).variable) = y;
-            else
-                n = length(M.block_structure_stat.block(b).variable);
-                [ss, T, ~, check] = solve_one_boundary(fh_static, ss, exo, ...
-                                                       params, [], T, M.block_structure_stat.block(b).variable, n, 1, false, b, 0, options.simul.maxit, ...
-                                                       options.solve_tolf, ...
-                                                       0, options.solve_algo, true, false, false, M, options, []);
-                if check
-                    info = 1;
-                    return
-                end
-            end
-        end
-        % Compute endogenous if the block is of type evaluate forward/backward or if there are recursive variables in a solve block.
-        % Also update the temporary terms vector (needed for the dynare_solve case)
-        [x, T] = fh_static(ss, exo, params, M.block_structure_stat.block(b).g1_sparse_rowval, ...
-                           M.block_structure_stat.block(b).g1_sparse_colval, ...
-                           M.block_structure_stat.block(b).g1_sparse_colptr, T);
-    end
-elseif options.bytecode
-    if options.solve_algo >= 5 && options.solve_algo <= 8
-        try
-            if options.block
-                x = bytecode('static', 'block_decomposed', x, exo, params);
-            else
-                x = bytecode('static', x, exo, params);
-            end
-        catch ME
-            disp(ME.message);
-            info = 1;
-            return
-        end
-    elseif options.block
-        T = NaN(M.block_structure_stat.tmp_nbr, 1);
-        for b = 1:length(M.block_structure_stat.block)
-            if M.block_structure_stat.block(b).Simulation_Type ~= 1 && ...
-                    M.block_structure_stat.block(b).Simulation_Type ~= 2
-                [y, errorflag] = dynare_solve('block_bytecode_mfs_steadystate', ...
-                                              x(M.block_structure_stat.block(b).variable), ...
-                                              options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
-                                              options, b, x, exo, params, T, M);
-                if errorflag
-                    info = 1;
-                    return
-                end
-                x(M.block_structure_stat.block(b).variable) = y;
-            end
-            % Compute endogenous if the block is of type evaluate forward/backward or if there are recursive variables in a solve block.
-            % Also update the temporary terms vector (needed for the dynare_solve case)
-            try
-                [~, ~, x, T] = bytecode(x, exo, params, x, 1, x, T, 'evaluate', 'static', ...
-                                        'block_decomposed', ['block = ' int2str(b)]);
-            catch ME
-                disp(ME.message);
-                info = 1;
-                return
-            end
-        end
-    else
-        [x, errorflag] = dynare_solve('bytecode_steadystate', y, ...
-                                      options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
-                                      options, exo, params);
-        if errorflag
-            info = 1;
-            return
-        end
-    end
-end
diff --git a/matlab/evaluate_steady_state.m b/matlab/evaluate_steady_state.m
index 2dba4e288f..b64c143d02 100644
--- a/matlab/evaluate_steady_state.m
+++ b/matlab/evaluate_steady_state.m
@@ -354,9 +354,85 @@ elseif ~options.bytecode && ~options.block
             end
         end
     end
-else
-    % block or bytecode
-    [ys,check] = dynare_solve_block_or_bytecode(ys_init,exo_ss, params, options, M);
+elseif ~options.bytecode && options.block
+    ys = ys_init;
+    T = NaN(M.block_structure_stat.tmp_nbr, 1);
+    for b = 1:length(M.block_structure_stat.block)
+        fh_static = str2func(sprintf('%s.sparse.block.static_%d', M.fname, b));
+        if M.block_structure_stat.block(b).Simulation_Type ~= 1 && ...
+                M.block_structure_stat.block(b).Simulation_Type ~= 2
+            if options.solve_algo <= 4 || options.solve_algo >= 9
+                [z, errorflag] = dynare_solve(@block_mfs_steadystate, ...
+                                              ys(M.block_structure_stat.block(b).variable), ...
+                                              options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
+                                              options, fh_static, b, ys, exo_ss, params, T, M);
+                if errorflag
+                    check = 1;
+                    break
+                end
+                ys(M.block_structure_stat.block(b).variable) = z;
+            else
+                n = length(M.block_structure_stat.block(b).variable);
+                [ys, T, ~, info2] = solve_one_boundary(fh_static, ys, exo_ss, ...
+                                                       params, [], T, M.block_structure_stat.block(b).variable, n, 1, false, b, 0, options.simul.maxit, ...
+                                                       options.solve_tolf, ...
+                                                       0, options.solve_algo, true, false, false, M, options, []);
+                if info2
+                    check = 1;
+                    break
+                end
+            end
+        end
+        % Compute endogenous if the block is of type evaluate forward/backward or if there are recursive variables in a solve block.
+        % Also update the temporary terms vector (needed for the dynare_solve case)
+        [ys, T] = fh_static(ys, exo_ss, params, M.block_structure_stat.block(b).g1_sparse_rowval, ...
+                            M.block_structure_stat.block(b).g1_sparse_colval, ...
+                            M.block_structure_stat.block(b).g1_sparse_colptr, T);
+    end
+elseif options.bytecode
+    if options.solve_algo >= 5 && options.solve_algo <= 8
+        try
+            if options.block
+                ys = bytecode('static', 'block_decomposed', ys_init, exo_ss, params);
+            else
+                ys = bytecode('static', ys_init, exo_ss, params);
+            end
+        catch ME
+            disp(ME.message);
+            check = 1;
+        end
+    elseif options.block
+        ys = ys_init;
+        T = NaN(M.block_structure_stat.tmp_nbr, 1);
+        for b = 1:length(M.block_structure_stat.block)
+            if M.block_structure_stat.block(b).Simulation_Type ~= 1 && ...
+                    M.block_structure_stat.block(b).Simulation_Type ~= 2
+                [z, errorflag] = dynare_solve(@block_bytecode_mfs_steadystate, ...
+                                              ys(M.block_structure_stat.block(b).variable), ...
+                                              options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
+                                              options, b, ys, exo_ss, params, T, M);
+                if errorflag
+                    check = 1;
+                    break
+                end
+                ys(M.block_structure_stat.block(b).variable) = z;
+            end
+            % Compute endogenous if the block is of type evaluate forward/backward or if there are recursive variables in a solve block.
+            % Also update the temporary terms vector (needed for the dynare_solve case)
+            try
+                [~, ~, ys, T] = bytecode(ys, exo_ss, params, ys, 1, ys, T, 'evaluate', 'static', ...
+                                         'block_decomposed', ['block = ' int2str(b)]);
+            catch ME
+                disp(ME.message);
+                check = 1;
+                break
+            end
+        end
+    else
+        [ys, check] = dynare_solve('bytecode_steadystate', ys_init, ...
+                                   options.simul.maxit, options.solve_tolf, options.solve_tolx, ...
+                                   options, exo_ss, params);
+    end
 end
 
 if check
@@ -417,3 +493,16 @@ function [resids,jac] = static_mcp_problem(y, x, params, nvar, fh_static_resid,
 j = fh_static_g1(y, x, params, sparse_rowval, sparse_colval, sparse_colptr, T_order, T);
 resids = r(eq_index);
 jac = j(eq_index,1:nvar);
+
+function [r, g1] = block_mfs_steadystate(y, fh_static, b, y_all, exo, params, T, M)
+% Wrapper around the static files, for block without bytecode
+y_all(M.block_structure_stat.block(b).variable) = y;
+[~,~,r,g1] = fh_static(y_all, exo, params, M.block_structure_stat.block(b).g1_sparse_rowval, ...
+                       M.block_structure_stat.block(b).g1_sparse_colval, ...
+                       M.block_structure_stat.block(b).g1_sparse_colptr, T);
+
+function [r, g1] = block_bytecode_mfs_steadystate(y, b, y_all, exo, params, T, M)
+% Wrapper around the static files, for block without bytecode
+indx = M.block_structure_stat.block(b).variable;
+y_all(indx) = y;
+[r, g1] = bytecode(y_all, exo, params, y_all, 1, y_all, T, 'evaluate', 'static', 'block_decomposed', ['block = ' int2str(b) ]);
-- 
GitLab