New shocks(learnt_in=…) and endval(learnt_in=…) blocks

For use with perfect_foresight_with_expectation_errors_setup.
fix-tolerance-parameters
Sébastien Villemot 2022-04-21 17:09:27 +02:00
parent c06be7fefd
commit 8488674ce4
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
6 changed files with 247 additions and 42 deletions

View File

@ -17,11 +17,7 @@ function perfect_foresight_with_expectation_errors_setup
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
global M_ oo_ options_ ys0_
if ~isempty(ys0_)
error('perfect_foresight_with_expectation_errors_setup: cannot be used in conjunction with endval')
end
global M_ oo_ options_ ys0_ ex0_
if ~isempty(M_.endo_histval)
error('perfect_foresight_with_expectation_errors_setup: cannot be used in conjunction with histval')
@ -32,37 +28,90 @@ end
periods = options_.periods;
%% Read CSV file
if ~exist(options_.datafile, 'file')
error(['perfect_foresight_with_expectation_errors_setup: cannot find ' options_.datafile ])
end
%% We cant use readcell (only in MATLAB ≥ R2019a), so instead rely on csvread and manual hacks
% Read numeric data, skipping first row and first column
raw_csv = csvread(options_.datafile, 1, 1);
if size(raw_csv, 1)-2 ~= periods
error(['perfect_foresight_with_expectation_errors_setup: the number of rows in ' options_.datafile ' does not match the periods setting'])
end
% Read first line (exogenous variable names)
fid = fopen(options_.datafile);
csv_first_line = fgetl(fid);
fclose(fid);
exo_header_names = strsplit(csv_first_line, ',');
exo_header_names = exo_header_names(2:end); % Remove first column
if numel(exo_header_names) ~= size(raw_csv, 2)
error(['perfect_foresight_with_expectation_errors_setup: first line malformed in ' options_.datafile])
end
%% Create and fill structures containing information sets
%% Initialize informational structures
oo_.pfwee.terminal_info = NaN(M_.exo_nbr, periods); % 2nd dimension is informational time
oo_.pfwee.shocks_info = NaN(M_.exo_nbr, periods, periods); % 2nd dimension is real time, 3rd dimension is informational time
for i = 1:size(raw_csv, 2)
exo_id = strmatch(exo_header_names{i}, M_.exo_names, 'exact');
period_id = raw_csv(1, i);
% Ignore irrelevant periods when copying shocks information
oo_.pfwee.shocks_info(exo_id, period_id:end, period_id) = raw_csv(1+period_id:end-1, i);
oo_.pfwee.terminal_info(exo_id, period_id) = raw_csv(end, i);
if exist(options_.datafile, 'file')
if ~isempty(M_.det_shocks) || ~isempty(M_.learnt_shocks) || ~isempty(ys0_) || ~isempty(M_.learnt_endval)
warning('perfect_foresight_with_expectation_errors_setup: since you passed the datafile option, the contents of shocks and endval blocks will be ignored')
end
%% Read CSV file
%% We cant use readcell (only in MATLAB ≥ R2019a), so instead rely on csvread and manual hacks
% Read numeric data, skipping first row and first column
raw_csv = csvread(options_.datafile, 1, 1);
if size(raw_csv, 1)-2 ~= periods
error(['perfect_foresight_with_expectation_errors_setup: the number of rows in ' options_.datafile ' does not match the periods setting'])
end
% Read first line (exogenous variable names)
fid = fopen(options_.datafile);
csv_first_line = fgetl(fid);
fclose(fid);
exo_header_names = strsplit(csv_first_line, ',');
exo_header_names = exo_header_names(2:end); % Remove first column
if numel(exo_header_names) ~= size(raw_csv, 2)
error(['perfect_foresight_with_expectation_errors_setup: first line malformed in ' options_.datafile])
end
%% Create and fill structures containing information sets
for i = 1:size(raw_csv, 2)
exo_id = strmatch(exo_header_names{i}, M_.exo_names, 'exact');
period_id = raw_csv(1, i);
% Ignore irrelevant periods when copying shocks information
oo_.pfwee.shocks_info(exo_id, period_id:end, period_id) = raw_csv(1+period_id:end-1, i);
oo_.pfwee.terminal_info(exo_id, period_id) = raw_csv(end, i);
end
else
%% No datafile option given, use the contents of shocks and endval blocks
if isempty(M_.learnt_shocks) && isempty(M_.learnt_endval)
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
%% 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) = oo_.exo_steady_state;
for i = 1:length(M_.det_shocks)
prds = M_.det_shocks(i).periods;
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_.pfwee.shocks_info(exo_id, prds, 1) .* v;
end
end
end
%% Construct information sets for subsequent informational periods
for p = 2:periods
oo_.pfwee.terminal_info(:, p) = oo_.pfwee.terminal_info(:, p-1);
if ~isempty(M_.learnt_endval)
idx = find([M_.learnt_endval.learnt_in] == p);
for i = 1:length(idx)
j = idx(i);
oo_.pfwee.terminal_info(M_.learnt_endval(j).exo_id, p) = M_.learnt_endval(j).value;
end
end
oo_.pfwee.shocks_info(:, :, p) = oo_.pfwee.shocks_info(:, :, p-1);
if ~isempty(M_.learnt_shocks)
idx = find([M_.learnt_shocks.learnt_in] == p);
for i = 1:length(idx)
j = idx(i);
oo_.pfwee.shocks_info(M_.learnt_shocks(j).exo_id, M_.learnt_shocks(j).periods, p) = M_.learnt_shocks(j).value;
end
end
end
end
% Build initial paths for endos and exos (only initial conditions are set, the rest is NaN)
oo_.endo_simul = [repmat(oo_.steady_state, 1, M_.maximum_lag) NaN(M_.endo_nbr, periods+M_.maximum_lead)];
oo_.exo_simul = [repmat(oo_.exo_steady_state',M_.maximum_lag,1); NaN(periods+M_.maximum_lead,M_.exo_nbr)];
if isempty(ys0_)
oo_.endo_simul = [repmat(oo_.steady_state, 1, M_.maximum_lag) NaN(M_.endo_nbr, periods+M_.maximum_lead)];
else
oo_.endo_simul = [repmat(ys0_, 1, M_.maximum_lag) NaN(M_.endo_nbr, periods+M_.maximum_lead)];
end
if isempty(ex0_)
oo_.exo_simul = [repmat(oo_.exo_steady_state',M_.maximum_lag,1); NaN(periods+M_.maximum_lead,M_.exo_nbr)];
else
oo_.exo_simul = [repmat(ex0_',M_.maximum_lag,1); NaN(periods+M_.maximum_lead,M_.exo_nbr)];
end

View File

@ -17,11 +17,11 @@ function perfect_foresight_with_expectation_errors_solver
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
global M_ oo_ options_
global M_ oo_ options_ ys0_
% Save initial steady state, for restoring it at the end
initial_steady_state = oo_.steady_state;
initial_exo_steady_state = oo_.exo_steady_state;
% Save original steady state, for restoring it at the end
orig_steady_state = oo_.steady_state;
orig_exo_steady_state = oo_.exo_steady_state;
% Same for periods (it will be modified before calling perfect_foresight_solver if constants_simulation_length option is false)
periods = options_.periods;
@ -34,6 +34,11 @@ exo_simul = oo_.exo_simul;
% Start main loop around informational periods
info_period = 1;
increment = 0;
if isempty(ys0_)
initial_steady_state = oo_.steady_state;
else
initial_steady_state = ys0_;
end
while info_period <= periods
% Compute terminal steady state as anticipated
oo_.exo_steady_state = oo_.pfwee.terminal_info(:, info_period);
@ -88,6 +93,6 @@ oo_.endo_simul = endo_simul;
oo_.exo_simul = exo_simul;
% Restore some values
oo_.steady_state = initial_steady_state;
oo_.exo_steady_state = initial_exo_steady_state;
oo_.steady_state = orig_steady_state;
oo_.exo_steady_state = orig_exo_steady_state;
options_.periods = periods;

@ -1 +1 @@
Subproject commit 54ca5d9cc08f6f2a3bec9ff57a3808f988e9b397
Subproject commit b5a4df16088d9d3c1f77db0aaa5bed4f4ee32354

View File

@ -390,6 +390,7 @@ MODFILES = \
deterministic_simulations/rbc_det_stack_solve_algo_7_exo_lead.mod \
deterministic_simulations/pfwee.mod \
deterministic_simulations/pfwee_constant_sim_length.mod \
deterministic_simulations/pfwee_learnt_in.mod \
lmmcp/rbc.mod \
lmmcp/sw_lmmcp.mod \
lmmcp/sw_newton.mod \

View File

@ -1,4 +1,5 @@
// Tests perfect_foresight_with_expectation_errors_{setup,solver}
/* Tests perfect_foresight_with_expectation_errors_{setup,solver}
using a CSV datafile */
var c k;
varexo x;

View File

@ -0,0 +1,149 @@
/* Tests perfect_foresight_with_expectation_errors_{setup,solver}
using the shocks(learnt_in=) and endval(learnt_in=) syntax */
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 = 1;
k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1));
c = aa*k^alph-delt*k;
end;
steady;
check;
// Describe the same scenario as in pfwee.csv, but using the Dynare syntax
shocks;
var x;
periods 1;
values 1.2;
end;
shocks(learnt_in = 2);
var x;
periods 2;
values 1.3;
end;
endval(learnt_in = 2);
x = 1.1;
end;
shocks(learnt_in = 3);
var x;
periods 3;
values 1.4;
end;
endval(learnt_in = 3);
x = 1.2;
end;
// Dummy block, that will be overwritten by the next one
shocks(learnt_in = 6);
var x;
periods 6:8;
values 10;
end;
shocks(learnt_in = 6, overwrite);
var x;
periods 6:7;
values 1.1;
end;
endval(learnt_in = 6);
x = 1.1;
end;
perfect_foresight_with_expectation_errors_setup(periods = 7);
// First simulation with default options
perfect_foresight_with_expectation_errors_solver;
pfwee1 = oo_.endo_simul;
// Second simulation with alternative guess values
perfect_foresight_with_expectation_errors_solver(terminal_steady_state_as_guess_value);
pfwee2 = oo_.endo_simul;
// Now compute the solution by hand to verify the results
perfect_foresight_setup;
// Information arriving in period 1 (temp shock now)
oo_.exo_simul(2,1) = 1.2;
perfect_foresight_solver;
// Information arriving in period 2 (temp shock now + permanent shock in future)
oo_.exo_simul(3,1) = 1.3;
oo_.exo_steady_state = 1.1;
oo_.exo_simul(end, 1) = oo_.exo_steady_state;
oo_.steady_state = evaluate_steady_state(oo_.steady_state, M_, options_, oo_, true);
oo_.endo_simul(:, end) = oo_.steady_state;
periods 6;
saved_endo = oo_.endo_simul(:, 1);
saved_exo = oo_.exo_simul(1, :);
oo_.endo_simul = oo_.endo_simul(:, 2:end);
oo_.exo_simul = oo_.exo_simul(2:end, :);
perfect_foresight_solver;
oo_.endo_simul = [ saved_endo oo_.endo_simul ];
oo_.exo_simul = [ saved_exo; oo_.exo_simul ];
// Information arriving in period 3 (temp shock now + permanent shock in future)
oo_.exo_simul(4,1) = 1.4;
oo_.exo_steady_state = 1.2;
oo_.exo_simul(end, 1) = oo_.exo_steady_state;
oo_.steady_state = evaluate_steady_state(oo_.steady_state, M_, options_, oo_, true);
oo_.endo_simul(:, end) = oo_.steady_state;
periods 5;
saved_endo = oo_.endo_simul(:, 1:2);
saved_exo = oo_.exo_simul(1:2, :);
oo_.endo_simul = oo_.endo_simul(:, 3:end);
oo_.exo_simul = oo_.exo_simul(3:end, :);
perfect_foresight_solver;
oo_.endo_simul = [ saved_endo oo_.endo_simul ];
oo_.exo_simul = [ saved_exo; oo_.exo_simul ];
// Information arriving in period 6 (permanent shock arriving now)
oo_.exo_simul(7,1) = 1.1;
oo_.exo_simul(8,1) = 1.1;
oo_.exo_steady_state = 1.1;
oo_.exo_simul(end, 1) = oo_.exo_steady_state;
oo_.steady_state = evaluate_steady_state(oo_.steady_state, M_, options_, oo_, true);
oo_.endo_simul(:, end) = oo_.steady_state;
periods 2;
saved_endo = oo_.endo_simul(:, 1:5);
saved_exo = oo_.exo_simul(1:5, :);
oo_.endo_simul = oo_.endo_simul(:, 6:end);
oo_.exo_simul = oo_.exo_simul(6:end, :);
perfect_foresight_solver;
oo_.endo_simul = [ saved_endo oo_.endo_simul ];
oo_.exo_simul = [ saved_exo; oo_.exo_simul ];
% We should have strict equality with first pfwee simulation, because algorithm
% and guess values are exactly the same.
if any(any(pfwee1-oo_.endo_simul ~= 0))
error('Error in perfect_foresight_with_expectation_errors')
end
% For the 2nd simulation, since the guess values are different, there are some
% numerical differences
if max(max(abs(pfwee2-oo_.endo_simul))) > 10*options_.dynatol.f
error('Error in perfect_foresight_with_expectation_errors + terminal_steady_state_as_guess_value')
end