New shocks(learnt_in=…) and endval(learnt_in=…) blocks
For use with perfect_foresight_with_expectation_errors_setup.fix-tolerance-parameters
parent
c06be7fefd
commit
8488674ce4
|
@ -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 can’t 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 can’t 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
|
||||
|
|
|
@ -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
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue