From b281d682f26ab04edd8eca79b99dbbc6afeb1f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Mon, 14 Sep 2020 18:42:04 +0200 Subject: [PATCH 01/14] =?UTF-8?q?Manual:=20document=20default=20name=20for?= =?UTF-8?q?=20=E2=80=9Cshock=5Fgroups=E2=80=9D=20blocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By the way, fix the syntax description for the name (it needs *not* be quoted). [skip ci] --- doc/manual/source/the-model-file.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index daa60ee8e..a9c154ab4 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -7551,11 +7551,12 @@ Shock Decomposition See :opt:`xls_range `. - .. option:: use_shock_groups [= STRING] + .. option:: use_shock_groups [= NAME] Uses shock grouping defined by the string instead of individual shocks in the decomposition. The groups of shocks - are defined in the :bck:`shock_groups` block. + are defined in the :bck:`shock_groups` block. If no group name is + given, ``default`` is assumed. .. option:: colormap = VARIABLE_NAME @@ -7624,7 +7625,8 @@ Shock Decomposition groups. It is possible to use several ``shock_groups`` blocks in a model file, each grouping being identified by a different name. This name must in turn be used in the - ``shock_decomposition`` command. + ``shock_decomposition`` command. If no name is given, ``default`` is + used. *Example* @@ -7703,9 +7705,9 @@ Shock Decomposition See :opt:`nobs `. - .. option:: use_shock_groups [= STRING] + .. option:: use_shock_groups [= NAME] - See :opt:`use_shock_groups `. + See :opt:`use_shock_groups `. .. option:: colormap = VARIABLE_NAME @@ -7846,9 +7848,9 @@ Shock Decomposition *Options* - .. option:: use_shock_groups [= STRING] + .. option:: use_shock_groups [= NAME] - See :opt:`use_shock_groups `. + See :opt:`use_shock_groups `. .. option:: colormap = VARIABLE_NAME From f6e7c2d061a9a837429010a215938f16679edd22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 18 Sep 2020 15:05:38 +0200 Subject: [PATCH 02/14] Manual: remove obsolete requirement for 'use_dll' on Windows [skip ci] --- doc/manual/source/the-model-file.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index a9c154ab4..e188c242e 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -925,9 +925,8 @@ The model is declared inside a ``model`` block: libraries (DLL) containing the model equations and derivatives, instead of writing those in M-files. You need a working compilation environment, i.e. a working ``mex`` - command (see :ref:`compil-install` for more details). On - MATLAB for Windows, you will need to also pass the compiler - name at the command line. Using this option can result in + command (see :ref:`compil-install` for more details). + Using this option can result in faster simulations or estimations, at the expense of some initial compilation time. [#f2]_ From 0ea2e40adfa8e99abeefd0b501b792d5bfa8042e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 18 Sep 2020 15:16:01 +0200 Subject: [PATCH 03/14] Manual: remove compilation warning due to nograph entry being in two different .rst files [skip ci] --- doc/manual/source/running-dynare.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/manual/source/running-dynare.rst b/doc/manual/source/running-dynare.rst index 6843352c9..23238168b 100644 --- a/doc/manual/source/running-dynare.rst +++ b/doc/manual/source/running-dynare.rst @@ -290,6 +290,7 @@ by the ``dynare`` command. computations. .. option:: nograph + :noindex: Activate the ``nograph`` option (see :opt:`nograph`), so that Dynare will not produce any graph. From a9fea692e9d1f4bcdd6a7347a9d17a8b36578a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 18 Sep 2020 15:20:00 +0200 Subject: [PATCH 04/14] Preprocessor: allow 'use_dll' option to be specified on the command line --- doc/manual/source/running-dynare.rst | 8 ++++++++ doc/manual/source/the-model-file.rst | 3 ++- preprocessor | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/manual/source/running-dynare.rst b/doc/manual/source/running-dynare.rst index 23238168b..77cc4733b 100644 --- a/doc/manual/source/running-dynare.rst +++ b/doc/manual/source/running-dynare.rst @@ -426,6 +426,14 @@ by the ``dynare`` command. understands by default that the model to be solved is deterministic. + .. option:: use_dll + :noindex: + + Instructs the preprocessor to create dynamic loadable libraries (DLL) + containing the model equations and derivatives, instead of writing + those in M-files. This is equivalent to the :opt:`use_dll` option of + the ``model`` block. + These options can be passed to the preprocessor by listing them after the name of the ``.mod`` file. They can alternatively be defined in the first line of the ``.mod`` file, this avoids typing diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index e188c242e..4ab202d60 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -928,7 +928,8 @@ The model is declared inside a ``model`` block: command (see :ref:`compil-install` for more details). Using this option can result in faster simulations or estimations, at the expense of some - initial compilation time. [#f2]_ + initial compilation time. Alternatively, this option can be + given to the ``dynare`` command (see :ref:`dyn-invoc`). [#f2]_ .. option:: block diff --git a/preprocessor b/preprocessor index de65e74c8..98d01cbbb 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit de65e74c8f9e433c0f94c30e1b0aff27c22dc6cd +Subproject commit 98d01cbbb669b7c5ee37ad6e23b1626ac9cc4dbb From 91b4cfd3a8d6bee55a19a61b552679bd164d71cd Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Wed, 15 Jul 2020 22:03:48 +0200 Subject: [PATCH 05/14] fixes handling of periods in histval_file/initval_file --- matlab/histvalf.m | 23 ------ matlab/histvalf_initvalf.m | 18 +++++ .../sim_exo_lead_lag_initvalf.mod | 77 +++++++++++++++++++ 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/matlab/histvalf.m b/matlab/histvalf.m index f15e72511..07a6a25a7 100644 --- a/matlab/histvalf.m +++ b/matlab/histvalf.m @@ -30,29 +30,6 @@ function [endo_histval, exo_histval, exo_det_histval] = histvalf(M, options) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if ~isfield(options, 'nobs') || isempty(options.nobs) - options.nobs = M.orig_maximum_lag; -end - -if ~isfield(options, 'first_obs') || isempty(options.first_obs) - if isfield(options, 'first_simulation_period') - options.first_obs = options.first_simulation_period ... - - options.nobs; - else - options.first_obs = 1; - end -elseif isfield(options, 'first_simulation_period') - nobs = options.first_simulation_period - opions_.first_obs; - if options.nobs ~= nobs - error(sprintf(['HISTVALF: first_obs = %d and', ... - ' first_simulation_period = %d', ... - ' don''t provide for the number of' ... - ' lags in the model.'], ... - options.first_obs, ... - options.first_simulation_period)) - end -end - series = histvalf_initvalf('HISTVAL', M, options); % capture the difference between stochastic and % perfect foresight setup diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index e65779c49..3a2610e51 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -129,6 +129,24 @@ nobs0 = series.nobs; first_obs_ispresent = false; last_obs_ispresent = false; + +if ~isfield(options, 'first_obs') || isempty(options.first_obs) + if isfield(options, 'first_simulation_period') + options.first_obs = options.first_simulation_period ... + - M.orig_maximum_lag; + end +elseif isfield(options, 'first_simulation_period') + nobs = options.first_simulation_period - opions_.first_obs; + if M.orig_maximum_lag ~= nobs + error(sprintf(['HISTVALF: first_obs = %d and', ... + ' first_simulation_period = %d', ... + ' don''t provide for the number of' ... + ' lags in the model.'], ... + options.first_obs, ... + options.first_simulation_period)) + end +end + if isfield(options, 'first_obs') i = options.first_obs; if i < 1 diff --git a/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod b/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod index e74b6c9b2..200734a96 100644 --- a/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod +++ b/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod @@ -24,6 +24,12 @@ model; end; initval_file(series = ds); +if oo_.initval_series.dates(1) ~= dates('1Y'); + error("Wrong initial date in oo_.initval_series"); +end; +if oo_.initval_series{'x'}.data(6) ~= 0.9; + error("Wrond value for x"); +end; perfect_foresight_setup(periods=200); perfect_foresight_solver(maxit=100); @@ -42,6 +48,13 @@ data1(8, 6) = 0.9; //shock to x in period 2 ds1 = dseries(data1, '1Y', {'c', 'cmav', 'k', 'z_backward', 'z_forward', 'x'}); initval_file(series = ds1, first_obs = 3, last_obs = 210, nobs = 208); +if oo_.initval_series.dates(1) ~= dates('1Y'); + error("Wrong initial date in oo_.initval_series"); +end; +if oo_.initval_series{'x'}.data(6) ~= 0.9; + error("Wrond value for x"); +end; + perfect_foresight_setup(periods=200); perfect_foresight_solver(maxit=100); @@ -54,3 +67,67 @@ base_results=load('sim_exo_lead_lag_results.mat'); if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1e-8 error('Simulation with leads and lags doesn''t match the one with auxiliary variables') end + +initval_file(series = ds1, first_obs = 3Y, last_obs = 210Y, nobs = 208); +if oo_.initval_series.dates(1) ~= dates('3Y'); + error("Wrong initial date in oo_.initval_series"); +end; +if oo_.initval_series{'x'}.data(6) ~= 0.9; + error("Wrond value for x"); +end; + + +perfect_foresight_setup(periods=200); +perfect_foresight_solver(maxit=100); + +if ~oo_.deterministic_simulation.status + error('Perfect foresight simulation failed'); +end + +base_results=load('sim_exo_lead_lag_results.mat'); +if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1e-8 + error('Simulation with leads and lags doesn''t match the one with auxiliary variables') +end + +initval_file(series = ds1, first_simulation_period = 7); +if oo_.initval_series.dates(1) ~= dates('1Y'); + error("Wrong initial date in oo_.initval_series"); +end; +if oo_.initval_series{'x'}.data(6) ~= 0.9; + error("Wrond value for x"); +end; + + +perfect_foresight_setup(periods=200); +perfect_foresight_solver(maxit=100); + +if ~oo_.deterministic_simulation.status + error('Perfect foresight simulation failed'); +end + +base_results=load('sim_exo_lead_lag_results.mat'); +if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1e-8 + error('Simulation with leads and lags doesn''t match the one with auxiliary variables') +end + +initval_file(series = ds1, first_simulation_period = 7Y); +if oo_.initval_series.dates(1) ~= dates('1Y'); + error("Wrong initial date in oo_.initval_series"); +end; +if oo_.initval_series{'x'}.data(6) ~= 0.9; + error("Wrond value for x"); +end; + + +perfect_foresight_setup(periods=200); +perfect_foresight_solver(maxit=100); + +if ~oo_.deterministic_simulation.status + error('Perfect foresight simulation failed'); +end + +base_results=load('sim_exo_lead_lag_results.mat'); +if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1e-8 + error('Simulation with leads and lags doesn''t match the one with auxiliary variables') +end + From b6582c2d5fc171cdbc86f233e93837665b0bd448 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Fri, 28 Aug 2020 15:46:56 +0200 Subject: [PATCH 06/14] fix handling firstsimulationperiod --- matlab/histvalf_initvalf.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index 3a2610e51..251bcaa97 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -134,6 +134,9 @@ if ~isfield(options, 'first_obs') || isempty(options.first_obs) if isfield(options, 'first_simulation_period') options.first_obs = options.first_simulation_period ... - M.orig_maximum_lag; + elseif isfield(options, 'firstsimulationperiod') + options.firstobs = options.firstsimulationperiod ... + - M.orig_maximum_lag; end elseif isfield(options, 'first_simulation_period') nobs = options.first_simulation_period - opions_.first_obs; From 9e94252d1ae4b4f5744aba435e403ebfc4d85f8b Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Fri, 28 Aug 2020 15:49:04 +0200 Subject: [PATCH 07/14] fix target values for periods --- tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod b/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod index 200734a96..044a1ee26 100644 --- a/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod +++ b/tests/histval_initval_file/sim_exo_lead_lag_initvalf.mod @@ -48,7 +48,7 @@ data1(8, 6) = 0.9; //shock to x in period 2 ds1 = dseries(data1, '1Y', {'c', 'cmav', 'k', 'z_backward', 'z_forward', 'x'}); initval_file(series = ds1, first_obs = 3, last_obs = 210, nobs = 208); -if oo_.initval_series.dates(1) ~= dates('1Y'); +if oo_.initval_series.dates(1) ~= dates('3Y'); error("Wrong initial date in oo_.initval_series"); end; if oo_.initval_series{'x'}.data(6) ~= 0.9; @@ -90,7 +90,7 @@ if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1 end initval_file(series = ds1, first_simulation_period = 7); -if oo_.initval_series.dates(1) ~= dates('1Y'); +if oo_.initval_series.dates(1) ~= dates('3Y'); error("Wrong initial date in oo_.initval_series"); end; if oo_.initval_series{'x'}.data(6) ~= 0.9; @@ -111,7 +111,7 @@ if max(max(abs(base_results.oo_.endo_simul(1:5,:) - oo_.endo_simul(1:5,:)))) > 1 end initval_file(series = ds1, first_simulation_period = 7Y); -if oo_.initval_series.dates(1) ~= dates('1Y'); +if oo_.initval_series.dates(1) ~= dates('3Y'); error("Wrong initial date in oo_.initval_series"); end; if oo_.initval_series{'x'}.data(6) ~= 0.9; From 57c94a1c760f713fa8769c6c5c4c04c556444737 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Sat, 19 Sep 2020 19:17:42 +0200 Subject: [PATCH 08/14] revise options checks --- matlab/histvalf_initvalf.m | 213 ++++++++++++++++++++----------------- 1 file changed, 113 insertions(+), 100 deletions(-) diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index 251bcaa97..f6032a7bf 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -130,115 +130,128 @@ nobs0 = series.nobs; first_obs_ispresent = false; last_obs_ispresent = false; -if ~isfield(options, 'first_obs') || isempty(options.first_obs) - if isfield(options, 'first_simulation_period') - options.first_obs = options.first_simulation_period ... - - M.orig_maximum_lag; - elseif isfield(options, 'firstsimulationperiod') - options.firstobs = options.firstsimulationperiod ... - - M.orig_maximum_lag; - end -elseif isfield(options, 'first_simulation_period') - nobs = options.first_simulation_period - opions_.first_obs; - if M.orig_maximum_lag ~= nobs - error(sprintf(['HISTVALF: first_obs = %d and', ... - ' first_simulation_period = %d', ... - ' don''t provide for the number of' ... - ' lags in the model.'], ... - options.first_obs, ... - options.first_simulation_period)) - end -end - -if isfield(options, 'first_obs') - i = options.first_obs; - if i < 1 - error([caller, '_FILE: the first requested period is before available', ... - ' data.']) - elseif i > nobs0 - error([caller, '_FILE: the first requested period is after available', ... - ' data.']) - end - first_obs = periods(i); - if nobs > 0 - last_obs = first_obs + nobs - 1; - last_obs_ispresent = true; - end - first_obs_ispresent = true; -elseif isfield(options, 'firstobs') - first_obs = options.firstobs; - if nobs > 0 - last_obs = first_obs + nobs - 1; - last_obs_ispresent = true; - end - first_obs_ispresent = true; -end - -if last_obs_ispresent - if isfield(options, 'last_obs') - i = options.last_obs; - if i < 1 - error([caller, '_FILE: the last requested period is before available', ... - ' data.']) - elseif i > nobs0 - error([caller, '_FILE: the last requested period is after available', ... - ' data.']) +first_obs = periods(1); +if isfield(options, 'first_obs') && ~isempty(options.first_obs) + if options.first_obs < 1 + error('first_obs must be a positive number') + elseif options.first_obs > nobs0 + error(sprintf([caller, '_FILE: first_obs = %d is larger than the number', ... + ' of observations in the data file (%d)'], ... + options.first_obs, nobs0)) + elseif isfield(options, 'first_simulation_period') + if options.first_obs == options.first_simulation_period ... + - M.orig_maximum_lag + first_obs = periods(options.first_obs); + else + error(sprintf([caller, '_FILE: first_obs = %d and', ... + ' first_simulation_period = %d have values', ... + ' inconsistent with a maximum lag of %d periods'], ... + options.first_obs, options_.first_simulation_period, ... + M.orig_maximum_lag)) end - if last_obs ~= periods(i) - error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... - ' inconsistent information. Use only two of these', ... - ' options.']) - end - elseif isfield(options, 'lastobs') - if last_obs ~= options.lastobs - error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... - ' inconsistent information. Use only two of these', ... - ' options.']) - end + elseif isfield(options, 'firstsimulationperiod') + if periods(options.first_obs) == options.firstsimulationperiod ... + - M.orig_maximum_lag + first_obs = periods(options.first_obs); + else + error(sprintf([caller, '_FILE: first_obs = %d and', ... + ' first_simulation_period = %s have values', ... + ' inconsistent with a maximum lag of %d periods'], ... + options.first_obs, options_.firstsimulationperiod, ... + M.orig_maximum_lag)) + end + else + first_obs = periods(options_.first_obs); end -elseif isfield(options, 'last_obs') - i = options.last_obs; - if i < 1 - error([caller, '_FILE: the last requested period is before available', ... - ' data.']) - elseif i > nobs0 - error([caller, '_FILE: the last requested period is after available', ... - ' data.']) + first_obs_ispresent = true; +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 + first_obs = options.firstobs; + else + error(sprintf([caller, '_File: first_obs = %s and', ... + ' first_simulation_period = %d have values', ... + ' inconsistent with a maximum lag of %d periods'], ... + options.firstobs, options_.first_simulation_period, ... + M.orig_maximum_lag)) + end + elseif isfield(options, 'firstsimulationperiod') + if options.firstobs == options.firstsimulationperiod ... + - M.orig_maximum_lag + first_obs = options.firstobs; + else + error(sprintf([caller, '_FILE: firstobs = %s and', ... + ' first_simulation_period = %s have values', ... + ' inconsistent with a maximum lag of %d periods'], ... + options.firstobs, options.firstsimulationperiod, ... + M.orig_maximum_lag)) + end + else + first_obs = options.firstobs; end - last_obs = periods(i); - if nobs > 0 - first_obs = last_obs - nobs + 1; - first_obs_ispresent = true; - end - last_obs_ispresent = true; -elseif isfield(options, 'lastobs') - last_obs = options.lastobs; - if nobs > 0 - first_obs = last_obs - nobs + 1; - first_obs_ispresent = true; - end - last_obs_ispresent = true; + first_obs_ispresent = true; end if ~first_obs_ispresent - first_obs = periods(1); -end - -if ~last_obs_ispresent - if nobs > 0 - last_obs = first_obs + nobs - 1; - else - last_obs = periods(end); + if isfield(options, 'first_simulation_period') + if options.first_simulation_period < options.maximum_lag + error(sprintf([caller, '_FILE: first_simulation_period = %d', ... + 'must be larger than the maximum lag (%d)'], ... + options.first_simulation_period, M.orig_maximum_lag)) + elseif options.first_simulation_period > nobs0 + error(sprintf([caller, '_FILE: first_simulations_period = %d', ... + ' is larger than the number of observations in', ... + ' the data file (%d)'], ... + options.first_obs, nobs0)) + else + first_obs = periods(options.first_simulation_period) - ... + M.orig_maximum_lag; + end + first_obs_ispresent = true; + elseif isfield(options, 'firstsimulationperiod') + first_obs = options.firstsimulationperiod - ... + M.orig_maximum_lag; + first_obs_ispresent = true; end end -if first_obs < series.init - error([caller, '_FILE: the first requested period is before available', ... - ' data.']) -elseif last_obs > series.last - error([caller, '_FILE: the last requested period is after available', ... - ' data.']) +if isfield(options, 'last_obs') + if options.last_obs > nobs0 + error(sprintf([caller, '_FILE: last_obs is larger than the number', ... + 'observations in the dataset (%d)'], ... + options.last_obs, nobs0)) + elseif first_obs_ispresent + if nobs > 0 && (periods(options.last_obs) ~= first_obs + nobs - 1) + error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... + ' inconsistent information. Use only two of these', ... + ' options.']) + else + last_obs = periods(options.last_obs) + end + end +elseif isfield(options, 'lastobs') + if options.lastobs > series.last + error(sprintf([caller, '_FILE: last_obs = %s is larger than the number', ... + 'observations in the dataset (%s)'], ... + options.lastobs, series.last)) + elseif first_obs_ispresent + if nobs > 0 && (options.lastobs ~= first_obs + nobs - 1) + error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... + ' inconsistent information. Use only two of these', ... + ' options.']) + else + last_obs = options.last_obs + end + end +elseif nobs > 0 + last_obs = first_obs + nobs - 1 else - series = series(first_obs:last_obs); + last_obs = series.last end +series = series(first_obs:last_obs); + + From c2e43c00938af8f0c9e57b1a7d3a7f76ea3d25d4 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Sun, 20 Sep 2020 11:11:26 +0200 Subject: [PATCH 09/14] fix histval_initval_file unit tests --- matlab/histvalf_initvalf.m | 40 +++++++++++++++++-------- tests/histval_initval_file/my_assert.m | 2 +- tests/histval_initval_file_unit_tests.m | 16 +++++----- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index f6032a7bf..5723d9979 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -133,7 +133,7 @@ last_obs_ispresent = false; first_obs = periods(1); if isfield(options, 'first_obs') && ~isempty(options.first_obs) if options.first_obs < 1 - error('first_obs must be a positive number') + error([caller, '_FILE: first_obs must be a positive number']) elseif options.first_obs > nobs0 error(sprintf([caller, '_FILE: first_obs = %d is larger than the number', ... ' of observations in the data file (%d)'], ... @@ -146,7 +146,7 @@ if isfield(options, 'first_obs') && ~isempty(options.first_obs) error(sprintf([caller, '_FILE: first_obs = %d and', ... ' first_simulation_period = %d have values', ... ' inconsistent with a maximum lag of %d periods'], ... - options.first_obs, options_.first_simulation_period, ... + options.first_obs, options.first_simulation_period, ... M.orig_maximum_lag)) end elseif isfield(options, 'firstsimulationperiod') @@ -157,11 +157,11 @@ if isfield(options, 'first_obs') && ~isempty(options.first_obs) error(sprintf([caller, '_FILE: first_obs = %d and', ... ' first_simulation_period = %s have values', ... ' inconsistent with a maximum lag of %d periods'], ... - options.first_obs, options_.firstsimulationperiod, ... + options.first_obs, options.firstsimulationperiod, ... M.orig_maximum_lag)) end else - first_obs = periods(options_.first_obs); + first_obs = periods(options.first_obs); end first_obs_ispresent = true; end @@ -172,10 +172,10 @@ if isfield(options, 'firstobs') && ~isempty(options.firstobs) - M.orig_maximum_lag first_obs = options.firstobs; else - error(sprintf([caller, '_File: first_obs = %s and', ... + error(sprintf([caller, '_FILE: first_obs = %s and', ... ' first_simulation_period = %d have values', ... ' inconsistent with a maximum lag of %d periods'], ... - options.firstobs, options_.first_simulation_period, ... + options.firstobs, options.first_simulation_period, ... M.orig_maximum_lag)) end elseif isfield(options, 'firstsimulationperiod') @@ -220,8 +220,8 @@ end if isfield(options, 'last_obs') if options.last_obs > nobs0 - error(sprintf([caller, '_FILE: last_obs is larger than the number', ... - 'observations in the dataset (%d)'], ... + error(sprintf([caller, '_FILE: last_obs = %d is larger than the number', ... + ' of observations in the dataset (%d)'], ... options.last_obs, nobs0)) elseif first_obs_ispresent if nobs > 0 && (periods(options.last_obs) ~= first_obs + nobs - 1) @@ -229,13 +229,20 @@ if isfield(options, 'last_obs') ' inconsistent information. Use only two of these', ... ' options.']) else - last_obs = periods(options.last_obs) + last_obs = periods(options.last_obs); + end + else + last_obs = periods(options.last_obs); + if nobs > 0 + first_obs = last_obs - nobs + 1; + else + first_obs = periods(1); end end elseif isfield(options, 'lastobs') if options.lastobs > series.last error(sprintf([caller, '_FILE: last_obs = %s is larger than the number', ... - 'observations in the dataset (%s)'], ... + ' of observations in the dataset (%s)'], ... options.lastobs, series.last)) elseif first_obs_ispresent if nobs > 0 && (options.lastobs ~= first_obs + nobs - 1) @@ -243,13 +250,20 @@ elseif isfield(options, 'lastobs') ' inconsistent information. Use only two of these', ... ' options.']) else - last_obs = options.last_obs + last_obs = options.last_obs; + end + else + last_obs = options.last_obs; + if nobs > 0 + first_obs = last_obs - nobs + 1; + else + first_obs = periods(1); end end elseif nobs > 0 - last_obs = first_obs + nobs - 1 + last_obs = first_obs + nobs - 1; else - last_obs = series.last + last_obs = series.last; end series = series(first_obs:last_obs); diff --git a/tests/histval_initval_file/my_assert.m b/tests/histval_initval_file/my_assert.m index 2ac132e12..6f30d2dbe 100644 --- a/tests/histval_initval_file/my_assert.m +++ b/tests/histval_initval_file/my_assert.m @@ -1,4 +1,4 @@ function failed_tests = my_assert(failed_tests, success, test_name) if ~success - failed_tests = cat(1, test_failed, test_name); + failed_tests = cat(1, failed_tests, test_name); end \ No newline at end of file diff --git a/tests/histval_initval_file_unit_tests.m b/tests/histval_initval_file_unit_tests.m index 4b81f71de..925ce1a57 100644 --- a/tests/histval_initval_file_unit_tests.m +++ b/tests/histval_initval_file_unit_tests.m @@ -16,6 +16,7 @@ M.endo_names = {'Variable_1','Variable_2','Variable_3'}; M.exo_nbr = 1; M.exo_names = {'Variable_4'}; M.exo_det_nbr = 0; +M.orig_maximum_lag = 2; caller = 'INITVAL'; @@ -88,9 +89,9 @@ try ds1 = histvalf_initvalf(caller, M, options); error('This test didn''t catch the error') catch me - if strcmp(me.message, ['INITVAL_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... - ' inconsistent information. Use only two of these', ... - ' options.']) == false + if ~strcmp(me.message, strcat('INITVAL_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... + ' inconsistent information. Use only two of these', ... + ' options.')) failed_tests = cat(1, failed_tests, 'Wrong nobs error message' ); end end @@ -98,14 +99,13 @@ num_tests = num_tests + 1; options = struct(); options.series = ds; -options.first_obs = -1; +options.first_obs = 0; try ds1 = histvalf_initvalf(caller, M, options); error('This test didn''t catch the error') catch me - if strcmp(me.message, [caller, '_FILE: the first requested period is', ... - ' before available data.']) == false + if ~strcmp(me.message, strcat(caller, '_FILE: first_obs must be a positive number')) failed_tests = cat(1, failed_tests, ... 'Wrong first period error message'); end @@ -120,8 +120,8 @@ try ds1 = histvalf_initvalf(caller, M, options); error('This test didn''t catch the error') catch me - if strcmp(me.message, [caller, '_FILE: the last requested period is', ... - ' after available data.']) == false + if ~strcmp(me.message, strcat(caller, '_FILE: last_obs = 11 is larger than the number', ... + ' of observations in the dataset (10)')) failed_tests = cat(1, failed_tests, ... 'Wrong last period error message'); end From c366a8c3da1197320185aee68beee340caced1ea Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Sun, 20 Sep 2020 16:52:31 +0200 Subject: [PATCH 10/14] fix bugs --- matlab/histvalf_initvalf.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index 5723d9979..7afb359d4 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -197,7 +197,7 @@ end if ~first_obs_ispresent if isfield(options, 'first_simulation_period') - if options.first_simulation_period < options.maximum_lag + if options.first_simulation_period < M.orig_maximum_lag error(sprintf([caller, '_FILE: first_simulation_period = %d', ... 'must be larger than the maximum lag (%d)'], ... options.first_simulation_period, M.orig_maximum_lag)) @@ -250,7 +250,7 @@ elseif isfield(options, 'lastobs') ' inconsistent information. Use only two of these', ... ' options.']) else - last_obs = options.last_obs; + last_obs = options.lastobs; end else last_obs = options.last_obs; From 8803bc14790a03e92118bf997d16ea76f7b2190c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Tue, 22 Sep 2020 16:42:33 +0200 Subject: [PATCH 11/14] Bytecode: minor improvement to debugging information --- mex/sources/bytecode/Interpreter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc index a3aa0bbe3..65d275d68 100644 --- a/mex/sources/bytecode/Interpreter.cc +++ b/mex/sources/bytecode/Interpreter.cc @@ -700,8 +700,8 @@ Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int blo else { #ifdef DEBUG - mexPrintf("endo in Block_Count=%d, block=%d, type=%d, steady_state=%d, print_it=%d, Block_Count=%d, fb->get_is_linear()=%d, fb->get_endo_nbr()=%d, fb->get_Max_Lag()=%d, fb->get_Max_Lead()=%d, fb->get_u_count_int()=%d\n", - Block_Count, fb->get_size(), fb->get_type(), steady_state, print_it, Block_Count, fb->get_is_linear(), fb->get_endo_nbr(), fb->get_Max_Lag(), fb->get_Max_Lead(), fb->get_u_count_int()); + mexPrintf("endo in Block_Count=%d, size=%d, type=%d, steady_state=%d, print_it=%d, fb->get_is_linear()=%d, fb->get_endo_nbr()=%d, fb->get_Max_Lag()=%d, fb->get_Max_Lead()=%d, fb->get_u_count_int()=%d\n", + Block_Count+1, fb->get_size(), fb->get_type(), steady_state, print_it, fb->get_is_linear(), fb->get_endo_nbr(), fb->get_Max_Lag(), fb->get_Max_Lead(), fb->get_u_count_int()); #endif bool result; if (sconstrained_extended_path.size()) From 73253a0620527ad7f6d20000fa70ee8fd0f573f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Tue, 22 Sep 2020 16:42:53 +0200 Subject: [PATCH 12/14] Bytecode + Block decomposition: fix crash with purely forward variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After simulating a block containing purely forward variables (thus of type “evaluate backward”), the it_ variable of the evaluator would be left in an inconsistent state (typically 0, which means that taking the value of a lagged variable would lead to an invalid read). By the way, fix a symmetric problem for backward blocks (which could potentially create a invalid read for purely backward models). Ref. #1727 --- mex/sources/bytecode/Evaluate.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/mex/sources/bytecode/Evaluate.cc b/mex/sources/bytecode/Evaluate.cc index 576edff9e..841d9365b 100644 --- a/mex/sources/bytecode/Evaluate.cc +++ b/mex/sources/bytecode/Evaluate.cc @@ -1513,6 +1513,7 @@ Evaluate::evaluate_over_periods(const bool forward) it_code = begining; compute_block_time(0, false, false); } + it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state } else { @@ -1521,6 +1522,7 @@ Evaluate::evaluate_over_periods(const bool forward) it_code = begining; compute_block_time(0, false, false); } + it_ = y_kmin; // Do not leave it_ in inconsistent state (see #1727) } } } @@ -1596,11 +1598,17 @@ Evaluate::solve_simple_over_periods(const bool forward) else { if (forward) - for (it_ = y_kmin; it_ < periods+y_kmin; it_++) - solve_simple_one_periods(); + { + for (it_ = y_kmin; it_ < periods+y_kmin; it_++) + solve_simple_one_periods(); + it_= periods+y_kmin-1; // Do not leave it_ in inconsistent state + } else - for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--) - solve_simple_one_periods(); + { + for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--) + solve_simple_one_periods(); + it_ = y_kmin; // Do not leave it_ in inconsistent state (see #1727) + } } mxFree(g1); mxFree(r); @@ -1665,6 +1673,7 @@ Evaluate::compute_complete_2b(const bool no_derivatives, double *_res1, double * else return; } + it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state return; } @@ -1757,6 +1766,7 @@ Evaluate::compute_complete(double lambda, double *crit) else return false; } + it_ = periods+y_kmin-1; // Do not leave it_ in inconsistent state } mexPrintf(" lambda=%e, res2=%e\n", lambda, res2_); *crit = res2_/2; From d61f4166ad45b438188ad80e2672728bbea92bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Tue, 22 Sep 2020 16:46:11 +0200 Subject: [PATCH 13/14] Testsuite: add a test for a purely forward variable in block+bytecode mode Closes: #1727 --- tests/block_bytecode/ls2003.mod | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/block_bytecode/ls2003.mod b/tests/block_bytecode/ls2003.mod index 87fca4a9f..62ffb6bb6 100644 --- a/tests/block_bytecode/ls2003.mod +++ b/tests/block_bytecode/ls2003.mod @@ -1,5 +1,5 @@ -var y y_s R pie dq pie_s de A y_obs pie_obs R_obs vv ww; -varexo e_R e_q e_ys e_pies e_A; +var y y_s R pie dq pie_s de A y_obs pie_obs R_obs vv ww pure_forward; +varexo e_R e_q e_ys e_pies e_A e_pure_forward; parameters psi1 psi2 psi3 rho_R tau alpha rr k rho_q rho_A rho_ys rho_pies; @@ -53,6 +53,10 @@ det = 0.25-0.02 = 0.23 = 1/0.23* = 1/0.23* = [ww] [0.1 0.5] [2] [1.1] [4.7826] */ + +/* Test a purely forward variable (thus within a block of type “evaluate + backward”). See #1727. */ +pure_forward = 0.9*pure_forward(+1) + e_pure_forward; end; shocks; @@ -76,6 +80,9 @@ shocks; var e_q; periods 1; values 0.5; +var e_pure_forward; +periods 19; +values 1; end; simul(periods=20, markowitz=0, stack_solve_algo = @{stack_solve_algo}); From 202bf913c0bf4134a2a9ac630b1a44a62266ecba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Wed, 23 Sep 2020 13:56:08 +0200 Subject: [PATCH 14/14] Cosmetic changes. --- matlab/histvalf_initvalf.m | 114 +++++++++++++------------------------ 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m index 7afb359d4..2ed72aee7 100644 --- a/matlab/histvalf_initvalf.m +++ b/matlab/histvalf_initvalf.m @@ -41,23 +41,19 @@ end % file datafile = ''; if isfield(options, 'filename') - warning([caller, '_FILE: option FILENAME is deprecated, please use', ... - ' option DATAFILE']) + warning('%s_FILE: option FILENAME is deprecated, please use option DATAFILE', caller) if dseries_ispresent - error([caller, '_FILE: you can''t use option FILENAME and option SERIES', ... - ' at the same time']) + error('%s_FILE: you can''t use option FILENAME and option SERIES at the same time', caller) end if isfield(options, 'datafile') - error([caller, '_FILE: you can''t use option DATAFILE and option FILENAME', ... - ' at the same time']) + error('%s_FILE: you can''t use option DATAFILE and option FILENAME at the same time', caller) end datafile = options.filename; end if isfield(options, 'datafile') if dseries_ispresent - error([caller, '_FILE: you can''t use option DATAFILE and option SERIES', ... - ' at the same time']) + error('%s_FILE: you can''t use option DATAFILE and option SERIES at the same time', caller) end datafile = options.datafile; end @@ -75,10 +71,9 @@ if datafile elseif exist([basename '.xlsx'],'file') extension = '.xlsx'; else - error([caller, '_FILE: Can''t find datafile: ' basename '.{m,mat,xls,xlsx}']); + error('%s_FILE: Can''t find datafile: %s.{m,mat,xls,xlsx}', caller, basename); end end - fullname = [basename extension]; series = dseries(fullname); end @@ -87,33 +82,30 @@ end error_flag = false; for i = 1:M.orig_endo_nbr if ~series.exist(M.endo_names{i}) - disp(sprintf('%s_FILE: endogenous variable %s is missing', ... - caller, M.endo_names{i})) + dprintf('%s_FILE: endogenous variable %s is missing', caller, M.endo_names{i}) error_flag = true; end end for i = 1:M.exo_nbr if ~series.exist(M.exo_names{i}) - disp(sprintf('%s_FILE: exogenous variable %s is missing', ... - caller, M.exo_names{i})) + dprintf('%s_FILE: exogenous variable %s is missing', caller, M.exo_names{i}) error_flag = true; end end for i = 1:M.exo_det_nbr if ~series.exist(M.exo_det_names{i}) - disp(sprintf('%s_FILE: exo_det variable %s is missing', ... - caller, M.exo_det_names{i})) + dprintf('%s_FILE: exo_det variable %s is missing', caller, M.exo_det_names{i}) error_flag = true; end end if error_flag - error([caller, '_FILE: some variables are missing']) + error('%s_FILE: some variables are missing', caller) end -if exist(sprintf('+%s/dynamic_set_auxiliary_series', M.fname), 'file') +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); end @@ -133,32 +125,23 @@ last_obs_ispresent = false; first_obs = periods(1); if isfield(options, 'first_obs') && ~isempty(options.first_obs) if options.first_obs < 1 - error([caller, '_FILE: first_obs must be a positive number']) + error('%s_FILE: first_obs must be a positive number', caller) elseif options.first_obs > nobs0 - error(sprintf([caller, '_FILE: first_obs = %d is larger than the number', ... - ' of observations in the data file (%d)'], ... - options.first_obs, nobs0)) + 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 - M.orig_maximum_lag first_obs = periods(options.first_obs); else - error(sprintf([caller, '_FILE: first_obs = %d and', ... - ' first_simulation_period = %d have values', ... - ' inconsistent with a maximum lag of %d periods'], ... - options.first_obs, options.first_simulation_period, ... - M.orig_maximum_lag)) + 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) end elseif isfield(options, 'firstsimulationperiod') - if periods(options.first_obs) == options.firstsimulationperiod ... - - M.orig_maximum_lag + if periods(options.first_obs) == options.firstsimulationperiod - M.orig_maximum_lag first_obs = periods(options.first_obs); else - error(sprintf([caller, '_FILE: first_obs = %d and', ... - ' first_simulation_period = %s have values', ... - ' inconsistent with a maximum lag of %d periods'], ... - options.first_obs, options.firstsimulationperiod, ... - M.orig_maximum_lag)) + 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) end else first_obs = periods(options.first_obs); @@ -168,26 +151,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) - M.orig_maximum_lag first_obs = options.firstobs; else - error(sprintf([caller, '_FILE: first_obs = %s and', ... - ' first_simulation_period = %d have values', ... - ' inconsistent with a maximum lag of %d periods'], ... - options.firstobs, options.first_simulation_period, ... - M.orig_maximum_lag)) + 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) end elseif isfield(options, 'firstsimulationperiod') - if options.firstobs == options.firstsimulationperiod ... - - M.orig_maximum_lag + if options.firstobs == options.firstsimulationperiod - M.orig_maximum_lag first_obs = options.firstobs; else - error(sprintf([caller, '_FILE: firstobs = %s and', ... - ' first_simulation_period = %s have values', ... - ' inconsistent with a maximum lag of %d periods'], ... - options.firstobs, options.firstsimulationperiod, ... - M.orig_maximum_lag)) + 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) end else first_obs = options.firstobs; @@ -198,36 +173,28 @@ end if ~first_obs_ispresent if isfield(options, 'first_simulation_period') if options.first_simulation_period < M.orig_maximum_lag - error(sprintf([caller, '_FILE: first_simulation_period = %d', ... - 'must be larger than the maximum lag (%d)'], ... - options.first_simulation_period, M.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) elseif options.first_simulation_period > nobs0 - error(sprintf([caller, '_FILE: first_simulations_period = %d', ... - ' is larger than the number of observations in', ... - ' the data file (%d)'], ... - options.first_obs, 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) - M.orig_maximum_lag; end first_obs_ispresent = true; elseif isfield(options, 'firstsimulationperiod') - first_obs = options.firstsimulationperiod - ... - M.orig_maximum_lag; + first_obs = options.firstsimulationperiod - M.orig_maximum_lag; first_obs_ispresent = true; end end if isfield(options, 'last_obs') if options.last_obs > nobs0 - error(sprintf([caller, '_FILE: last_obs = %d is larger than the number', ... - ' of observations in the dataset (%d)'], ... - 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([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... - ' inconsistent information. Use only two of these', ... - ' options.']) + error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller) else last_obs = periods(options.last_obs); end @@ -241,14 +208,11 @@ if isfield(options, 'last_obs') end elseif isfield(options, 'lastobs') if options.lastobs > series.last - error(sprintf([caller, '_FILE: last_obs = %s is larger than the number', ... - ' of observations in the dataset (%s)'], ... - 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([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ... - ' inconsistent information. Use only two of these', ... - ' options.']) + error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller) else last_obs = options.lastobs; end @@ -266,6 +230,4 @@ else last_obs = series.last; end -series = series(first_obs:last_obs); - - +series = series(first_obs:last_obs); \ No newline at end of file