Aiyagari (1994) Model

I wrote a code to solve the Aiyagari (1994) model. Here is my code.

heterogeneity_dimension households;

var(heterogeneity=households) c a eff;

varexo(heterogeneity=households) e;

var Y r w K;

parameters alpha delta sigma Z beta L_ss;

alpha=0.36;

delta=0.08;

sigma=3.00;

Z=1.00;

verbatim;

l_unemp=0.1;

l_emp=1.0;

grid_e=[l_unemp,l_emp];

Pi_e=[0.50,0.50;0.05,0.95];

[V,D]=eig(Pi_e’);

[~,idx]=min(abs(diag(D)-1));

invdist=V(:,idx)/sum(V(:,idx));

L_val=sum(grid_e.*invdist’);

r_target=0.035;

rk=r_target+delta;

K_val=L_val*(alpha*Z/rk)^(1/(1-alpha));

w_val=(1-alpha)*Z*(K_val/L_val)^alpha;

initial_guess=struct;

initial_guess.agg.r=r_target;

initial_guess.agg.w=w_val;

initial_guess.agg.K=K_val;

initial_guess.agg.Y=Z*K_val^alpha*L_val^(1-alpha);

initial_guess.free_parameters.beta.initial_guess=0.96;

initial_guess.free_parameters.beta.lower_bound=0.90;

initial_guess.free_parameters.beta.upper_bound=0.98;

initial_guess.shocks.grids.e=grid_e;

initial_guess.shocks.Pi.e=Pi_e;

grid_a=logspace(log10(0.2),log10(150.2),500)-0.2;

initial_guess.pol.grids.a=grid_a;

[A_mesh,E_mesh]=meshgrid(grid_a,grid_e);

coh=(1+r_target)*A_mesh+w_val*E_mesh;

c_guess=0.05*coh+0.1;

initial_guess.pol.values.c=c_guess;

initial_guess.pol.values.a=coh-c_guess;

initial_guess.pol.values.eff=E_mesh;

initial_guess.pol.order={‘e’,‘a’};

end;

L_ss=L_val;

model(heterogeneity=households);

beta*(1+r(+1))*c(+1)^(-sigma)=c^(-sigma)⟂a>=0;

c+a=(1+r)*a(-1)+w*e;

eff=e;

end;

model;

Y=Z*K(-1)^alpha*L_ss^(1-alpha);

r=alpha*Z*(K(-1)/L_ss)^(alpha-1)-delta;

w=(1-alpha)*Z*(K(-1)/L_ss)^alpha;

K=SUM(a);

end;

heterogeneity_compute_steady_state(variable=initial_guess);

Dynare can solve this model but the log shows that " Time iteration did not converge". I’m not sure about this warning. Anyone can give me some suggestions?

Here is the log file.

Iter 146: ||Δpolicy|| = 9.5979E-08, tol = 1.0000E-08
Iter 147: ||Δpolicy|| = 9.7603E-08, tol = 1.0000E-08
Iter 148: ||Δpolicy|| = 1.1577E-07, tol = 1.0000E-08
Iter 149: ||Δpolicy|| = 1.2666E-07, tol = 1.0000E-08
Early stopping: 3 consecutive increases in ||Δpolicy||
Warning: Time iteration did not converge
=== Aggregate variables and residuals ===
Aggregate residuals:
Y: 0.000000E+00
r: 0.000000E+00
w: 0.000000E+00
K: -1.047369E-05
Max norm: 1.047369E-05, tol = 1.000000E-04
Calibration iteration complete
beta = 9.54031E-01
Calibration converged successfully!
Calibrated parameters:
beta = 9.54031E-01
Converged in 7 function evaluations
Calibration complete

=== Calibrated Parameters ===
beta = 0.954031

STEADY STATE

Aggregate variables:
Y 1.74464
r 0.035
w 1.21607
K 5.46149

Heterogeneous state variables (unconditional moments):
Mean Std. dev.
a 5.4615 1.4621

RESIDUALS (at the steady state)

Aggregate equations:
Equation 1 (Y) 0
Equation 2 (r) 0
Equation 3 (w) 0
Equation 4 (K) -1.04737e-05

Heterogenous equations (infinite-norm over the grid):
Equation 1 5.9344e-10
Equation 2 2.84217e-14

Equation 3 0
Total computing time : 0h00m33s

Hello @Rui,

Thanks for your interest in our new solution methods!

Nothing is wrong with your solution. The warning is informational. Look at your residuals at the returned steady state:

  • Heterogeneous equations: max 5.93e-10
  • Aggregate K residual: 1.05e-5 (calibration tolerance is 1e-4 by default)
  • Calibration converged in 7 evaluations

The household problem and equilibrium are both solved correctly. What’s happening is a bit subtle. The time-iteration stopping criterion (time_iteration_tol = 1e-8 by default) is stricter than the noise floor of the inner trust-region solver in the presence of the MCP constraint ⟂ a >= 0. For simple well-behaved problems, this noise floor can become the limiting factor in further pushing down the residuals. In your log, ‖Δpolicy‖ decreases monotonically until iter 139 (down to 8.2e-8) and then jumps and oscillates in the 1e-7 band: that’s a household near the borrowing constraint flipping its Fischer-Burmeister state, and after that the regularization keeps the policy update wiggling at ~1e-7 indefinitely. The default time_iteration_early_stopping = 3 (stop after 3 consecutive non-monotone iterates) detects this and bails out, which is the right thing to do.

If you want to get rid of the those last ugly oscillating iterations, there are 2 solutions. If you’re satisfied with the obtained precision before oscillations begin, you can simply bring up the time-iteration tolerance. I tried it using

heterogeneity_compute_steady_state(variable=initial_guess, time_iteration_tol=1e-7);

and got rid of the early-stopping warning while keeping residuals in the same order of magnitude:

RESIDUALS (at the steady state)

Aggregate equations:
Equation 1 (Y)  0
Equation 2 (r)  0
Equation 3 (w)  0
Equation 4 (K)  -1.04683e-05

Heterogenous equations (infinite-norm over the grid):
Equation 1      1.22837e-09
Equation 2      2.84217e-14
Equation 3      0
Total computing time : 0h00m56s

On the contrary, if you want to further lower the residuals of the heterogeneous equations while getting rid of the early-stopping warnings, you can tighten the inner Newton solver so the Fischer-Burmeister noise floor no longer bites. For example, using

heterogeneity_compute_steady_state(variable=initial_guess, time_iteration_solver_tolf=1e-12, time_iteration_solver_tolx=1e-12);

leads to

RESIDUALS (at the steady state)

Aggregate equations:
Equation 1 (Y)  0
Equation 2 (r)  0
Equation 3 (w)  0
Equation 4 (K)  -1.04745e-05

Heterogenous equations (infinite-norm over the grid):
Equation 1      5.75281e-11
Equation 2      2.84217e-14
Equation 3      0
Total computing time : 0h01m13s
>> 

Hope it helps,

Best,

Normann