From f408be5793b8426adc812f7299c4943f52ab0dff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 22 Nov 2024 17:44:50 +0100
Subject: [PATCH] =?UTF-8?q?Perfect=20foresight=20with=20expectation=20erro?=
 =?UTF-8?q?rs:=20handle=20dates=20in=20the=20=E2=80=9Clearnt=5Fin=E2=80=9D?=
 =?UTF-8?q?=20keyword?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ..._foresight_with_expectation_errors_setup.m | 23 +++++++++++++------
 preprocessor                                  |  2 +-
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m
index 7c938f9432..fce1048a21 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_with_expectation_errors_setup.m
@@ -78,10 +78,13 @@ else
         allperiods = [allperiods, {M_.det_shocks.periods}];
     end
     if ~isempty(M_.learnt_shocks)
-        allperiods = [allperiods, {M_.learnt_shocks.periods}];
+        allperiods = [allperiods, {M_.learnt_shocks.periods, M_.learnt_shocks.learnt_in }];
+    end
+    if ~isempty(M_.learnt_endval)
+        allperiods = [allperiods, {M_.learnt_endval.learnt_in }];
     end
     if any(cellfun(@(x) isa(x, 'dates'), allperiods)) && isempty(first_simulation_period)
-        error('perfect_foresight_with_expectations_error_setup: at least one periods statement is specified using a date but neither first_simulation_period nor last_simulation_period option was passed')
+        error('perfect_foresight_with_expectations_error_setup: at least one periods statement or learnt_in option is specified using a date but neither first_simulation_period nor last_simulation_period option was passed')
     end
 
     %% Initialize information set at period 1 using “bare” shocks and endval blocks (or initval if there is no endval)
@@ -111,11 +114,17 @@ else
     end
 
     %% Construct information sets for subsequent informational periods
-    for p = 2:periods
-        oo_.pfwee.terminal_info(:, p) = oo_.pfwee.terminal_info(:, p-1);
-        oo_.pfwee.shocks_info(:, :, p) = oo_.pfwee.shocks_info(:, :, p-1);
+    % Since the learnt_in=… option with a dates object is never translated to a
+    % “bare” shocks or endval block by the preprocessor (contrary to
+    % learnt_in=1), the loop starts with p=1 to also handle dates objects
+    % in learnt_in option corresponding to the first period.
+    for p = 1:periods
+        if p > 1
+            oo_.pfwee.terminal_info(:, p) = oo_.pfwee.terminal_info(:, p-1);
+            oo_.pfwee.shocks_info(:, :, p) = oo_.pfwee.shocks_info(:, :, p-1);
+        end
         if ~isempty(M_.learnt_endval)
-            idx = find([M_.learnt_endval.learnt_in] == p);
+            idx = find(cellfun(@(x) (isa(x, 'numeric') && x == p) || (isa(x, 'dates') && x - first_simulation_period + 1 == p), {M_.learnt_endval.learnt_in}));
             for i = 1:length(idx)
                 j = idx(i);
                 exo_id = M_.learnt_endval(j).exo_id;
@@ -133,7 +142,7 @@ else
             end
         end
         if ~isempty(M_.learnt_shocks)
-            idx = find([M_.learnt_shocks.learnt_in] == p);
+            idx = find(cellfun(@(x) (isa(x, 'numeric') && x == p) || (isa(x, 'dates') && x - first_simulation_period + 1 == p), {M_.learnt_shocks.learnt_in}));
             for i = 1:length(idx)
                 j = idx(i);
                 exo_id = M_.learnt_shocks(j).exo_id;
diff --git a/preprocessor b/preprocessor
index 8e3cdd9464..a88ac75488 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 8e3cdd94643b32e885a19ae4c79441ed952a5e2f
+Subproject commit a88ac75488d86a51f8febbead4692769722881c1
-- 
GitLab