Add new option last_simulation_period to initval_file command.

Also adjust the periods in Simulated_time_series (output of the perfect
foresight solver in the workspace). Note that this dseries object contains the
observations for the initial condition (M_.orig_maximum_lag observations) and
for the terminal condition (M_.orig_maximum_lead observations).

See #1838.

Fix testsuite (wrong file name)
trustregion
Stéphane Adjemian (Ryûk) 2022-01-21 16:45:45 +01:00
parent 38e1cd5d4e
commit f5f47cd834
Signed by: stepan
GPG Key ID: 295C1FE89E17EB3C
8 changed files with 136 additions and 52 deletions

View File

@ -1996,6 +1996,13 @@ in this case ``initval`` is used to specify the terminal conditions.
file as the only dates necessary for initialization are before
that date.
.. option:: last_simulation_period = {INTEGER | DATE}
The observation number in the file or the date (see
:ref:`dates <dates-members>`) at which the simulation (or the forecast) is
ending. This option avoids to have to compute the maximum
number of leads in the model.
.. option:: last_obs = {INTEGER | DATE}
The observaton number or the date (see
@ -2265,6 +2272,13 @@ in this case ``initval`` is used to specify the terminal conditions.
file as the only dates necessary for initialization are before
that date.
.. option:: last_simulation_period = {INTEGER | DATE}
The observation number in the file or the date (see
:ref:`dates <dates-members>`) at which the simulation (or the forecast) is
ending. This option avoids to have to compute the maximum
number of leads in the model.
.. option:: last_obs = {INTEGER | DATE}
The observation number or the date (see :ref:`dates-members`) of the

View File

@ -1,18 +1,17 @@
function series = histvalf_initvalf(caller, M, options)
% function initvalf(M)
%
% handles options for histvalf_initvalf() and initvalf()
function [series, p] = histvalf_initvalf(caller, DynareModel, options)
% Handles options for histvalf() and initvalf()
%
% INPUTS
% caller: string, name of calling function
% M: model structure
% options: options specific to initivalf
% - caller [char] row array, name of calling function
% - DynareModel [struct] model description, a.k.a M_
% - options [struct] options specific to initivalf
%
% OUTPUTS
% series: dseries containing selected data from a file or a dseries
%
% - series [dseries] selected data from a file or a dseries
% - p [integer] number of periods (excluding the initial and terminal conditions)
% Copyright (C) 2003-2021 Dynare Team
% Copyright © 2003-2022 Dynare Team
%
% This file is part of Dynare.
%
@ -80,23 +79,23 @@ end
% checking that all variable are present
error_flag = false;
for i = 1:M.orig_endo_nbr
if ~series.exist(M.endo_names{i})
dprintf('%s_FILE: endogenous variable %s is missing', caller, M.endo_names{i})
for i = 1:DynareModel.orig_endo_nbr
if ~series.exist(DynareModel.endo_names{i})
dprintf('%s_FILE: endogenous variable %s is missing', caller, DynareModel.endo_names{i})
error_flag = true;
end
end
for i = 1:M.exo_nbr
if ~series.exist(M.exo_names{i})
dprintf('%s_FILE: exogenous variable %s is missing', caller, M.exo_names{i})
for i = 1:DynareModel.exo_nbr
if ~series.exist(DynareModel.exo_names{i})
dprintf('%s_FILE: exogenous variable %s is missing', caller, DynareModel.exo_names{i})
error_flag = true;
end
end
for i = 1:M.exo_det_nbr
if ~series.exist(M.exo_det_names{i})
dprintf('%s_FILE: exo_det variable %s is missing', caller, M.exo_det_names{i})
for i = 1:DynareModel.exo_det_nbr
if ~series.exist(DynareModel.exo_det_names{i})
dprintf('%s_FILE: exo_det variable %s is missing', caller, DynareModel.exo_det_names{i})
error_flag = true;
end
end
@ -105,8 +104,8 @@ if error_flag
error('%s_FILE: some variables are missing', caller)
end
if exist(sprintf('+%s/dynamic_set_auxiliary_series.m', M.fname), 'file')
series = feval(sprintf('%s.dynamic_set_auxiliary_series', M.fname), series, M.params);
if exist(sprintf('+%s/dynamic_set_auxiliary_series.m', DynareModel.fname), 'file')
series = feval(sprintf('%s.dynamic_set_auxiliary_series', DynareModel.fname), series, DynareModel.params);
end
% selecting observations
@ -130,18 +129,18 @@ if isfield(options, 'first_obs') && ~isempty(options.first_obs)
error('%s_FILE: first_obs = %d is larger than the number of observations in the data file (%d)', ...
caller, options.first_obs, nobs0)
elseif isfield(options, 'first_simulation_period')
if options.first_obs == options.first_simulation_period - M.orig_maximum_lag
if options.first_obs == options.first_simulation_period - DynareModel.orig_maximum_lag
first_obs = periods(options.first_obs);
else
error('%s_FILE: first_obs = %d and first_simulation_period = %d have values inconsistent with a maximum lag of %d periods', ...
caller, options.first_obs, options.first_simulation_period, M.orig_maximum_lag)
caller, options.first_obs, options.first_simulation_period, DynareModel.orig_maximum_lag)
end
elseif isfield(options, 'firstsimulationperiod')
if periods(options.first_obs) == options.firstsimulationperiod - M.orig_maximum_lag
if periods(options.first_obs) == options.firstsimulationperiod - DynareModel.orig_maximum_lag
first_obs = periods(options.first_obs);
else
error('%s_FILE: first_obs = %d and first_simulation_period = %s have values inconsistent with a maximum lag of %d periods', ...
caller, options.first_obs, options.firstsimulationperiod, M.orig_maximum_lag)
caller, options.first_obs, options.firstsimulationperiod, DynareModel.orig_maximum_lag)
end
else
first_obs = periods(options.first_obs);
@ -151,18 +150,18 @@ end
if isfield(options, 'firstobs') && ~isempty(options.firstobs)
if isfield(options, 'first_simulation_period')
if options.firstobs == periods(options.first_simulation_period) - M.orig_maximum_lag
if options.firstobs == periods(options.first_simulation_period) - DynareModel.orig_maximum_lag
first_obs = options.firstobs;
else
error('%s_FILE: first_obs = %s and first_simulation_period = %d have values inconsistent with a maximum lag of %d periods', ...
caller, options.firstobs, options.first_simulation_period, M.orig_maximum_lag)
caller, options.firstobs, options.first_simulation_period, DynareModel.orig_maximum_lag)
end
elseif isfield(options, 'firstsimulationperiod')
if options.firstobs == options.firstsimulationperiod - M.orig_maximum_lag
if options.firstobs == options.firstsimulationperiod - DynareModel.orig_maximum_lag
first_obs = options.firstobs;
else
error('%s_FILE: firstobs = %s and first_simulation_period = %s have values inconsistent with a maximum lag of %d periods', ...
caller, options.firstobs, options.firstsimulationperiod, M.orig_maximum_lag)
caller, options.firstobs, options.firstsimulationperiod, DynareModel.orig_maximum_lag)
end
else
first_obs = options.firstobs;
@ -172,26 +171,25 @@ end
if ~first_obs_ispresent
if isfield(options, 'first_simulation_period')
if options.first_simulation_period < M.orig_maximum_lag
if options.first_simulation_period < DynareModel.orig_maximum_lag
error('%s_FILE: first_simulation_period = %d must be larger than the maximum lag (%d)', ...
caller, options.first_simulation_period, M.orig_maximum_lag)
caller, options.first_simulation_period, DynareModel.orig_maximum_lag)
elseif options.first_simulation_period > nobs0
error('%s_FILE: first_simulations_period = %d is larger than the number of observations in the data file (%d)', ...
caller, options.first_obs, nobs0)
else
first_obs = periods(options.first_simulation_period) - M.orig_maximum_lag;
first_obs = periods(options.first_simulation_period) - DynareModel.orig_maximum_lag;
end
first_obs_ispresent = true;
elseif isfield(options, 'firstsimulationperiod')
first_obs = options.firstsimulationperiod - M.orig_maximum_lag;
first_obs = options.firstsimulationperiod - DynareModel.orig_maximum_lag;
first_obs_ispresent = true;
end
end
if isfield(options, 'last_obs')
if options.last_obs > nobs0
error('%s_FILE: last_obs = %d is larger than the number of observations in the dataset (%d)', ...
caller, options.last_obs, nobs0)
error('%s_FILE: last_obs = %d is larger than the number of observations in the dataset (%d)', caller, options.last_obs, nobs0)
elseif first_obs_ispresent
if nobs > 0 && (periods(options.last_obs) ~= first_obs + nobs - 1)
error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller)
@ -208,8 +206,7 @@ if isfield(options, 'last_obs')
end
elseif isfield(options, 'lastobs')
if options.lastobs > series.last
error('%s_FILE: last_obs = %s is larger than the number of observations in the dataset (%s)', ...
caller, options.lastobs, series.last)
error('%s_FILE: last_obs = %s is larger than the number of observations in the dataset (%s)', caller, options.lastobs, series.last)
elseif first_obs_ispresent
if nobs > 0 && (options.lastobs ~= first_obs + nobs - 1)
error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller)
@ -230,4 +227,31 @@ else
last_obs = series.last;
end
series = series(first_obs:last_obs);
if isfield(options, 'last_simulation_period')
lastsimulationperiod = periods(options.last_simulation_period);
end
if isfield(options, 'lastsimulationperiod')
lastsimulationperiod = options.lastsimulationperiod;
end
if exist('lastsimulationperiod', 'var')
if lastsimulationperiod<=last_obs-DynareModel.orig_maximum_lead
last_obs = lastsimulationperiod+DynareModel.orig_maximum_lead;
else
error('%s_FILE: LAST_SIMULATION_PERIOD is too large compared to the available data.', caller)
end
end
if exist('lastsimulationperiod', 'var') && exist('firstsimulationperiod', 'var')
p = lastsimulationperiod-firstsimulationperiod+1;
elseif exist('lastsimulationperiod', 'var')
p = lastsimulationperiod-(first_obs+DynareModel.orig_maximum_lag)+1;
elseif exist('firstsimulationperiod', 'var')
p = (last_obs-DynareModel.orig_maximum_lead)-firstsimulationperiod+1;
else
p = (last_obs-DynareModel.orig_maximum_lead)-(first_obs+DynareModel.orig_maximum_lag)+1;
end
series = series(first_obs:last_obs);

