Calibrate infinite horizon model

I’m interested in learning how to use intermediateEqns and CustomModelStats. Could you please provide an example Aiyagari model that demonstrates these features? Thank you very much.

2 Likes

Will do this in the next day or two, is easy enough.

Workshop OLG Model 2 demos intermediateEqns. They don’t let you do anything new, they just make it much cleaner/easier to write out GeneralEqmEqns and give you more feedback on what it happening in the model while you are solving for general eqm (which also helps you avoid making mistakes, and helps diagnose why the model is not working yet while you are setting it up).

CustomModelStats is there so that when you want a model statistic that is complicated and cannot just be done using ‘AllStats’ (or similar) then you can hand code that model statistic (and it can then be used in a general eqm eqn or as a calibration/estimation target).

2 Likes

You can have a look at my repo on Pijoan-Mas model.

It is an Aiyagari model with endogenous labor supply. The script main.m finds values of parameters that match certain targets (in general equilibrium). I use CustomStats to compute the correlation between hours of work and productivity.

Please let me know if you find bugs!
Besides CustomStats, it also shows a bunch of other toolkit features such as Grid interpolation, Howard sparse, etc.

1 Like

Thanks so much. I have a sense of how to configure them in the toolkit, but the script returns errors when do_GE=0.

Index exceeds matrix dimension.

Error in ValueFnIter_Refine_postGI_raw (line 306)
Policy(1,:,:)=reshape(dstar(temppolicyindex),[N_a,N_z]); % note: dstar is defined on the fine grid
                      ^^^^^^^^^^^^^^^^^^^^^^
