Merge pull request #1042 from JohannesPfeifer/discretionary
Various fixes for discretionary_policytime-shift
commit
866ab33575
|
@ -35,6 +35,6 @@ if options_.noprint == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%oo_ = evaluate_planner_objective(oo_.dr,M_,oo_,options_);
|
oo_.planner_objective_value = evaluate_planner_objective(M_,options_,oo_);
|
||||||
|
|
||||||
options_ = oldoptions;
|
options_ = oldoptions;
|
|
@ -1,6 +1,6 @@
|
||||||
function [dr,ys,info]=discretionary_policy_1(oo_,Instruments)
|
function [dr,ys,info]=discretionary_policy_1(oo_,Instruments)
|
||||||
|
|
||||||
% Copyright (C) 2007-2012 Dynare Team
|
% Copyright (C) 2007-2015 Dynare Team
|
||||||
%
|
%
|
||||||
% This file is part of Dynare.
|
% This file is part of Dynare.
|
||||||
%
|
%
|
||||||
|
@ -78,7 +78,8 @@ it_ = MaxLag + 1 ;
|
||||||
if exo_nbr == 0
|
if exo_nbr == 0
|
||||||
oo_.exo_steady_state = [] ;
|
oo_.exo_steady_state = [] ;
|
||||||
end
|
end
|
||||||
[junk,jacobia_] = feval([M_.fname '_dynamic'],z, [oo_.exo_simul ...
|
|
||||||
|
[junk,jacobia_] = feval([M_.fname '_dynamic'],z, [zeros(size(oo_.exo_simul)) ...
|
||||||
oo_.exo_det_simul], M_.params, zeros(endo_nbr,1), it_);
|
oo_.exo_det_simul], M_.params, zeros(endo_nbr,1), it_);
|
||||||
if any(junk~=0)
|
if any(junk~=0)
|
||||||
error(['discretionary_policy: the model must be written in deviation ' ...
|
error(['discretionary_policy: the model must be written in deviation ' ...
|
||||||
|
@ -88,6 +89,13 @@ end
|
||||||
eq_nbr= size(jacobia_,1);
|
eq_nbr= size(jacobia_,1);
|
||||||
instr_nbr=endo_nbr-eq_nbr;
|
instr_nbr=endo_nbr-eq_nbr;
|
||||||
|
|
||||||
|
if instr_nbr==0
|
||||||
|
error('discretionary_policy:: There are no available instruments, because the model has as many equations as variables.')
|
||||||
|
end
|
||||||
|
if size(Instruments,1)~= instr_nbr
|
||||||
|
error('discretionary_policy:: There are more declared instruments than omitted equations.')
|
||||||
|
end
|
||||||
|
|
||||||
instr_id=nan(instr_nbr,1);
|
instr_id=nan(instr_nbr,1);
|
||||||
for j=1:instr_nbr
|
for j=1:instr_nbr
|
||||||
vj=deblank(Instruments(j,:));
|
vj=deblank(Instruments(j,:));
|
||||||
|
@ -126,24 +134,49 @@ if info
|
||||||
dr=[];
|
dr=[];
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
Hold=H;
|
Hold=H; %save previous solution
|
||||||
% Hold=[]; use this line if persistent command is not used.
|
% Hold=[]; use this line if persistent command is not used.
|
||||||
end
|
end
|
||||||
% update the following elements
|
% update the following elements
|
||||||
|
|
||||||
LLI=lead_lag_incidence;
|
LLI=lead_lag_incidence;
|
||||||
LLI(MaxLag,:)=any(H);
|
LLI(MaxLag,:)=any(H); %check if variable drops out in solution
|
||||||
|
|
||||||
LLI=LLI';
|
LLI=LLI';
|
||||||
tmp=find(LLI);
|
tmp=find(LLI);
|
||||||
LLI(tmp)=1:numel(tmp);
|
LLI(tmp)=1:numel(tmp); %renumber
|
||||||
|
|
||||||
M_.lead_lag_incidence = LLI';
|
M_.lead_lag_incidence = LLI'; %update lead_lag_incidence
|
||||||
|
|
||||||
|
%update info in M_
|
||||||
|
max_lag = M_.maximum_endo_lag;
|
||||||
|
endo_nbr = M_.endo_nbr;
|
||||||
|
lead_lag_incidence = M_.lead_lag_incidence;
|
||||||
|
|
||||||
|
fwrd_var = find(lead_lag_incidence(max_lag+2:end,:))';
|
||||||
|
if max_lag > 0
|
||||||
|
pred_var = find(lead_lag_incidence(1,:))';
|
||||||
|
both_var = intersect(pred_var,fwrd_var);
|
||||||
|
pred_var = setdiff(pred_var,both_var);
|
||||||
|
fwrd_var = setdiff(fwrd_var,both_var);
|
||||||
|
stat_var = setdiff([1:endo_nbr]',union(union(pred_var,both_var),fwrd_var)); % static variables
|
||||||
|
else
|
||||||
|
pred_var = [];
|
||||||
|
both_var = [];
|
||||||
|
stat_var = setdiff([1:endo_nbr]',fwrd_var);
|
||||||
|
end
|
||||||
|
M_.nstatic=length(stat_var);
|
||||||
|
M_.nfwrd=length(fwrd_var);
|
||||||
|
M_.npred=length(pred_var);
|
||||||
|
M_.nboth=length(both_var);
|
||||||
|
M_.nspred=M_.npred+M_.nboth;
|
||||||
|
M_.nsfwrd=M_.nfwrd+M_.nboth;
|
||||||
|
M_.ndynamic=M_.endo_nbr-M_.nstatic;
|
||||||
|
|
||||||
% set the state
|
% set the state
|
||||||
dr=oo_.dr;
|
dr=oo_.dr;
|
||||||
dr.ys =zeros(endo_nbr,1);
|
dr.ys =zeros(endo_nbr,1);
|
||||||
dr=set_state_space(dr,M_,options_);
|
dr=set_state_space(dr,M_,options_); %relies on M_.lead_lag_incidence being updated
|
||||||
order_var=dr.order_var;
|
order_var=dr.order_var;
|
||||||
|
|
||||||
T=H(order_var,order_var);
|
T=H(order_var,order_var);
|
||||||
|
|
|
@ -1,16 +1,54 @@
|
||||||
function [H,G,retcode]=discretionary_policy_engine(AAlag,AA0,AAlead,BB,bigw,instr_id,beta,solve_maxit,discretion_tol,qz_criterium,H00,verbose)
|
function [H,G,retcode]=discretionary_policy_engine(AAlag,AA0,AAlead,BB,bigw,instr_id,beta,solve_maxit,discretion_tol,qz_criterium,H00,verbose)
|
||||||
|
|
||||||
% Solves the discretionary problem for a model of the form:
|
% Solves the discretionary problem for a model of the form:
|
||||||
% AAlag*yy_{t-1}+AA0*yy_t+AAlead*yy_{t+1}+BB*e=0, with W the weight on the
|
%
|
||||||
% variables in vector y_t and instr_id is the location of the instruments
|
% Loss=E_0 sum_{t=0}^{\infty} beta^t [y_t'*W*y+x_t'*Q*x_t]
|
||||||
% in the yy_t vector.
|
% subject to
|
||||||
|
% AAlag*yy_{t-1}+AA0*yy_t+AAlead*yy_{t+1}+BB*e=0
|
||||||
|
%
|
||||||
|
% with W the weight on the variables in vector y_t.
|
||||||
|
%
|
||||||
|
% The solution takes the form
|
||||||
|
% y_t=H*y_{t-1}+G*e_t
|
||||||
|
% where H=[H1;F1] and G=[H2;F2].
|
||||||
|
%
|
||||||
% We use the Dennis (2007, Macroeconomic Dynamics) algorithm and so we need
|
% We use the Dennis (2007, Macroeconomic Dynamics) algorithm and so we need
|
||||||
% to re-write the model in the form
|
% to re-write the model in the form
|
||||||
% A0*y_t=A1*y_{t-1}+A2*y_{t+1}+A3*x_t+A4*x_{t+1}+A5*e_t, with W the
|
% A0*y_t=A1*y_{t-1}+A2*y_{t+1}+A3*x_t+A4*x_{t+1}+A5*e_t, with W the
|
||||||
% weight on the y_t vector and Q the weight on the x_t vector of
|
% weight on the y_t vector and Q the weight on the x_t vector of
|
||||||
% instruments.
|
% instruments.
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% AAlag [double] matrix of coefficients on lagged
|
||||||
|
% variables
|
||||||
|
% AA0 [double] matrix of coefficients on
|
||||||
|
% contemporaneous variables
|
||||||
|
% AAlead [double] matrix of coefficients on
|
||||||
|
% leaded variables
|
||||||
|
% BB [double] matrix of coefficients on
|
||||||
|
% shocks
|
||||||
|
% bigw [double] matrix of coefficients on variables in
|
||||||
|
% loss/objective function; stacks [W and Q]
|
||||||
|
% instr_id [double] location vector of the instruments in the yy_t vector.
|
||||||
|
% beta [scalar] planner discount factor
|
||||||
|
% solve_maxit [scalar] maximum number of iterations
|
||||||
|
% discretion_tol [scalar] convergence criterion for solution
|
||||||
|
% qz_criterium [scalar] tolerance for QZ decomposition
|
||||||
|
% H00
|
||||||
|
% verbose [scalar] dummy to control verbosity
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% H [double] (endo_nbr*endo_nbr) solution matrix for endogenous
|
||||||
|
% variables, stacks [H1 and H1]
|
||||||
|
% G [double] (endo_nbr*exo_nbr) solution matrix for shocks, stacks [H2 and F2]
|
||||||
|
%
|
||||||
|
% retcode [scalar] return code
|
||||||
|
%
|
||||||
|
% Algorithm:
|
||||||
|
% Dennis, Richard (2007): Optimal policy in rational expectations models: new solution algorithms,
|
||||||
|
% Macroeconomic Dynamics, 11, 31–55.
|
||||||
|
|
||||||
% Copyright (C) 2007-2012 Dynare Team
|
% Copyright (C) 2007-2015 Dynare Team
|
||||||
%
|
%
|
||||||
% This file is part of Dynare.
|
% This file is part of Dynare.
|
||||||
%
|
%
|
||||||
|
@ -53,14 +91,15 @@ end
|
||||||
|
|
||||||
[A0,A1,A2,A3,A4,A5,W,Q,endo_nbr,exo_nbr,aux,endo_augm_id]=GetDennisMatrices(AAlag,AA0,AAlead,BB,bigw,instr_id);
|
[A0,A1,A2,A3,A4,A5,W,Q,endo_nbr,exo_nbr,aux,endo_augm_id]=GetDennisMatrices(AAlag,AA0,AAlead,BB,bigw,instr_id);
|
||||||
% aux is a logical index of the instruments which appear with lags in the
|
% aux is a logical index of the instruments which appear with lags in the
|
||||||
% model. Their location in the state vector is instr_id(aux)
|
% model. Their location in the state vector is instr_id(aux);
|
||||||
% endo_augm_id is index (not logical) of locations of the augmented vector
|
% endo_augm_id is index (not logical) of locations of the augmented vector
|
||||||
% of non-instrumental variables
|
% of non-instrumental variables
|
||||||
|
|
||||||
AuxiliaryVariables_nbr=sum(aux);
|
AuxiliaryVariables_nbr=sum(aux);
|
||||||
H0=zeros(endo_nbr+AuxiliaryVariables_nbr);
|
H0=zeros(endo_nbr+AuxiliaryVariables_nbr);
|
||||||
if ~isempty(H00)
|
if ~isempty(H00)
|
||||||
H0(1:endo_nbr,1:endo_nbr)=H00;clear H00
|
H0(1:endo_nbr,1:endo_nbr)=H00;
|
||||||
|
clear H00
|
||||||
end
|
end
|
||||||
|
|
||||||
H10=H0(endo_augm_id,endo_augm_id);
|
H10=H0(endo_augm_id,endo_augm_id);
|
||||||
|
@ -69,6 +108,7 @@ F10=H0(instr_id,endo_augm_id);
|
||||||
iter=0;
|
iter=0;
|
||||||
H1=H10;
|
H1=H10;
|
||||||
F1=F10;
|
F1=F10;
|
||||||
|
%solve equations (20) and (22) via fixed point iteration
|
||||||
while 1
|
while 1
|
||||||
iter=iter+1;
|
iter=iter+1;
|
||||||
P=SylvesterDoubling(W+beta*F1'*Q*F1,beta*H1',H1,discretion_tol,solve_maxit);
|
P=SylvesterDoubling(W+beta*F1'*Q*F1,beta*H1',H1,discretion_tol,solve_maxit);
|
||||||
|
@ -79,11 +119,11 @@ while 1
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
D=A0-A2*H1-A4*F1;
|
D=A0-A2*H1-A4*F1; %equation (20)
|
||||||
Dinv=inv(D);
|
Dinv=inv(D);
|
||||||
A3DPD=A3'*Dinv'*P*Dinv;
|
A3DPD=A3'*Dinv'*P*Dinv;
|
||||||
F1=-(Q+A3DPD*A3)\(A3DPD*A1);
|
F1=-(Q+A3DPD*A3)\(A3DPD*A1); %component of (26)
|
||||||
H1=Dinv*(A1+A3*F1);
|
H1=Dinv*(A1+A3*F1); %component of (27)
|
||||||
|
|
||||||
[rcode,NQ]=CheckConvergence([H1;F1]-[H10;F10],iter,solve_maxit,discretion_tol);
|
[rcode,NQ]=CheckConvergence([H1;F1]-[H10;F10],iter,solve_maxit,discretion_tol);
|
||||||
if rcode
|
if rcode
|
||||||
|
@ -97,16 +137,17 @@ while 1
|
||||||
F10=F1;
|
F10=F1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%check if successful
|
||||||
retcode = 0;
|
retcode = 0;
|
||||||
switch rcode
|
switch rcode
|
||||||
case 3 % nan
|
case 3 % nan
|
||||||
retcode=63;
|
retcode=63;
|
||||||
retcode(2)=10000;
|
retcode(2)=10000;
|
||||||
if verbose
|
if verbose
|
||||||
disp([mfilename,':: NAN elements in the solution'])
|
disp([mfilename,':: NaN elements in the solution'])
|
||||||
end
|
end
|
||||||
case 2% maxiter
|
case 2% maxiter
|
||||||
retcode = 61
|
retcode = 61;
|
||||||
if verbose
|
if verbose
|
||||||
disp([mfilename,':: Maximum Number of Iterations reached'])
|
disp([mfilename,':: Maximum Number of Iterations reached'])
|
||||||
end
|
end
|
||||||
|
@ -125,8 +166,8 @@ if retcode(1)
|
||||||
H=[];
|
H=[];
|
||||||
G=[];
|
G=[];
|
||||||
else
|
else
|
||||||
F2=-(Q+A3DPD*A3)\(A3DPD*A5);
|
F2=-(Q+A3DPD*A3)\(A3DPD*A5); %equation (29)
|
||||||
H2=Dinv*(A5+A3*F2);
|
H2=Dinv*(A5+A3*F2); %equation (31)
|
||||||
H=zeros(endo_nbr+AuxiliaryVariables_nbr);
|
H=zeros(endo_nbr+AuxiliaryVariables_nbr);
|
||||||
G=zeros(endo_nbr+AuxiliaryVariables_nbr,exo_nbr);
|
G=zeros(endo_nbr+AuxiliaryVariables_nbr,exo_nbr);
|
||||||
H(endo_augm_id,endo_augm_id)=H1;
|
H(endo_augm_id,endo_augm_id)=H1;
|
||||||
|
@ -159,6 +200,7 @@ end
|
||||||
end
|
end
|
||||||
|
|
||||||
function [A00,A11,A22,A33,A44,A55,WW,Q,endo_nbr,exo_nbr,aux,endo_augm_id]=GetDennisMatrices(AAlag,AA0,AAlead,BB,bigw,instr_id)
|
function [A00,A11,A22,A33,A44,A55,WW,Q,endo_nbr,exo_nbr,aux,endo_augm_id]=GetDennisMatrices(AAlag,AA0,AAlead,BB,bigw,instr_id)
|
||||||
|
%get the matrices to use the Dennis (2007) algorithm
|
||||||
[eq_nbr,endo_nbr]=size(AAlag);
|
[eq_nbr,endo_nbr]=size(AAlag);
|
||||||
exo_nbr=size(BB,2);
|
exo_nbr=size(BB,2);
|
||||||
y=setdiff(1:endo_nbr,instr_id);
|
y=setdiff(1:endo_nbr,instr_id);
|
||||||
|
@ -211,7 +253,7 @@ end
|
||||||
|
|
||||||
function v = SylvesterHessenbergSchur(d,g,h)
|
function v = SylvesterHessenbergSchur(d,g,h)
|
||||||
%
|
%
|
||||||
% DSYLHS Solves a discrete time sylvester equation using the
|
% DSYLHS Solves a discrete time sylvester equation using the
|
||||||
% Hessenberg-Schur algorithm
|
% Hessenberg-Schur algorithm
|
||||||
%
|
%
|
||||||
% v = DSYLHS(g,d,h) computes the matrix v that satisfies the
|
% v = DSYLHS(g,d,h) computes the matrix v that satisfies the
|
||||||
|
|
|
@ -11,7 +11,7 @@ function planner_objective_value = evaluate_planner_objective(M,options,oo)
|
||||||
% SPECIAL REQUIREMENTS
|
% SPECIAL REQUIREMENTS
|
||||||
% none
|
% none
|
||||||
|
|
||||||
% Copyright (C) 2007-2012 Dynare Team
|
% Copyright (C) 2007-2015 Dynare Team
|
||||||
%
|
%
|
||||||
% This file is part of Dynare.
|
% This file is part of Dynare.
|
||||||
%
|
%
|
||||||
|
@ -29,19 +29,10 @@ function planner_objective_value = evaluate_planner_objective(M,options,oo)
|
||||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
dr = oo.dr;
|
dr = oo.dr;
|
||||||
endo_nbr = M.endo_nbr;
|
|
||||||
exo_nbr = M.exo_nbr;
|
exo_nbr = M.exo_nbr;
|
||||||
nstatic = M.nstatic;
|
nstatic = M.nstatic;
|
||||||
nspred = M.nspred;
|
nspred = M.nspred;
|
||||||
lead_lag_incidence = M.lead_lag_incidence;
|
|
||||||
beta = get_optimal_policy_discount_factor(M.params,M.param_names);
|
beta = get_optimal_policy_discount_factor(M.params,M.param_names);
|
||||||
if options.ramsey_policy
|
|
||||||
i_org = (1:M.orig_endo_nbr)';
|
|
||||||
else
|
|
||||||
i_org = (1:M.endo_nbr)';
|
|
||||||
end
|
|
||||||
ipred = find(lead_lag_incidence(M.maximum_lag,:))';
|
|
||||||
order_var = dr.order_var;
|
|
||||||
|
|
||||||
Gy = dr.ghx(nstatic+(1:nspred),:);
|
Gy = dr.ghx(nstatic+(1:nspred),:);
|
||||||
Gu = dr.ghu(nstatic+(1:nspred),:);
|
Gu = dr.ghu(nstatic+(1:nspred),:);
|
||||||
|
@ -51,11 +42,9 @@ gu(dr.order_var,:) = dr.ghu;
|
||||||
|
|
||||||
ys = oo.dr.ys;
|
ys = oo.dr.ys;
|
||||||
|
|
||||||
u = oo.exo_simul(1,:)';
|
|
||||||
|
|
||||||
[U,Uy,Uyy] = feval([M.fname '_objective_static'],ys,zeros(1,exo_nbr), ...
|
[U,Uy,Uyy] = feval([M.fname '_objective_static'],ys,zeros(1,exo_nbr), ...
|
||||||
M.params);
|
M.params);
|
||||||
|
%second order terms
|
||||||
Uyy = full(Uyy);
|
Uyy = full(Uyy);
|
||||||
|
|
||||||
[Uyygygy, err] = A_times_B_kronecker_C(Uyy,gy,gy,options.threads.kronecker.A_times_B_kronecker_C);
|
[Uyygygy, err] = A_times_B_kronecker_C(Uyy,gy,gy,options.threads.kronecker.A_times_B_kronecker_C);
|
||||||
|
@ -65,7 +54,7 @@ mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
[Uyygygu, err] = A_times_B_kronecker_C(Uyy,gy,gu,options.threads.kronecker.A_times_B_kronecker_C);
|
[Uyygygu, err] = A_times_B_kronecker_C(Uyy,gy,gu,options.threads.kronecker.A_times_B_kronecker_C);
|
||||||
mexErrCheck('A_times_B_kronecker_C', err);
|
mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
|
|
||||||
Wbar =U/(1-beta);
|
Wbar =U/(1-beta); %steady state welfare
|
||||||
Wy = Uy*gy/(eye(nspred)-beta*Gy);
|
Wy = Uy*gy/(eye(nspred)-beta*Gy);
|
||||||
Wu = Uy*gu+beta*Wy*Gu;
|
Wu = Uy*gu+beta*Wy*Gu;
|
||||||
Wyy = Uyygygy/(eye(nspred*nspred)-beta*kron(Gy,Gy));
|
Wyy = Uyygygy/(eye(nspred*nspred)-beta*kron(Gy,Gy));
|
||||||
|
@ -75,7 +64,7 @@ mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
mexErrCheck('A_times_B_kronecker_C', err);
|
mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
Wuu = Uyygugu+beta*Wyygugu;
|
Wuu = Uyygugu+beta*Wyygugu;
|
||||||
Wyu = Uyygygu+beta*Wyygygu;
|
Wyu = Uyygygu+beta*Wyygygu;
|
||||||
Wss = beta*Wuu*M.Sigma_e(:)/(1-beta);
|
Wss = beta*Wuu*M.Sigma_e(:)/(1-beta); % at period 0, we are in steady state, so the deviation term only starts in period 1, thus the beta in front
|
||||||
|
|
||||||
% initialize yhat1 at the steady state
|
% initialize yhat1 at the steady state
|
||||||
yhat1 = oo.steady_state;
|
yhat1 = oo.steady_state;
|
||||||
|
@ -92,7 +81,6 @@ if ~isempty(M.endo_histval)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
yhat1 = yhat1(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred)));
|
yhat1 = yhat1(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred)));
|
||||||
yhat2 = yhat2(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred)));
|
|
||||||
u = oo.exo_simul(1,:)';
|
u = oo.exo_simul(1,:)';
|
||||||
|
|
||||||
[Wyyyhatyhat1, err] = A_times_B_kronecker_C(Wyy,yhat1,yhat1,options.threads.kronecker.A_times_B_kronecker_C);
|
[Wyyyhatyhat1, err] = A_times_B_kronecker_C(Wyy,yhat1,yhat1,options.threads.kronecker.A_times_B_kronecker_C);
|
||||||
|
@ -104,6 +92,7 @@ mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
planner_objective_value(1) = Wbar+Wy*yhat1+Wu*u+Wyuyhatu1 ...
|
planner_objective_value(1) = Wbar+Wy*yhat1+Wu*u+Wyuyhatu1 ...
|
||||||
+ 0.5*(Wyyyhatyhat1 + Wuuuu+Wss);
|
+ 0.5*(Wyyyhatyhat1 + Wuuuu+Wss);
|
||||||
if options.ramsey_policy
|
if options.ramsey_policy
|
||||||
|
yhat2 = yhat2(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred)));
|
||||||
[Wyyyhatyhat2, err] = A_times_B_kronecker_C(Wyy,yhat2,yhat2,options.threads.kronecker.A_times_B_kronecker_C);
|
[Wyyyhatyhat2, err] = A_times_B_kronecker_C(Wyy,yhat2,yhat2,options.threads.kronecker.A_times_B_kronecker_C);
|
||||||
mexErrCheck('A_times_B_kronecker_C', err);
|
mexErrCheck('A_times_B_kronecker_C', err);
|
||||||
[Wyuyhatu2, err] = A_times_B_kronecker_C(Wyu,yhat2,u,options.threads.kronecker.A_times_B_kronecker_C);
|
[Wyuyhatu2, err] = A_times_B_kronecker_C(Wyu,yhat2,u,options.threads.kronecker.A_times_B_kronecker_C);
|
||||||
|
@ -115,9 +104,13 @@ end
|
||||||
if ~options.noprint
|
if ~options.noprint
|
||||||
skipline()
|
skipline()
|
||||||
disp('Approximated value of planner objective function')
|
disp('Approximated value of planner objective function')
|
||||||
disp([' - with initial Lagrange multipliers set to 0: ' ...
|
if options.ramsey_policy
|
||||||
|
disp([' - with initial Lagrange multipliers set to 0: ' ...
|
||||||
num2str(planner_objective_value(2)) ])
|
num2str(planner_objective_value(2)) ])
|
||||||
disp([' - with initial Lagrange multipliers set to steady state: ' ...
|
disp([' - with initial Lagrange multipliers set to steady state: ' ...
|
||||||
num2str(planner_objective_value(1)) ])
|
num2str(planner_objective_value(1)) ])
|
||||||
|
elseif options.discretionary_policy
|
||||||
|
fprintf('with discretionary policy: %10.8f',planner_objective_value(1))
|
||||||
|
end
|
||||||
skipline()
|
skipline()
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,6 +46,7 @@ MODFILES = \
|
||||||
optimal_policy/Ramsey/Gali_commitment.mod \
|
optimal_policy/Ramsey/Gali_commitment.mod \
|
||||||
optimal_policy/RamseyConstraints/test1.mod \
|
optimal_policy/RamseyConstraints/test1.mod \
|
||||||
discretionary_policy/dennis_1.mod \
|
discretionary_policy/dennis_1.mod \
|
||||||
|
discretionary_policy/Gali_discretion.mod \
|
||||||
initval_file/ramst_initval_file.mod \
|
initval_file/ramst_initval_file.mod \
|
||||||
ramst_normcdf_and_friends.mod \
|
ramst_normcdf_and_friends.mod \
|
||||||
ramst_vec.mod \
|
ramst_vec.mod \
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* This file implements the baseline New Keynesian model of Jordi Galí (2008): Monetary Policy, Inflation,
|
||||||
|
* and the Business Cycle, Princeton University Press, Chapter 5
|
||||||
|
*
|
||||||
|
* This implementation was written by Johannes Pfeifer.
|
||||||
|
*
|
||||||
|
* Please note that the following copyright notice only applies to this Dynare
|
||||||
|
* implementation of the model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-15 Johannes Pfeifer
|
||||||
|
*
|
||||||
|
* This 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.
|
||||||
|
*
|
||||||
|
* It 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.
|
||||||
|
*
|
||||||
|
* For a copy of the GNU General Public License,
|
||||||
|
* see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
var pi
|
||||||
|
y_gap
|
||||||
|
r_e
|
||||||
|
y_e
|
||||||
|
r_nat
|
||||||
|
i
|
||||||
|
u
|
||||||
|
a
|
||||||
|
p
|
||||||
|
;
|
||||||
|
|
||||||
|
varexo eps_a
|
||||||
|
eps_u;
|
||||||
|
|
||||||
|
parameters alppha
|
||||||
|
betta
|
||||||
|
rho_a
|
||||||
|
rho_u
|
||||||
|
siggma
|
||||||
|
phi
|
||||||
|
phi_y
|
||||||
|
eta
|
||||||
|
epsilon
|
||||||
|
theta
|
||||||
|
;
|
||||||
|
%----------------------------------------------------------------
|
||||||
|
% Parametrization, p. 52
|
||||||
|
%----------------------------------------------------------------
|
||||||
|
siggma = 1;
|
||||||
|
phi=1;
|
||||||
|
phi_y = .5/4;
|
||||||
|
theta=2/3;
|
||||||
|
rho_u = 0;
|
||||||
|
rho_a = 0.9;
|
||||||
|
betta = 0.99;
|
||||||
|
eta =4;
|
||||||
|
alppha=1/3;
|
||||||
|
epsilon=6;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%----------------------------------------------------------------
|
||||||
|
% First Order Conditions
|
||||||
|
%----------------------------------------------------------------
|
||||||
|
|
||||||
|
model(linear);
|
||||||
|
//Composite parameters
|
||||||
|
#Omega=(1-alppha)/(1-alppha+alppha*epsilon); //defined on page 47
|
||||||
|
#psi_n_ya=(1+phi)/(siggma*(1-alppha)+phi+alppha); //defined on page 48
|
||||||
|
#lambda=(1-theta)*(1-betta*theta)/theta*Omega; //defined on page 47
|
||||||
|
#kappa=lambda*(siggma+(phi+alppha)/(1-alppha)); //defined on page 49
|
||||||
|
#alpha_x=kappa/epsilon; //defined on page 96
|
||||||
|
#phi_pi=(1-rho_u)*kappa*siggma/(alpha_x)+rho_u; //defined on page 101
|
||||||
|
|
||||||
|
r_e=siggma*(y_e(+1)-y_e);
|
||||||
|
y_e=psi_n_ya*a;
|
||||||
|
pi=betta*pi(+1)+kappa*y_gap + u;
|
||||||
|
y_gap=-1/siggma*(i-pi(+1)-r_e)+y_gap(+1);
|
||||||
|
//3. Interest Rate Rule eq. (25)
|
||||||
|
% i=r_e+phi_pi*pi;
|
||||||
|
|
||||||
|
r_nat=siggma*psi_n_ya*(a(+1)-a);
|
||||||
|
u=rho_u*u(-1)+eps_u;
|
||||||
|
a=rho_a*a(-1)+eps_a;
|
||||||
|
|
||||||
|
pi=p-p(-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
%----------------------------------------------------------------
|
||||||
|
% define shock variances
|
||||||
|
%---------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
shocks;
|
||||||
|
var eps_u = 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
planner_objective pi^2 +(((1-theta)*(1-betta*theta)/theta*((1-alppha)/(1-alppha+alppha*epsilon)))*(siggma+(phi+alppha)/(1-alppha)))/epsilon*y_gap^2;
|
||||||
|
|
||||||
|
discretionary_policy(instruments=(i),irf=20,planner_discount=betta,discretionary_tol=1e-12) y_gap pi p u;
|
||||||
|
|
||||||
|
verbatim;
|
||||||
|
%% Check correctness
|
||||||
|
Omega=(1-alppha)/(1-alppha+alppha*epsilon); %defined on page 47
|
||||||
|
lambda=(1-theta)*(1-betta*theta)/theta*Omega; %defined on page 47
|
||||||
|
kappa=lambda*(siggma+(phi+alppha)/(1-alppha)); %defined on page 49
|
||||||
|
alpha_x=kappa/epsilon; %defined on page 96
|
||||||
|
Psi=1/(kappa^2+alpha_x*(1-betta*rho_u)); %defined on page 99
|
||||||
|
Psi_i=Psi*(kappa*siggma*(1-rho_u)+alpha_x*rho_u); %defined on page 101
|
||||||
|
phi_pi=(1-rho_u)*kappa*siggma/(alpha_x)+rho_u; %defined on page 101
|
||||||
|
|
||||||
|
%Compute theoretical solution
|
||||||
|
var_pi_theoretical=(alpha_x*Psi)^2; %equation (6), p.99
|
||||||
|
var_y_gap_theoretical=(-kappa*Psi)^2; %equation (7), p.99
|
||||||
|
|
||||||
|
pi_pos=strmatch('pi',var_list_,'exact');
|
||||||
|
y_gap_pos=strmatch('y_gap',var_list_,'exact');
|
||||||
|
if abs(oo_.var(pi_pos,pi_pos)-var_pi_theoretical)>1e-10 || abs(oo_.var(y_gap_pos,y_gap_pos)-var_y_gap_theoretical)>1e-10
|
||||||
|
error('Variances under optimal policy are wrong')
|
||||||
|
end
|
||||||
|
|
||||||
|
%Compute theoretical objective function
|
||||||
|
V=betta/(1-betta)*(var_pi_theoretical+alpha_x*var_y_gap_theoretical); %evaluate at steady state in first period
|
||||||
|
|
||||||
|
if abs(V-oo_.planner_objective_value)>1e-10
|
||||||
|
error('Computed welfare deviates from theoretical welfare')
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
%% repeat exercise with initial shock of 1 to check whether planner objective is correctly specified
|
||||||
|
initval;
|
||||||
|
eps_u = 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
%Compute theoretical objective function
|
||||||
|
V=var_pi_theoretical+alpha_x*var_y_gap_theoretical+ betta/(1-betta)*(var_pi_theoretical+alpha_x*var_y_gap_theoretical); %evaluate at steady state in first period
|
||||||
|
|
||||||
|
discretionary_policy(instruments=(i),irf=20,discretionary_tol=1e-12,planner_discount=betta) y_gap pi p u;
|
||||||
|
if abs(V-oo_.planner_objective_value)>1e-10
|
||||||
|
error('Computed welfare deviates from theoretical welfare')
|
||||||
|
end
|
|
@ -19,7 +19,7 @@ y = y(+1) -(omega/sigma)*(i-pi(+1))+g;
|
||||||
pi = beta*pi(+1)+kappa*y+u;
|
pi = beta*pi(+1)+kappa*y+u;
|
||||||
pi_c = pi+(alpha/(1-alpha))*(q-q(-1));
|
pi_c = pi+(alpha/(1-alpha))*(q-q(-1));
|
||||||
q = q(+1)-(1-alpha)*(i-pi(+1))+(1-alpha)*e;
|
q = q(+1)-(1-alpha)*(i-pi(+1))+(1-alpha)*e;
|
||||||
i = 1.5*pi;
|
% i = 1.5*pi;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
shocks;
|
shocks;
|
||||||
|
@ -29,6 +29,5 @@ var e; stderr 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
planner_objective pi_c^2 + y^2;
|
planner_objective pi_c^2 + y^2;
|
||||||
|
discretionary_policy(instruments=(i),irf=0,planner_discount=beta);
|
||||||
discretionary_policy(instruments=(i),irf=0,qz_criterium=0.999999);
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue