-
Notifications
You must be signed in to change notification settings - Fork 5
/
recsSolveDeterministicPb.m
127 lines (109 loc) · 4.87 KB
/
recsSolveDeterministicPb.m
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
function [x,s,z,F,exitflag,N] = recsSolveDeterministicPb(model,s0,T,xss,zss,sss,options)
% RECSSOLVEDETERMINISTICPB Solves a perfect foresight problem
%
% X = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS) tries to find the perfect
% foresight solution of the model defined in the object MODEL. The initial
% values of state variable are provided by the 1-by-d vector S0. Time horizon
% (number of periods) is given by the integer T. XSS, ZSS and SSS are,
% respectively, a 1-by-m vector containing the values of response variables at the
% deterministic steady state, a 1-by-p vector containing the values of expectations
% variables at steady state, and a 1-by-d vector containing the values of the state
% variables at steady state. RECSSOLVEDETERMINISTICPB returns X, a T-by-m matrix,
% the value of response variables over the time horizon.
%
% X = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,OPTIONS) solves the problem with the
% parameters defined by the structure OPTIONS. The fields of the structure are
% eqsolver : 'fsolve', 'lmmcp' (default), 'ncpsolve' or 'path'
% eqsolveroptions : options structure to be passed to eqsolver (default:
% empty structure)
%
% [X,S] = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,...) returns S, a T-by-d
% matrix, containing the value of state variables over the time horizon.
%
% [X,S,Z] = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,...) returns Z, a
% T-by-p matrix, containing the value of expectations variables over the time
% horizon.
%
% [X,S,Z,F] = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,...) returns F, a
% T-by-m matrix, containing the values of equilibrium equations over the time
% horizon.
%
% [X,S,Z,F,EXITFLAG] = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,...)
%
% [X,S,Z,F,EXITFLAG,N] = RECSSOLVEDETERMINISTICPB(MODEL,S0,T,XSS,ZSS,SSS,...)
%
% See also RECSFIRSTGUESS, RECSSOLVEREE, RECSSS, SCP.
% Copyright (C) 2011-2016 Christophe Gouel
% Licensed under the Expat license, see LICENSE.txt
%% Initialization
defaultopt = struct( ...
'checkfinalstate' , 0 ,...
'eqsolver' , 'lmmcp' ,...
'eqsolveroptions' , struct('Diagnostics' , 'off' ,...
'DerivativeCheck', 'off' ,...
'Jacobian' , 'on'));
if nargin <=6
options = defaultopt;
else
if isfield(options,'eqsolveroptions')
options.eqsolveroptions = catstruct(defaultopt.eqsolveroptions,options.eqsolveroptions);
end
options = catstruct(defaultopt,options);
end
eqsolver = lower(options.eqsolver);
eqsolveroptions = options.eqsolveroptions;
[d,m,p] = model.dim{1:3};
n = T*(m+p+d);
e = repmat(model.shocks.w'*model.shocks.e,T,1);
fp = model.functions.fp;
gp = model.functions.gp;
hp = model.functions.hp;
params = model.params;
nx = model.infos.nxvarbounds;
M = m+sum(nx);
n = n+T*sum(nx);
w = zeros(1,nx(1));
v = zeros(1,nx(2));
[LBx,UBx] = model.functions.bp(sss,params);
LB = [LBx -inf(1,p+d)];
UB = [UBx +inf(1,p+d)];
LB = reshape(LB(ones(T,1),:)',n,1);
UB = reshape(UB(ones(T,1),:)',n,1);
X = [xss w v zss sss];
X = X(ones(T,1),:)';
X = reshape(X,n,1);
%% Number of nonzero elements in the Jacobian
IM = structfun(@(X) sum(X(:)),...
model.infos.IncidenceMatrices,'UniformOutput',false);
nnzJac = T*(IM.fx+2*(IM.lbs+IM.ubs)+IM.fz+IM.hx+p+IM.hsnext+IM.gx+d)+... % Main diagonal blocks
(T-1)*(IM.fs+IM.lbs+IM.ubs+IM.hs+IM.gs)+... % Subdiagonal blocks
(T-1)*IM.hxnext; % Superdiagonal blocks
eqsolveroptions.nnzJ = nnzJac;
%% Solve deterministic problem
% Precalculation of indexes for the sparse Jacobian
tmp = zeros(M+p+d,M+p+d,T);
[~,grid] = blktridiag(tmp,tmp(:,:,1:end-1),tmp(:,:,1:end-1));
SCPSubProblem = @(X0,S0) runeqsolver(@recsDeterministicPb,X0,LB,UB,eqsolver, ...
eqsolveroptions,fp,gp,hp,S0,xss,p,e, ...
params,nx,grid);
% Simple continuation problem applied on a Newton solve
[X,F,exitflag,N] = SCP(X,s0,sss,SCPSubProblem,1);
if exitflag~=1
warning('RECS:FailureDeterministic',...
'Failure to find the perfect foresight solution');
end
%% Prepare output
X = reshape(X,M+p+d,T)';
x = X(:,1:m);
z = X(:,(M+1):(M+p));
s = [s0; X(1:end-1,(M+p+1):(M+p+d))];
if ~isempty(F), F = reshape(F,M+p+d,T)'; end
%% Check is the final state is self-replicating (meaning that sT=sss and xT=xss)
if options.checkfinalstate
deltafinal = max(abs([s(end,:)-sss x(end,:)-xss]));
if deltafinal>sqrt(eps)
warning('RECS:FinalState',...
'Final state is not self-replicating (max(|delta|)=%g)',...
deltafinal);
end
end