From 5145bd0708697230c7adeb23c8a0dabf37f4cb3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Wed, 18 Oct 2023 16:45:06 -0400 Subject: [PATCH] =?UTF-8?q?New=20option=20=E2=80=9Crelative=5Fto=5Finitval?= =?UTF-8?q?=E2=80=9D=20to=20=E2=80=9Cmshocks=E2=80=9D=20block?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/manual/source/the-model-file.rst | 48 ++++++++++++----- matlab/+gui/+perfect_foresight/run.m | 6 +-- matlab/evaluate_planner_objective.m | 6 +-- matlab/perfect-foresight-models/make_ex_.m | 25 ++++++--- ..._foresight_with_expectation_errors_setup.m | 14 +++-- meson.build | 1 + preprocessor | 2 +- .../ramst_mshocks_relative_to_initval.mod | 51 +++++++++++++++++++ 8 files changed, 122 insertions(+), 31 deletions(-) create mode 100644 tests/deterministic_simulations/ramst_mshocks_relative_to_initval.mod diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index 4d5f88a43..175244e33 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -2738,14 +2738,19 @@ blocks. forecast; .. block:: mshocks ; - mshocks(overwrite); + mshocks (OPTIONS...); |br| The purpose of this block is similar to that of the ``shocks`` block for deterministic shocks, except that the numeric values given will be interpreted in a multiplicative way. For example, if a value of ``1.05`` is given as shock value for some - exogenous at some date, it means 5% above its steady state value - (as given by the last ``initval`` or ``endval`` block). + exogenous at some date, it means 5% above its steady state value. + + If no ``endval`` block is present, the steady state as specified in the + ``initval`` block is used as the basis for the multiplication. If an + ``endval`` block is present, the terminal steady state as specified in the + ``endval`` block will be used as the basis for the multiplication (unless + the ``relative_to_initval`` option is passed). The syntax is the same as ``shocks`` in a deterministic context. @@ -2756,7 +2761,17 @@ blocks. * on deterministic exogenous variables with a non-zero steady state, in a stochastic setup. - See above for the meaning of the ``overwrite`` option. + *Options* + + .. option:: overwrite + + Same meaning as in the :bck:`shocks` block. + + .. option:: relative_to_initval + + If an ``endval`` block is present, the initial steady state as specified + in the ``initval`` block will be used as the basis for multiplication + (instead of the terminal steady state). .. block:: heteroskedastic_shocks ; heteroskedastic_shocks(overwrite); @@ -4125,7 +4140,7 @@ and ``endval`` blocks which are given a special ``learnt_in`` option. ``endval(learnt_in=p)`` block with ``p>3``. .. block:: mshocks(learnt_in=INTEGER) ; - mshocks(learnt_in=INTEGER,overwrite) ; + mshocks(learnt_in=INTEGER,OPTIONS...) ; |br| The ``mshocks(learnt_in=INTEGER)`` syntax can be used to specify temporary shocks that are learnt in a specific period, specified in a multiplicative @@ -4138,18 +4153,27 @@ and ``endval`` blocks which are given a special ``learnt_in`` option. As in the regular :bck:`mshocks` block (without the ``learnt_in`` option), the values are interpreted as a multiplicative factor over the steady state - value of the exogenous variable, either the initial steady state as given - by ``initval`` if there is no ``endval`` block, or the terminal steady - state if there is an ``endval`` block. Note that in the latter case, it is - the terminal steady state as anticipated from the period given in the - ``learnt_in`` option that is used for the computation. + value of the exogenous variable (the latter being taken either from the + ``initval`` or ``endval``, see :bck:`mshocks` for the details). - The ``overwrite`` option says that this block cancels and replaces previous - ``shocks`` and ``mshocks`` blocks that have the same ``learnt_in`` option. + If the terminal steady state as specified in the ``endval`` block is used + as a basis for the multiplication, its value as anticipated from the period + given in the ``learnt_in`` option will be used. Note that a ``mshocks(learnt_in=1)`` block is equivalent to a regular :bck:`mshocks` block. + *Options* + + .. option:: overwrite + + This block cancels and replaces previous ``shocks`` and ``mshocks`` + blocks that have the same ``learnt_in`` option. + + .. option:: relative_to_initval + + Same meaning as in the regular :bck:`mshocks` block. + *Example* :: diff --git a/matlab/+gui/+perfect_foresight/run.m b/matlab/+gui/+perfect_foresight/run.m index 58333c937..03ff8f947 100644 --- a/matlab/+gui/+perfect_foresight/run.m +++ b/matlab/+gui/+perfect_foresight/run.m @@ -13,7 +13,7 @@ function run(json) % SPECIAL REQUIREMENTS % none -% Copyright © 2019-2022 Dynare Team +% Copyright © 2019-2023 Dynare Team % % This file is part of Dynare. % @@ -84,7 +84,7 @@ if ~isempty(jm.anticipated_permanent_shocks) || ~isempty(jm.endval_endo) struct(... 'exo_det', false, ... 'exo_id', s.exo_id, ... - 'multiplicative', false, ... + 'type', 'level', ... 'periods', 1:s.start_date, ... 'value', 0)]; end @@ -99,7 +99,7 @@ if ~isempty(jm.anticipated_transitory_shocks) M_.det_shocks; ... struct('exo_det', false, ... 'exo_id', s.exo_id, ... - 'multiplicative', false, ... + 'type', 'level', ... 'periods', s.start_date:s.end_date, ... 'value', s.value)]; end diff --git a/matlab/evaluate_planner_objective.m b/matlab/evaluate_planner_objective.m index 3af5f20af..b5bb82c13 100644 --- a/matlab/evaluate_planner_objective.m +++ b/matlab/evaluate_planner_objective.m @@ -396,10 +396,10 @@ if ~isempty(M_.det_shocks) 'evaluate_planner_objective: Note that they will be ignored.\n']) end shock_indices=find(periods==1); - if any([M_.det_shocks(shock_indices).multiplicative]) - fprintf(['\nevaluate_planner_objective: Shock values need to be specified as additive.\n']) + if any(cellfun(@(x) ~strcmp(x, 'level'), { M_.det_shocks(shock_indices).type })) + fprintf(['\nevaluate_planner_objective: Shock values need to be specified in level.\n']) end u([M_.det_shocks(shock_indices).exo_id])=[M_.det_shocks(shock_indices).value]; else u = oo_.exo_simul(1,:)'; %first value of simulation series (set by simult.m if periods>0), 1 otherwise -end \ No newline at end of file +end diff --git a/matlab/perfect-foresight-models/make_ex_.m b/matlab/perfect-foresight-models/make_ex_.m index 37ade675f..8533805d6 100644 --- a/matlab/perfect-foresight-models/make_ex_.m +++ b/matlab/perfect-foresight-models/make_ex_.m @@ -86,16 +86,25 @@ if isfield(M_, 'det_shocks') ivar = M_.det_shocks(i).exo_id; v = M_.det_shocks(i).value; if ~M_.det_shocks(i).exo_det - if ~M_.det_shocks(i).multiplicative - oo_.exo_simul(k,ivar) = v; - else - oo_.exo_simul(k,ivar) = oo_.exo_steady_state(ivar) * v; + switch M_.det_shocks(i).type + case 'level' + oo_.exo_simul(k,ivar) = v; + case 'multiply_steady_state' + oo_.exo_simul(k,ivar) = oo_.exo_steady_state(ivar) * v; + case 'multiply_initial_steady_state' + if isempty(ex0_) + error('Option relative_to_initval of mshocks block cannot be used without an endval block') + end + oo_.exo_simul(k,ivar) = ex0_(ivar) * v; end else - if ~M_.det_shocks(i).multiplicative - oo_.exo_det_simul(k,ivar) = v; - else - oo_.exo_det_simul(k,ivar) = oo_.exo_det_steady_state(ivar) * v; + switch M_.det_shocks(i).type + case 'level' + oo_.exo_det_simul(k,ivar) = v; + case 'multiply_steady_state' + oo_.exo_det_simul(k,ivar) = oo_.exo_det_steady_state(ivar) * v; + case 'multiply_initial_steady_state' + error('Option relative_to_initval of mshocks block cannot be used with a deterministic exogenous variable') end end end 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 33c418d44..f7b07adc3 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 @@ -75,10 +75,16 @@ else exo_id = M_.det_shocks(i).exo_id; v = M_.det_shocks(i).value; if ~M_.det_shocks(i).exo_det - if ~M_.det_shocks(i).multiplicative - oo_.pfwee.shocks_info(exo_id, prds, 1) = v; - else - oo_.pfwee.shocks_info(exo_id, prds, 1) = oo_.exo_steady_state(exo_id) * v; + switch M_.det_shocks(i).type + case 'level' + oo_.pfwee.shocks_info(exo_id, prds, 1) = v; + case 'multiply_steady_state' + oo_.pfwee.shocks_info(exo_id, prds, 1) = oo_.exo_steady_state(exo_id) * v; + case 'multiply_initial_steady_state' + if isempty(ex0_) + error('Option relative_to_initval of mshocks block cannot be used without an endval block') + end + oo_.pfwee.shocks_info(exo_id, prds, 1) = ex0_(exo_id) * v; end end end diff --git a/meson.build b/meson.build index 27fc7fe56..2b05a8774 100644 --- a/meson.build +++ b/meson.build @@ -1265,6 +1265,7 @@ mod_and_m_tests = [ { 'test' : [ 'deterministic_simulations/ramst_a.mod' ] }, { 'test' : [ 'deterministic_simulations/ramst_mshocks.mod' ] }, { 'test' : [ 'deterministic_simulations/ramst_mshocks_vec.mod' ] }, + { 'test' : [ 'deterministic_simulations/ramst_mshocks_relative_to_initval.mod' ] }, { 'test' : [ 'deterministic_simulations/predetermined_variables.mod' ] }, { 'test' : [ 'deterministic_simulations/histval_det.mod' ] }, { 'test' : [ 'deterministic_simulations/ramst_vec.mod' ] }, diff --git a/preprocessor b/preprocessor index 6af84b8ca..f78c428d9 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 6af84b8cac54777bc97d4bc232452f8cf9b4498c +Subproject commit f78c428d99884c4b336dba0a7df20c7ad41fb682 diff --git a/tests/deterministic_simulations/ramst_mshocks_relative_to_initval.mod b/tests/deterministic_simulations/ramst_mshocks_relative_to_initval.mod new file mode 100644 index 000000000..4cd2e939f --- /dev/null +++ b/tests/deterministic_simulations/ramst_mshocks_relative_to_initval.mod @@ -0,0 +1,51 @@ +// Test “relative_to_initval” option of “mshocks” block + +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^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam); +end; + +initval; +x = 2; +k = ((delt+bet)/(1.0*aa*x*alph))^(1/(alph-1)); +c = aa*x*k^alph-delt*k; +end; + +steady; + +endval; + x = 3; +end; + +steady; + +mshocks(relative_to_initval); + var x; + periods 1 2:3; + values 1.2 0.8; +end; + +mshocks; + var x; + periods 4; + values 0.9; +end; + +perfect_foresight_setup(periods=200); +perfect_foresight_solver; + +if ~all(oo_.exo_simul(M_.maximum_lag+(1:4)) == [ 2.4; 1.6; 1.6; 2.7]) ... + || ~all(oo_.exo_simul(M_.maximum_lag+(5:200)) == 3) + error('mshocks not correctly applied') +end