Skip to content

Commit e8ef1ce

Browse files
committed
expasset for inf horz
1 parent 1305b6f commit e8ef1ce

9 files changed

+967
-94
lines changed

ReturnFnMatrix/ReturnFnParamNamesFn.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
% Remove d2
4343
l_d=l_d-vfoptions.refine_d(2);
4444
end
45+
if isfield(vfoptions,'endotype')
46+
if max(vfoptions.endotype)==1
47+
l_aprime=l_aprime-sum(vfoptions.endotype); % Some of the endogenous states is an endogenous type, so it won't appear at this
48+
l_a=l_a-sum(vfoptions.endotype); % Some of the endogenous states is an endogenous type, so it won't appear at this
49+
l_z=l_z+sum(vfoptions.endotype); % The variables after z is the endogenous types
50+
end
51+
end
52+
4553
% Figure out ReturnFnParamNames from ReturnFn
4654
temp=getAnonymousFnInputNames(ReturnFn);
4755
if length(temp)>(l_d+l_aprime+l_a+l_z+l_e) % This is largely pointless, the ReturnFn is always going to have some parameters

ValueFnIter/FHorz/ExperienceAsset/ValueFnIter_Case1_FHorz_ExpAsset_nod1_e_raw.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@
6868
[a2primeIndex,a2primeProbs]=CreateExperienceAssetFnMatrix_Case1(aprimeFn, n_d2, n_a2, d2_grid, a2_grid, aprimeFnParamsVec,2); % Note, is actually aprime_grid (but a_grid is anyway same for all ages)
6969
% Note: aprimeIndex is [N_d2,N_a2], whereas aprimeProbs is [N_d2,N_a2]
7070

71-
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
72-
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
71+
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
72+
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
7373
aprimeProbs=repmat(a2primeProbs,N_a1,1,N_z); % [N_d2*N_a1,N_a2,N_z]
7474

7575
Vnext=sum(shiftdim(pi_e_J(:,N_j),-2).*reshape(vfoptions.V_Jplus1,[N_a,N_z,N_e]),3); % Expectations over e
@@ -156,8 +156,8 @@
156156
[a2primeIndex,a2primeProbs]=CreateExperienceAssetFnMatrix_Case1(aprimeFn, n_d2, n_a2, d2_grid, a2_grid, aprimeFnParamsVec,2); % Note, is actually aprime_grid (but a_grid is anyway same for all ages)
157157
% Note: aprimeIndex is [N_d2,N_a2], whereas aprimeProbs is [N_d2,N_a2]
158158

159-
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
160-
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
159+
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
160+
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
161161
aprimeProbs=repmat(a2primeProbs,N_a1,1,N_z); % [N_d2*N_a1,N_a2,N_z]
162162

163163
Vnext=sum(V(:,:,:,jj+1).*shfitdim(pi_e_J(:,jj),-2),3);

ValueFnIter/FHorz/ExperienceAsset/ValueFnIter_Case1_FHorz_ExpAsset_raw.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@
124124
[a2primeIndex,a2primeProbs]=CreateExperienceAssetFnMatrix_Case1(aprimeFn, n_d2, n_a2, d2_grid, a2_grid, aprimeFnParamsVec,2); % Note, is actually aprime_grid (but a_grid is anyway same for all ages)
125125
% Note: aprimeIndex is [N_d2,N_a2], whereas aprimeProbs is [N_d2,N_a2]
126126

