diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index 38d43c3281e6a681b65031b6dbbf4509b0a29bac..062114c2f44965f5db67f0b5976e879ef8240f2b 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -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 diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index ac0b251688248282d8585ab1f25416deba961667..4ce0da3cb08f300b9b2a49962fd8eced8a4d2ad5 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -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); \ No newline at end of file diff --git a/matlab/initvalf.m b/matlab/initvalf.m index 707d349e17b901838e2580ec866956270850e6e7..c40009738f079d6979019ec64939ad0194852d44 100644 --- a/matlab/initvalf.m +++ b/matlab/initvalf.m @@ -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); \ No newline at end of file +[series, p] = histvalf_initvalf('INITVALF', DynareModel, options); \ No newline at end of file diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m index d303d59db43642f0c0b8b50a814577849ea8ce2b..3f1049925f6b385a7fb23138d988752b4a77a82b 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_solver.m +++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m @@ -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 \ No newline at end of file diff --git a/preprocessor b/preprocessor index 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3..c56d58822e6c581926ac765b7604b29e1ecdf557 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3 +Subproject commit c56d58822e6c581926ac765b7604b29e1ecdf557 diff --git a/tests/Makefile.am b/tests/Makefile.am index 750ca5af64277732b47298f763add0231bc52874..c4e4371db307993d85dc1af1e64fdbe66b866f6a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ diff --git a/tests/histval_initval_file/ramst_initval_file_with_dseries.mod b/tests/histval_initval_file/ramst_initval_file_with_dseries.mod new file mode 100644 index 0000000000000000000000000000000000000000..e777d091ace753424166ea0097434d4ef9d4a8d9 --- /dev/null +++ b/tests/histval_initval_file/ramst_initval_file_with_dseries.mod @@ -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) diff --git a/tests/histval_initval_file_unit_tests.m b/tests/histval_initval_file_unit_tests.m index 34f558b6b39e8cf99b7c142665cde412020ecf2c..e2f6e514eadc5bc1876f386d2fca588b591ccc79 100644 --- a/tests/histval_initval_file_unit_tests.m +++ b/tests/histval_initval_file_unit_tests.m @@ -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';