{
"cells": [
{
"cell_type": "markdown",
"id": "6d30f7d2",
"metadata": {},
"source": [
"\n",
""
]
},
{
"cell_type": "markdown",
"id": "b3182a68",
"metadata": {},
"source": [
"# Job Search II: Search and Separation\n",
"\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"id": "13456f9b",
"metadata": {},
"source": [
"## Contents\n",
"\n",
"- [Job Search II: Search and Separation](#Job-Search-II:-Search-and-Separation) \n",
" - [Overview](#Overview) \n",
" - [The Model](#The-Model) \n",
" - [Solving the Model using Dynamic Programming](#Solving-the-Model-using-Dynamic-Programming) \n",
" - [Implementation](#Implementation) \n",
" - [The Reservation Wage](#The-Reservation-Wage) \n",
" - [Exercises](#Exercises) \n",
" - [Solutions](#Solutions) "
]
},
{
"cell_type": "markdown",
"id": "91c4a914",
"metadata": {},
"source": [
"## Overview\n",
"\n",
"Previously [we looked](https://julia.quantecon.org/mccall_model.html) at the McCall job search model [[McC70](https://julia.quantecon.org/../zreferences.html#id109)] as a way of understanding unemployment and worker decisions.\n",
"\n",
"One unrealistic feature of the model is that every job is permanent.\n",
"\n",
"In this lecture we extend the McCall model by introducing job separation.\n",
"\n",
"Once separation enters the picture, the agent comes to view\n",
"\n",
"- the loss of a job as a capital loss, and \n",
"- a spell of unemployment as an *investment* in searching for an acceptable job "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cfa7727b",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"using LinearAlgebra, Statistics\n",
"using Distributions, Expectations, LaTeXStrings,NLsolve, Plots"
]
},
{
"cell_type": "markdown",
"id": "9e1bb81d",
"metadata": {},
"source": [
"## The Model\n",
"\n",
"The model concerns the life of an infinitely lived worker and\n",
"\n",
"- the opportunities he or she (let’s say he to save one character) has to work at different wages \n",
"- exogenous events that destroy his current job \n",
"- his decision making process while unemployed \n",
"\n",
"\n",
"The worker can be in one of two states: employed or unemployed.\n",
"\n",
"He wants to maximize\n",
"\n",
"\n",
"\n",
"$$\n",
"{\\mathbb E} \\sum_{t=0}^\\infty \\beta^t u(Y_t) \\tag{29.1}\n",
"$$\n",
"\n",
"The only difference from the [baseline model](https://julia.quantecon.org/mccall_model.html) is that\n",
"we’ve added some flexibility over preferences by introducing a utility function $ u $.\n",
"\n",
"It satisfies $ u'> 0 $ and $ u'' < 0 $."
]
},
{
"cell_type": "markdown",
"id": "992f96af",
"metadata": {},
"source": [
"### Timing and Decisions\n",
"\n",
"Here’s what happens at the start of a given period in our model with search and separation.\n",
"\n",
"If currently *employed*, the worker consumes his wage $ w $, receiving utility $ u(w) $.\n",
"\n",
"If currently *unemployed*, he\n",
"\n",
"- receives and consumes unemployment compensation $ c $ \n",
"- receives an offer to start work *next period* at a wage $ w' $ drawn from a known distribution $ p_1, \\ldots, p_n $ \n",
"\n",
"\n",
"He can either accept or reject the offer.\n",
"\n",
"If he accepts the offer, he enters next period employed with wage $ w' $.\n",
"\n",
"If he rejects the offer, he enters next period unemployed.\n",
"\n",
"When employed, the agent faces a constant probability $ \\alpha $ of becoming unemployed at the end of the period.\n",
"\n",
"(Note: we do not allow for job search while employed—this topic is taken\n",
"up in a [later lecture](https://julia.quantecon.org/jv.html))"
]
},