View File

@ -1,18 +1,17 @@
function series = initvalf(M, options)
% function initvalf(M)
%
% handles options for histvalf() and initvalf()
function [series, p] = initvalf(DynareModel, options)
% Handles options for histvalf() and initvalf()
%
% INPUTS
% caller: string, name of calling function
% M: model structure
% options: options specific to initivalf
% - caller [char] row array, name of calling function
% - DynareModel [struct] model description, a.k.a M_
% - options [struct] options specific to initivalf
%
% OUTPUTS
% series: dseries containing selected data from a file or a dseries
%
% - series [dseries] selected data from a file or a dseries
% - p [integer] number of periods (excluding the initial and terminal conditions)
% Copyright (C) 2003-2020 Dynare Team
% Copyright © 2003-2022 Dynare Team
%
% This file is part of Dynare.
%
@ -29,4 +28,4 @@ function series = initvalf(M, options)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
series = histvalf_initvalf('INITVALF', M, options);
[series, p] = histvalf_initvalf('INITVALF', DynareModel, options);

View File

@ -228,14 +228,23 @@ end
dyn2vec(M_, oo_, options_);
if ~isdates(options_.initial_period) && isnan(options_.initial_period)
if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
initial_period = oo_.initval_series.dates(1)+(M_.orig_maximum_lag-1);
elseif ~isdates(options_.initial_period) && isnan(options_.initial_period)
initial_period = dates(1,1);
else
initial_period = options_.initial_period;
end
ts = dseries([transpose(oo_.endo_simul(1:M_.orig_endo_nbr,:)), oo_.exo_simul], initial_period, [M_.endo_names(1:M_.orig_endo_nbr); M_.exo_names]);
if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
names = ts.name;
ts = merge(oo_.initval_series{names{:}}, ts);
end
assignin('base', 'Simulated_time_series', ts);
if oo_.deterministic_simulation.status
oo_.gui.ran_perfect_foresight = true;
end
end

