Implementing Acemoglu–Shimer (2000) with finite-horizon VFI Toolkit: semi-exogenous employment states, directed search choices, and voluntary quitting
Hi Robert and everyone,
I am trying to implement the dynamic model in Acemoglu and Shimer (2000), “Productivity Gains from Unemployment Insurance,” European Economic Review, Section 3, using the MATLAB VFI Toolkit. The paper is here: Productivity Gains from Unemployment Insurance | NBER
The one substantive change is to assume a finite horizon (t=1,\ldots,T) instead of infinitely lived workers. I am not adding the on-the-job-search extension from Section 5.4. In particular, I want to retain the baseline model’s voluntary quitting option: a worker in a bad job can quit, lose UI eligibility, and search while unemployed.
My proposed implementation uses:
- One endogenous state: financial assets a; one endogenous-state choice: a'.
- One semi-exogenous discrete state with four employment/UI statuses.
- Two ordinary discrete decision variables: hours h and a three-valued action k (“stay employed,” “search good,” “search bad”).
- A directly supplied, precomputed
vfoptions.pi_semizrather thanvfoptions.SemiExoStateFn.
I would appreciate confirmation that this is the appropriate mapping, especially regarding the quitting option and the timing of a same-period quit followed by uninsured search.
1. Original model, with a finite horizon
Let the employment state be
where E_g is a good job, E_b a bad job, U_I insured unemployment, and U_N uninsured unemployment. Both wages and job-finding rates are exogenous in this dynamic model: w_g>w_b and m_g<m_b. A worker devoting h hours to search in market j\in\{g,b\} finds a job with probability m_jh (restricted to [0,1]). Jobs separate exogenously with probabilities \delta_g,\delta_b. UI is b when eligible and expires with probability \chi after an unsuccessful search. Employed workers pay tax rate \tau. After an exogenous separation, workers are UI-eligible; voluntary quitters are not.
The paper uses CRRA preferences over a consumption–leisure composite. In the notation used below,
with c>0, 0\le h<\bar h. Hours are work hours when staying employed and search hours when unemployed or quitting. There is a borrowing constraint a'\ge0.
Growth normalization. To retain the deterministic productivity growth \Gamma>1 in the EER paper, use normalized assets a_t=A_t/\Gamma^t, consumption c_t=C_t/\Gamma^t, and constant normalized w_g,w_b,b. The normalized budget is
For \sigma\ne1, the normalized Bellman discount factor is \widetilde\beta=\beta\Gamma^{1-\sigma}. (Alternatively, one could solve in levels with age-dependent wages/benefits and ordinary discount factor \beta.) I would use the normalized formulation to stay close to the paper.
The four Bellman equations
Writing V_{g,t}(a), V_{b,t}(a), V_{I,t}(a) and V_{N,t}(a) for the four values, and using the normalized \widetilde\beta:
Good job (continue working):
Bad job (stay or quit): define the value of staying as
The quitting option is the same-period uninsured-unemployment value:
This implements quitting before current-period labour income/search: the quitter receives no current wage or UI but can search immediately. Is that also the correct interpretation of “workers may voluntarily quit a job at any time” in the paper? The paper states that the bad-job Bellman equation has this option but does not write the nested max explicitly.
Uninsured unemployment:
Insured unemployment:
At the finite-horizon terminal date, assume no bequest motive and no value after T; provided 0 belongs to the asset grid, optimal a' should be zero at T when current consumption has positive marginal utility.
2. Proposed Toolkit state and decision layout
I would map the objects as follows:
| Economic object | VFI Toolkit object |
|---|---|
| Current assets a | a |
| Chosen next assets a' | aprime |
| Employment/UI state e | semiz with grid [1;2;3;4] |
| Hours (work or search) h | First discrete decision d1 |
| Employment/search action k | Second discrete decision d2 |
| Calendar time | Finite-horizon index j=1,...,N_j |
Encode the four semiz states as 1=E_g, 2=E_b, 3=U_I, 4=U_N. Rather than adding a third binary “quit” decision, let the action be
For E_b, k=1 or 2 means quit and search as uninsured. For U_I or U_N, k=1 or 2 is normal search. The action k=0 is infeasible for unemployed workers. (For E_g one can either rule out quitting because it is dominated in the baseline, or allow it explicitly with the same quitting treatment.)
This expands the choice set, but crucially turns the same-period max \max\{S_{b,t},V_{N,t}\} into an ordinary max over mutually exclusive actions. Thus the Toolkit can solve all four state values in one backward-induction call.
The relevant setup is:
n_h = numel(h_grid);
k_grid = [0; 1; 2]; % stay, search good, search bad
n_d = [n_h, 3];
d_grid = [h_grid; k_grid];
n_a = numel(a_grid);
n_z = 0; % no additional exogenous Markov shock
vfoptions.n_semiz = 4;
vfoptions.semiz_grid = (1:4)';
vfoptions.l_dsemiz = 2; % both h and k affect transitions
The order of the return-function arguments is important: all d variables, then aprime, then a, then semiz, then any ordinary exogenous shocks, then parameters. In our case (no z or e shocks):
ReturnFn = @(h,k,aprime,a,semiz,R,Gamma,wg,wb,tau,b,hbar,eta,sigma) ...
AS_ReturnFn(h,k,aprime,a,semiz,R,Gamma,wg,wb,tau,b,hbar,eta,sigma);
3. Semi-exogenous transition probabilities
This is the part for which the Toolkit’s semi-exogenous feature seems particularly useful. Let
be the probability of next period’s employment/UI state. Its rows correspond to current states and columns to next states, both in order (E_g,E_b,U_I,U_N).
When a worker stays employed (k=0), the rows for good and bad jobs are:
When an insured unemployed worker searches in job type j, put p=m_jh:
When an uninsured unemployed worker searches:
Finally, if an employed worker chooses to quit and search, the corresponding row is exactly the uninsured search row, not the insured one. This is how we enforce loss of UI eligibility on quitting.
Option A: create pi_semiz directly (my preferred implementation)
From the Toolkit exogenous-shock documentation and SemiExogShockSetup_FHorz.m, vfoptions.pi_semiz can be a precomputed array with dimensions
when transitions do not vary with age. The Toolkit broadcasts it over t=1,\dots,T-1. Its third dimension uses the MATLAB column-major combination index
Here is my proposed construction:
function pi_semiz = AS_CreatePiSemiz(h_grid,delta_g,delta_b,mg,mb,chi)
% Four states (current and next): 1 Eg, 2 Eb, 3 UI, 4 UN.
% Actions: 0 stay; 1 search good; 2 search bad.
% The last two ordinary decisions are (h,k).
nh = numel(h_grid);
k_grid = [0;1;2];
pi_semiz = zeros(4,4,nh*numel(k_grid));
for ik = 1:numel(k_grid)
k = k_grid(ik);
for ih = 1:nh
h = h_grid(ih);
P = zeros(4,4);
if k == 0
% Valid choices for employed workers: work and stay.
P(1,:) = [1-delta_g, 0, delta_g, 0];
P(2,:) = [0, 1-delta_b, delta_b, 0];
% Placeholder probability rows for forbidden U + stay action.
% ReturnFn will assign -Inf to that action.
P(3,:) = [0, 0, 1-chi, chi];
P(4,:) = [0, 0, 0, 1];
else
if k == 1
p = mg*h;
target = 1;
else
p = mb*h;
target = 2;
end
assert(p >= 0 && p <= 1, 'Search probability outside [0,1]');
% A quitter from E_g or E_b searches without UI.
quitter = zeros(1,4);
quitter(target) = p;
quitter(4) = 1-p;
P(1,:) = quitter; % optionally disallow E_g quitting in ReturnFn
P(2,:) = quitter;
% Insured unemployed: UI can expire if search fails.
P(3,target) = p;
P(3,3) = (1-p)*(1-chi);
P(3,4) = (1-p)*chi;
% Uninsured unemployed.
P(4,:) = quitter;
end
idx = ih + (ik-1)*nh;
pi_semiz(:,:,idx) = P;
end
end
assert(all(pi_semiz(:) >= 0));
assert(max(abs(sum(pi_semiz,2)-1),[],'all') < 1e-12);
end
Even action/state combinations forbidden by the return function have valid transition probabilities so every slice is stochastic. The ReturnFn is responsible for ruling out economically infeasible actions.
Then simply:
vfoptions.pi_semiz = AS_CreatePiSemiz( ...
h_grid, delta_g, delta_b, mg, mb, chi);
If matching/separation/UI-expiration probabilities depend on age, I understand that a four-dimensional array [4,4,3*n_h,N_j-1] is also allowed.
Option B: supply SemiExoStateFn
I understand that the alternative is a function returning a scalar probability:
vfoptions.SemiExoStateFn = ...
@(semiz,semizprime,h,k,delta_g,delta_b,mg,mb,chi) ...
AS_SemiExoProbability(semiz,semizprime,h,k, ...
delta_g,delta_b,mg,mb,chi);
The Toolkit would use the function to construct the same array internally. Because there are only four states and the probabilities are simple, I lean towards Option A, which is particularly easy to inspect/test. Are there any practical advantages to using SemiExoStateFn instead?
4. Return function and quitting
The same ReturnFn must handle staying, searching, and quitting. The key point is that a quitter must not receive current employed income or current UI. Instead, she consumes and searches as an uninsured unemployed worker in the same period.
The income entering the normalized budget is
Here is a schematic scalar return function, intended for the Toolkit’s discrete-return evaluation (without a separate z shock):
function F = AS_ReturnFn(h,k,aprime,a,semiz, ...
R,Gamma,wg,wb,tau,b,hbar,eta,sigma)
% semiz = 1 Eg, 2 Eb, 3 UI, 4 UN
% k = 0 stay; 1 search good; 2 search bad
F = -Inf;
% All employed states may quit. To restrict quitting to bad jobs,
% also require k==0 when semiz==1.
validAction = ((semiz==1 || semiz==2) && k==0) || ...
((k==1 || k==2) && semiz>=1 && semiz<=4);
if validAction && aprime>=0 && h>=0 && h<hbar
income = 0;
if semiz==1 && k==0
income = (1-tau)*wg*h;
elseif semiz==2 && k==0
income = (1-tau)*wb*h;
elseif semiz==3
income = b;
end
% All other admissible search actions have zero current income.
% For semiz 1 or 2 with k>0, this is an immediate uninsured quit.
c = a + income - (Gamma/R)*aprime;
if c>0
if sigma==1
F = log(c) + eta*log(hbar-h);
else
F = (c*(hbar-h)^eta)^(1-sigma)/(1-sigma);
end
end
end
end
The transition array accounts for the next employment state; ReturnFn supplies only current-period utility and feasibility. Importantly, the ReturnFn argument order is
(d1,d2,aprime,a,semiz,parameters...), not (a,semiz,aprime,d1,d2,...).
5. Schematic call to the finite-horizon solver
The following illustrates the overall setup, using paper-like parameters and illustrative grids. It is a proposed implementation, not yet a tested replication:
% --- Model parameters (weekly frequency, illustrative) ---
Parameters.R = 1.0006;
Parameters.Gamma = 1.0003;
Parameters.beta = 0.998;
Parameters.sigma = 4;
Parameters.eta = 1/6;
Parameters.hbar = 1;
Parameters.wg = 1.3;
Parameters.wb = 1.0;
Parameters.b = 0.4;
Parameters.tau = 0.022; % fixed here; see budget note below
Parameters.betaeff = Parameters.beta * ...
Parameters.Gamma^(1-Parameters.sigma);
mg = 0.05;
mb = 0.50;
delta_g = 0.005;
delta_b = 0.005;
chi = 0.04;
N_j = 120; % short finite-horizon test; use longer horizon later
h_grid = linspace(0,0.95,21)';
a_grid = (linspace(0,sqrt(40),151)').^2;
n_h = numel(h_grid);
n_d = [n_h, 3];
d_grid = [h_grid; 0; 1; 2];
n_a = numel(a_grid);
n_z = 0;
z_grid = [];
pi_z = [];
vfoptions = struct();
vfoptions.n_semiz = 4;
vfoptions.semiz_grid = (1:4)';
vfoptions.l_dsemiz = 2;
vfoptions.pi_semiz = AS_CreatePiSemiz( ...
h_grid,delta_g,delta_b,mg,mb,chi);
vfoptions.gridinterplayer = 0; % first validate plain VFI
vfoptions.parallel = 2; % use GPU where available
ReturnFn = @(h,k,aprime,a,semiz,R,Gamma,wg,wb,tau,b,hbar,eta,sigma) ...
AS_ReturnFn(h,k,aprime,a,semiz,R,Gamma,wg,wb,tau,b,hbar,eta,sigma);
ReturnFnParamNames = {'R','Gamma','wg','wb','tau','b', ...
'hbar','eta','sigma'};
DiscountFactorParamNames = {'betaeff'};
[V,Policy] = ValueFnIter_Case1_FHorz( ...
n_d,n_a,n_z,N_j,d_grid,a_grid,z_grid,pi_z, ...
ReturnFn,Parameters,DiscountFactorParamNames, ...
ReturnFnParamNames,vfoptions);
The expected shape of V is [n_a,4,N_j], with the four columns corresponding to employment/UI states. Policy should identify chosen hours, the three-valued action, and aprime at each (a,e,t) (subject to the Toolkit’s policy-index representation).
The government-budget equation remains an outer equilibrium condition, not part of worker VFI. For this first implementation I would condition on \tau and b. With a finite horizon, a fully budget-balanced experiment would additionally require an initial cross-sectional distribution and a specified tax-financing rule over time. The original infinite-horizon paper balances the UI system using the stationary employment/wealth distribution.
6. Checks I would perform
- Stochastic transitions: each row of each
pi_semiz(:,:,idx)sums to one; all probabilities are nonnegative. Check a few known (h,k) pairs by hand. - Correct quitting: in state E_b with k=1 or 2, current wage and UI income are both zero, and an unsuccessful search leads to U_N, not U_I.
- Bellman identity: compare the Toolkit bad-job value to an independently computed \max\{S_{b,t}(a),V_{N,t}(a)\} on a small asset grid. They should agree numerically if the timing is correct.
- Dominance: V_{b,t}(a)\ge V_{N,t}(a) at every feasible (a,t) when quitting is allowed.
- Finite-horizon terminal period: check that a'_{T}=0 in the absence of bequests (and that search effort becomes irrelevant at T).
- Zero-income corner: U_N with a=0 has no feasible strictly positive consumption under the original no-borrowing, zero-uninsured-income assumptions. With CRRA utility, this can produce
-Infvalues; I do not want to silently introduce a consumption floor that changes the model. Is there a preferred Toolkit treatment for these infeasible boundary states?
7. Questions for the VFI Toolkit forum
- Is the expanded action-space approach the right way to implement voluntary quitting? In particular, does combining
ReturnFnandpi_semizin this way reproduce a worker’s ability to quit and enter uninsured search in the same period, without solving a separate nested Bellman equation? - Is direct
vfoptions.pi_semizpreferable here tovfoptions.SemiExoStateFn, given that the 4\times4\times(3n_h) array is small and independent of assets? - Any implementation pitfalls with two decision variables controlling the semi-exogenous transition (
vfoptions.l_dsemiz=2), forbidden actions assigned-Inf, or the terminal-period/zero-asset cases? - Once the basic implementation is validated, would you recommend
vfoptions.gridinterplayerfor the asset choice in this particular semi-exogenous finite-horizon setup, or are there branch-specific considerations?
Thanks in advance for any feedback!