
{
"cell_type": "markdown",
"id": "e300c0b9",
"metadata": {},
"source": [
"## Solving the Model using Dynamic Programming\n",
"\n",
"Let\n",
"\n",
"- $ V(w) $ be the total lifetime value accruing to a worker who enters the current period *employed* with wage $ w $. \n",
"- $ U $ be the total lifetime value accruing to a worker who is *unemployed* this period. \n",
"\n",
"\n",
"Here *value* means the value of the objective function [(29.1)](#equation-objective) when the worker makes optimal decisions at all future points in time.\n",
"\n",
"Suppose for now that the worker can calculate the function $ V $ and the constant $ U $ and use them in his decision making.\n",
"\n",
"Then $ V $ and $ U $ should satisfy\n",
"\n",
"\n",
"\n",
"$$\n",
"V(w) = u(w) + \\beta [(1-\\alpha)V(w) + \\alpha U ] \\tag{29.2}\n",
"$$\n",
"\n",
"and\n",
"\n",
"\n",
"\n",
"$$\n",
"U = u(c) + \\beta \\sum_i \\max \\left\\{ U, V(w_i) \\right\\} p_i \\tag{29.3}\n",
"$$\n",
"\n",
"Let’s interpret these two equations in light of the fact that today’s tomorrow is tomorrow’s today.\n",
"\n",
"- The left hand sides of equations [(29.2)](#equation-bell1-mccall) and [(29.3)](#equation-bell2-mccall) are the values of a worker in a particular situation *today*. \n",
"- The right hand sides of the equations are the discounted (by $ \\beta $) expected values of the possible situations that worker can be in *tomorrow*. \n",
"- But *tomorrow* the worker can be in only one of the situations whose values *today* are on the left sides of our two equations. \n",
"\n",
"\n",
"Equation [(29.3)](#equation-bell2-mccall) incorporates the fact that a currently unemployed worker will maximize his own welfare.\n",
"\n",
"In particular, if his next period wage offer is $ w' $, he will choose to remain unemployed unless $ U < V(w') $.\n",
"\n",
"Equations [(29.2)](#equation-bell1-mccall) and [(29.3)](#equation-bell2-mccall) are the Bellman equations\n",
"for this model.\n",
"\n",
"Equations [(29.2)](#equation-bell1-mccall) and [(29.3)](#equation-bell2-mccall) provide enough information to solve out for both $ V $ and $ U $.\n",
"\n",
"Before discussing this, however, let’s make a small extension to the model."
]
},
{
"cell_type": "markdown",
"id": "e327570f",
"metadata": {},
"source": [
"### Stochastic Offers\n",
"\n",
"Let’s suppose now that unemployed workers don’t always receive job offers.\n",
"\n",
"Instead, let’s suppose that unemployed workers only receive an offer with probability $ \\gamma $.\n",
"\n",
"If our worker does receive an offer, the wage offer is drawn from $ p $ as before.\n",
"\n",
"He either accepts or rejects the offer.\n",
"\n",
"Otherwise the model is the same.\n",
"\n",
"With some thought, you will be able to convince yourself that $ V $ and $ U $ should now satisfy\n",
"\n",
"\n",
"\n",
"$$\n",
"V(w) = u(w) + \\beta [(1-\\alpha)V(w) + \\alpha U ] \\tag{29.4}\n",
"$$\n",
"\n",
"and\n",
"\n",
"\n",
"\n",
"$$\n",
"U = u(c) +\n",
" \\beta (1 - \\gamma) U +\n",
" \\beta \\gamma \\sum_i \\max \\left\\{ U, V(w_i) \\right\\} p_i \\tag{29.5}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "1e32eafb",
"metadata": {},
"source": [
"### Solving the Bellman Equations\n",
"\n",
"We’ll use the same iterative approach to solving the Bellman equations that we\n",
"adopted in the [first job search lecture](https://julia.quantecon.org/mccall_model.html).\n",
"\n",
"Here this amounts to\n",
"\n",
"1. make guesses for $ U $ and $ V $ \n",
"1. plug these guesses into the right hand sides of [(29.4)](#equation-bell01-mccall) and [(29.5)](#equation-bell02-mccall) \n",
"1. update the left hand sides from this rule and then repeat \n",
"\n",
"\n",
"In other words, we are iterating using the rules\n",
"\n",
"\n",
"\n",
"$$\n",
"V_{n+1} (w_i) = u(w_i) + \\beta [(1-\\alpha)V_n (w_i) + \\alpha U_n ] \\tag{29.6}\n",
"$$\n",
"\n",
"and\n",
"\n",
"\n",
"\n",
"$$\n",
"U_{n+1} = u(c) +\n",
" \\beta (1 - \\gamma) U_n +\n",
" \\beta \\gamma \\sum_i \\max \\{ U_n, V_n(w_i) \\} p_i \\tag{29.7}\n",
"$$\n",
"\n",
"starting from some initial conditions $ U_0, V_0 $.\n",
"\n",
"Formally, we can define a “Bellman operator” T which maps:\n",
"\n",
"\n",
"\n",
"$$\n",
"TV(\\cdot) = u(\\cdot) + \\beta (1-\\alpha)V(\\cdot) + \\alpha U \\tag{29.8}\n",
"$$\n",
"\n",
"In which case we are searching for a fixed point\n",
"\n",
"\n",
"\n",
"$$\n",
"TV^{*} = V^* \\tag{29.9}\n",
"$$\n",
"\n",
"As before, the system always converges to the true solutions—in this case,\n",
"the $ V $ and $ U $ that solve [(29.4)](#equation-bell01-mccall) and [(29.5)](#equation-bell02-mccall).\n",
"\n",
"A proof can be obtained via the Banach contraction mapping theorem."
]
},