diff --git a/models/We-Would-Like-In-Econ-ARK/CGM.pdf b/models/We-Would-Like-In-Econ-ARK/CGM.pdf new file mode 100644 index 0000000..5ca7780 Binary files /dev/null and b/models/We-Would-Like-In-Econ-ARK/CGM.pdf differ diff --git a/models/We-Would-Like-In-Econ-ARK/CGM/CGM.pdf b/models/We-Would-Like-In-Econ-ARK/CGM/CGM.pdf new file mode 100644 index 0000000..5ca7780 Binary files /dev/null and b/models/We-Would-Like-In-Econ-ARK/CGM/CGM.pdf differ diff --git a/models/We-Would-Like-In-Econ-ARK/CGM/Consumption and Portfolio Choice Over the Life Cycle-CGM.ipynb b/models/We-Would-Like-In-Econ-ARK/CGM/Consumption and Portfolio Choice Over the Life Cycle-CGM.ipynb new file mode 100644 index 0000000..46079d8 --- /dev/null +++ b/models/We-Would-Like-In-Econ-ARK/CGM/Consumption and Portfolio Choice Over the Life Cycle-CGM.ipynb @@ -0,0 +1,391 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Consumption and Portfolio Choice Over the Life Cycle (2005)\n", + "## John F. Cocco, Francisco J. Gomes and Pascal J. Maenhout (Review of Financial Studies)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Why I chose this paper \n", + "\n", + "I picked up this paper because of the seminar that we had the other day by Prof. Sylvain Catherine of Wharton. His paper, \"Countercyclical Income Risk and Portfolio Choices over the Life-Cycle\" *(forthcoming, RFS)*. To quote from Sylavain (2019),\n", + "\n", + "* a large literature (Cocco et.al 05) studies how human capital risk\n", + " affects the optimal demand for stocks over the life-cycle. Because the correlation between stock\n", + " market returns and labor income shocks is close to zero, most papers conclude that human capital\n", + "is a substitute for bonds and should increase the demand for equity. This conclusion creates two\n", + "problems. \n", + "\n", + "* First, as the share of human capital in total wealth declines over the life-cycle, so should\n", + " the share of financial wealth invested in equity (Jagannathan and R. Kocherlakota (1996)).1 This\n", + " prediction is not supported by the data. On the contrary, the stock market participation rate of US households rises with age until retirement. \n", + "\n", + "* conditional on participation, the share\n", + " of financial wealth they invest in equity does not decrease before retirement (Bertaut and StarrMcCluer (2002), Ameriks and Zeldes (2004)). Second, when human capital increases the demand\n", + " for stocks, life-cycle models need unrealistically high levels of risk aversion to match the average\n", + " equity share of working households.\n", + " These discrepancies are evidence that households make significant investment mistakes or that\n", + " economists do not understand the nature of their background risk." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C:\\Users\\AKG\n" + ] + } + ], + "source": [ + "cd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## This paper's objective\n", + "\n", + "* The main contribution of their article is to solve a realistically calibrated life cycle model of consumption and portfolio choice with uninsurable labor income risk, which allows them to obtain a measure of the importance of market-incompleteness and labor income risk for investment behavior. Moreover, they quantify the utility cost associated with alternative portfolio rules, for realistic heterogeneity in investors. To sum up, heterogeneity plays a role through the investors.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Associated Literature \n", + "\n", + "* Several Papers that look at portfolio choice and consumption decisions.\n", + "\n", + " * Heaton and Lucas (1997), Koo (1998), and Viceira (2001) consider infinite-horizon models of portfolio choice with uninsurable labor income risk. Viceira (2001) captures retirement effects through a constant probability of zero labor income forever.\n", + " * Bertaut and Haliassos (1997), Davis and Willen (2000), and Gakidis (1999) consider finite-horizon models and to this extent are closer to our article. Dammon, Spatt, and Zhang (2001) introduce taxes inthis framework, while Constantinides, Donaldson, and Mehra (2002) and Storesletten, Telmer, and Yaron (2000) explore the asset pricing implications of these models. The papers by Cocco (2004), Hu (2002), and Yao and Zhang (2004) study the implications of introducing housing in a life-cycle model.\n", + " * Their model can be seen as extending the recent consumption literature on buffer-stock saving [Deaton (1991), Carroll (1997), and Gourinchas and Parker (2002)] to include an asset allocation decision." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* t denotes adult age.\n", + "* The investor is adult for a max. of T periods out of which he works the first K (exogenous and deterministic).\n", + "* $p_{t}$ denotes the conditional probability that the investor is alive at date t+1 given being alive at date t.\n", + "* Investor's preferences are given by time-separable utility function:\n", + "\n", + "\n", + "$$\n", + "E_{1} \\sum_{t=1}^{T} \\delta^{t-1}\\left(\\prod_{j=0}^{t-2} p_{j}\\right)\\left\\{p_{t-1} \\frac{C_{i t}^{1-\\gamma}}{1-\\gamma}+b\\left(1-p_{t-1}\\right) \\frac{D_{i t}^{1-\\gamma}}{1-\\gamma}\\right\\}\n", + "$$\n", + "\n", + "where $\\delta <1$ is the discount factor. $C_{it}$ is the level of date t consumption for the $i^{th}$ investor, $\\gamma$ is the coefficient of risk aversion and $D_{it}$ is the amount of wealth investor bequeaths to his descendants at death.\n", + "\n", + "\n", + "* Labor Income Process\n", + "$$\n", + "The labor income process. Before retirement, investor $i^{th}$ age t labor income $Y_{it}$ is exogenously given by\n", + "\n", + "\\begin{aligned} \\log \\left(Y_{i t}\\right)=f\\left(t, Z_{i t}\\right)+v_{i t}+\\varepsilon_{i t} \\end{aligned} for t $\\leq$ K.\n", + "\n", + "where $v_{it}$ is given by\n", + "\n", + "\\begin{aligned} v_{i,t}=v_{i,t-1}+u_{it} \\end{aligned}\n", + "\n", + "where $u_{it}$ is distributed as $N(0,\\sigma_{u}^2)$ and is uncorrelated with $\\varepsilon_{i,t}$.\n", + "\n", + "* The assumption that labor income is exogenous is made primarily for simplicity. In reality individuals must decide how many hours to work and how much effort to put on the job, decisions that will influence the amount of labor income received.\n", + "\n", + "* Retirement income is modeled as a constant fraction $\\lambda$ of permanent labor income in the last working year\n", + "\n", + "\\begin{aligned} \\log (Y_{i t})=\\log (\\lambda)+f\\left(K, Z_{i K}\\right)+v_{i K} \\end{aligned} for t $\\geq$ K \n", + "$$\n", + "\n", + "* Financial Assets\n", + " Two risky assets (riskless and risky), with borrowing and short-selling constraints.\n", + "\n", + "\n", + "* The investor solves the classic oprimization problem\n", + "$$\n", + "\\begin{array}{l}{\\text { The Bellman equation for this problem is given by: }} \\\\ {\\qquad V_{i t}\\left(X_{i t}\\right)=\\operatorname{Max}_{C_{n} \\geq 0,0 \\leq \\alpha_{w} \\leq 1}\\left[U\\left(C_{i t}\\right)+\\delta p_{t} E_{t} V_{i, t+1}\\left(X_{i, t+1}\\right)\\right] \\text { for } t 0$ (where $v(\\epsilon,k)$ is the value function of an incumbent firm and $m^{*}$ is the mass of entrants in equilibrium.)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Household##\n", + "\n", + "Finally, there is a representative household with preferences over consumption $C_{t}$ and labor $N_{t}$ represented by the expected utility function\n", + "\n", + "$$\\mathrm E_{0} \\sum_{t=0}^{\\infty} \\beta^{t}(log C_{t}- aN_{t})$$\n", + "where $\\beta$ and $a$ are parameters. Output here is used for consumption, investment, capital adjustment costs, entry costs and operating costs. A steady state recursive competitive equilibrium of this economy is a set of incumbent value functions $\\nu(\\epsilon,k)$. policy rules $k'(\\epsilon,k)$ and $n(\\epsilon,k)$, a mass of entrants per period $m^{*}$, a measure of active firms at the beginning of period $g^{*}(\\epsilon,k)$ and real wage $w^{*}$ such that \n", + "\n", + "\\begin{itemize}\n", + "\n", + "\\item incumbent firms maximize their firm value;\n", + "\n", + "\\item the free entry condition holds;\n", + "\n", + "\\item the labor market clears;\n", + "\n", + "\\item the measure of active firms $g^{*}(\\epsilon,k)$ is stationary.\n", + "\n", + "\\end{itemize}\n", + "\n", + "More formally, let me define the recursive equilibirum now." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Recursive Equilibrium\n", + "\n", + "At the beginning of each period, incumbent firms must pay a fixed cost \\( c_{f} \\) units of output to remain in operation. A firm that does not pay this fixed cost permanently exits the economy immediately and sells its entire capital stock with value \\( (1-\\delta) k, \\)\n", + "i.e. \\( V_{x}(k)=(1-\\delta) k \\)​\n", + "​\n", + "Then, the start-of-period value of an incumbent firm is dictated by the function \\( V(\\lambda, k, s) \\) which solves the following functional equation:​\n", + "\\[ V(\\varepsilon, k)=\\max \\left\\{V_{x}(k), \\tilde{V}(\\varepsilon, k)-c_{f}\\right\\} \\] Given that firms accumulate capital according to the accumulation equation \\( k_{j t+1}= \\) \\( (1-\\delta) k_{j t}+i_{j t} \\) and capital accumulation incurs the adjustment cost \\( -\\frac{\\varphi}{2}\\left(\\frac{i_{jt} }{k_{j t}}\\right)^{2} k_{j t} \\), in units of output​\n", + "​\n", + "The prospective value of an entrant is \\[ V(\\varepsilon, 0)=\\max \\left\\{0, \\tilde{V}(\\varepsilon, 0)-c_{e}\\right\\} \\] hence, she will invest and start operating if and only if \\( c_{e} \\leq \\int V(\\varepsilon, 0) d \\varepsilon \\)\n", + "For a given Markov process, a recursive competitive equilibrium consists of\n", + "(i) value functions \\( V(\\varepsilon, k), \\bar{V}(\\varepsilon, k) \\) and \\( V_{e}(\\varepsilon, 0), \\);\n", + "(ii) policy functions \\( n(\\varepsilon, k), k^{\\prime}(\\varepsilon, k), \\);\n", + "(iii) bounded sequences of wages \\( \\left\\{w_{t}\\right\\}_{t=0}^{\\infty}, \\) incumbents' measures \\( \\left\\{g_{t}\\right\\}_{t=1}^{\\infty}, \\) and entrants' measures \\( \\left\\{m_{t}\\right\\}_{t=0}^{\\infty} \\) such that, for all \\( t \\geq 0 \\).\n", + "\n", + "1. \\( V(\\varepsilon, k), \\tilde{V}(\\varepsilon, k), \\) and \\( n(\\varepsilon, k) \\) solve the incumbent's optimization problem;\n", + "\n", + "2. \\( V_{e}(\\varepsilon, 0) \\) and \\( k^{\\prime}(\\lambda, 0) \\) solve the entrant's optimization problem;\n", + "\n", + "3. The representative houschold chooses consumption and labour such that \\( \\frac{w(g)}{C(g)}= \\) \\( \\frac{a}{N(g)} \\);\n", + "\n", + "4. The labour market clears: \\( N\\left(w_{t}\\right)=\\int n\\left(\\varepsilon_{t}, k\\right) g_{t}(\\varepsilon, k) d \\varepsilon d k \\forall t \\geq 0 \\);\n", + "\n", + "5. The goods market clears: \\( C\\left(g_{t}\\right)=\\int\\left[y\\left(\\varepsilon_{t}, k\\right)-i\\left(\\varepsilon_{t}, k\\right)\\right] g_{t}(\\varepsilon, k) d \\varepsilon d k: \\forall t \\geq 0 \\)." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "# Need to put all of them in one class, \n", + "# Workhorse model for Firm Heterogeneity, \n", + "# Works well for Khan and Thomas (2008),Clementi and Palazzo (AEJ Macro 2016)\n", + "# Parameters set-up\n", + "\n", + "theta = 0.21 #capital share\n", + "mu = 0.64 #labor share\n", + "delta = 0.1 #depreciation\n", + "beta = 0.96 #discount factor\n", + "varphi = 0.5 #convex cost adjustment parameter \n", + "rho = 0.9 #Idiosyncratic process parameter\n", + "sigma = 0.02 # Standard dev. of idiosyncratic iid shocks\n", + "n_ss = 0.6 #labor supply steady state\n", + "cf = 0.01 #Incumbent's cost of operation\n", + "ce= 0.02 #entrant's cost of operation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Representative Agent Steady State" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We begin by analysing the steady state equilibrium of the model in which there is a representative firm and productivity is equal to the mean value of \\( \\varepsilon \\). In this scenario, the steady state recursive competitive equilibrium is characterized by a set \\( V^{*}(\\bar{\\varepsilon}, k), C^{*}, N^{*}, w^{*} \\) and \\( g(\\bar{\\varepsilon}, k)^{*} \\) such that​\n", + "1. \\( V^{*}(\\bar{\\varepsilon}, k) \\) solves the representative firm's optimization problem (i.e. Bellman eq.);​\n", + "2. Taking \\( N^{*} \\) as given, the representative household's optimization is satisfied by \\( \\frac{w^{*}}{C^{*}}=\\frac{a}{N^{*}} \\)\n", + "3. Labour market clearing follows from \\( N^{*}\\left(w_{t}\\right)=\\int n(\\bar{\\varepsilon}, k) g(\\bar{\\varepsilon}, k) d k \\forall t \\geq 0 \\)\n", + "4. The goods market satisfies \\( C^{*}=\\int[y(\\bar{\\varepsilon}, k)-i(\\bar{\\varepsilon}, k)] g(\\bar{\\varepsilon}, k) d k \\forall t \\geq 0 \\)\n", + "​\n", + "Now, assume that steady state labour supply is \\( N_{r e p}^{*}=0.6 . \\) Then, we can use the following system of equations to solve for \\( K_{r e p}^{*} \\) and \\( w_{r e p}^{*}=0.6 . \\) Then, we can use the \\[ \\bar{n}=0.6 \\]​\n", + "\\( \\bar{r}=\\frac{1}{\\beta}-(1-\\delta) \\)\n", + "\\( \\bar{k}=\\frac{1}{\\beta}-(1-\\delta) \\)\n", + "\\( \\bar{k}=\\delta \\bar{k} \\)\n", + "\\( \\bar{i}=\\nu \\bar{k} \\)​\n", + "\\( \\bar{w}=\\nu \\bar{k}^{\\theta} \\bar{n}^{\\nu-1} \\)​\n", + "\\( \\bar{c}=\\bar{k}^{\\theta} \\bar{n}^{\\nu}-\\bar{i} \\)​\n", + "\\( \\bar{a}=\\frac{w^{*} n^{*}}{c^{*}} \\)​\n", + "​\n", + "In particular, \\( K_{r e p}^{*}=1.09 \\) and \\( w_{r e p}^{*}=0.78 . \\)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "def get_ss():\n", + " \n", + " r = (1 / beta) - (1 - delta)\n", + " n = n_ss\n", + " eps = 0\n", + " k = (r / ((n ** mu) * theta * np.exp(eps))) ** (1 / (theta - 1))\n", + " y = np.exp(eps) * (k ** theta) * (n ** mu)\n", + " i = delta * k\n", + " c = y - i\n", + " w = mu * y / n\n", + " a = w / c\n", + " \n", + " return k, w " + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.0881001887382777\n", + "0.7829715643830996\n" + ] + } + ], + "source": [ + "k_ss, w_ss = get_ss()\n", + "print(k_ss)\n", + "print(w_ss)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Incumbent Firms' Decision Rule (Tauchen's method first usage)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "### k_grid\n", + "N_k = 50\n", + "k_low = k_ss - 0.5\n", + "k_high = k_ss + 0.5\n", + "k_grid = np.linspace(k_low, k_high, N_k)\n", + "\n", + "### eps_grid using Tauchen\n", + "## https://lectures.quantecon.org/jl/finite_markov.html\n", + "N_eps = 10\n", + "trans_eps_MC = tauchen(rho, sigma, n=N_eps).P\n", + "\n", + "sigma_y = np.sqrt( sigma ** 2 / (1 - rho ** 2) )\n", + "m = 3\n", + "eps_grid = np.zeros(N_eps)\n", + "eps_grid[0] = -m * sigma_y\n", + "eps_grid[N_eps-1] = m * sigma_y\n", + "s = (eps_grid[N_eps-1] - eps_grid[0]) / (N_eps - 1)\n", + "for i in range(1, N_eps-1):\n", + " eps_grid[i] = eps_grid[i-1] + s\n", + " \n", + "\n", + "# Now we initialize the value function:\n", + "V_init = np.zeros((N_eps, N_k))" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5881001887382777" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "k_low" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.5881001887382777" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "k_high" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[5.30478170e-01, 4.15375002e-01, 5.32885772e-02, 8.56706028e-04,\n", + " 1.54439460e-06, 2.92857183e-10, 5.66213743e-15, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [9.67966302e-02, 4.93930466e-01, 3.69971746e-01, 3.87971726e-02,\n", + " 5.03259844e-04, 7.25892202e-07, 1.09655174e-10, 1.66533454e-15,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [3.71959075e-03, 1.21954964e-01, 5.23228103e-01, 3.23146274e-01,\n", + " 2.76615366e-02, 2.89198006e-04, 3.33562232e-07, 4.01295663e-11,\n", + " 4.44089210e-16, 0.00000000e+00],\n", + " [2.52812798e-05, 5.78316444e-03, 1.54270165e-01, 5.43701344e-01,\n", + " 2.76746317e-01, 1.93110204e-02, 1.62557651e-04, 1.49849563e-07,\n", + " 1.43532963e-11, 2.22044605e-16],\n", + " [2.82551739e-08, 4.80546862e-05, 8.83083400e-03, 1.91241547e-01,\n", + " 5.54230974e-01, 2.32360418e-01, 1.31987073e-02, 8.93711456e-05,\n", + " 6.58100220e-08, 5.01754194e-12],\n", + " [5.01748193e-12, 6.58100220e-08, 8.93711456e-05, 1.31987073e-02,\n", + " 2.32360418e-01, 5.54230974e-01, 1.91241547e-01, 8.83083400e-03,\n", + " 4.80546862e-05, 2.82551740e-08],\n", + " [1.39013711e-16, 1.43532786e-11, 1.49849563e-07, 1.62557651e-04,\n", + " 1.93110204e-02, 2.76746317e-01, 5.43701344e-01, 1.54270165e-01,\n", + " 5.78316444e-03, 2.52812798e-05],\n", + " [5.94563576e-22, 4.89150847e-16, 4.01295059e-11, 3.33562232e-07,\n", + " 2.89198006e-04, 2.76615366e-02, 3.23146274e-01, 5.23228103e-01,\n", + " 1.21954964e-01, 3.71959075e-03],\n", + " [3.89946474e-28, 2.57578327e-21, 1.68195357e-15, 1.09655162e-10,\n", + " 7.25892202e-07, 5.03259844e-04, 3.87971726e-02, 3.69971746e-01,\n", + " 4.93930466e-01, 9.67966302e-02],\n", + " [3.90429771e-35, 2.08116592e-27, 1.09035811e-20, 5.65165946e-15,\n", + " 2.92857227e-10, 1.54439460e-06, 8.56706028e-04, 5.32885772e-02,\n", + " 4.15375002e-01, 5.30478170e-01]])" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trans_eps_MC" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-0.13764944, -0.10706068, -0.07647191, -0.04588315, -0.01529438,\n", + " 0.01529438, 0.04588315, 0.07647191, 0.10706068, 0.13764944])" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eps_grid" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "n = lambda eps, k: (w / (mu * np.exp(eps) * k ** theta)) ** (1 / (mu - 1)) #closed form solution for n" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "w = w_ss" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((eps, k)>, 0.7829715643830996)" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n,w" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Value Function Iteration (with interpolation) , plotting the value function with indicator for continuation" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "def vf_update(eps_index, k_index, V_old_interp, w, cf):\n", + " \"\"\"\n", + " input:\n", + " k_index: index so that k_grid[index] corresponds to value of capital this period (state)\n", + " V_old: approximation to the value function. V_old[i] approximates V(k_grid[i]).\n", + " \n", + " output:\n", + " action_value: value of all possible state-action pairs.\n", + " \"\"\"\n", + " \n", + " ### solve v1\n", + " eps = eps_grid[eps_index]\n", + " k = k_grid[k_index]\n", + "\n", + " n = (w / (mu*np.exp(eps)*k**theta))**(1/(mu-1))\n", + " action_value = np.zeros((N_k, N_eps))\n", + " \n", + " \n", + " profit = np.exp(eps) * (k ** theta) * (n ** mu) - w * n - (k_grid - (1 - delta) * k) \\\n", + " - varphi / 2 * (k_grid / k - (1 - delta)) ** 2 * k \n", + " \n", + " \n", + " action_value = profit + beta * np.dot((trans_eps_MC[eps_index, :]).T, V_old_interp(eps_grid, k_grid).T)\n", + " \n", + " V1_new = np.max(action_value)\n", + " \n", + " ### solve v_new\n", + " V_new = max((1 - delta) * k, V1_new - cf)\n", + " \n", + " return V_new, action_value" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "def vf_update_iteration(V_old, V_old_interp, w, cf):\n", + " \"\"\"\n", + " input: \n", + " V_old: array with current approximation of the value function\n", + " \n", + " output:\n", + " V_new: updated approximation of the value function\n", + " \"\"\"\n", + " V_new = np.zeros_like(V_old)\n", + " \n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " V_new[i, j], action_value = vf_update(i, j, V_old_interp, w, cf)\n", + "\n", + " return V_new" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "def solve_value_func_iter(w, cf, plot=True):\n", + " difference_list = []\n", + " threshold = 1e-10\n", + " max_iterations = 10000\n", + " plot_interval = 50\n", + "\n", + " V = V_init.copy()\n", + "\n", + " for iteration in range(max_iterations):\n", + " \n", + " # x.size = m and y.size = n, if z.ndim == 2, then z must have shape (n, m)\n", + " V_interp = intpl.interp2d(eps_grid, k_grid, V.T, kind='linear')\n", + " V_new = vf_update_iteration(V, V_interp, w, cf)\n", + " #V_new = vf_update_iteration(V, V_interp, w, cf)\n", + " \n", + " \n", + " difference = np.amax(abs(V_new - V))\n", + " # print('Iteration: {}, difference: {}'.format(iteration + 1, difference))\n", + "\n", + " difference_list.append(difference) \n", + "\n", + " V = V_new\n", + "\n", + " if difference < threshold:\n", + " #print('Converged after iteration {}'.format(iteration + 1))\n", + " #print('Iteration: {}, difference: {}'.format(iteration + 1, difference))\n", + " \n", + " if plot:\n", + " fig = plt.figure()\n", + " ax = fig.gca(projection='3d')\n", + " EPS, K = np.meshgrid(eps_grid, k_grid)\n", + " surf1 = ax.scatter(EPS, K, V.T, cmap=cm.autumn)\n", + " surf2 = ax.plot_surface(EPS, K, (1 - delta) * K)\n", + " #fig.colorbar(surf1, shrink=.5, aspect=5)\n", + " ax.set_xlabel(r'$\\epsilon$')\n", + " ax.set_ylabel(r'$k$')\n", + " ax.set_zlabel(r'V')\n", + " ax.set_title(\"Value Function\")\n", + " #plt.show()\n", + " #plt.close()\n", + " \n", + " break\n", + " \n", + " return V, V_interp\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Value Function Plot" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "poly_grid = extract_policy(V, V_interp, w)" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": { + "code_folding": [] + }, + "outputs": [], + "source": [ + "#poly_grid" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Indicator for whether firm will continue" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "def firm_continue(eps, k, V_interp):\n", + " V_val = V_interp(eps, k)\n", + " if V_val == (1 - delta) * k:\n", + " return False\n", + " else:\n", + " return True" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "firm_continue(0, 5, V_interp) # for different shock realizations" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "firm_continue(0.01, 1, V_interp)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "def firm_continue_grid(V):\n", + " V_new = np.zeros_like(V)\n", + " for i in range(N_k):\n", + " V_new[:, i] = ((1 - delta) * k_grid[i] != V[:, i]) \n", + " return V_new" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [], + "source": [ + "firm_cont_grid = firm_continue_grid(V)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Function $\\hat{V}(\\epsilon)$" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [], + "source": [ + "def get_v_hat(eps, V_interp):\n", + " \n", + " eps_index = np.where(eps_grid == eps)[0][0]\n", + " vals = []\n", + " \n", + " for k_index in range(N_k):\n", + " val = - k_grid[k_index] + beta * np.dot(trans_eps_MC[eps_index, :], V_interp(eps_grid, k_grid[k_index]))\n", + " vals.append(val)\n", + " \n", + " return max(vals) " + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.3570456138244533" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_v_hat(eps_grid[4], V_interp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Market-Clearing Wage (with entry)\n", + "\n", + "Here, the free-entry condition must hold with equality, i.e. $c_{e}=\\int \\hat{v(\\epsilon)} \\nu (d\\epsilon) $. We will go for root casting where we solve the equation for w*." + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "### https://dilawarnotes.wordpress.com/2017/11/07/stationary-distribution-of-markov-chains-using-python/\n", + "def solveStationary( A ):\n", + " n = A.shape[0]\n", + " a = np.eye( n ) - A\n", + " a = np.vstack( (a.T, np.ones( n )) )\n", + " b = np.matrix( [0] * n + [ 1 ] ).T\n", + " return np.linalg.lstsq( a, b )[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Stationary Distribution of $\\epsilon$" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\AKG\\AppData\\Roaming\\Python\\Python37\\site-packages\\ipykernel_launcher.py:7: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", + "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n", + " import sys\n" + ] + }, + { + "data": { + "text/plain": [ + "array([[0.00575924],\n", + " [0.02496288],\n", + " [0.07627247],\n", + " [0.16041558],\n", + " [0.23258983],\n", + " [0.23258983],\n", + " [0.16041558],\n", + " [0.07627247],\n", + " [0.02496288],\n", + " [0.00575924]])" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stationary_dist_eps = np.array(solveStationary(trans_eps_MC))\n", + "stationary_dist_eps" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.9999999999999997" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sum(stationary_dist_eps)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Solving for Market-Clearing Wage" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [], + "source": [ + "def mark_wage_err(w, ce, cf):\n", + " V_new, V_interp_new = solve_value_func_iter(w, cf, plot=False)\n", + " \n", + " V_hats = np.zeros_like(eps_grid)\n", + " # iterate loop in parallel\n", + " \n", + " for i in range(len(eps_grid)):\n", + " V_hats[i] = get_v_hat(eps_grid[i], V_interp_new)\n", + " \n", + " integral = np.dot(V_hats, stationary_dist_eps)\n", + " err = ce - integral\n", + " #print(err)\n", + " return np.array(err)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "def solve_mark_wage(w_guess, ce, cf):\n", + " args = (ce, cf)\n", + " result = opt.root(mark_wage_err, w_guess, args = args)\n", + " return result.x[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "w_star = solve_mark_wage(0.9, 0.02, 0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.1477168978636114" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "w_star" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It could very well be the case that there might not be a solution to the above system of equations. In that case, my presumption is that the entry costs are so high that firms will never find it profitable to enter the economy." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stationary measure of firms and mass of entrants" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "poly_grid = extract_policy(V, V_interp, w_star)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "firm_cont_grid = firm_continue_grid(V)\n", + "#firm_cont_grid" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 1: Solving $g(\\epsilon, k)$" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "g_init = np.random.uniform(low=0, high=1, size=(N_eps, N_k))\n", + "g_init = g_init / np.sum(g_init)\n", + "g = g_init.copy()\n", + "m_star = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.0" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sum(g)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "@jit(nopython=True, parallel=True)\n", + "def update_g(g):\n", + " g_new = np.zeros((N_eps, N_k))\n", + " \n", + " # iterate loop in parallel\n", + " for k in range(N_eps):\n", + " for l in range(N_k):\n", + " C = (poly_grid == k_grid[l])\n", + " \n", + " summation = 0\n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " \n", + " sum_ij = trans_eps_MC[i,k] * C[i, j] * firm_cont_grid[i, j] * g[i, j] \n", + " summation += sum_ij\n", + " \n", + " summation += m_star * stationary_dist_eps[k][0]\n", + " g_new[k, l] = summation\n", + " \n", + " return g_new" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "def solve_g(plot=True):\n", + " threshold = 1e-8\n", + " max_iterations = 1000\n", + " diff = 1\n", + " g = g_init.copy()\n", + " \n", + " while (diff > 1e-5):\n", + " g_new = update_g(g) \n", + " #print('sum :', np.sum(g_new))\n", + " diff = np.max(np.abs(g_new - g))\n", + " #print(diff)\n", + " g = g_new.copy()\n", + " \n", + " g_normalized = g_new / np.sum(g_new)\n", + " \n", + " if plot:\n", + " \n", + " fig = plt.figure()\n", + " ax = fig.gca(projection='3d')\n", + " EPS, K = np.meshgrid(eps_grid, k_grid)\n", + " surf1 = ax.scatter(EPS, K, g_normalized.T, cmap=cm.autumn)\n", + " #fig.colorbar(surf1, shrink=.5, aspect=5)\n", + " #surf1 = ax.plot_wireframe(EPS, K, g_normalized.T)\n", + " ax.set_xlabel(r'$\\epsilon$')\n", + " ax.set_ylabel(r'$k$')\n", + " ax.set_zlabel(r\"$g$\")\n", + " ax.set_title(\"Law of Motion g\")\n", + " \n", + " return g_normalized" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.008800400230045531\n", + "\n", + "\n", + "iteration 2\n", + "cf val: 0.013\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.06085775753333736\n", + "\n", + "\n", + "iteration 4\n", + "cf val: 0.015\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.20422840896794556\n", + "\n", + "\n" + ] + } + ], + "source": [ + "cal_cf, error = calibrate_cf()" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.015" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cal_cf " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### (ii) Calibrating exit costs: Calibrate to target average size of new firms to be 40% of average size of all firms" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "def calibrate_ce():\n", + " \n", + " ce_range = [0.01, 0.05, 0.1, 0.2, 0.5]\n", + " error = 1000\n", + " cal_ce = 0\n", + " iteration = 1\n", + " for ce_val in ce_range:\n", + " \n", + " #print(\"iteration \", iteration)\n", + " #print(\"ce val: \", ce_val)\n", + " \n", + " w_guess = 0.9\n", + " w_star = solve_mark_wage(w_guess, ce, cal_cf)\n", + " #print(\"w_star:\", w_star)\n", + " m_guess = 0.05\n", + " m_star = solve_m(m_guess, g, w_star)\n", + " #print(\"m_star :\", m_star)\n", + " \n", + " new_error = abs(m_star - 0.4)\n", + " if new_error < error:\n", + " error = new_error\n", + " cal_ce = ce_val\n", + " \n", + " iteration += 1\n", + " \n", + " return cal_ce, error" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "cal_ce, error = calibrate_ce()" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cal_ce " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting Investment rates" + ] + } + ], + "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.7.3" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/models/We-Would-Like-In-Econ-ARK/Firm-Final/placeholder b/models/We-Would-Like-In-Econ-ARK/Firm-Final/placeholder new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/models/We-Would-Like-In-Econ-ARK/Firm-Final/placeholder @@ -0,0 +1 @@ + diff --git a/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/Firm Heterogeneity (Khan-Thomas-Winberry).ipynb b/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/Firm Heterogeneity (Khan-Thomas-Winberry).ipynb new file mode 100644 index 0000000..beed29f --- /dev/null +++ b/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/Firm Heterogeneity (Khan-Thomas-Winberry).ipynb @@ -0,0 +1,8992 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Idiosyncratic Shocks and the Role of Nonconvexities in Plant and Aggregate Investment Dynamics\n", + "## [Aubhik Khan and Julia Thomas (Econometrica, 2008)](https://www.aubhik-khan.net/ecta5894.pdf)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The paper's objective\n", + "\n", + "\n", + "* A model of lumpy investment wherein firms face persistent shocks to common and plant-specific productivity, and nonconvex adjustment costs.\n", + "\n", + "* The model extends the real business cycle model to include firm heterogeneity and fixed capital adjustment costs. The aggregate state vector of the model contains the distribution of firms over idiosyncratic productivity and capital, which evolves over time in response to aggregate productivity shocks.\n", + "\n", + "* The dynamics of the distribution must satisfy a complicated fixed point problem: each firm’s investment decision depends on its expectations of the dynamics of the distribution, and the dynamics of the distribution depend on firms’ investment decisions.\n", + "\n", + "* **This infinite-dimensional fixed point problem is at the heart of the computational challenges faced by the heterogeneous agent literature.**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Find toolbox analogue in HARK \n", + "# Analogue of tauchen for HARK\n", + "%matplotlib notebook\n", + "import numpy as np\n", + "from quantecon.markov.approximation import tauchen\n", + "import scipy.optimize as opt\n", + "from matplotlib import pyplot as plt\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "import quantecon\n", + "import scipy.interpolate as intpl\n", + "from matplotlib import cm\n", + "from numba import vectorize, jit, njit, float64, prange" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Associated Literature\n", + "\n", + "* Host of Papers that look at the heterogeneity through the firm channel.\n", + "\n", + "\n", + " * Micro-level Heterogeneity and Transmission: [Reiter, Sveen and Weinke (2013)] **(_Lumpy investment and the monetary transmission mechanism_)**, [Koby and Wolf (2019)] **(_Investment Stimulus: From Micro Elasticities to Macro Counterfactuals_)**.\n", + " \n", + " * Financial heterogeneity and the business cycle dynamics of aggregate investment: [Khan, Senga and Thomas (2016)] **(_Default Risk and Aggregate Fluctuations in an Economy with Production Heterogeneity_)**.\n", + "\n", + " * Investment and Business Cycle: [Cooper, Haltiwanger (2006)] **(_Machine Replacement and the Business Cycle: Lumps and Bumps_)**. \n", + " \n", + " * Heterogeneity and computation: [Krusell, Smith (1998)] **(_Income and wealth heterogeneity in the macroeconomy_)**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Empirics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* First, Microeconomic lumpiness continues to have perceptible effects on aggregate investment dynamics only when equilibrium factor supply considerations are ignored.\n", + " * General equilibrium itself matters tremendously in shaping aggregate dynamics. \n", + " \n", + " * First, it is extremely effective in smoothing changes in aggregate series, yielding investment rates close to the postwar U.S. data in both their cyclical variability and persistence, irrespective of capital adjustment costs. \n", + " * Second, it dampens much of the movement along the extensive margin that would otherwise distinguish the lumpy investment economy, leaving no trace of aggregate nonlinearities.\n", + "\n", + "* Second, they find that the near-zero skewness and excess kurtosis in their general equilibrium models’ aggregate investment rate series matches the third and fourth moments of postwar U.S. aggregate investment rates reasonably well, and far more closely than does the partial equilibrium lumpy model.\n", + "\n", + "* Third, they find that the microeconomic role of nonconvex capital adjustment costs can change substantially in the presence of persistent idiosyncratic risk. When plant-specific productivity shocks are volatile relative to aggregate shocks, as suggested by the data, nonconvex costs no longer cause the plant-level investment spikes that are the hallmark of lumpy investment.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Model (Winberry version of KT)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I adopt the Winberry adaptation (2018) of KT. It is useful for computation and is a little bit more tractable. This is the standard Benchmark RBC model with firm heterogeneity.\n", + "\n", + "* **Firms**\n", + "\n", + "\n", + "There is a fixed mass of firms j $\\in$ [0, 1] which produce output $y_{t}$ according to the\n", + "production function\n", + "\n", + "$$\n", + "y_{j t}=e^{z_{t}} e^{\\varepsilon_{j t}} k_{j t}^{\\theta} n_{j t}^{\\nu}, \\theta+\\nu<1\n", + "$$\n", + "\n", + "where \\( z_{t} \\) is an aggregate productivity shock, \\( \\varepsilon_{j t} \\) is an idiosyncratic productivity shock, \\( k_{j t} \\) is capital, \\( n_{j t} \\) is labor, \\( \\theta \\) is the elasticity of output with respect to capital, and \\( \\nu \\) is the elasticity of output with respect to labor. The aggregate shock \\( z_{t} \\) is common to all firms and follows the AR ( 1) process \n", + "\\[ z_{t+1}=\\rho_{z} z_{t}+\\sigma_{z} \\omega_{t+1}^{z}, \\text { where } \\omega_{t+1}^{z} \\sim N(0,1) \\]\n", + "\n", + "The idiosyncratic shock \\( \\varepsilon_{j t} \\) independently distributed across firms, but within firms follows the AR ( 1) process\n", + "\\[ \\varepsilon_{j t+1}=\\rho_{\\varepsilon} \\varepsilon_{j t}+\\sigma_{\\varepsilon} \\omega_{t+1}^{\\varepsilon}, \\text { where } \\omega_{t+1}^{\\varepsilon} \\sim N(0,1) \\]\n", + "\n", + "In each period, the firm \\( j \\) inherits its capital stock from previous periods' investments, observes the two productivity shocks, hires labor from a competitive labor market, and produces output.\n", + "\n", + "After production, the firm invests in capital for the next period. Gross investment \\( i_{j t} \\) yields \\( k_{j t+1}=(1-\\delta) k_{j t}+i_{j t} \\) units of capital next period, where \\( \\delta \\) is the depreciation rate of capital. If \\( \\frac{i_{t}}{k_{j t}} \\notin[-a, a], \\) the firm must pay a fixed adjustment cost \\( \\xi_{j t} \\) in units of labor. The parameter \\( a \\) governs a region around zero investment within firms do not incur the fixed cost. The fixed cost \\( \\xi_{j t} \\) is a random variable distributed uniformly \\( [0, ], \\) and independently over firms and time.\n", + "\n", + "* **Households**\n", + "\n", + "The function \\[ \\mathbb{E} \\sum_{t=0}^{\\infty} \\beta^{t}\\left[\\frac{C_{t}^{1-\\sigma}-1}{1-\\sigma}-\\chi \\frac{N_{t}^{1+\\alpha}}{1+\\alpha}\\right] \\] where \\( C_{t} \\) is consumption, \\( N_{t} \\) is labor supplied to the market, \\( \\beta \\) is the discount factor, \\( \\sigma \\) is the coefficient of relative risk aversion, \\( \\chi \\) governs the disutility of labor supply, and \\( 1 / \\alpha \\) is the Frisch elasticity of labor supply. The total time endowment per period is normalized to 1, so that \\( N_{t} \\in[0,1] \\). The household owns all the firms in the economy and markets are complete.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solving the Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The household optimization is loaded into the firm's optimization problem by approximating the transformed value as is done in Khan and Thomas (2008),\n", + "\n", + "\\begin{equation}\n", + "\\begin{aligned} \n", + "v(\\varepsilon, k, \\xi ; \\mathbf{s}) &=\\lambda(\\mathbf{s}) \\max _{n}\\left\\{e^{z} e^{\\varepsilon} k^{\\theta} n^{\\nu}-w(\\mathbf{s}) n\\right\\} \\\\ &+\\max \\left\\{v^{a}(\\varepsilon, k ; \\mathbf{s})-\\xi \\lambda(\\mathbf{s}) w(\\mathbf{s}), v^{n}(\\varepsilon, k ; \\mathbf{s})\\right\\} \n", + "\\end{aligned}\n", + "\\end{equation}\n", + "\n", + "where \\( \\mathrm{s} \\) is the aggregate state vector (defined below), \\( \\lambda(\\mathrm{s})=C(\\mathrm{s})^{-\\sigma} \\) is the marginal of consumption in equilibrium,\n", + "\\[ v^{a}(\\varepsilon, k ; \\mathrm{s})=\\max _{k^{\\prime} \\in \\mathbb{R}}-\\lambda(\\mathrm{s})\\left(k^{\\prime}-(1-\\delta) k\\right)+\\beta \\mathbb{E}\\left[\\widehat{v}\\left(\\varepsilon^{\\prime}, k^{\\prime} ; \\mathrm{s}^{\\prime}\\left(z^{\\prime} ; \\mathrm{s}\\right) | \\varepsilon, k ; \\mathrm{s}\\right]\\right. \\] \n", + "\n", + "\\( v^{n}(\\varepsilon, k ; \\mathbf{s})=\\max _{k^{\\prime} \\in[(1-\\delta-a) k,(1-\\delta+a) k]}-\\lambda(\\mathbf{s})\\left(k^{\\prime}-(1-\\delta) k\\right)+\\beta \\mathbb{E}\\left[\\widehat{v}\\left(\\varepsilon^{\\prime}, k^{\\prime} ; \\mathbf{s}^{\\prime}\\left(z^{\\prime} ; \\mathbf{s}\\right) | \\varepsilon, k ; \\mathbf{s}\\right]\\right. \\)\n", + "\n", + "\n", + "and \\( \\widehat{v}(\\varepsilon, k ; \\mathbf{s})=\\mathbb{E}_{\\xi} v(\\varepsilon, k, \\xi ; \\mathbf{s}) \\). Denote the unconstrained capital choice from ( 2) by \\( k^{a}(\\varepsilon, k ; \\mathbf{s}) \\) and the constrained choice from ( 3) by \\( k^{n}(\\varepsilon, k ; \\mathbf{s}) . \\) The firm will choose to pay the fixed cost if and only if \\( v^{a}(\\varepsilon, k ; \\mathbf{s})-\\xi \\lambda(\\mathbf{s}) w(\\mathbf{s}) \\geq v^{n}(\\varepsilon, k ; \\mathbf{s}) . \\) Hence, there is a unique threshold value of the fixed cost \\( \\xi \\) which makes the firm indifferent between these two options, \\[ \\tilde{\\xi}(\\varepsilon, k ; \\mathbf{s})=\\frac{v^{a}(\\varepsilon, k ; \\mathbf{s})-v^{n}(\\varepsilon, k ; \\mathbf{s})}{\\lambda(\\mathbf{s}) w(\\mathbf{s})} \\]\n", + "\n", + "Denote \\( \\widehat{\\xi}(\\varepsilon, k ; \\mathbf{s}) \\) as the threshold bounded to be within the support of \\( \\xi, \\) i.e., \\( \\widehat{\\xi}(\\varepsilon, k ; \\mathbf{s})= \\) \\( \\min \\{\\max \\{0, \\widetilde{\\xi}(\\varepsilon, k ; \\mathbf{s})\\}, \\bar{\\xi}\\}\\} \\) It will be numerically convenient to approximate the ex-ante value function \\( \\widehat{v}(\\varepsilon, k ; \\mathbf{s})= \\) \\( \\mathbb{E}_{\\xi} v(\\varepsilon, k, \\xi ; \\mathbf{s}) \\). Given that the extensive margin decision is characterized by the cutoff ( 4) and the fixed cost \\( \\xi \\) is uniformly distributed, the expectation can be computed analytically as\n", + "\n", + "\\( \\widehat{v}(\\varepsilon, k ; \\mathbf{s})=\\lambda(\\mathbf{s}) \\max _{n}\\left\\{e^{z} e^{\\varepsilon} k^{\\theta} n^{\\nu}-w(\\mathbf{s}) n\\right\\} \\)\n", + "\\[ \\quad+\\frac{\\hat{\\xi}(\\varepsilon, k ; \\mathbf{s})}{\\xi}\\left(v^{a}(\\varepsilon, k ; \\mathbf{s})-\\lambda(\\mathbf{s}) w(\\mathbf{s}) \\frac{\\widehat{\\xi}(\\varepsilon, k ; \\mathbf{s})}{\\bar{\\xi}}\\right) v^{n}(\\varepsilon, k ; \\mathbf{s}) \\]\n", + "\n", + "\n", + "* Recursive Competitive Equilibrium\n", + "\n", + "In the recursive competitive equilibrium, the aggregate state s contains the current draw of the aggregate productivity shock, \\( z, \\) and the density of firms over \\( (\\varepsilon, k) \\) -space, \\( g(\\varepsilon, k) . \\)\n", + "\n", + "A recursive competitive equilibrium for this model is a set \\( \\widehat{v}(\\varepsilon, k ; \\mathbf{s}), \\) \\( n(\\varepsilon, k ; \\mathbf{s}), k^{a}(\\varepsilon, k ; \\mathbf{s}), k^{n}(\\varepsilon, k ; \\mathbf{s}), \\widehat{\\xi}(\\varepsilon, k ; \\mathbf{s}), \\lambda(\\mathbf{s}), w(\\mathbf{s}), \\) and \\( \\mathbf{s}^{\\prime}\\left(z^{\\prime} ; \\mathbf{s}\\right)=\\left(z^{\\prime} ; g^{\\prime}(z, g)\\right) \\) such that\n", + "\n", + "1) (Firm optimization) Taking \\( w(\\mathbf{s}), \\lambda(\\mathbf{s}), \\lambda(\\mathbf{s}), \\) and \\( \\mathbf{s}^{\\prime}\\left(z^{\\prime} ; \\mathbf{s}\\right) \\) as given, \\( \\widehat{v}(\\varepsilon, k ; \\mathbf{s}), n(\\varepsilon, k ; \\mathbf{s}) \\) \\( \\quad k^{a}(\\varepsilon, k ; \\mathbf{s}), k^{n}(\\varepsilon, k ; \\mathbf{s}), \\) and \\( \\hat{\\xi}(\\varepsilon, k ; \\mathbf{s}) \\) solve the firm's optimization problem.\n", + "\n", + "2) (Household Optimization) \\(\\lambda(\\mathbf{s})=C(\\mathbf{s})^{-\\sigma}, \\) where \\( C(\\mathbf{s})=\\int\\left[e^{z} e^{\\varepsilon} k^{\\theta} n(\\varepsilon, k ; \\mathbf{s})^{\\nu}+(1-\\delta) k-\\left(\\frac{\\widehat{\\xi}(\\varepsilon, k ; \\mathbf{s})}{\\xi}\\right) k^{a}(\\varepsilon, k ; \\mathbf{s})\\right. \\) \\( \\left.-\\left(1-\\frac{\\hat{\\xi}(\\varepsilon, k ; \\mathbf{s})}{\\xi}\\right) k^{n}(\\varepsilon, k ; \\mathbf{s})\\right] g(\\varepsilon, k) d \\varepsilon d k \\) \\(w(\\mathbf{s}) \\) satisfies \\( \\int\\left(n(\\varepsilon, k ; \\mathbf{s})+\\frac{\\hat{\\xi}(\\varepsilon, k ; \\mathbf{s})^{2}}{2 \\xi}\\right) g(\\varepsilon, k) d \\varepsilon d k=\\left(\\frac{w(\\mathbf{s}) \\lambda(\\mathbf{s})}{x}\\right)^{\\frac{1}{\\alpha}} \\)\n", + "\n", + "3) (Law of motion for distribution) For all \\( \\left(\\varepsilon^{\\prime}, k^{\\prime}\\right) \\) \\( g^{\\prime}\\left(\\varepsilon^{\\prime}, k^{\\prime} ; z, \\mathbf{m}\\right)=\\iiint_{ } 1\\left\\{\\rho_{\\varepsilon} \\varepsilon+\\sigma_{\\varepsilon} \\omega_{\\varepsilon}^{\\prime}=\\varepsilon^{\\prime}\\right\\} \\times\\left[\\frac{\\hat{\\xi}(\\varepsilon, k ; z, \\mathbf{m})}{\\xi} 1\\left\\{k^{a}(\\varepsilon, k ; z, \\mathbf{m})=k^{\\prime}\\right\\}\\right] \\)\n", + "\\( \\left.g^{\\prime}\\left(\\varepsilon^{\\prime}, k^{\\prime} ; z, \\mathbf{m}\\right)=\\iiint_{^{-}}^{T}\\left(1-\\frac{\\hat{\\varepsilon}(\\varepsilon, k ; \\mathbf{m})}{\\xi}\\right) 1\\left\\{k^{n}(\\varepsilon, k ; z, \\mathbf{m})=k^{\\prime}\\right\\}\\right] \\)\n", + "\\( \\times p\\left(\\omega_{\\varepsilon}^{\\prime}\\right) g(\\varepsilon, k ; \\mathbf{m}) d \\omega_{\\varepsilon}^{\\prime} d \\varepsilon d k \\) where \\( p \\) is the pdf. of idiosyncratic productivity shocks.\n", + "\n", + "4) (Law of motion for aggregate shocks) \\( z^{\\prime}=\\rho_{z} z+\\sigma_{z} \\omega_{z}^{\\prime}, \\) where \\( \\omega_{z}^{\\prime} \\sim N(0,1) \\)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parametrization\n", + "\n", + "% Center the Table\n", + "\n", + "\n", + "| Parameter | Description | Value |\n", + "| --- | --- | --- |\n", + "| $\\beta$ | Discount Factor | .961 |\n", + "| $\\sigma$ | Utility curvature | 1 |\n", + "| $\\alpha$ | Inverse Frisch | lim $\\alpha \\rightarrow$ 0 |\n", + "| $\\chi$ | Labor Disutility | N*$=\\frac{1}{3}$ |\n", + "| $\\nu$ | Labor Share | 0.64 |\n", + "| $\\theta$ | Capital Share | 0.256|\n", + "| $\\delta$ | Capital Depreciation | 0.085 |\n", + "| $\\rho_{z}$ | Aggregate TFP AR(1) | 0.859 |\n", + "| $\\sigma_{z}$ | Aggregate TFP AR(1) | 0.014 |\n", + "| $a$ | No fixed cost region | 0.011 |\n", + "| $\\rho_{e}$ | Idiosyncratic TFP AR(1) | 0.859 |\n", + "| $\\sigma_{e}$ | Idiosyncratic TFP AR(1) | 0.022 |\n", + "| $\\bar{\\xi}$ | Fixed Cost | 0.0083 |\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computational Method \n", + "\n", + "A code readme is placed in github (to-do) to detail the method. I outline the steps briefly here.\n", + "\n", + "There are three steps involved here. \n", + "* **Step 1**\n", + "\n", + "\n", + "Approximate the model’s equilibrium objects – the value function and distribution – using finitedimensional global approximations with respect to individual state variables. This step yields\n", + "a finite-dimensional representation of the equilibrium at every point in time. \n", + "\n", + "* **Step 2**\n", + "\n", + "\n", + "Compute the stationary equilibrium of the finite-dimensional model in which there are no aggregate shocks but still idiosyncratic shocks. \n", + "\n", + "* **Step 3**\n", + "\n", + "\n", + "The final step is to compute the aggregate dynamics of the finite-dimensional model using a locally accurate\n", + "Taylor expansion around the stationary equilibrium.\n", + "\n", + "\n", + "Numerous approximation types are employed such as quadrature methods, spline approximations to move ahead with solving the model." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I try a simpler model of here and progressively will add features to it." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#Parameters (I start with fixed labor supply in steady state)\n", + "\n", + "theta = 0.21\n", + "mu = 0.64\n", + "delta = 0.1\n", + "beta = 0.96\n", + "varphi = 0.5\n", + "rho = 0.9\n", + "sigma = 0.02\n", + "n_ss = 0.6" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Steady State Block\n", + "def get_ss():\n", + " \n", + " r = (1 / beta) - (1 - delta)\n", + " n = n_ss\n", + " eps = 0\n", + " k = (r / ((n ** mu) * theta * np.exp(eps))) ** (1 / (theta - 1))\n", + " y = np.exp(eps) * (k ** theta) * (n ** mu)\n", + " i = delta * k\n", + " c = y - i\n", + " w = mu * y / n\n", + " a = w / c\n", + " \n", + " return k, w, c, a, i, y" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.0881001887382777\n", + "0.7829715643830996\n" + ] + } + ], + "source": [ + "k_ss, w_ss, c_ss, a_ss, i_ss, y_ss = get_ss()\n", + "print(k_ss)\n", + "print(w_ss)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "N_k = 50\n", + "k_low = k_ss - 0.5\n", + "k_high = k_ss + 0.5\n", + "k_grid = np.linspace(k_low, k_high, N_k)\n", + "\n", + "### eps_grid (Tauchen Analogue)\n", + "\n", + "N_eps = 10\n", + "trans_eps_MC = tauchen(rho, sigma, n=N_eps).P\n", + "\n", + "sigma_y = np.sqrt( sigma ** 2 / (1 - rho ** 2) )\n", + "m = 3\n", + "eps_grid = np.zeros(N_eps)\n", + "eps_grid[0] = -m * sigma_y\n", + "eps_grid[N_eps-1] = m * sigma_y\n", + "s = (eps_grid[N_eps-1] - eps_grid[0]) / (N_eps - 1)\n", + "for i in range(1, N_eps-1):\n", + " eps_grid[i] = eps_grid[i-1] + s\n", + " \n", + "\n", + "# Now we initialize the value function:\n", + "V_init = np.zeros((N_eps, N_k))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[5.30478170e-01, 4.15375002e-01, 5.32885772e-02, 8.56706028e-04,\n", + " 1.54439460e-06, 2.92857183e-10, 5.66213743e-15, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [9.67966302e-02, 4.93930466e-01, 3.69971746e-01, 3.87971726e-02,\n", + " 5.03259844e-04, 7.25892202e-07, 1.09655174e-10, 1.66533454e-15,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [3.71959075e-03, 1.21954964e-01, 5.23228103e-01, 3.23146274e-01,\n", + " 2.76615366e-02, 2.89198006e-04, 3.33562232e-07, 4.01295663e-11,\n", + " 4.44089210e-16, 0.00000000e+00],\n", + " [2.52812798e-05, 5.78316444e-03, 1.54270165e-01, 5.43701344e-01,\n", + " 2.76746317e-01, 1.93110204e-02, 1.62557651e-04, 1.49849563e-07,\n", + " 1.43532963e-11, 2.22044605e-16],\n", + " [2.82551739e-08, 4.80546862e-05, 8.83083400e-03, 1.91241547e-01,\n", + " 5.54230974e-01, 2.32360418e-01, 1.31987073e-02, 8.93711456e-05,\n", + " 6.58100220e-08, 5.01754194e-12],\n", + " [5.01748193e-12, 6.58100220e-08, 8.93711456e-05, 1.31987073e-02,\n", + " 2.32360418e-01, 5.54230974e-01, 1.91241547e-01, 8.83083400e-03,\n", + " 4.80546862e-05, 2.82551740e-08],\n", + " [1.39013711e-16, 1.43532786e-11, 1.49849563e-07, 1.62557651e-04,\n", + " 1.93110204e-02, 2.76746317e-01, 5.43701344e-01, 1.54270165e-01,\n", + " 5.78316444e-03, 2.52812798e-05],\n", + " [5.94563576e-22, 4.89150847e-16, 4.01295059e-11, 3.33562232e-07,\n", + " 2.89198006e-04, 2.76615366e-02, 3.23146274e-01, 5.23228103e-01,\n", + " 1.21954964e-01, 3.71959075e-03],\n", + " [3.89946474e-28, 2.57578327e-21, 1.68195357e-15, 1.09655162e-10,\n", + " 7.25892202e-07, 5.03259844e-04, 3.87971726e-02, 3.69971746e-01,\n", + " 4.93930466e-01, 9.67966302e-02],\n", + " [3.90429771e-35, 2.08116592e-27, 1.09035811e-20, 5.65165946e-15,\n", + " 2.92857227e-10, 1.54439460e-06, 8.56706028e-04, 5.32885772e-02,\n", + " 4.15375002e-01, 5.30478170e-01]])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trans_eps_MC" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "n = lambda eps, k: (w / (mu * np.exp(eps) * k ** theta)) ** (1 / (mu - 1))\n", + "cf = 0.01\n", + "w = w_ss" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The model establishes consistency with essential features of the microeconomic data, as well as its nonlinearities in partial equilibrium, and then comes up with some results for aggregate dynamics.\n", + "\n", + "* **Result 1** \n", + "When relative prices vary over time to clear the\n", + "markets for labor and goods, we find that aggregate nonlinearities associated\n", + "with lumpy investment disappear, leaving the economy’s dynamics virtually indistinguishable from those in the standard frictionless environment. \n", + "\n", + "* **Result 2**\n", + "Fluctuations in target capital stocks are smoothed dramatically, and thus so are the sharp changes along the extensive margin that generate the large positive skewness and excess kurtosis seen above. Moreover, by restraining changes\n", + "along both the intensive and extensive margins, market-clearing relative price\n", + "movements also smooth away the excessively large and abrupt fluctuations in\n", + "aggregate investment demand one sees in partial equilibrium, thereby yielding\n", + "an aggregate investment rate with persistence and **volatility close to the data.**" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def vf_update(eps_index, k_index, V_old_interp, w, cf):\n", + " \"\"\"\n", + " input:\n", + " k_index: index so that k_grid[index] corresponds to value of capital this period (state)\n", + " V_old: approximation to the value function. V_old[i] approximates V(k_grid[i]).\n", + " \n", + " output:\n", + " action_value: value of all possible state-action pairs.\n", + " \"\"\"\n", + " \n", + " ### solve v1\n", + " eps = eps_grid[eps_index]\n", + " k = k_grid[k_index]\n", + "\n", + " n = (w / (mu*np.exp(eps)*k**theta))**(1/(mu-1))\n", + " action_value = np.zeros((N_k, N_eps))\n", + " \n", + " \n", + " profit = np.exp(eps) * (k ** theta) * (n ** mu) - w * n - (k_grid - (1 - delta) * k) \\\n", + " - varphi / 2 * (k_grid / k - (1 - delta)) ** 2 * k \n", + " \n", + " \n", + " action_value = profit + beta * np.dot((trans_eps_MC[eps_index, :]).T, V_old_interp(eps_grid, k_grid).T)\n", + " \n", + " V1_new = np.max(action_value)\n", + " \n", + " ### solve v_new\n", + " V_new = max((1 - delta) * k, V1_new - cf)\n", + " \n", + " return V_new, action_value" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def vf_update_iteration(V_old, V_old_interp, w, cf):\n", + " \"\"\"\n", + " input: \n", + " V_old: array with current approximation of the value function\n", + " \n", + " output:\n", + " V_new: updated approximation of the value function\n", + " \"\"\"\n", + " V_new = np.zeros_like(V_old)\n", + " \n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " V_new[i, j], action_value = vf_update(i, j, V_old_interp, w, cf)\n", + "\n", + " return V_new\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def solve_value_func_iter(w, cf, plot=True):\n", + " difference_list = []\n", + " threshold = 1e-10\n", + " max_iterations = 10000\n", + " plot_interval = 50\n", + "\n", + " V = V_init.copy()\n", + "\n", + " for iteration in range(max_iterations):\n", + " \n", + " # x.size = m and y.size = n, if z.ndim == 2, then z must have shape (n, m)\n", + " V_interp = intpl.interp2d(eps_grid, k_grid, V.T, kind='linear')\n", + " V_new = vf_update_iteration(V, V_interp, w, cf)\n", + " #V_new = vf_update_iteration(V, V_interp, w, cf)\n", + " \n", + " \n", + " difference = np.amax(abs(V_new - V))\n", + " # print('Iteration: {}, difference: {}'.format(iteration + 1, difference))\n", + "\n", + " difference_list.append(difference) \n", + "\n", + " V = V_new\n", + "\n", + " if difference < threshold:\n", + " #print('Converged after iteration {}'.format(iteration + 1))\n", + " #print('Iteration: {}, difference: {}'.format(iteration + 1, difference))\n", + " \n", + " if plot:\n", + " fig = plt.figure()\n", + " ax = fig.gca(projection='3d')\n", + " EPS, K = np.meshgrid(eps_grid, k_grid)\n", + " surf1 = ax.scatter(EPS, K, V.T, cmap=cm.autumn)\n", + " #fig.colorbar(surf1, shrink=.5, aspect=5)\n", + " ax.set_xlabel(r'$\\epsilon$')\n", + " ax.set_ylabel(r'$k$')\n", + " ax.set_zlabel(r'V')\n", + " ax.set_title(\"Value Function\")\n", + " #plt.show()\n", + " #plt.close()\n", + " \n", + " break\n", + " \n", + " return V, V_interp\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "poly_grid = extract_policy(V, V_interp, w)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\AKG\\AppData\\Roaming\\Python\\Python37\\site-packages\\ipykernel_launcher.py:48: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", + "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.022483086312935815\n", + "\n", + "\n", + "iteration 2\n", + "cf val: 0.013\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.13406633900178572\n", + "\n", + "\n", + "iteration 4\n", + "cf val: 0.015\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction of exiting firms: 0.13906643107363217\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "0.01" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Firms continue\n", + "def firm_continue(eps, k, V_interp):\n", + " V_val = V_interp(eps, k)\n", + " if V_val == (1 - delta) * k:\n", + " return False\n", + " else:\n", + " return True\n", + "\n", + "firm_continue(0, 5, V_interp)\n", + "\n", + "firm_continue(0.2, 1, V_interp)\n", + "\n", + "def firm_continue_grid(V):\n", + " V_new = np.zeros_like(V)\n", + " for i in range(N_k):\n", + " V_new[:, i] = ((1 - delta) * k_grid[i] != V[:, i]) \n", + " return V_new\n", + "\n", + "firm_cont_grid = firm_continue_grid(V)\n", + "\n", + "\n", + "\n", + "### Function $\\hat{V}(\\epsilon)$\n", + "\n", + "def get_v_hat(eps, V_interp):\n", + " \n", + " eps_index = np.where(eps_grid == eps)[0][0]\n", + " vals = []\n", + " \n", + " for k_index in range(N_k):\n", + " val = - k_grid[k_index] + beta * np.dot(trans_eps_MC[eps_index, :], V_interp(eps_grid, k_grid[k_index]))\n", + " vals.append(val)\n", + " \n", + " return max(vals) \n", + "\n", + "get_v_hat(eps_grid[4], V_interp)\n", + "\n", + "\n", + "\n", + "ce = 0.02\n", + "\n", + "### https://dilawarnotes.wordpress.com/2017/11/07/stationary-distribution-of-markov-chains-using-python/\n", + "def solveStationary( A ):\n", + " n = A.shape[0]\n", + " a = np.eye( n ) - A\n", + " a = np.vstack( (a.T, np.ones( n )) )\n", + " b = np.matrix( [0] * n + [ 1 ] ).T\n", + " return np.linalg.lstsq( a, b )[0]\n", + "\n", + "#### Stationary Distribution of $\\epsilon$\n", + "\n", + "stationary_dist_eps = np.array(solveStationary(trans_eps_MC))\n", + "stationary_dist_eps\n", + "\n", + "np.sum(stationary_dist_eps)\n", + "\n", + "### Solving for Market-Clearing Wage\n", + "\n", + "def mark_wage_err(w, ce, cf):\n", + " V_new, V_interp_new = solve_value_func_iter(w, cf, plot=False)\n", + " \n", + " V_hats = np.zeros_like(eps_grid)\n", + " # iterate loop in parallel\n", + " \n", + " for i in range(len(eps_grid)):\n", + " V_hats[i] = get_v_hat(eps_grid[i], V_interp_new)\n", + " \n", + " integral = np.dot(V_hats, stationary_dist_eps)\n", + " err = ce - integral\n", + " #print(err)\n", + " return np.array(err)\n", + "\n", + "def solve_mark_wage(w_guess, ce, cf):\n", + " args = (ce, cf)\n", + " result = opt.root(mark_wage_err, w_guess, args = args)\n", + " return result.x[0]\n", + "\n", + "w_star = solve_mark_wage(0.9, 0.02, 0.01)\n", + "\n", + "w_star\n", + "\n", + "\n", + "\n", + "## Q Stationary measure of firms and mass of entrants\n", + "\n", + "V, V_interp = solve_value_func_iter(w_star, cf)\n", + "\n", + "poly_grid = extract_policy(V, V_interp, w_star)\n", + "\n", + "firm_cont_grid = firm_continue_grid(V)\n", + "#firm_cont_grid\n", + "\n", + "### Step 1: Solving $g(\\epsilon, k)$\n", + "\n", + "g_init = np.random.uniform(low=0, high=1, size=(N_eps, N_k))\n", + "g_init = g_init / np.sum(g_init)\n", + "g = g_init.copy()\n", + "m_star = 1\n", + "\n", + "np.sum(g)\n", + "\n", + "@jit(nopython=True, parallel=True)\n", + "def update_g(g):\n", + " g_new = np.zeros((N_eps, N_k))\n", + " \n", + " # iterate loop in parallel\n", + " for k in range(N_eps):\n", + " for l in range(N_k):\n", + " C = (poly_grid == k_grid[l])\n", + " \n", + " summation = 0\n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " \n", + " sum_ij = trans_eps_MC[i,k] * C[i, j] * firm_cont_grid[i, j] * g[i, j] \n", + " summation += sum_ij\n", + " \n", + " summation += m_star * stationary_dist_eps[k][0]\n", + " g_new[k, l] = summation\n", + " \n", + " return g_new\n", + "\n", + "def solve_g(plot=True):\n", + " threshold = 1e-8\n", + " max_iterations = 1000\n", + " diff = 1\n", + " g = g_init.copy()\n", + " \n", + " while (diff > 1e-5):\n", + " g_new = update_g(g) \n", + " #print('sum :', np.sum(g_new))\n", + " diff = np.max(np.abs(g_new - g))\n", + " #print(diff)\n", + " g = g_new.copy()\n", + " \n", + " g_normalized = g_new / np.sum(g_new)\n", + " \n", + " if plot:\n", + " \n", + " fig = plt.figure()\n", + " ax = fig.gca(projection='3d')\n", + " EPS, K = np.meshgrid(eps_grid, k_grid)\n", + " surf1 = ax.scatter(EPS, K, g_normalized.T, cmap=cm.autumn)\n", + " #fig.colorbar(surf1, shrink=.5, aspect=5)\n", + " #surf1 = ax.plot_wireframe(EPS, K, g_normalized.T)\n", + " ax.set_xlabel(r'$\\epsilon$')\n", + " ax.set_ylabel(r'$k$')\n", + " ax.set_zlabel(r\"$g$\")\n", + " ax.set_title(\"Law of Motion g\")\n", + " \n", + " return g_normalized\n", + "\n", + "g = solve_g()\n", + "\n", + "\n", + "\n", + "### Step 2: Solving m*\n", + "\n", + "def get_g_star(g, m):\n", + " return g.copy() * m\n", + "\n", + "def n(eps, k, w):\n", + " n = (w / (mu * np.exp(eps) * k **theta)) ** (1/(mu - 1))\n", + " return n\n", + "\n", + "def agg_l_d(g_star, w_star):\n", + " \n", + " n_d = 0\n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " n_d += n(eps_grid[i], k_grid[j], w_star) * g_star[i, j]\n", + " return n_d\n", + "\n", + "def m_error(m_guess, *args):\n", + " \n", + " g, w_star = args\n", + " g_star = get_g_star(g, m_guess)\n", + " n_d = agg_l_d(g_star, w_star)\n", + " m_error = n_d - 0.6\n", + " return m_error\n", + "\n", + "def solve_m(m_guess, g, w_star):\n", + " \n", + " args = (g, w_star)\n", + " result = opt.root(m_error, m_guess, args=args)\n", + " return result.x[0]\n", + "\n", + "m_guess = 0.5\n", + "m_star = solve_m(m_guess, g, w_star)\n", + "m_star\n", + "\n", + "\n", + "\n", + "### Step 3: Solving value of a\n", + "\n", + "def get_agg_Y():\n", + " \n", + " agg_Y = 0\n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " agg_Y += ( np.exp(eps_grid[i]) * k_grid[i] ** theta * n(eps_grid[i], k_grid[j], w_star) ) * g[i, j]\n", + " \n", + " return agg_Y\n", + "\n", + "get_agg_Y()\n", + "\n", + "def get_agg_I():\n", + " \n", + " agg_I = 0\n", + " for i in range(N_eps):\n", + " for j in range(N_k):\n", + " agg_I += ( poly_grid[i, j] - (1 - delta) * k_grid[j] ) * g[i, j]\n", + " \n", + " return agg_I\n", + "\n", + "get_agg_I()\n", + "\n", + "def get_agg_C():\n", + " \n", + " Y = get_agg_Y()\n", + " I = get_agg_I()\n", + " C = Y - I\n", + " return C\n", + "\n", + "get_agg_C()\n", + "\n", + "def get_a():\n", + " \n", + " C = get_agg_C()\n", + " a = C * w_star\n", + " \n", + " return a\n", + "\n", + "get_a()\n", + "\n", + "\n", + "\n", + "## Calibration to parameters in the data, here it is the entry and exit costs\n", + "\n", + "### (i) Calibrating entry cost: Calibrate to target annual exit rate of 10%.\n", + "\n", + "def calibrate_cf():\n", + " \n", + " cf_range = [0.01, 0.013, 0.014, 0.015, 0.016]\n", + " error = 1000\n", + " cal_cf = 0\n", + " iteration = 1\n", + " for cf_val in cf_range:\n", + " \n", + " print(\"iteration \", iteration)\n", + " print(\"cf val: \", cf_val)\n", + " V, V_interp = solve_value_func_iter(w_star, cf_val, plot=True)\n", + " \n", + " frac_exit_sum = 0\n", + " for i in range(N_k):\n", + " V_i = V[:, i]\n", + " exit_val = (1 - delta) * k_grid[i]\n", + " exit_bool = (V_i == exit_val)\n", + " \n", + " frac_exit_i = exit_bool * g[:, i]\n", + " frac_exit_sum += frac_exit_i.sum()\n", + " \n", + " print(\"Fraction of exiting firms:\", frac_exit_sum) \n", + " print(\"\\n\")\n", + " new_error = abs(frac_exit_sum - 0.1)\n", + " #print(new_error)\n", + " \n", + " if new_error < error:\n", + " error = new_error\n", + " cal_cf = cf_val\n", + " \n", + " iteration += 1\n", + " \n", + " return cal_cf, error \n", + "\n", + "cal_cf, error = calibrate_cf()\n", + "\n", + "cal_cf \n", + "\n", + "\n", + "\n", + "### (ii) Calibrating exit costs: Calibrate to target average size of new firms to be 40% of average size of all firms\n", + "\n", + "def calibrate_ce():\n", + " \n", + " ce_range = [0.01, 0.05, 0.1, 0.2, 0.5]\n", + " error = 1000\n", + " cal_ce = 0\n", + " iteration = 1\n", + " for ce_val in ce_range:\n", + " \n", + " #print(\"iteration \", iteration)\n", + " #print(\"ce val: \", ce_val)\n", + " \n", + " w_guess = 0.9\n", + " w_star = solve_mark_wage(w_guess, ce, cal_cf)\n", + " #print(\"w_star:\", w_star)\n", + " m_guess = 0.05\n", + " m_star = solve_m(m_guess, g, w_star)\n", + " #print(\"m_star :\", m_star)\n", + " \n", + " new_error = abs(m_star - 0.4)\n", + " if new_error < error:\n", + " error = new_error\n", + " cal_ce = ce_val\n", + " \n", + " iteration += 1\n", + " \n", + " return cal_ce, error\n", + "\n", + "cal_ce, error = calibrate_ce()\n", + "\n", + "cal_ce " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " * Micro-level Heterogeneity and Transmission: [Reiter, Sveen and Weinke (2013)] (_Lumpy investment and the monetary transmission mechanism_), [Koby and Wolf (2019)] **(_Investment Stimulus: From Micro Elasticities to Macro Counterfactuals_)**.\n", + " \n", + " * Financial heterogeneity and the business cycle dynamics of aggregate investment: [Khan, Senga and Thomas (2016)] **(_Default Risk and Aggregate Fluctuations in an Economy with Production Heterogeneity_)**.\n", + "\n", + " * Investment and Business Cycle: [Cooper, Haltiwanger (2006)] **(_Machine Replacement and the Business Cycle: Lumps and Bumps_)**. \n", + " \n", + " * Heterogeneity and computation: [Krusell, Smith (1998)] **(_Income and wealth heterogeneity in the macroeconomy_)**.\n", + "\n", + " * Khan, A. and Thomas, J. K. (2008), Idiosyncratic Shocks and the Role of Nonconvexities in Plant and Aggregate Investment Dynamics. Econometrica, 76: 395-436.\n", + " \n", + " * Winberry, T. (2018), A method for solving and estimating heterogeneous agent macro models. Quantitative Economics, 9: 1123-1151." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "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.7.3" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/placeholder b/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/placeholder new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/models/We-Would-Like-In-Econ-ARK/Khan-Thomas/placeholder @@ -0,0 +1 @@ +