127-
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
128-
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2,N_u)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
127+
aprimeIndex=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex-1,N_a1,1,1); % [N_d2*N_a1,N_a2]
128+
aprimeplus1Index=repelem((1:1:N_a1)',N_d2,N_a2)+N_a1*repmat(a2primeIndex,N_a1,1,1); % [N_d2*N_a1,N_a2]
129129
aprimeProbs=repmat(a2primeProbs,N_a1,1,N_z); % [N_d2*N_a1,N_a2,N_z]
130130

131131
Vlower=reshape(V(aprimeIndex(:),:,jj+1),[N_d2*N_a1,N_a2,N_z]);

ValueFnIter/InfHorz/DivideConquer/ValueFnIter_DC1_nod_raw.m

Lines changed: 117 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,149 @@
1-
function [VKron, Policy]=ValueFnIter_Case1_NoD_Par2_raw(VKron, n_a, n_z, pi_z, DiscountFactorParamsVec, ReturnMatrix, Howards,Howards2,Tolerance,maxiter) % Verbose, a_grid, z_grid,
2-
%Does pretty much exactly the same as ValueFnIter_Case1, only without any decision variable (n_d=0)
1+
function [VKron, Policy]=ValueFnIter_DC1_nod_raw(V0, n_a, n_z, a_grid, z_gridvals, pi_z, ReturnFn, DiscountFactorParamsVec, ReturnFnParamsVec, vfoptions)
32

43
N_a=prod(n_a);
54
N_z=prod(n_z);
65

7-
% PolicyIndexes=zeros(N_a,N_z,'gpuArray');
8-
% Ftemp=zeros(N_a,N_z,'gpuArray');
6+
% n-Monotonicity
7+
% vfoptions.level1n=11;
8+
level1ii=round(linspace(1,n_a,vfoptions.level1n));
9+
level1iidiff=level1ii(2:end)-level1ii(1:end-1)-1;
910

11+
%% Start by setting up ReturnFn for the first-level (as we can reuse this every iteration)
12+
ReturnMatrixLvl1=CreateReturnFnMatrix_Case1_Disc_DC1_nod_Par2(ReturnFn, n_z, a_grid, a_grid(level1ii), z_gridvals, ReturnFnParamsVec, 1);
13+
14+
V=reshape(V0,[N_a,N_z]);
15+
Policy=zeros(N_a,N_z,'gpuArray');
16+
17+
% for Howards, preallocate
18+
Ftemp=zeros(N_a,N_z,'gpuArray');
19+
% and we need
1020
bbb=reshape(shiftdim(pi_z,-1),[1,N_z*N_z]);
1121
ccc=kron(ones(N_a,1,'gpuArray'),bbb);
1222
aaa=reshape(ccc,[N_a*N_z,N_z]);
1323

14-
addindexforaz=gpuArray(N_a*(0:1:N_a-1)'+N_a*N_a*(0:1:N_z-1));
24+
% precompute
25+
Epi_z=shiftdim(pi_z',-1); % pi_z in the form we need it to compute the expectations
26+
27+
% I want the print that tells you distance to have number of decimal points corresponding to vfoptions.tolerance
28+
distvstolstr=['ValueFnIter: after %i iterations the dist is %4.',num2str(-round(log10(vfoptions.tolerance))),'f \n'];
1529

1630
%%
17-
tempcounter=1;
1831
currdist=Inf;
19-
while currdist>Tolerance && tempcounter<=maxiter
20-
VKronold=VKron;
32+
tempcounter=1;
33+
while currdist>vfoptions.tolerance && tempcounter<=vfoptions.maxiter
34+
35+
Vold=V;
2136

2237
%Calc the condl expectation term (except beta), which depends on z but not on control variables
23-
EV=VKronold.*shiftdim(pi_z',-1); %kron(ones(N_a,1),pi_z(z_c,:));
38+
EV=Vold.*Epi_z;
2439
EV(isnan(EV))=0; %multilications of -Inf with 0 gives NaN, this replaces them with zeros (as the zeros come from the transition probabilites)
2540
EV=sum(EV,2); % sum over z', leaving a singular second dimension
2641

27-
entireRHS=ReturnMatrix+DiscountFactorParamsVec*EV; %aprime by a by z
42+
DiscountedEV=DiscountFactorParamsVec*reshape(EV,[N_a,1,N_z]);
43+
44+
%% Level 1
45+
% We can just reuse ReturnMatrixLvl1
46+
entireRHS_ii=ReturnMatrixLvl1+DiscountedEV;
47+
48+
% First, we want aprime conditional on (1,a,z)
49+
[Vtempii,maxindex1]=max(entireRHS_ii,[],2);
50+
51+
% Store
52+
% curraindex=level1ii';
53+
V(level1ii,:)=shiftdim(Vtempii,1);
54+
Policy(level1ii,:)=shiftdim(maxindex1,1);
55+
56+
% Need to keep Ftemp for Howards policy iteration improvement
57+
Ftemp(level1ii,:)=ReturnMatrixLvl1(shiftdim(maxindex1,1)+N_a*(0:1:vfoptions.level1n-1)'+N_a*vfoptions.level1n*(0:1:N_z-1));
58+
59+
% Attempt for improved version
60+
maxgap=squeeze(max(maxindex1(1,2:end,:)-maxindex1(1,1:end-1,:),[],3));
61+
for ii=1:(vfoptions.level1n-1)
62+
curraindex=(level1ii(ii)+1:1:level1ii(ii+1)-1)';
63+
if maxgap(ii)>0
64+
loweredge=min(maxindex1(1,ii,:),N_a-maxgap(ii)); % maxindex(ii,:), but avoid going off top of grid when we add maxgap(ii) points
65+
% loweredge is 1-by-1-by-n_z
66+
aprimeindexes=loweredge+(0:1:maxgap(ii));
67+
% aprime possibilities are maxgap(ii)+1-by-1-by-n_z
68+
ReturnMatrix_ii=CreateReturnFnMatrix_Case1_Disc_DC1_nod_Par2(ReturnFn, n_z, a_grid(aprimeindexes), a_grid(level1ii(ii)+1:level1ii(ii+1)-1), z_gridvals, ReturnFnParamsVec,2);
69+
aprimez=repelem(aprimeindexes-1,1,level1iidiff(ii),1)+N_a*shiftdim((0:1:N_z-1),-1); % the current aprimeii(ii):aprimeii(ii+1)
70+
entireRHS_ii=ReturnMatrix_ii+DiscountedentireEV(reshape(aprimez,[(maxgap(ii)+1),level1iidiff(ii),N_z]));
71+
[Vtempii,maxindex]=max(entireRHS_ii,[],1);
72+
V(curraindex,:)=shiftdim(Vtempii,1);
73+
% the a1prime is relative to loweredge(allind), need to 'add' the loweredge
74+
zind=shiftdim((0:1:N_z-1),-1); % already includes -1
75+
Policy(curraindex,:)=shiftdim(maxindex+N_d*(loweredge(zind)-1),1);
76+
77+
% Need to keep Ftemp for Howards policy iteration improvement
78+
Ftemp(curraindex,:)=ReturnMatrix_ii(shiftdim(maxindex,1)+(maxgap(ii)+1)*(0:1:level1iidiff(ii)-1)'+(maxgap(ii)+1)*level1iidiff(ii)*(0:1:N_z-1));
79+
80+
else
81+
loweredge=maxindex1(:,1,ii,:);
82+
% Just use aprime(ii) for everything
83+
ReturnMatrix_ii=CreateReturnFnMatrix_Case1_Disc_DC1_nod_Par2(ReturnFn, n_z, a_grid(loweredge), a_grid(level1ii(ii)+1:level1ii(ii+1)-1), z_gridvals, ReturnFnParamsVec,2);
84+
aprimez=repelem(loweredge-1,1,level1iidiff(ii),1)+N_a*shiftdim((0:1:N_z-1),-1); % the current aprimeii(ii):aprimeii(ii+1)
85+
entireRHS_ii=ReturnMatrix_ii+DiscountedentireEV(reshape(aprimez,[1,level1iidiff(ii),N_z]));
86+
[Vtempii,maxindex]=max(entireRHS_ii,[],1);
87+
V(curraindex,:)=shiftdim(Vtempii,1);
88+
% the aprime is relative to loweredge(allind), need to 'add' the loweredge
89+
zind=shiftdim((0:1:N_z-1),-1); % already includes -1
90+
Policy(curraindex,:)=shiftdim(maxindex+N_d*(loweredge(zind)-1),1);
91+
92+
% Need to keep Ftemp for Howards policy iteration improvement
93+
Ftemp(curraindex,:)=ReturnMatrix_ii(shiftdim(maxindex,1)+(0:1:level1iidiff(ii)-1)'+level1iidiff(ii)*(0:1:N_z-1));
2894

29-
%Calc the max and it's index
30-
[VKron,PolicyIndexes]=max(entireRHS,[],1);
31-
32-
tempmaxindex=shiftdim(PolicyIndexes,1)+addindexforaz; % aprime index, add the index for a and z
33-
34-
Ftemp=reshape(ReturnMatrix(tempmaxindex),[N_a,N_z]); % keep return function of optimal policy for using in Howards
95+
end
96+
end
3597

36-
PolicyIndexes=PolicyIndexes(:); % a by z (this shape is just convenient for Howards)
37-
VKron=shiftdim(VKron,1); % a by z
98+
%% Finish up
99+
% Update currdist
100+
Vdist=V(:)-Vold(:);
101+
Vdist(isnan(Vdist))=0;
102+
currdist=max(abs(Vdist));
38103

39-
VKrondist=VKron(:)-VKronold(:);
40-
VKrondist(isnan(VKrondist))=0;
41-
currdist=max(abs(VKrondist));
42-
43-
% Use Howards Policy Fn Iteration Improvement (except for first few and last few iterations, as it is not a good idea there)
44-
if isfinite(currdist) && currdist/Tolerance>10 && tempcounter<Howards2
45-
for Howards_counter=1:Howards
46-
EVKrontemp=VKron(PolicyIndexes,:);
104+
if isfinite(currdist) && currdist/vfoptions.tolerance>10 && tempcounter<vfoptions.maxhowards % Use Howards Policy Fn Iteration Improvement
105+
Policy_Vind=Policy(:);
106+
for Howards_counter=1:vfoptions.howards
107+
EVKrontemp=V(Policy_Vind,:);
47108
EVKrontemp=EVKrontemp.*aaa;
48109
EVKrontemp(isnan(EVKrontemp))=0;
49-
EVKrontemp=reshape(sum(EVKrontemp,2),[N_a,N_z]);
50-
VKron=Ftemp+DiscountFactorParamsVec*EVKrontemp;
110+
EVKrontemp=sum(EVKrontemp,2);
111+
V=Ftemp+DiscountFactorParamsVec*reshape(EVKrontemp,[N_a,N_z]);
112+
end
113+
end
114+
115+
if vfoptions.verbose==1
116+
if rem(tempcounter,10)==0 % Every 10 iterations
117+
fprintf(distvstolstr, tempcounter,currdist) % use enough decimal points to be able to see countdown of currdist to 0
51118
end
52119
end
53120

54121
tempcounter=tempcounter+1;
122+
end
123+
55124

125+
126+
127+
%% Cleaning up the output
128+
if vfoptions.outputkron==0
129+
V=reshape(V,[n_a,n_z]);
130+
Policy=UnKronPolicyIndexes_Case1(Policy, 0, n_a, n_z,vfoptions);
131+
else
132+
return
56133
end
57134

58-
Policy=reshape(PolicyIndexes,[N_a,N_z]);
135+
if vfoptions.polindorval==2
136+
Policy=PolicyInd2Val_Case1(Policy,0,n_a,n_z,d_grid, a_grid);
137+
end
138+
139+
% Sometimes numerical rounding errors (of the order of 10^(-16) can mean
140+
% that Policy is not integer valued. The following corrects this by converting to int64 and then
141+
% makes the output back into double as Matlab otherwise cannot use it in
142+
% any arithmetical expressions.
143+
if vfoptions.policy_forceintegertype==1
144+
Policy=uint64(Policy);
145+
Policy=double(Policy);
146+
end
59147

60148

61149

0 commit comments

Comments
 (0)