diff --git a/matlab/perfect-foresight-models/make_ex_.m b/matlab/perfect-foresight-models/make_ex_.m index e98f4c4b5dffb48d5644c97a66e1256ef0ebe20a..0d796d89e26376ebf23aabab6b1dc75051aebae6 100644 --- a/matlab/perfect-foresight-models/make_ex_.m +++ b/matlab/perfect-foresight-models/make_ex_.m @@ -28,11 +28,12 @@ function oo_ = make_ex_(M_, options_, oo_) % along with Dynare. If not, see <https://www.gnu.org/licenses/>. try - periods = get_simulation_periods(options_); + [periods, first_simulation_period] = get_simulation_periods(options_); catch ME if strcmp(ME.identifier, 'Dynare:periodsNotSet') % This function is called from dyn_forecast in some contexts where periods is not set periods = 0; + first_simulation_period = options_.simul.first_simulation_period; else rethrow(ME); end @@ -91,11 +92,20 @@ end % Add temporary shocks if isfield(M_, 'det_shocks') - if ~isempty(M_.det_shocks) && any([M_.det_shocks.periods]==0) && ~M_.maximum_lag - error('make_ex_: The model does not have lags, so you cannot set values for period 0'); %leads are taken care of by preprocessor - end for i = 1:length(M_.det_shocks) - k = M_.det_shocks(i).periods + M_.maximum_lag; + if isa(M_.det_shocks(i).periods, 'numeric') + k = M_.det_shocks(i).periods + M_.maximum_lag; + if any(k == 0) + error('make_ex_: The model does not have lags, so you cannot set values for period 0'); + end + else % dates + k = M_.det_shocks(i).periods - first_simulation_period + 1 + M_.maximum_lag; + if any(k <= 1) + %% Contrary to the numeric case, we don’t allow k=0 for the dates case, because it + %% was a design mistake to allow them here (histval should rather be used) + error('make_ex_: some shocks are set at a date before the first simulation period'); + end + end ivar = M_.det_shocks(i).exo_id; v = M_.det_shocks(i).value; if ~M_.det_shocks(i).exo_det diff --git a/matlab/perfect-foresight-models/perfect_foresight_setup.m b/matlab/perfect-foresight-models/perfect_foresight_setup.m index bcbc17d9e90af24ad49c3f15aa3a50ea5ffcb79e..ff65afb797ee3395c9b8816d6cc228ce662e48e2 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_setup.m +++ b/matlab/perfect-foresight-models/perfect_foresight_setup.m @@ -47,19 +47,25 @@ if size(M_.lead_lag_incidence,2)-nnz(M_.lead_lag_incidence(M_.maximum_endo_lag+1 error(mess) end -periods = get_simulation_periods(options_); +[periods, ~, last_simulation_period] = get_simulation_periods(options_); -if ~isempty(M_.det_shocks) && periods < max([M_.det_shocks.periods]) - % Some expected shocks happen after the terminal period. - mess = sprintf('\nPERFECT_FORESIGHT_SETUP: Problem with the declaration of the expected shocks:\n'); +if ~isempty(M_.det_shocks) + % Check whether some expected shocks happen after the terminal period. + mess = ''; for i=1:length(M_.det_shocks) - if any(M_.det_shocks(i).periods > periods) + if isa(M_.det_shocks(i).periods, 'dates') && isempty(last_simulation_period) + error('PERFECT_FORESIGHT_SETUP: temporary shocks are specified using dates but neither first_simulation_period nor last_simulation_period option was passed') + end + if (isa(M_.det_shocks(i).periods, 'numeric') && any(M_.det_shocks(i).periods > periods)) ... + || (isa(M_.det_shocks(i).periods, 'dates') && any(M_.det_shocks(i).periods > last_simulation_period)) mess = sprintf('%s\n At least one expected value for %s has been declared after the terminal period.', mess, M_.exo_names{M_.det_shocks(i).exo_id}); end end - disp(mess) - skipline() - error('PERFECT_FORESIGHT_SETUP: Please check the declaration of the shocks or increase the number of periods in the simulation.') + if ~isempty(mess) + disp(sprintf('\nPERFECT_FORESIGHT_SETUP: Problem with the declaration of the expected shocks:\n%s', mess)); + skipline() + error('PERFECT_FORESIGHT_SETUP: Please check the declaration of the shocks or increase the number of periods in the simulation.') + end end if options_.simul.endval_steady && M_.maximum_lead == 0 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 545f566c5089cca9ca182a9d29c81f34c33d5734..7c938f9432acbd2899b638a71e5e2344c972e3c3 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 @@ -31,7 +31,7 @@ if ~isempty(oo_.initval_series) error('perfect_foresight_with_expectation_errors_setup: cannot be used in conjunction with histval_file/initval_file') end -periods = get_simulation_periods(options_); +[periods, first_simulation_period] = get_simulation_periods(options_); %% Initialize informational structures oo_.pfwee.terminal_info = NaN(M_.exo_nbr, periods); % 2nd dimension is informational time @@ -72,11 +72,27 @@ else warning('perfect_foresight_with_expectation_errors_setup: there is no shocks(learnt_in=...) or endval(learnt_in=...) block, and you did not pass the datafile option, so there is no point in using this command') end + %% Check that dates can be processed, if any + allperiods = {}; + if ~isempty(M_.det_shocks) + allperiods = [allperiods, {M_.det_shocks.periods}]; + end + if ~isempty(M_.learnt_shocks) + allperiods = [allperiods, {M_.learnt_shocks.periods}]; + 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') + end + %% Initialize information set at period 1 using “bare” shocks and endval blocks (or initval if there is no endval) oo_.pfwee.terminal_info(:, 1) = oo_.exo_steady_state; oo_.pfwee.shocks_info(:, :, 1) = repmat(oo_.exo_steady_state, 1, periods); for i = 1:length(M_.det_shocks) - prds = M_.det_shocks(i).periods; + if isa(M_.det_shocks(i).periods, 'numeric') + prds = M_.det_shocks(i).periods; + else % dates + prds = M_.det_shocks(i).periods - first_simulation_period + 1; + end exo_id = M_.det_shocks(i).exo_id; v = M_.det_shocks(i).value; if ~M_.det_shocks(i).exo_det @@ -121,7 +137,11 @@ else for i = 1:length(idx) j = idx(i); exo_id = M_.learnt_shocks(j).exo_id; - prds = M_.learnt_shocks(j).periods; + if isa(M_.learnt_shocks(j).periods, 'numeric') + prds = M_.learnt_shocks(j).periods; + else % dates + prds = M_.learnt_shocks(j).periods - first_simulation_period + 1; + end switch M_.learnt_shocks(j).type case 'level' oo_.pfwee.shocks_info(exo_id, prds, p) = M_.learnt_shocks(j).value; diff --git a/preprocessor b/preprocessor index 35b68b1411ae18c1403882ab784897983c3193fd..8e3cdd94643b32e885a19ae4c79441ed952a5e2f 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 35b68b1411ae18c1403882ab784897983c3193fd +Subproject commit 8e3cdd94643b32e885a19ae4c79441ed952a5e2f