-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrecsSolveREESP.m
154 lines (140 loc) · 4.99 KB
/
recsSolveREESP.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
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
function [interp,X,exitflag,output] = recsSolveREESP(model,interp,X,options)
% RECSSOLVEREESP
% Copyright (C) 2011-2016 Christophe Gouel
% Licensed under the Expat license, see LICENSE.txt
%% Initialization
defaultopt = struct( ...
'ArrayProblem' , false ,...
'eqsolver' , 'lmmcp' ,...
'eqsolveroptions' , struct('atol' , sqrt(eps),...
'Diagnostics' , 'off' ,...
'DerivativeCheck', 'off' ,...
'Jacobian' , 'on' ,...
'maxit' , 1000) ,...
'extrapolate' , 1 ,...
'Display' , 'iter' ,...
'loop_over_s' , 0 ,...
'funapprox' , 'resapprox' ,...
'UseParallel' , 'always');
if nargin <4
options = defaultopt;
else
if isfield(options,'eqsolveroptions')
options.eqsolveroptions = catstruct(defaultopt.eqsolveroptions,options.eqsolveroptions);
end
options = catstruct(options,struct('funapprox','resapprox'));
options = catstruct(defaultopt,options);
end
Display = options.Display;
switch lower(Display)
case 'iter'
showiters = 1;
case {'off','none'}
showiters = 0;
end
atol = options.eqsolveroptions.atol;
maxit = options.eqsolveroptions.maxit;
extrapolate = options.extrapolate;
% Extract fields of model
nperiods = model.nperiods;
params = model.params;
shocks = model.shocks;
functions = model.functions;
ixforward = cell(nperiods,1);
for i=1:nperiods, ixforward{i} = model.infos(i).ixforward; end
% Extract fields of interp
if nargin<=2 || isempty(X), X = interp.X; end
s = interp.s;
fspace = interp.fspace;
Phi = interp.Phi;
if ~isfield(interp,'cX')
cX = cellfun(@funfitxy,fspace,Phi,X,'UniformOutput', false);
else
cX = interp.cX;
end
cnrm = 1;
it = 0;
vec = @(x) cell2mat(cellfun(@(z) z(:),x,'UniformOutput',false));
inext = @(iperiod) (iperiod+1)*(iperiod<nperiods)+1*(iperiod==nperiods);
exitEQ = zeros(nperiods,1);
%% Solve for the rational expectations equilibrium
if showiters
fprintf(1,'Successive approximation\n');
fprintf(1,' Iter\tResidual\n');
end
while(cnrm > atol && it < maxit)
it = it+1;
cXold = cX;
for i=nperiods:-1:1
[LB,UB] = functions(i).b(s{i},params);
[X{i},~,exitEQ(i)] = recsSolveEquilibrium(s{i},X{i},...
zeros(size(s{i},1),0),...
functions(inext(i)).b,...
functions(i).f,...
functions(i).g,...
functions(i).h,...
params,...
cX{inext(i)}(:,ixforward{i}),...
shocks{inext(i)}.e,shocks{inext(i)}.w,...
fspace{inext(i)},...
ixforward{i},...
options,LB,UB);
cX{i} = funfitxy(fspace{i},Phi{i},X{i});
end % for i=nperiods:-1:1
cnrm = norm(vec(cX)-vec(cXold));
if showiters, fprintf(1,'%7i\t%8.2E\n',it,cnrm); end
end % while(cnrm > atol && it < maxit)
%% Output treatment
% Check if state satisfies bounds
output = struct();
output.snextmin = cell(nperiods,1);
output.snextmax = cell(nperiods,1);
for i=1:nperiods
si = s{i};
xi = X{i};
ei = shocks{inext(i)}.e;
n = size(si,1);
k = size(ei,1);
ind = (1:n);
ind = ind(ones(1,k),:);
ss = si(ind,:);
ee = ei(repmat(1:k,1,n),:);
xx = xi(ind,:);
snext = functions(i).g(ss,xx,ee,params);
output.snextmin{i} = min(snext);
output.snextmax{i} = max(snext);
if extrapolate==2 || extrapolate==-1
vari = 1:fspace{inext(i)}.d;
varmin = vari(min(snext)<fspace{inext(i)}.a);
varmax = vari(max(snext)>fspace{inext(i)}.b);
if ~isempty(varmin)
warning('RECS:Extrapolation','State variables (%s) in subperiod %i beyond smin',...
int2str(varmin),inext(i))
end
if ~isempty(varmax)
warning('RECS:Extrapolation','State variables (%s) in subperiod %i beyond smax',...
int2str(varmax),inext(i))
end
end
end % for i=1:nperiods
% exitflag
if it==maxit
exitflag = 0;
if showiters
warning('RECS:FailureREE','Failure to find a rational expectations equilibrium');
fprintf(1,'Too many iterations\n');
end
else
if all(exitEQ)
exitflag = 1;
if showiters
fprintf(1,'Solution found - Residual lower than absolute tolerance\n');
end
else
exitflag = 0;
warning('RECS:FailureREE','Failure to find a rational expectations equilibrium');
end
end
% interp
interp.cX = cX;
interp.X = X;