@ -1 +1 @@
Subproject commit 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3
Subproject commit c56d58822e6c581926ac765b7604b29e1ecdf557

View File

@ -152,6 +152,7 @@ MODFILES = \
discretionary_policy/Gali_2015_chapter_3.mod \
discretionary_policy/Gali_2015_chapter_3_nonlinear.mod \
histval_initval_file/ramst_initval_file.mod \
histval_initval_file/ramst_initval_file_with_dseries.mod \
histval_initval_file/ramst_data_generate.mod \
histval_initval_file/ramst_datafile.mod \
histval_initval_file/sim_exo_lead_lag.mod \

View File

@ -0,0 +1,36 @@
var c k;
varexo x;
parameters alph gam delt bet aa;
alph=0.5;
gam=0.5;
delt=0.02;
bet=0.05;
aa=0.5;
model;
c + k - aa*x*k(-1)^alph - (1-delt)*k(-1);
(c/c(-2))^(-gam) - (1+bet)^(-1)*(aa*alph*x(+2)*k^(alph-1) + 1 - delt)*(c(+1)/c(-1))^(-gam);
end;
kstar = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1));
cstar = aa*kstar^alph-delt*kstar;
initval;
x = 1;
k = kstar;
c = cstar;
end;
steady;
// Instantiate dseries object with paths for the endogenous and exogenous variables
baseline= dseries([.81*kstar, .81*cstar, .81; .9*kstar, .9*cstar, .9; repmat([kstar, cstar, 1], 998, 1)], 2000Q1, {'k', 'c', 'x'});
initval_file(series=baseline, first_simulation_period=2000Q3, last_simulation_period=2050Q2);
perfect_foresight_setup;
perfect_foresight_solver;
Simulated_time_series(2000Q3:2050Q2)

View File

@ -17,6 +17,7 @@ M.exo_nbr = 1;
M.exo_names = {'Variable_4'};
M.exo_det_nbr = 0;
M.orig_maximum_lag = 2;
M.orig_maximum_lead = 0;
caller = 'INITVAL';