
{
"cell_type": "markdown",
"id": "b32d0e77",
"metadata": {},
"source": [
"## Implementation\n",
"\n",
"Let’s implement this iterative process"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ce7511e1",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"using Distributions, LinearAlgebra, Expectations, NLsolve, Plots\n",
"\n",
"function solve_mccall_model(mcm; U_iv = 1.0, V_iv = ones(length(mcm.w)), tol = 1e-5,\n",
" iter = 2_000)\n",
" (; alpha, beta, sigma, c, gamma, w, dist, u) = mcm\n",
"\n",
" # parameter validation\n",
" @assert c > 0.0\n",
" @assert minimum(w) > 0.0 # perhaps not strictly necessary, but useful here\n",
"\n",
" # necessary objects\n",
" u_w = mcm.u.(w, sigma)\n",
" u_c = mcm.u(c, sigma)\n",
" E = expectation(dist) # expectation operator for wage distribution\n",
"\n",
" # Bellman operator T. Fixed point is x* s.t. T(x*) = x*\n",
" function T(x)\n",
" V = x[1:(end - 1)]\n",
" U = x[end]\n",
" [u_w + beta * ((1 - alpha) * V .+ alpha * U);\n",
" u_c + beta * (1 - gamma) * U + beta * gamma * E * max.(U, V)]\n",
" end\n",
"\n",
" # value function iteration\n",
" x_iv = [V_iv; U_iv] # initial x val\n",
" xstar = fixedpoint(T, x_iv, iterations = iter, xtol = tol, m = 0).zero\n",
" V = xstar[1:(end - 1)]\n",
" U = xstar[end]\n",
"\n",
" # compute the reservation wage\n",
" wbarindex = searchsortedfirst(V .- U, 0.0)\n",
" if wbarindex >= length(w) # if this is true, you never want to accept\n",
" w_bar = Inf\n",
" else\n",
" w_bar = w[wbarindex] # otherwise, return the number\n",
" end\n",
"\n",
" # return a NamedTuple, so we can select values by name\n",
" return (; V, U, w_bar)\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "fab7295f",
"metadata": {},
"source": [
"The approach is to iterate until successive iterates are closer together than some small tolerance level.\n",
"\n",
"We then return the current iterate as an approximate solution.\n",
"\n",
"Let’s plot the approximate solutions $ U $ and $ V $ to see what they look like.\n",
"\n",
"We’ll use the default parameterizations found in the code above."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c84787fa",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"function McCallModel(; alpha = 0.2,\n",
" beta = 0.98, # discount rate\n",
" gamma = 0.7,\n",
" c = 6.0, # unemployment compensation\n",
" sigma = 2.0,\n",
" u = (c, sigma) -> (c^(1 - sigma) - 1) / (1 - sigma),\n",
" w = range(10, 20, length = 60), # wage values\n",
" dist = BetaBinomial(59, 600, 400)) # distribution over wage values\n",
" return (; alpha, beta, gamma, c, sigma, u, w, dist)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d33045fc",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"# plots setting\n",
"\n",
"mcm = McCallModel()\n",
"(; V, U) = solve_mccall_model(mcm)\n",
"U_vec = fill(U, length(mcm.w))\n",
"\n",
"plot(mcm.w, [V U_vec], lw = 2, alpha = 0.7, label = [L\"V\" L\"U\"])"
]
},