I’m testing the new grid interpolation feature of the toolkit in a model with a “d” variable (really happy about this addition to the toolkit ) and I found some bugs. The code is available in the online repo: GitHub - aledinola/PijoanMasTaxes: Aiyagari model with endogenous labor (as in Pijoan-Mas 2006), with VFI toolkit
These are my basic settings for VFI options:
vfoptions=struct();
vfoptions.lowmemory = 0;
vfoptions.verbose = 0;
vfoptions.tolerance = 1e-6;
vfoptions.maxiter = 500;
vfoptions.howards = 80;
vfoptions.maxhowards = 500;
vfoptions.howardsgreedy = 0;
CASE 1
Without grid interpolation, all is good and I get these results (in partial equilibrium with HA maxiter=0):
Time VFI (seconds): 0.39
PARAMETERS
crra (Coeff of risk aversion) : 1.458000
nu (Curvature labor utility) : 2.833000
lambda (Weight of labor in disutil) : 0.856000
beta (Discount factor) : 0.945000
theta (Labor share in Cobb-Douglas) : 0.640000
delta (Capital depreciation rate) : 0.083000
lambda_hsv : 1.000000
tau_hsv : 0.000000
------------------------------------
GENERAL EQUILIBRIUM PRICES
K_to_L : 5.534500
r : 0.037429
w : 1.184918
------------------------------------
MOMENTS
Corr(h,z) : NaN
CV(h) : 0.205128
Hours : 0.354671
K/Y : 3.013323
w*L/Y : 0.637126
I/Y : 0.250106
------------------------------------
CV
CV(Hours) : 0.205128
CV(Earnings): 0.636984
CV(Income) : 0.624952
CV(Wealth) : 1.364293
------------------------------------
GINI
Gini(Hours) : 0.106121
Gini(Earnings): 0.322589
Gini(Income) : 0.311692
Gini(Wealth) : 0.646641
------------------------------------
CORR
corr(Hours,z) : NaN
corr(Wealth,z): NaN
------------------------------------
SHARES EARNINGS
q1 earnings: 0.074485
q2 earnings: 0.124297
q3 earnings: 0.173624
q4 earnings: 0.229642
q5 earnings: 0.397952
------------------------------------
SHARES WEALTH
q1 wealth: 0.000706
q2 wealth: 0.021652
q3 wealth: 0.092324
q4 wealth: 0.232139
q5 wealth: 0.653179
CASE 2
Now I set vfoptions.gridinterplayer=1;
but I forget to set ngridinterp
. I get this error:
Error using ValueFnIter_Case1 (line 71)
When using vfoptions.gridinterplayer=1 you must set vfoptions.gridinterplayer
The error message has a typo: it should read you must set vfoptions.ngridinterp
CASE 3
Now I remember to set both options:
vfoptions.gridinterplayer = 1;
vfoptions.ngridinterp = 15;
but I get this new error message:
Error using gpuArray/reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the
appropriate size for that dimension.
Error in PolicyInd2Val_Case1 (line 202)
Policy=reshape(Policy,[l_d+l_aprime,N_a*N_z]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in EvalFnOnAgentDist_AggVars_Case1 (line 156)
PolicyValues=PolicyInd2Val_Case1(Policy,n_d,n_a,n_z,d_grid,a_grid,simoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1_subfn (line 56)
AggVars=EvalFnOnAgentDist_AggVars_Case1(StationaryDist, Policy, FnsToEvaluateCell, Parameters, FnsToEvaluateParamNames, n_d, n_a, n_z, d_grid, a_grid, z_gridvals, simoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1>@(p)HeteroAgentStationaryEqm_Case1_subfn(p,n_d,n_a,n_z,d_grid,a_grid,z_grid,pi_z,ReturnFn,FnsToEvaluate,FnsToEvaluateCell,GeneralEqmEqnsCell,Parameters,DiscountFactorParamNames,ReturnFnParamNames,FnsToEvaluateParamNames,GeneralEqmEqnParamNames,GEPriceParamNames,GEeqnNames,AggVarNames,nGEprices,heteroagentoptions,simoptions,vfoptions) (line 609)
GeneralEqmConditionsFnOpt=@(p) HeteroAgentStationaryEqm_Case1_subfn(p, n_d, n_a, n_z, d_grid, a_grid, z_grid, pi_z, ReturnFn, FnsToEvaluate, FnsToEvaluateCell, GeneralEqmEqnsCell, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, GeneralEqmEqnParamNames, GEPriceParamNames, GEeqnNames, AggVarNames, nGEprices, heteroagentoptions, simoptions, vfoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1 (line 610)
GeneralEqmConditions=GeneralEqmConditionsFnOpt(p_eqm_vec_untranformed);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Low Memory
Note that the error reported above happens in the general equilibrium loop, not in the VFI per se. So I test now only the VFI but it is slow (see comment below). Maybe my 4 GB gpu works better with low memory, so I set
vfoptions.lowmemory = 1;
vfoptions.verbose = 0;
vfoptions.tolerance = 1e-6;
vfoptions.maxiter = 500;
vfoptions.howards = 80;
vfoptions.maxhowards = 500;
vfoptions.howardsgreedy = 0;
vfoptions.gridinterplayer = 1;
vfoptions.ngridinterp = 15;
but there is a new errro, this time in VFI, in function ValueFnIter_Refine_preGI_raw
:
Unable to perform assignment because the size of the left side is 4785-by-300-by-1 and the size of the
right side is 300-by-1.
Error in ValueFnIter_Refine_preGI_raw (line 47)
ReturnMatrixfine(:,:,z_c)=shiftdim(ReturnMatrixfine_z,1);
^^^^^^^^^^^^^^^^^^^^^^^^^
Error in ValueFnIter_GridInterpLayer (line 58)
[V,Policy]=ValueFnIter_Refine_preGI_raw(V0, n_d, n_a, n_z, d_gridvals, a_grid, z_gridvals, pi_z, ReturnFn, DiscountFactorParamsVec, ReturnFnParamsVec, vfoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in ValueFnIter_Case1 (line 421)
[V,Policy]=ValueFnIter_GridInterpLayer(V0, n_d, n_a, n_z, d_gridvals, a_grid, z_gridvals, pi_z, ReturnFn, DiscountFactorParamsVec, ReturnFnParamsVec, vfoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1_subfn (line 52)
[V,Policy]=ValueFnIter_Case1(n_d,n_a,n_z,d_grid,a_grid,z_gridvals, pi_z, ReturnFn, Parameters, DiscountFactorParamNames,ReturnFnParamNames,vfoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1>@(p)HeteroAgentStationaryEqm_Case1_subfn(p,n_d,n_a,n_z,d_grid,a_grid,z_grid,pi_z,ReturnFn,FnsToEvaluate,FnsToEvaluateCell,GeneralEqmEqnsCell,Parameters,DiscountFactorParamNames,ReturnFnParamNames,FnsToEvaluateParamNames,GeneralEqmEqnParamNames,GEPriceParamNames,GEeqnNames,AggVarNames,nGEprices,heteroagentoptions,simoptions,vfoptions) (line 609)
GeneralEqmConditionsFnOpt=@(p) HeteroAgentStationaryEqm_Case1_subfn(p, n_d, n_a, n_z, d_grid, a_grid, z_grid, pi_z, ReturnFn, FnsToEvaluate, FnsToEvaluateCell, GeneralEqmEqnsCell, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, GeneralEqmEqnParamNames, GEPriceParamNames, GEeqnNames, AggVarNames, nGEprices, heteroagentoptions, simoptions, vfoptions);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1 (line 610)
GeneralEqmConditions=GeneralEqmConditionsFnOpt(p_eqm_vec_untranformed);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Other comments
The VFI runs surprisingly slow. My grid sizes are
Pijoan-Mas discretization of z with 7 points
n_a = 300, n_d = 51
The bottleneck is in the function ValueFnIter_Refine_preGI_raw
, line 27 when the code calls CreateReturnFnMatrix_Case2_Disc_Par2
. On my laptop with 4 GB of RAM it takes 30 seconds. It could be that my gpu is not very good, but this is a small problem, so I am surprised.
Could it be that this algorithm is so memory-hungry (I thought the opposite was true but maybe I don’t have a clear understanding of the algo)? If I set anything bigger, it goes out of memory. Instead, without grid interpolation, I can set n_a=1000 and it works fine, albeit slow.
In the Pijoan-Mas model, one of the targeted moment is the correlation between hours of work d(a,z) and labor productivity z. Once the toolkit can compute correlations, I will add it to my example. For now, I left it NaN.
All in all, the toolkit is becoming more and more flexible over time