1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
function info = perfect_foresight_simulation(compute_linear_solution,steady_state)
% Performs deterministic simulations with lead or lag on one period
%
% INPUTS
% endo_simul [double] n*T matrix, where n is the number of endogenous variables.
% exo_simul [double] q*T matrix, where q is the number of shocks.
% compute_linear_solution [integer] scalar equal to zero or one.
%
% OUTPUTS
% none
%
% ALGORITHM
% Laffargue, Boucekkine, Juillard (LBJ)
% see Juillard (1996) Dynare: A program for the resolution and
% simulation of dynamic models with forward variables through the use
% of a relaxation algorithm. CEPREMAP. Couverture Orange. 9602.
%
% SPECIAL REQUIREMENTS
% None.
% Copyright (C) 2009-2015 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 M_ options_ it_ oo_
persistent lead_lag_incidence dynamic_model ny nyp nyf nrs nrc iyf iyp isp is isf isf1 iz icf ghx iflag
if ~nargin && isempty(iflag)% Initialization of the persistent variables.
lead_lag_incidence = M_.lead_lag_incidence;
dynamic_model = [M_.fname '.dynamic'];
ny = size(oo_.endo_simul,1);
nyp = nnz(lead_lag_incidence(1,:));% number of lagged variables.
nyf = nnz(lead_lag_incidence(3,:));% number of leaded variables.
nrs = ny+nyp+nyf+1;
nrc = nyf+1;
iyf = find(lead_lag_incidence(3,:)>0);% indices for leaded variables.
iyp = find(lead_lag_incidence(1,:)>0);% indices for lagged variables.
isp = 1:nyp;
is = (nyp+1):(nyp+ny); % Indices for contemporaneaous variables.
isf = iyf+nyp;
isf1 = (nyp+ny+1):(nyf+nyp+ny+1);
iz = 1:(ny+nyp+nyf);
icf = 1:size(iyf,2);
info = [];
iflag = 1;
return
end
initial_endo_simul = oo_.endo_simul;
warning_old_state = warning;
warning off all
if nargin<1
compute_linear_solution = 0;
else
if nargin<2
error('The steady state (second input argument) is missing!');
end
end
if ~isstruct(compute_linear_solution) && compute_linear_solution
[dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_);
elseif isstruct(compute_linear_solution)
dr = compute_linear_solution;
compute_linear_solution = 1;
end
if compute_linear_solution
ghx(dr.order_var,:) = dr.ghx;
ghx = ghx(iyf,:);
end
periods = options_.periods;
stop = 0 ;
it_init = M_.maximum_lag+1;
info.convergence = 1;
info.time = 0;
info.error = 0;
info.iterations.time = zeros(options_.simul.maxit,1);
info.iterations.error = info.iterations.time;
last_line = options_.simul.maxit;
error_growth = 0;
h1 = clock;
for iter = 1:options_.simul.maxit
h2 = clock;
if options_.terminal_condition
c = zeros(ny*(periods+1),nrc);
else
c = zeros(ny*periods,nrc);
end
it_ = it_init;
z = [ oo_.endo_simul(iyp,it_-1) ; oo_.endo_simul(:,it_) ; oo_.endo_simul(iyf,it_+1) ];
[d1,jacobian] = feval(dynamic_model,z,oo_.exo_simul, M_.params, it_);
jacobian = [jacobian(:,iz) , -d1];
ic = 1:ny;
icp = iyp;
c(ic,:) = jacobian(:,is)\jacobian(:,isf1) ;
for it_ = it_init+(1:periods-1-(options_.terminal_condition==2))
z = [ oo_.endo_simul(iyp,it_-1) ; oo_.endo_simul(:,it_) ; oo_.endo_simul(iyf,it_+1)];
[d1,jacobian] = feval(dynamic_model,z,oo_.exo_simul, M_.params, it_);
jacobian = [jacobian(:,iz) , -d1];
jacobian(:,[isf nrs]) = jacobian(:,[isf nrs])-jacobian(:,isp)*c(icp,:);
ic = ic + ny;
icp = icp + ny;
c(ic,:) = jacobian(:,is)\jacobian(:,isf1);
end
if options_.terminal_condition
if options_.terminal_condition==1% Terminal condition is Y_{T} = Y_{T+1}
s = eye(ny);
s(:,isf) = s(:,isf)+c(ic,1:nyf);
ic = ic + ny;
c(ic,nrc) = s\c(ic,nrc);
else% Terminal condition is Y_{T+1}-Y^{\star} = TransitionMatrix*(Y_{T}-Y^{\star})
it_ = it_+1;
z = [ oo_.endo_simul(iyp,it_-1) ; oo_.endo_simul(:,it_) ; oo_.endo_simul(iyf,it_+1) ] ;
[d1,jacobian] = feval(dynamic_model,z,oo_.exo_simul, M_.params, it_);
jacobian = [jacobian(:,iz) -d1];
jacobian(:,[isf nrs]) = jacobian(:,[isf nrs])-jacobian(:,isp)*c(icp,:) ;
ic = ic + ny;
icp = icp + ny;
s = jacobian(:,is);
s(:,iyp) = s(:,iyp)+jacobian(:,isf)*ghx;
c (ic,:) = s\jacobian(:,isf1);
end
c = bksup0(c,ny,nrc,iyf,icf,periods);
c = reshape(c,ny,periods+1);
oo_.endo_simul(:,it_init+(0:periods)) = oo_.endo_simul(:,it_init+(0:periods))+options_.slowc*c;
else% Terminal condition is Y_{T}=Y^{\star}
c = bksup0(c,ny,nrc,iyf,icf,periods);
c = reshape(c,ny,periods);
oo_.endo_simul(:,it_init+(0:periods-1)) = oo_.endo_simul(:,it_init+(0:periods-1))+options_.slowc*c;
end
err = max(max(abs(c)));
info.iterations.time(iter) = etime(clock,h2);
info.iterations.error(iter) = err;
if iter>1
error_growth = error_growth + (info.iterations.error(iter)>info.iterations.error(iter-1));
end
if isnan(err) || error_growth>3
last_line = iter;
break
end
if err < options_.dynatol.f
stop = 1;
info.time = etime(clock,h1);
info.error = err;
info.iterations.time = info.iterations.time(1:iter);
info.iterations.error = info.iterations.error(1:iter);
break
end
end
if stop && options_.terminal_condition==2
% Compute the distance to the deterministic steady state (for the subset of endogenous variables with a non zero
% steady state) at the last perdiod.
idx = find(abs(oo_.steady_state)>0);
distance_to_steady_state = abs(((oo_.endo_simul(idx,end)-oo_.steady_state(idx))./oo_.steady_state(idx)))*100;
disp(['(max) Distance to steady state at the end is (in percentage):' num2str(max(distance_to_steady_state))])
end
if ~stop
info.time = etime(clock,h1);
info.error = err;
info.convergence = 0;
info.iterations.time = info.iterations.time(1:last_line);
info.iterations.error = info.iterations.error(1:last_line);
oo_.endo_simul = initial_endo_simul;
end
warning(warning_old_state);
|