Error in ValueFnIter_GridInterpLayer (line 149)
                    [V,Policy]=ValueFnIter_Refine_postGI_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 465)
    [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 main (line 192)
[~, Policy] = ValueFnIter_Case1( ...
              ^^^^^^^^^^^^^^^^^^^^^^

The following error messages appeared when do_GE is equal to 1.

Index exceeds matrix dimension.

Error in ValueFnIter_Refine_postGI_raw (line 306)
Policy(1,:,:)=reshape(dstar(temppolicyindex),[N_a,N_z]); % note: dstar is defined on the fine grid
                      ^^^^^^^^^^^^^^^^^^^^^^
Error in ValueFnIter_GridInterpLayer (line 149)
                    [V,Policy]=ValueFnIter_Refine_postGI_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 465)
    [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 29)
[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_gridvals,pi_z,ReturnFn,FnsToEvaluate,FnsToEvaluateCell,GeneralEqmEqnsCell,Parameters,DiscountFactorParamNames,ReturnFnParamNames,FnsToEvaluateParamNames,GeneralEqmEqnParamNames,GEPriceParamNames,GEeqnNames,AggVarNames,nGEprices,heteroagentoptions,simoptions,vfoptions) (line 392)
        GeneralEqmConditionsFnOpt=@(p) HeteroAgentStationaryEqm_Case1_subfn(p, n_d, n_a, n_z, d_grid, a_grid, z_gridvals, pi_z, ReturnFn, FnsToEvaluate, FnsToEvaluateCell, GeneralEqmEqnsCell, Parameters, DiscountFactorParamNames, ReturnFnParamNames, FnsToEvaluateParamNames, GeneralEqmEqnParamNames, GEPriceParamNames, GEeqnNames, AggVarNames, nGEprices, heteroagentoptions, simoptions, vfoptions);
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in fminsearch (line 209)
f = funfcn(x,varargin{:});
    ^^^^^^^^^^^^^^^^^^^^^
Error in HeteroAgentStationaryEqm_Case1 (line 422)
        [p_eqm_vec,GeneralEqmConditions]=fminsearch(GeneralEqmConditionsFnOpt,GEparamsvec0,minoptions);
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in main (line 168)
    [p_eqm, ~, GeneralEqmCondn] = HeteroAgentStationaryEqm_Case1( ...
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I also came across a note in the custom_stats file mentioning that “z_gridvals is a joint-grid rather than whatever the user set”. I’m unsure what this means exactly.

1 Like

Did you sync with the latest version of the toolkit? I pointed out this error to @robertdkirkby some time ago and I think he fixed it, see this post:

The error is still there, I ran the main file in my repo and I got the same mistake. ValueFnIter_Refine_postGI_raw still has a bug. @robertdkirkby if you run main.m of my Pijoan-Mas repo, you will see it.

I will go fix the error today (hopefully).

If you want to understand the differences between ‘stacked-column grid’ and ‘joint-grid’ see Appendix on discretizing shocks in Intro to Life-Cycle Models. [You don’t need to, just if you want to. Internally the toolkit converts everything into joint-grids as these nest all the other possibilities, but for users convenience any of these types of grid can be input.]

2 Likes

Should be fixed now. [Because postGI does the VFI once and then the postGI once, the iteration counter needs to be reset between them, it wasn’t and this was the error, as it did the first, skipped the postGI, and then ended up with a result that was the wrong shape. Silly minor error, just added lines to reset counter at each stage.]

2 Likes

Now it works. Is it reasonable that vfoptions.maxhowards = 500; and vfoptions.maxhowards = 0; take more or less the same time for one VFI? (this based on my Pijoan-Mas example)

1 Like

I see. Thanks for the reply.

1 Like

I would be interested in this even for models like the stochastic RBC that are infinite horizon

There is now a command called CalibrateBIHAModel.m. It will be another month before it gets proper documentation but experienced users will probably be able to see how it works as it looks a lot like the CalibrateOLGModel() command [most of the inputs are the usual things, and you can see how to set up CalibParamNames and TargetMoments if you look at the examples on GMM estimation in the Intro to Life-Cycle Models and the calibration of life-cycle models in the Workshop].

Everyone who is not an experience user will just have to wait till sometime in April when I document this and provide examples. Just wanted to mention that it is coming (due to popular demand and what not).

PS. BIHA=Bewley-Imrohorglu-Hugget-Aiyagari, so stationary eqm in the incomplete markets with idiosyncratic shocks.

2 Likes

Very useful new feature!
I might test it in my Pijoan-Mas example

Could I for example use this new routine to calibrate the standard deviation of the AR1 shock to labor productivity? Something like:

  • Choose sigma_e
  • given sigma_e, create z_grid and pi_z using Tauchen or analogous method
  • Given all parameters solve for general equilibrium and find the GE interest rate r
  • Compute model moment of interest, in this case the variance of log earnings
  • Update sigma_e until the data moment and the model moment are matched.

I ask this question since I noticed that z_grid and pi_z are input arguments in the calibrate BIHAModel function. In what I have in mind, z_grid and pi_z should be created internally in the calibration routine and updated every time sigma_e is updated.

1 Like

Yes.

Use vfoptions.ExogShockFn [this parameterizes z_grid and pi_z] with sigma_e (and whatever else) as inputs, then put ‘sigma_e’ in CalibParaNames. You put TargetMoments.AllStats.logearnings.Variance as a target, based on FnsToEvaluate.logearnings.

[Internally, if you use vfoptions.ExogShockFn the calibration (and stationary general eqm, and transition path) commands all check if the inputs to ExogShockFn overlap with the general eqm/calibration parameters, if NO they just evaluate z_grid and pi_z once, then eliminate the ExogShockFn, if YES they evaluate z_grid and pi_z at every iteration.]

PS. Based on personal experience, InfHorz models often struggle to identify the AR(1) parameters on labor efficiency units when you have endogenous labor supply, and are calibrating with general eqm, and also have some of the leisure preference parameters being calibrated. So to actually get the sigma_e accurate you might need a whole bunch of relevant targets, not just the variance of log earnings. [If you have exogenous labor it will be much easier.]

PPS. In FHorz, TargetMoments can contain anything from AllStats and AgeConditionalStats. In InfHorz, TargetMoments can contain anything from AllStats, AutoCorrTransProbs, and CrossSectionCovarCorr.

2 Likes

Regarding identification: it was just to understand the how the calibration code works. In Aiyagari 1994 with inelastic labor, labor earnings are exogenous so you can choose sigma_e to match the variance of log earnings outside of the model, you don’t need the toolkit :slight_smile:
A better example would be to choose sigma_e to match the dispersion of wealth. Even better: calibrate a version of Aiyagari 1994 with superstar shock and estimate the parameters of the superstar shock (i.e. prob of becoming a superstar, superstar earnings level, prob of falling back) to match some wealth inequality moments.

1 Like

All of these are things the CalibrateBIHAModel can do straightforwardly enough.

You would use ‘ExogShockFn’ to set up the earnings process with superstar shock as depending on some parameters. Then using TargetMoments based on AllStats you can include all sorts of earnings and wealth inequality targets (and you can also add autocorrelations, and covariances of earnings with wealth).

1 Like

Added
CalibrateInfHorzAgentModel
which is without general eqm.

Also added _PType versions, so both CalibrateInfHorzAgentModel_PType and CalibrateBIHAModel_PType.

2 Likes