dynare/matlab/perfect-foresight-models/det_cond_forecast.m

918 lines
38 KiB
Matlab

function data_set = det_cond_forecast(varargin)
% Computes conditional forecasts using the extended path method.
%
% INPUTS
% o plan [structure] A structure describing the different shocks and the endogenous varibales, the date of the shocks and the path of the shock.
% The plan structure is created by the functions init_plan, basic_plan and flip_plan
% o [dataset] [dseries] A dserie containing the initial values of the shocks and the endogenous variables (usually the dseries generated by the smoother).
% o [starting_date] [dates] The first date of the forecast.
%
%
% OUTPUTS
% dataset [dseries] Returns a dseries containing the forecasted endgenous variables and shocks
%
% Copyright (C) 2013-2020 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
global options_ oo_ M_
pp = 2;
initial_conditions = oo_.steady_state;
verbosity = options_.verbosity;
if options_.periods == 0
options_.periods = 25;
end
%We have to get an initial guess for the conditional forecast
% and terminal conditions for the non-stationary variables, we
% use the first order approximation of the rational expectation solution.
if ~isfield(oo_,'dr') || ~isfield(oo_.dr,'ghx')
fprintf('computing the first order solution of the model as initial guess...');
dr = struct();
oo_.dr=set_state_space(dr,M_,options_);
options_.order = 1;
[dr,Info,M_,options_,oo_] = resol(0,M_,options_,oo_);
fprintf('done\n');
end
b_surprise = 0;
b_pf = 0;
surprise = 0;
pf = 0;
is_shock = [];
is_constraint = [];
if length(varargin) > 3
% regular way to call
constrained_paths = varargin{1};
max_periods_simulation = size(constrained_paths, 2);
constrained_vars = varargin{2};
options_cond_fcst = varargin{3};
constrained_perfect_foresight = varargin{4};
constraint_index = cell(max_periods_simulation,1);
nvars = length(constrained_vars);
for i = 1:max_periods_simulation
constraint_index{i} = 1:nvars;
end
direct_mode = 0;
shocks_present = 0;
controlled_varexo = options_cond_fcst.controlled_varexo;
nvarexo = size(controlled_varexo, 1);
options_cond_fcst.controlled_varexo = zeros(nvarexo,1);
exo_names = M_.exo_names;
for i = 1:nvarexo
j = find(strcmp(controlled_varexo(i,:), exo_names));
if ~isempty(j)
options_cond_fcst.controlled_varexo(i) = j;
else
error(['Unknown exogenous variable ' controlled_varexo(i,:)]);
end
end
else
% alternative way to call: plan, dset, dates_of_frcst
plan = varargin{1};
if length(varargin) >= 2
dset = varargin{2};
if ~isa(dset,'dseries')
error('the second argmuent should be a dseries');
end
if length(varargin) >= 3
range = varargin{3};
if ~isa(range,'dates')
error('the third argmuent should be a dates');
end
%if (range(range.ndat) > dset.time(dset.nobs) )
if (range(range.ndat) > dset.dates(dset.nobs)+1 )
s1 = strings(dset.dates(dset.nobs));
s2 = strings(range(range.ndat));
error(['the dseries ' inputname(2) ' finish at time ' s1{1} ' before the last period of forecast ' s2{1}]);
end
sym_dset = dset(dates(-range(1)):dates(range(range.ndat)));
periods = options_.periods + M_.maximum_lag + M_.maximum_lead;
total_periods = periods + range.ndat;
if isfield(oo_, 'exo_simul')
if size(oo_.exo_simul, 1) ~= total_periods
oo_.exo_simul = repmat(oo_.exo_steady_state',total_periods,1);
end
else
oo_.exo_simul = repmat(oo_.exo_steady_state',total_periods,1);
end
oo_.endo_simul = repmat(oo_.steady_state, 1, total_periods);
for i = 1:sym_dset.vobs
iy = find(strcmp(strtrim(sym_dset.name{i}), strtrim(plan.endo_names)));
if ~isempty(iy)
oo_.endo_simul(iy,1:sym_dset.nobs) = sym_dset.data(:, i);
initial_conditions(iy) = sym_dset.data(1, i);
else
ix = find(strcmp(strtrim(sym_dset.name{i}), strtrim(plan.exo_names)));
if ~isempty(ix)
oo_.exo_simul(1, ix) = sym_dset.data(1, i)';
else
%warning(['The variable ' sym_dset.name{i} ' in the dataset ' inputname(2) ' is not a endogenous neither an exogenous variable!!']);
end
end
end
for i = 1:length(M_.aux_vars)
if M_.aux_vars(i).type == 1 %lag variable
iy = find(strcmp(M_.endo_names{M_.aux_vars(i).orig_index}, sym_dset.name));
if ~isempty(iy)
oo_.endo_simul(M_.aux_vars(i).endo_index, 1:sym_dset.nobs) = dset(dates(range(1) + (M_.aux_vars(i).orig_lead_lag - 1))).data(:,iy);
initial_conditions(M_.aux_vars(i).endo_index) = dset(dates(range(1) + (M_.aux_vars(i).orig_lead_lag - 1))).data(:,iy);
else
warning(['The variable auxiliary ' M_.endo_names{M_.aux_vars(i).endo_index} ' associated to the variable ' M_.endo_names{M_.aux_vars(i).orig_index} ' do not appear in the dataset']);
end
else
oo_.endo_simul(M_.aux_vars(i).endo_index, 1:sym_dset.nobs) = repmat(oo_.steady_state(M_.aux_vars(i).endo_index), 1, range.ndat + 1);
end
end
%Compute the initial path using the the steady-state
% steady-state
%for jj = 2 : (options_.periods + 2)
for jj = 2 : (range.ndat + 2)
oo_.endo_simul(:, jj) = oo_.steady_state;
end
missings = isnan(oo_.endo_simul(:,1));
if any(missings)
for jj = 1:M_.endo_nbr
if missings(jj)
oo_.endo_simul(jj,1) = oo_.steady_state(jj,1);
end
end
end
if options_.bytecode
save_options_dynatol_f = options_.dynatol.f;
options_.dynatol.f = 1e-7;
[endo, exo] = bytecode('extended_path', plan, oo_.endo_simul, oo_.exo_simul, M_.params, oo_.steady_state, options_.periods);
options_.dynatol.f = save_options_dynatol_f;
oo_.endo_simul = endo;
oo_.exo_simul = exo;
endo = endo';
endo_l = size(endo(1+M_.maximum_lag:end,:),1);
jrng = dates(plan.date(1)):dates(plan.date(1)+endo_l);
data_set = dseries(nan(endo_l, dset.vobs), plan.date(1), dset.name);
for i = 1:length(dset.name)
pos = find(strcmp(dset.name{i},plan.endo_names));
if ~isempty(pos)
data_set.(dset.name{i}) = dseries(endo(1+M_.maximum_lag:end,pos), plan.date(1), dset.name{i});
else
pos = find(strcmp(dset.name{i},plan.exo_names));
if ~isempty(pos)
data_set{dset.name{i}} = dseries(exo(1+M_.maximum_lag:end,pos), plan.date(1),dset.name{i});
end
end
end
data_set = [dset(dset.dates(1):(plan.date(1)-1)) ; data_set];
for i=1:M_.exo_nbr
pos = find(strcmp(M_.exo_names{i}, dset.name));
if isempty(pos)
data_set{M_.exo_names{i}} = dseries(exo(1+M_.maximum_lag:end,i), plan.date(1), M_.exo_names{i});
else
data_set{M_.exo_names{i}}(plan.date(1):plan.date(1)+ (size(exo, 1) - M_.maximum_lag)) = exo(1+M_.maximum_lag:end,i);
end
end
data_set = merge(dset(dset.dates(1):(plan.date(1)-1)), data_set);
return
union_names = union(data_set.name, dset.name);
dif = setdiff(union_names, data_set.name);
data_set_nobs = data_set.nobs;
for i = 1:length(dif)
data_set{dif{i}} = dseries(nan(data_set_nobs,1),plan.date(1), dif(i), dif(i));
end
dif = setdiff(union_names, dset.name);
dset_nobs = dset.nobs;
for i = 1:length(dif)
dset{dif{i}} = dseries(nan(dset_nobs,1),dset.dates(1), dif(i), dif(i));
end
data_set = [dset(dset.dates(1):(plan.date(1)-1)) ; data_set];
return
end
else
error('impossible case');
end
else
oo_.exo_simul = repmat(oo_.exo_steady_state',options_.periods+2,1);
oo_.endo_simul = repmat(oo_.steady_state, 1, options_.periods+2);
end
direct_mode = 1;
constrained_paths = plan.constrained_paths_;
constrained_vars = plan.constrained_vars_;
options_cond_fcst = plan.options_cond_fcst_;
constrained_perfect_foresight = plan.constrained_perfect_foresight_;
constrained_periods = plan.constrained_date_;
if ~isempty(plan.shock_paths_)
shock_paths = plan.shock_paths_;
shock_vars = plan.shock_vars_;
shock_perfect_foresight = plan.shock_perfect_foresight_;
shock_periods = plan.shock_date_;
shocks_present = 1;
else
shocks_present = 0;
end
total_periods = plan.date;
end
if ~isfield(options_cond_fcst,'periods') || isempty(options_cond_fcst.periods)
options_cond_fcst.periods = 100;
end
options_.periods = 10;
if direct_mode == 1
n_periods = length(constrained_periods);
is_constraint = zeros(length(total_periods), n_periods);
constrained_paths_cell = constrained_paths;
clear constrained_paths;
constrained_paths = zeros(n_periods, length(total_periods));
max_periods_simulation = 0;
for i = 1:n_periods
period_i = constrained_periods{i};
%period_i
tp = total_periods(1);
if size(period_i) > 1
init_periods = period_i(1);
tp_end = period_i(end);
else
init_periods = period_i;
tp_end = period_i;
end
tp0 = tp;
while tp < init_periods
tp = tp + 1;
end
j = 0;
while tp <= tp_end
is_constraint(tp - tp0 + 1, i) = 1;
constrained_paths(i, tp - tp0 + 1) = constrained_paths_cell{i}(j + 1);
tp = tp + 1;
j = j + 1;
end
if tp - tp0 > max_periods_simulation
max_periods_simulation = tp - tp0;
end
end
n_nnz = length(sum(is_constraint,2));
if n_nnz > 0
constraint_index = cell(n_nnz,1);
for i= 1:n_nnz
constraint_index{i} = find(is_constraint(i,:));
end
end
if shocks_present
n_periods = length(shock_periods);
shock_paths_cell = shock_paths;
clear shock_paths;
shock_paths = zeros(n_periods, length(total_periods));
is_shock = zeros(length(total_periods), n_periods);
for i = 1:n_periods
period_i = shock_periods{i};
%period_i
tp = total_periods(1);
if size(period_i) > 1
init_periods = period_i(1);
tp_end = period_i(end);
else
init_periods = period_i;
tp_end = period_i;
end
tp0 = tp;
while tp < init_periods
tp = tp + 1;
end
j = 0;
while tp <= tp_end
is_shock(tp - tp0 + 1, i) = 1;
shock_paths(i, tp - tp0 + 1) = shock_paths_cell{i}(j + 1);
tp = tp + 1;
j = j + 1;
end
if tp - tp0 > max_periods_simulation
max_periods_simulation = tp - tp0;
end
end
n_nnz = length(sum(is_shock,2));
if n_nnz > 0
shock_index = cell(n_nnz, 1);
for i= 1:n_nnz
shock_index{i} = find(is_shock(i,:));
end
end
end
else
is_constraint = ones(size(constrained_paths));
end
maximum_lag = M_.maximum_lag;
ys = oo_.steady_state;
ny = size(ys,1);
xs = [oo_.exo_steady_state ; oo_.exo_det_steady_state];
nx = size(xs,1);
constrained_periods = max_periods_simulation;
n_endo_constrained = size(constrained_vars,1);
if isfield(options_cond_fcst,'controlled_varexo')
n_control_exo = size(options_cond_fcst.controlled_varexo, 1);
if n_control_exo ~= n_endo_constrained
error(['det_cond_forecast: the number of exogenous controlled variables (' int2str(n_control_exo) ') has to be equal to the number of constrained endogenous variabes (' int2str(n_endo_constrained) ')'])
end
else
error('det_cond_forecast: to run a deterministic conditional forecast you have to specified the exogenous variables controlled using the option controlled_varexo in forecast command');
end
% if n_endo_constrained == 0
% options_.ep.use_bytecode = options_.bytecode;
% data_set = extended_path(initial_conditions, max_periods_simulation);
% end
if length(varargin) >= 1
controlled_varexo = options_cond_fcst.controlled_varexo;
else
exo_names = M_.exo_names;
controlled_varexo = zeros(1,n_control_exo);
for i = 1:nx
for j=1:n_control_exo
if strcmp(exo_names{i}, deblank(options_cond_fcst.controlled_varexo(j,:)))
controlled_varexo(j) = i;
end
end
end
end
%todo check if zero => error message
save_options_initval_file = options_.initval_file;
options_.initval_file = '__';
[pos_constrained_pf, ~] = find(constrained_perfect_foresight);
indx_endo_solve_pf = constrained_vars(pos_constrained_pf);
if isempty(indx_endo_solve_pf)
pf = 0;
else
pf = length(indx_endo_solve_pf);
end
indx_endo_solve_surprise = setdiff(constrained_vars, indx_endo_solve_pf);
if isempty(indx_endo_solve_surprise)
surprise = 0;
else
surprise = length(indx_endo_solve_surprise);
end
eps = options_.solve_tolf;
maxit = options_.simul.maxit;
past_val = 0;
save_options_periods = options_.periods;
options_.periods = options_cond_fcst.periods;
save_options_dynatol_f = options_.dynatol.f;
options_.dynatol.f = 1e-8;
eps1 = 1e-7;%1e-4;
exo = zeros(maximum_lag + options_cond_fcst.periods, nx);
endo = zeros(maximum_lag + options_cond_fcst.periods, ny);
endo(1,:) = oo_.steady_state';
% if all the endogenous paths are perfectly anticipated we do not need to
% implement the extended path
if pf && ~surprise
time_index_constraint = maximum_lag + 1:maximum_lag + constrained_periods;
second_system_size = pf * constrained_periods;
J = zeros(second_system_size,second_system_size);
r = zeros(second_system_size,1);
indx_endo = zeros(second_system_size,1);
col_count = 1;
for j = 1:length(constrained_vars)
indx_endo(col_count : col_count + constrained_periods - 1) = constrained_vars(j) + (time_index_constraint - 1) * ny;
col_count = col_count + constrained_periods;
end
oo_=make_ex_(M_,options_,oo_);
oo_=make_y_(M_,options_,oo_);
it = 1;
convg = 0;
normra = 1e+50;
while ~convg && it <= maxit
disp('---------------------------------------------------------------------------------------------');
disp(['iteration ' int2str(it)]);
not_achieved = 1;
alpha = 1;
while not_achieved
simul();
result = sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint)))) == ny * constrained_periods;
if result
y = oo_.endo_simul(constrained_vars, time_index_constraint);
ys = oo_.endo_simul(indx_endo);
col_count = 1;
for j = 1:length(constrained_vars)
y = oo_.endo_simul(constrained_vars(j), time_index_constraint);
r(col_count:col_count+constrained_periods - 1) = (y - constrained_paths(j,1:constrained_periods))';
col_count = col_count + constrained_periods;
end
normr = norm(r, 1);
end
if (~oo_.deterministic_simulation.status || ~result || normr > normra) && it > 1
not_achieved = 1;
alpha = alpha / 2;
col_count = 1;
for j = controlled_varexo'
oo_.exo_simul(time_index_constraint,j) = (old_exo(:,j) + alpha * D_exo(col_count: (col_count + constrained_periods - 1)));
col_count = col_count + constrained_periods;
end
disp(['Divergence in Newton: reducing the path length alpha=' num2str(alpha)]);
oo_.endo_simul = repmat(oo_.steady_state, 1, options_cond_fcst.periods + 2);
else
not_achieved = 0;
end
end
per = 30;
z = oo_.endo_simul(:, 1 : per + 2 );
zx = oo_.exo_simul(1: per + 2,:);
g1 = spalloc(M_.endo_nbr * (per ), M_.endo_nbr * (per ), 3* M_.endo_nbr * per );
g1_x = spalloc(M_.endo_nbr * (per ), M_.exo_nbr, M_.endo_nbr * (per )* M_.exo_nbr );
lag_indx = find(M_.lead_lag_incidence(1,:));
cur_indx = M_.endo_nbr + find(M_.lead_lag_incidence(2,:));
lead_indx = 2 * M_.endo_nbr + find(M_.lead_lag_incidence(3,:));
cum_l1 = 0;
cum_index_d_y_x = [];
indx_x = [];
for k = 1 : per
if k == 1
if (isfield(M_,'block_structure'))
data1 = M_.block_structure.block;
Size = length(M_.block_structure.block);
else
data1 = M_;
Size = 1;
end
data1 = M_;
if (options_.bytecode)
[zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1);
else
[zz, g1b] = feval([M_.fname '.dynamic'], z', zx, M_.params, oo_.steady_state, k);
data1.g1_x = g1b(:,end - M_.exo_nbr + 1:end);
data1.g1 = g1b(:,1 : end - M_.exo_nbr);
end
end
if k == 1
g1(1:M_.endo_nbr,-M_.endo_nbr + [cur_indx lead_indx]) = data1.g1(:,M_.nspred + 1:end);
elseif k == per
g1(M_.endo_nbr * (k - 1) + 1 :M_.endo_nbr * k,M_.endo_nbr * (k -2) + [lag_indx cur_indx]) = data1.g1(:,1:M_.nspred + M_.endo_nbr);
else
g1(M_.endo_nbr * (k - 1) + 1 :M_.endo_nbr * k, M_.endo_nbr * (k -2) + [lag_indx cur_indx lead_indx]) = data1.g1;
end
l2 = 1;
pf_c = 1;
if k <= constrained_periods
for l = constraint_index{k}
l1 = controlled_varexo(l);
g1_x(M_.endo_nbr * (k - 1) + 1:M_.endo_nbr * k,1 + cum_l1) = data1.g1_x(:,l1);
if k == 1
indx_x(l2) = l ;
l2 = l2 + 1;
for ii = 2:constrained_periods
indx_x(l2) = length(controlled_varexo) + pf * (ii - 2) + constraint_index{k + ii - 1}(pf_c);
l2 = l2 + 1;
end
pf_c = pf_c + 1;
cum_index_d_y_x = [cum_index_d_y_x; constrained_vars(l)];
else
cum_index_d_y_x = [cum_index_d_y_x; constrained_vars(l) + (k - 1) * M_.endo_nbr];
end
cum_l1 = cum_l1 + length(l1);
end
end
end
d_y_x = - g1 \ g1_x;
cum_l1 = 0;
count_col = 1;
cum_index_J = 1:length(cum_index_d_y_x(indx_x));
J= zeros(length(cum_index_J));
for j1 = 1:length(controlled_varexo)
cum_l1 = 0;
for k = 1:(constrained_periods)
l1 = constraint_index{k};
l1 = find(constrained_perfect_foresight(l1) | (k == 1));
if constraint_index{k}( j1)
J(cum_index_J,count_col) = d_y_x(cum_index_d_y_x(indx_x),indx_x(count_col));
count_col = count_col + 1;
end
cum_l1 = cum_l1 + length(l1);
end
cum_l1 = cum_l1 + length(constrained_vars(j1));
end
% col_count = 1;
% for j = controlled_varexo'
% for time = time_index_constraint
% saved = oo_.exo_simul(time,j);
% oo_.exo_simul(time,j) = oo_.exo_simul(time,j) + eps1;
% simul();
% J1(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
% oo_.exo_simul(time,j) = saved;
% col_count = col_count + 1;
% end
% end
% J1
% sdfmlksdf;
disp(['iteration ' int2str(it) ' error = ' num2str(normr)]);
if normr <= eps
convg = 1;
disp('convergence achieved');
else
% Newton update on exogenous shocks
old_exo = oo_.exo_simul(time_index_constraint,:);
D_exo = - J \ r;
col_count = 1;
%constrained_periods
for j = controlled_varexo'
oo_.exo_simul(time_index_constraint,j) = oo_.exo_simul(time_index_constraint,j) + D_exo(col_count: (col_count + constrained_periods - 1));
col_count = col_count + constrained_periods - 1;
end
end
it = it + 1;
normra = normr;
end
endo = oo_.endo_simul';
exo = oo_.exo_simul;
else
for t = 1:constrained_periods
if direct_mode && ~isempty(is_constraint)
[pos_constrained_pf, ~] = find(constrained_perfect_foresight .* is_constraint(t, :)');
indx_endo_solve_pf = constrained_vars(pos_constrained_pf);
if isempty(indx_endo_solve_pf)
pf = 0;
else
pf = length(indx_endo_solve_pf);
end
[pos_constrained_surprise, ~] = find((1-constrained_perfect_foresight) .* is_constraint(t, :)');
indx_endo_solve_surprise = constrained_vars(pos_constrained_surprise);
if isempty(indx_endo_solve_surprise)
surprise = 0;
else
surprise = length(indx_endo_solve_surprise);
end
end
if direct_mode && ~isempty(is_shock)
[pos_shock_pf, ~] = find(shock_perfect_foresight .* is_shock(t, :)');
indx_endo_solve_pf = shock_vars(pos_shock_pf);
if isempty(indx_endo_solve_pf)
b_pf = 0;
else
b_pf = length(indx_endo_solve_pf);
end
[pos_shock_surprise, ~] = find((1-shock_perfect_foresight) .* is_shock(t, :)');
indx_endo_solve_surprise = shock_vars(pos_shock_surprise);
if isempty(indx_endo_solve_surprise)
b_surprise = 0;
else
b_surprise = length(indx_endo_solve_surprise);
end
end
disp('===============================================================================================');
disp(['t=' int2str(t) ' conditional (surprise=' int2str(surprise) ' perfect foresight=' int2str(pf) ') unconditional (surprise=' int2str(b_surprise) ' perfect foresight=' int2str(b_pf) ')']);
disp('===============================================================================================');
if t == 1
oo_=make_ex_(M_,options_,oo_);
if maximum_lag > 0
exo_init = oo_.exo_simul;
else
exo_init = zeros(size(oo_.exo_simul));
end
oo_=make_y_(M_,options_,oo_);
end
%exo_init
oo_.exo_simul = exo_init;
oo_.endo_simul(:,1) = initial_conditions;
time_index_constraint = maximum_lag + 1:maximum_lag + constrained_periods - t + 1;
if direct_mode
nb_shocks = length(plan.shock_vars_);
if nb_shocks > 0
shock_index_t = shock_index{t};
shock_vars_t = shock_vars(shock_index_t);
for shock_indx = shock_index_t
if shock_perfect_foresight(shock_indx)
oo_.exo_simul(time_index_constraint,shock_vars_t(shock_indx)) = shock_paths(shock_indx,t:constrained_periods);
else
oo_.exo_simul(maximum_lag + 1,shock_vars_t(shock_indx)) = shock_paths(shock_indx,t);
end
end
end
end
%Compute the initial path using the first order solution around the
% steady-state
oo_.endo_simul(:, 1) = oo_.endo_simul(:, 1) - oo_.steady_state;
for jj = 2 : (options_.periods + 2)
oo_.endo_simul(:,jj) = oo_.dr.ghx(oo_.dr.inv_order_var,:) * oo_.endo_simul(oo_.dr.state_var, jj-1) + oo_.dr.ghu * oo_.exo_simul(jj,:)';
end
for jj = 1 : (options_.periods + 2)
oo_.endo_simul(:,jj) = oo_.steady_state + oo_.endo_simul(:,jj);
end
constraint_index_t = constraint_index{t};
controlled_varexo_t = controlled_varexo(constraint_index_t);
constrained_vars_t = constrained_vars(constraint_index_t);
second_system_size = surprise + pf * (constrained_periods - t + 1);
indx_endo = zeros(second_system_size,1);
col_count = 1;
for j = 1:length(constrained_vars_t)
if constrained_perfect_foresight(j)
indx_endo(col_count : col_count + constrained_periods - t) = constrained_vars(j) + (time_index_constraint - 1) * ny;
col_count = col_count + constrained_periods - t + 1;
else
indx_endo(col_count) = constrained_vars(j) + maximum_lag * ny;
col_count = col_count + 1;
end
end
r = zeros(second_system_size,1);
convg = 0;
it = 1;
while ~convg && it <= maxit
disp('-----------------------------------------------------------------------------------------------');
disp(['iteration ' int2str(it) ' time ' int2str(t)]);
not_achieved = 1;
alpha = 1;
while not_achieved
perfect_foresight_setup;
perfect_foresight_solver;
result = sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint)))) == ny * length(time_index_constraint);
if (~oo_.deterministic_simulation.status || ~result) && it > 1
not_achieved = 1;
alpha = alpha / 2;
col_count = 1;
for j1 = constraint_index_t
j = controlled_varexo(j1);
if constrained_perfect_foresight(j1)
oo_.exo_simul(time_index_constraint,j) = (old_exo(time_index_constraint,j) + alpha * D_exo(col_count: col_count + constrained_periods - t));
col_count = col_count + constrained_periods - t + 1;
else
oo_.exo_simul(maximum_lag + 1,j) = old_exo(maximum_lag + 1,j) + alpha * D_exo(col_count);
col_count = col_count + 1;
end
end
disp(['Divergence in Newton: reducing the path length alpha=' num2str(alpha) ' result=' num2str(result) ' sum(sum)=' num2str(sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint))))) ' ny * length(time_index_constraint)=' num2str(ny * length(time_index_constraint)) ' oo_.deterministic_simulation.status=' num2str(oo_.deterministic_simulation.status)]);
oo_.endo_simul = [initial_conditions repmat(oo_.steady_state, 1, options_cond_fcst.periods + 1)];
else
not_achieved = 0;
end
end
if t==constrained_periods
ycc = oo_.endo_simul;
end
yc = oo_.endo_simul(:,maximum_lag + 1);
ys = oo_.endo_simul(indx_endo);
col_count = 1;
for j = constraint_index_t
if constrained_perfect_foresight(j)
y = oo_.endo_simul(constrained_vars(j), time_index_constraint);
r(col_count:col_count+constrained_periods - t) = (y - constrained_paths(j,t:constrained_periods))';
col_count = col_count + constrained_periods - t + 1;
else
y = yc(constrained_vars(j));
r(col_count) = y - constrained_paths(j,t);
col_count = col_count + 1;
end
end
disp('computation of derivatives w.r. to exogenous shocks');
per = 30;
z = oo_.endo_simul(:, 1 : per + 2 );
zx = oo_.exo_simul(1: per + 2,:);
g1 = spalloc(M_.endo_nbr * (per ), M_.endo_nbr * (per ), 3* M_.endo_nbr * per );
g1_x = spalloc(M_.endo_nbr * (per ), M_.exo_nbr, M_.endo_nbr * (per )* M_.exo_nbr );
lag_indx = find(M_.lead_lag_incidence(1,:));
cur_indx = M_.endo_nbr + find(M_.lead_lag_incidence(2,:));
lead_indx = 2 * M_.endo_nbr + find(M_.lead_lag_incidence(3,:));
cum_l1 = 0;
%indx_x = zeros(length(constraint_index_t)* constrained_periods, 1);
cum_index_d_y_x = [];
indx_x = [];
for k = 1 : per
if k == 1
if (isfield(M_,'block_structure'))
data1 = M_.block_structure.block;
Size = length(M_.block_structure.block);
else
data1 = M_;
Size = 1;
end
data1 = M_;
if (options_.bytecode)
[zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1);
else
[zz, g1b] = feval([M_.fname '.dynamic'], z', zx, M_.params, oo_.steady_state, k);
data1.g1_x = g1b(:,end - M_.exo_nbr + 1:end);
data1.g1 = g1b(:,1 : end - M_.exo_nbr);
end
end
if k == 1
g1(1:M_.endo_nbr,-M_.endo_nbr + [cur_indx lead_indx]) = data1.g1(:,M_.nspred + 1:end);
elseif k == per
g1(M_.endo_nbr * (k - 1) + 1 :M_.endo_nbr * k,M_.endo_nbr * (k -2) + [lag_indx cur_indx]) = data1.g1(:,1:M_.nspred + M_.endo_nbr);
else
g1(M_.endo_nbr * (k - 1) + 1 :M_.endo_nbr * k, M_.endo_nbr * (k -2) + [lag_indx cur_indx lead_indx]) = data1.g1;
end
l2 = 1;
pf_c = 1;
if t + k - 1 <= constrained_periods
for l = constraint_index{t + k - 1}
l1 = controlled_varexo(l);
if (k == 1) || ((k > 1) && constrained_perfect_foresight(l))
g1_x(M_.endo_nbr * (k - 1) + 1:M_.endo_nbr * k,1 + cum_l1) = data1.g1_x(:,l1);
if k == 1
if constrained_perfect_foresight(l)
indx_x(l2) = l ;
l2 = l2 + 1;
for ii = 2:constrained_periods - t + 1
indx_x(l2) = length(controlled_varexo) + pf * (ii - 2) + constraint_index{k + ii - 1}(pf_c);
l2 = l2 + 1;
end
pf_c = pf_c + 1;
else
indx_x(l2) = l;
l2 = l2 + 1;
end
cum_index_d_y_x = [cum_index_d_y_x; constrained_vars_t(l)];
else
cum_index_d_y_x = [cum_index_d_y_x; constrained_vars_t(l) + (k - 1) * M_.endo_nbr];
end
cum_l1 = cum_l1 + length(l1);
end
end
end
end
d_y_x = - g1 \ g1_x;
cum_l1 = 0;
count_col = 1;
cum_index_J = 1:length(cum_index_d_y_x(indx_x));
J= zeros(length(cum_index_J));
for j1 = constraint_index_t
if constrained_perfect_foresight(j1)
cum_l1 = 0;
for k = 1:(constrained_periods - t + 1)
l1 = constraint_index{k};
l1 = find(constrained_perfect_foresight(l1) | (k == 1));
if constraint_index{k}( j1)
J(cum_index_J,count_col) = d_y_x(cum_index_d_y_x(indx_x),indx_x(count_col));
count_col = count_col + 1;
end
cum_l1 = cum_l1 + length(l1);
end
else
J(cum_index_J,count_col) = d_y_x(cum_index_d_y_x(indx_x),indx_x(count_col));
count_col = count_col + 1;
end
cum_l1 = cum_l1 + length(constrained_vars_t(j1));
end
% % Numerical computation of the derivatives in the second systme
% J1 = [];
% col_count = 1;
% for j = constraint_index_t
% j_pos = controlled_varexo(j);
% if constrained_perfect_foresight(j)
% for time = time_index_constraint
% saved = oo_.exo_simul(time,j_pos);
% oo_.exo_simul(time,j_pos) = oo_.exo_simul(time,j_pos) + eps1;
% simul();
% J1(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
% oo_.exo_simul(time,j_pos) = saved;
% col_count = col_count + 1;
% end
% else
% saved = oo_.exo_simul(maximum_lag+1,j_pos);
% oo_.exo_simul(maximum_lag+1,j_pos) = oo_.exo_simul(maximum_lag+1,j_pos) + eps1;
% simul();
% % indx_endo
% J1(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
% % J(:,col_count) = (oo_.endo_simul((pp - 1) * M_.endo_nbr + 1: pp * M_.endo_nbr) - ys) / eps1;
% oo_.exo_simul(maximum_lag+1,j_pos) = saved;
% col_count = col_count + 1;
% end
% end
% disp('J1');
% disp(full(J1));
% sdfmlk;
normr = norm(r, 1);
disp(['iteration ' int2str(it) ' error = ' num2str(normr) ' at time ' int2str(t)]);
if normr <= eps
convg = 1;
disp('convergence achieved');
else
% Newton update on exogenous shocks
try
D_exo = - J \ r;
catch
[V, D] = eig(full(J));
ev = diag(D);
[ev abs(ev)]
z_root = find(abs(ev) < 1e-4);
z_root
disp(V(:,z_root));
end
old_exo = oo_.exo_simul;
col_count = 1;
for j = constraint_index_t
j_pos=controlled_varexo(j);
if constrained_perfect_foresight(j)
oo_.exo_simul(time_index_constraint,j_pos) = (oo_.exo_simul(time_index_constraint,j_pos) + D_exo(col_count:(col_count + constrained_periods - t) ));
col_count = col_count + constrained_periods - t + 1;
else
oo_.exo_simul(maximum_lag + 1,j_pos) = oo_.exo_simul(maximum_lag + 1,j_pos) + D_exo(col_count);
col_count = col_count + 1;
end
end
end
it = it + 1;
end
if ~convg
error(['convergence not achived at time ' int2str(t) ' after ' int2str(it) ' iterations']);
end
for j = constraint_index_t
j_pos=controlled_varexo(j);
if constrained_perfect_foresight(j)
% in case of mixed surprise and perfect foresight on the
% endogenous path, at each date all the exogenous paths have to be
% stored. The paths are stacked in exo.
for time = time_index_constraint;
exo(past_val + time,j_pos) = oo_.exo_simul(time,j_pos);
end
else
exo(maximum_lag + t,j_pos) = oo_.exo_simul(maximum_lag + 1,j_pos);
end
end
past_val = past_val + length(time_index_constraint);
if t < constrained_periods
endo(maximum_lag + t,:) = yc;
else
endo(maximum_lag + t :maximum_lag + options_cond_fcst.periods ,:) = ycc(:,maximum_lag + 1:maximum_lag + options_cond_fcst.periods - constrained_periods + 1)';
end
initial_conditions = yc;
if maximum_lag > 0
exo_init(1,:) = exo(maximum_lag + t,:);
end
end
end
options_.periods = save_options_periods;
options_.dynatol.f = save_options_dynatol_f;
options_.initval_file = save_options_initval_file;
options_.verbosity = verbosity;
oo_.endo_simul = endo';
oo_.exo_simul = exo;
if direct_mode
data_set = dseries([endo(2:end,1:M_.orig_endo_nbr) exo(2:end,:)], total_periods(1), {plan.endo_names{:} plan.exo_names{:}}, {plan.endo_names{:} plan.exo_names{:}});
end