
{
"cell_type": "markdown",
"id": "85ea48e5",
"metadata": {},
"source": [
"The value $ V $ is increasing because higher $ w $ generates a higher wage flow conditional on staying employed.\n",
"\n",
"At this point, it’s natural to ask how the model would respond if we perturbed the parameters.\n",
"\n",
"These calculations, called comparative statics, are performed in the next section."
]
},
{
"cell_type": "markdown",
"id": "f90b7bf7",
"metadata": {},
"source": [
"## The Reservation Wage\n",
"\n",
"Once $ V $ and $ U $ are known, the agent can use them to make decisions in the face of a given wage offer.\n",
"\n",
"If $ V(w) > U $, then working at wage $ w $ is preferred to unemployment.\n",
"\n",
"If $ V(w) < U $, then remaining unemployed will generate greater lifetime value.\n",
"\n",
"Suppose in particular that $ V $ crosses $ U $ (as it does in the preceding figure).\n",
"\n",
"Then, since $ V $ is increasing, there is a unique smallest $ w $ in the set of possible wages such that $ V(w) \\geq U $.\n",
"\n",
"We denote this wage $ \\bar w $ and call it the reservation wage.\n",
"\n",
"Optimal behavior for the worker is characterized by $ \\bar w $\n",
"\n",
"- if the wage offer $ w $ in hand is greater than or equal to $ \\bar w $, then the worker accepts \n",
"- if the wage offer $ w $ in hand is less than $ \\bar w $, then the worker rejects \n",
"\n",
"\n",
"If $ V(w) < U $ for all $ w $, then the function returns np.inf.\n",
"\n",
"Let’s use it to look at how the reservation wage varies with parameters.\n",
"\n",
"In each instance below we’ll show you a figure and then ask you to reproduce it in the exercises."
]
},
{
"cell_type": "markdown",
"id": "5771db46",
"metadata": {},
"source": [
"### The Reservation Wage and Unemployment Compensation\n",
"\n",
"First, let’s look at how $ \\bar w $ varies with unemployment compensation.\n",
"\n",
"In the figure below, we use the default parameters in the McCallModel tuple, apart from\n",
"c (which takes the values given on the horizontal axis)\n",
"\n",
"![https://julia.quantecon.org/_static/figures/mccall_resw_c.png](https://julia.quantecon.org/_static/figures/mccall_resw_c.png)\n",
"\n",
" \n",
"As expected, higher unemployment compensation causes the worker to hold out for higher wages.\n",
"\n",
"In effect, the cost of continuing job search is reduced."
]
},
{
"cell_type": "markdown",
"id": "e2d72b65",
"metadata": {},
"source": [
"### The Reservation Wage and Discounting\n",
"\n",
"Next let’s investigate how $ \\bar w $ varies with the discount rate.\n",
"\n",
"The next figure plots the reservation wage associated with different values of\n",
"$ \\beta $\n",
"\n",
"![https://julia.quantecon.org/_static/figures/mccall_resw_beta.png](https://julia.quantecon.org/_static/figures/mccall_resw_beta.png)\n",
"\n",
" \n",
"Again, the results are intuitive: More patient workers will hold out for higher wages."
]
},
{
"cell_type": "markdown",
"id": "0e4af2d0",
"metadata": {},
"source": [
"### The Reservation Wage and Job Destruction\n",
"\n",
"Finally, let’s look at how $ \\bar w $ varies with the job separation rate $ \\alpha $.\n",
"\n",
"Higher $ \\alpha $ translates to a greater chance that a worker will face termination in each period once employed.\n",
"\n",
"![https://julia.quantecon.org/_static/figures/mccall_resw_alpha.png](https://julia.quantecon.org/_static/figures/mccall_resw_alpha.png)\n",
"\n",
" \n",
"Once more, the results are in line with our intuition.\n",
"\n",
"If the separation rate is high, then the benefit of holding out for a higher wage falls.\n",
"\n",
"Hence the reservation wage is lower."
]
},