From 9f65299d8a7e63de8432a73bffdc8899eb27e936 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 1 Mar 2024 17:29:29 +0100
Subject: [PATCH] =?UTF-8?q?New=20=E2=80=9Chomotopy=5Fexclude=5Fvarexo?=
 =?UTF-8?q?=E2=80=9D=20option=20to=20=E2=80=9Cperfect=5Fforesight=5Fsolver?=
 =?UTF-8?q?=E2=80=9D=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 doc/manual/source/the-model-file.rst          |  6 +++
 matlab/default_option_values.m                |  1 +
 .../perfect_foresight_solver.m                |  7 +++
 meson.build                                   |  1 +
 preprocessor                                  |  2 +-
 .../homotopy_exclude_varexo.mod               | 49 +++++++++++++++++++
 6 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 tests/deterministic_simulations/homotopy_exclude_varexo.mod

diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst
index cfbca027d8..99ec3998d4 100644
--- a/doc/manual/source/the-model-file.rst
+++ b/doc/manual/source/the-model-file.rst
@@ -3834,6 +3834,12 @@ speed-up on large models.
        beyond a certain point, so as to save computing time, while at the same
        time getting an approximate solution.
 
+    .. option:: homotopy_exclude_varexo = (VARIABLE_NAME...)
+
+       A list of exogenous variables which are to be excluded from the homotopy
+       procedure, *i.e.* which must be kept at their value corresponding to
+       100% of the shock during all homotopy iterations.
+
     .. option:: markowitz = DOUBLE
 
        Value of the Markowitz criterion, used to select the
diff --git a/matlab/default_option_values.m b/matlab/default_option_values.m
index baeb79deed..13c4275fda 100644
--- a/matlab/default_option_values.m
+++ b/matlab/default_option_values.m
@@ -335,6 +335,7 @@ options_.simul.homotopy_step_size_increase_success_count = 3;
 options_.simul.homotopy_initial_step_size = 1;
 options_.simul.homotopy_linearization_fallback = false;
 options_.simul.homotopy_marginal_linearization_fallback = 0; % Size of the step used for the marginal linearization; 0 means disabled
+options_.simul.homotopy_exclude_varexo = [];
 
 % Options used by perfect_foresight_* commands when they compute the steady
 % state corresponding to a terminal condition
diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m
index c7a4f12127..d09de3787b 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_solver.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m
@@ -461,6 +461,13 @@ function [steady_success, endo_simul, exo_simul, steady_state, exo_steady_state]
 
 % Compute convex combination for the path of exogenous
 exo_simul = exoorig*share/shareorig + exobase*(1-share/shareorig);
+if ~isempty(options_.simul.homotopy_exclude_varexo)
+    [is_exo, excluded_exo_ids] = ismember(options_.simul.homotopy_exclude_varexo, M_.exo_names);
+    if ~all(is_exo)
+        error('Option homotopy_exclude_varexo must be given exogenous variable names')
+    end
+    exo_simul(:, excluded_exo_ids) = exoorig(:, excluded_exo_ids);
+end
 
 % Compute convex combination for the initial condition
 % In most cases, the initial condition is a steady state and this does nothing
diff --git a/meson.build b/meson.build
index 7594ad0d31..ca8c3fce87 100644
--- a/meson.build
+++ b/meson.build
@@ -1367,6 +1367,7 @@ mod_and_m_tests = [
   { 'test' : [ 'deterministic_simulations/homotopy_histval.mod' ] },
   { 'test' : [ 'deterministic_simulations/homotopy_endval_steady_linearization.mod' ] },
   { 'test' : [ 'deterministic_simulations/homotopy_marginal_linearization.mod' ] },
+  { 'test' : [ 'deterministic_simulations/homotopy_exclude_varexo.mod' ] },
   { 'test' : [ 'deterministic_simulations/rbc_det_exo_lag_2a.mod',
                'deterministic_simulations/rbc_det_exo_lag_2b.mod',
                'deterministic_simulations/rbc_det_exo_lag_2c.mod' ] },
diff --git a/preprocessor b/preprocessor
index 3a9a7924bf..585dc63680 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 3a9a7924bfbddc7f45404bc2da2c7e049a06f320
+Subproject commit 585dc63680bfdb5dcdc02ba1418648e7a0420b2c
diff --git a/tests/deterministic_simulations/homotopy_exclude_varexo.mod b/tests/deterministic_simulations/homotopy_exclude_varexo.mod
new file mode 100644
index 0000000000..ee3ae5dcc1
--- /dev/null
+++ b/tests/deterministic_simulations/homotopy_exclude_varexo.mod
@@ -0,0 +1,49 @@
+// Example that triggers homotopy in perfect foresight simulation.
+// Tests the homotopy_exclude_varexo option
+
+var Consumption, Capital, LoggedProductivity;
+
+varexo LoggedProductivityInnovation dummy;
+
+parameters beta, alpha, delta, rho;
+
+beta = .985;
+alpha = 1/3;
+delta = alpha/10;
+rho = .9;
+
+model;
+  1/Consumption = beta/Consumption(1)*(alpha*exp(LoggedProductivity(1))*Capital^(alpha-1)+1-delta)*dummy;
+  Capital = exp(LoggedProductivity)*Capital(-1)^alpha+(1-delta)*Capital(-1)-Consumption;
+  LoggedProductivity = rho*LoggedProductivity(-1)+LoggedProductivityInnovation;
+end;
+
+initval;
+  LoggedProductivityInnovation = 0;
+  dummy = 1;
+end;
+
+steady;
+
+endval;
+  LoggedProductivityInnovation = 1;
+  dummy = 1;
+  Consumption = 0.1;
+  Capital = 1;
+end;
+
+perfect_foresight_setup(periods=200, endval_steady);
+
+perfect_foresight_solver(homotopy_exclude_varexo = (dummy),
+                         homotopy_max_completion_share = 0.7,
+                         homotopy_linearization_fallback,
+                         steady_solve_algo = 13);
+
+if ~oo_.deterministic_simulation.status
+   error('Perfect foresight simulation failed')
+end
+
+if oo_.deterministic_simulation.sim1.exo_simul(end, 1) ~= 0.7 ... % productivity must be rescaled
+   || oo_.deterministic_simulation.sim1.exo_simul(end, 2) ~= 1    % but not dummy
+    error('Option homotopy_exclude_varexo not working properly')
+end
-- 
GitLab