Skip to content

Commit

Permalink
misc
Browse files Browse the repository at this point in the history
  • Loading branch information
jstac committed Sep 19, 2018
1 parent 1781e79 commit 90382fb
Showing 1 changed file with 396 additions and 0 deletions.
396 changes: 396 additions & 0 deletions finite_life_job_search/job_search_finite.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,396 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem Set 2: Job Search"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A Python solution to the finite life Job Search problem.\n",
"\n",
"We start with some imports"
]
},
{
"cell_type": "code",
"execution_count": 151,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import quantecon as qe\n",
"\n",
"from numba import njit, prange\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To keep the code simple, some variables will be global."
]
},
{
"cell_type": "code",
"execution_count": 152,
"metadata": {},
"outputs": [],
"source": [
"T = 65\n",
"w_vals = (7, 10, 11)\n",
"p = (0.25, 0.5, 0.25)\n",
"p_cdf = np.cumsum(p)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here's a little function to draw from $p$"
]
},
{
"cell_type": "code",
"execution_count": 153,
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def draw_from_offer_distribution():\n",
" return qe.random.draw(p_cdf)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"The next function computes values and policies.\n",
"\n",
"The possible wage values are $w_0, w_1, w_2$\n",
"\n",
"The value functions $v_t(w)$ are returned as a matrix $V$ of the form\n",
"\n",
"$$\n",
"V = \n",
"\\begin{pmatrix}\n",
" v_0(w_0) & v_0(w_1) & v_0(w_2) \\\\\n",
" v_1(w_0) & v_1(w_1) & v_1(w_2) \\\\\n",
" & \\vdots & \\\\\n",
" v_t(w_0) & v_t(w_1) & v_t(w_2) \\\\\n",
" & \\vdots & \n",
"\\end{pmatrix}\n",
"$$\n",
"\n",
"The policy functions, which give the optimal choice at each state and time, have the interpretation\n",
"\n",
"$$ \\sigma_t(w) =\n",
"\\begin{cases}\n",
" 1 & \\text{if accept $w$ at time $t$} \\\\\n",
" 0 & \\text{otherwise}\n",
"\\end{cases}\n",
"$$\n",
"\n",
"The policy functions are returned as a matrix $\\sigma$ of the form\n",
"\n",
"$$\n",
"\\sigma = \n",
"\\begin{pmatrix}\n",
" \\sigma_0(w_0) & \\sigma_0(w_1) & \\sigma_0(w_2) \\\\\n",
" \\sigma_1(w_0) & \\sigma_1(w_1) & \\sigma_1(w_2) \\\\\n",
" & \\vdots & \\\\\n",
" \\sigma_t(w_0) & \\sigma_t(w_1) & \\sigma_t(w_2) \\\\\n",
" & \\vdots & \n",
"\\end{pmatrix}\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 154,
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def compute_values_and_policies(β=0.96, c=8):\n",
"\n",
" n = len(w_vals) \n",
" V = np.empty((T, n))\n",
" σ = np.zeros((T, n), dtype=np.int64)\n",
"\n",
" t = T-1\n",
" for i, w in enumerate(w_vals):\n",
" V[t, i] = max(c, w) \n",
" σ[t, i] = (w > c)\n",
"\n",
" while t > 0:\n",
" for i, w in enumerate(w_vals):\n",
" \n",
" accept_val = w * (1 - β**(T-t+1)) / (1 - β)\n",
" EV = 0.0\n",
" for j in range(n):\n",
" EV += V[t, j] * p[j]\n",
" continue_val = c + β * EV\n",
" \n",
" if accept_val > continue_val:\n",
" σ[t-1, i] = 1\n",
" V[t-1, i] = accept_val\n",
" else:\n",
" V[t-1, i] = continue_val\n",
" \n",
" t -= 1\n",
"\n",
" return V, σ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here's jitted code that simulates the life of one agent, recording the wage that they accept at and their age when they accept."
]
},
{
"cell_type": "code",
"execution_count": 166,
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def sim_life(σ):\n",
" for t in range(T):\n",
" i = draw_from_offer_distribution()\n",
" if σ[t, i] == 1:\n",
" accepted_wage = w_vals[i]\n",
" start_work_age = t\n",
" return accepted_wage, start_work_age+1\n",
" \n",
" start_work_age = T\n",
" accepted_wage = 0\n",
" return accepted_wage, start_work_age"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here's a function that simulates the lives of many agents and takes an average over their statistics.\n",
"\n",
"Parallelization is not implemented because the individual calculations are so short."
]
},
{
"cell_type": "code",
"execution_count": 167,
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def sim_stats(σ, m=1_000_000):\n",
" wage_mean = 0\n",
" age_mean = 0\n",
" for i in range(m):\n",
" accepted_wage, start_work_age = sim_life(σ)\n",
" age_mean += start_work_age\n",
" wage_mean += accepted_wage\n",
" return wage_mean / m, age_mean / m\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's actually compute the optimal policies and simulate some agents to calculate statistics."
]
},
{
"cell_type": "code",
"execution_count": 178,
"metadata": {},
"outputs": [],
"source": [
"\n",
"V, σ = compute_values_and_policies()"
]
},
{
"cell_type": "code",
"execution_count": 179,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 153 ms, sys: 0 ns, total: 153 ms\n",
"Wall time: 151 ms\n"
]
}
],
"source": [
"%%time\n",
"\n",
"wage_mean, age_mean = sim_stats(σ)"
]
},
{
"cell_type": "code",
"execution_count": 180,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"11.0"
]
},
"execution_count": 180,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wage_mean"
]
},
{
"cell_type": "code",
"execution_count": 181,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.999721"
]
},
"execution_count": 181,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"age_mean"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Total time to simulate for 1,000,000 agents is a few hundred ms on my machine."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What happens when we change $c$?"
]
},
{
"cell_type": "code",
"execution_count": 182,
"metadata": {},
"outputs": [],
"source": [
"\n",
"V, σ = compute_values_and_policies(c=4.5)"
]
},
{
"cell_type": "code",
"execution_count": 183,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 103 ms, sys: 0 ns, total: 103 ms\n",
"Wall time: 101 ms\n"
]
}
],
"source": [
"%%time\n",
"\n",
"wage_mean, age_mean = sim_stats(σ)"
]
},
{
"cell_type": "code",
"execution_count": 184,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10.71835"
]
},
"execution_count": 184,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wage_mean"
]
},
{
"cell_type": "code",
"execution_count": 185,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.876221"
]
},
"execution_count": 185,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"age_mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 90382fb

Please sign in to comment.