
{
"cell_type": "markdown",
"id": "44cae2d0",
"metadata": {},
"source": [
"## Exercises"
]
},
{
"cell_type": "markdown",
"id": "ff59e07b",
"metadata": {},
"source": [
"### Exercise 1\n",
"\n",
"Reproduce all the reservation wage figures shown above."
]
},
{
"cell_type": "markdown",
"id": "af37143d",
"metadata": {},
"source": [
"### Exercise 2\n",
"\n",
"Plot the reservation wage against the job offer rate $ \\gamma $.\n",
"\n",
"Use"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4768bef4",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"gamma_vals = range(0.05, 0.95, length = 25)"
]
},
{
"cell_type": "markdown",
"id": "54b6e88c",
"metadata": {},
"source": [
"Interpret your results."
]
},
{
"cell_type": "markdown",
"id": "31261c06",
"metadata": {},
"source": [
"## Solutions"
]
},
{
"cell_type": "markdown",
"id": "cfbf5371",
"metadata": {},
"source": [
"### Exercise 1\n",
"\n",
"Using the solve_mccall_model function mentioned earlier in the lecture,\n",
"we can create an array for reservation wages for different values of $ c $,\n",
"$ \\beta $ and $ \\alpha $ and plot the results like so"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "07324f9f",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"c_vals = range(2, 12, length = 25)\n",
"\n",
"models = [McCallModel(c = cval) for cval in c_vals]\n",
"sols = solve_mccall_model.(models)\n",
"w_bar_vals = [sol.w_bar for sol in sols]\n",
"\n",
"plot(c_vals,\n",
" w_bar_vals,\n",
" lw = 2,\n",
" alpha = 0.7,\n",
" xlabel = \"unemployment compensation\",\n",
" ylabel = \"reservation wage\",\n",
" label = L\"$\\overline{w}$ as a function of $c$\")"
]
},
{
"cell_type": "markdown",
"id": "c7880f8c",
"metadata": {},
"source": [
"Note that we could’ve done the above in one pass (which would be important if, for example, the parameter space was quite large)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "11eca699",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"w_bar_vals = [solve_mccall_model(McCallModel(c = cval)).w_bar for cval in c_vals];\n",
"# doesn't allocate new arrays for models and solutions"
]
},
{
"cell_type": "markdown",
"id": "428e18bd",
"metadata": {},
"source": [
"### Exercise 2\n",
"\n",
"Similar to above, we can plot $ \\bar w $ against $ \\gamma $ as follows"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3702b0a1",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"gamma_vals = range(0.05, 0.95, length = 25)\n",
"\n",
"models = [McCallModel(gamma = gammaval) for gammaval in gamma_vals]\n",
"sols = solve_mccall_model.(models)\n",
"w_bar_vals = [sol.w_bar for sol in sols]\n",
"\n",
"plot(gamma_vals, w_bar_vals, lw = 2, alpha = 0.7, xlabel = \"job offer rate\",\n",
" ylabel = \"reservation wage\",\n",
" label = L\"$\\overline{w}$ as a function of $\\gamma$\")"
]
},
{
"cell_type": "markdown",
"id": "b5a3be48",
"metadata": {},
"source": [
"As expected, the reservation wage increases in $ \\gamma $.\n",
"\n",
"This is because higher $ \\gamma $ translates to a more favorable job\n",
"search environment.\n",
"\n",
"Hence workers are less willing to accept lower offers."
]
}
],
"metadata": {
"date": 1704478550.8050246,
"filename": "mccall_model_with_separation.md",
"kernelspec": {
"display_name": "Julia",
"language": "julia",
"name": "julia-1.10"
},
"title": "Job Search II: Search and Separation"
},
"nbformat": 4,
"nbformat_minor": 5
}