{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Livestock Feeding" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Akira Matsushita**\n", "\n", "*Department of Economics, University of Tokyo*" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "From Miranda and Fackler, *Applied Computational Economics and Finance*, 2002, Section 8.4.8 and 9.7.8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.4.8 Model Formulation and Solution by hand" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* A livestock producer feeds their stock for $T$ periods and sells it at the beginning of period $T+1$\n", "* Each period $t$, the producer determine the amount of feed: $x_t \\geq 0$. The fixed unit cost of grain is $\\kappa \\geq 0$\n", "* $s_t$, the weight of livestock at time $t$, follows the deterministic process: $s_{t+1} = g(s_t, x_t), s_0 = \\bar{s}$. Assume $s_t \\geq 0$ for all $t$ \n", "* The selling price of the livestock at time $T+1$ is given by $s_{T+1} \\times p$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then the profit maximization problem for producer is formulated as:\n", "\n", "\\begin{align*}\n", "\\underset{ \\{x_t \\geq 0 \\}_{t=1}^T}{\\max} \\delta^T p s_{T+1} - \\sum_{t=1}^{T} \\delta^{t-1} \\kappa x_t \n", "\\hspace{1em} \\text{s.t.} \\hspace{1em} \n", "\\begin{cases}\n", "s_{t+1} = g(s_t, x_t) \\\\\n", "s_0 = \\bar{s}\n", "\\end{cases}\n", "\\end{align*}\n", "\n", "where $\\delta \\geq 0$ is the discount factor" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The corresponding Bellman equation is:\n", "\n", "\\begin{align*}\n", "\\begin{cases}\n", "V_t(s_t) = \\underset{x_t \\geq 0}{\\max} \\{ -\\kappa x_t + \\delta V_{t+1}(g(s_t, x_t)) \\} \\hspace{1em} t=1, \\ldots, T \\\\\n", "V_{T+1}(s_{T+1}) = ps_{T+1}\n", "\\end{cases}\n", "\\end{align*}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Euler Conditions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's derive the Euler Equilibrium Conditions from the Bellman equation\n", "\n", "Assume $g: \\mathbb{R}_+ \\times \\mathbb{R}_+ \\rightarrow \\mathbb{R}_+$ is differentiable on the entire domain (so $g$ is partially differentiable by both $s$ and $x$)\n", "\n", "Define $g_x = \\frac{\\partial g}{\\partial x}$ and $g_s = \\frac{\\partial g}{\\partial s}$\n", "\n", "Assume $g_x(s, 0)$ is large enough so that the nonnegative constraint of $x$ will not be binded at an optimum (ensures an interior point solution)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let $X_t^*$ be the optimal solution correspondence, i.e., \n", "\n", "\\begin{align*}\n", "X_t^*(s) = \\left\\{ x_t^* \\in [0, \\infty) \\mid V_t(s) = -\\kappa x_t^* + \\delta V_{t+1}(g(s_t, x_t^*)) \\right\\}\n", "\\end{align*}\n", "\n", "and $x_t^*(s) \\in X_t^*(s)$ be a selection of it. Assume $x_t^*(s)$ is differentiable for all $t$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that by using $x_t^*(s)$ the optimal value function at time 1 is derived as\n", "\n", "\\begin{align*}\n", "V_1(\\bar{s}) &= -\\kappa x_1^*(\\bar{s}) + \\delta V_2(g(\\bar{s}, x_1^*(\\bar{s}))) \\\\\n", "&= -\\kappa \\left[ x_1^*(\\bar{s}) + \\delta x_2^*(g(\\bar{s}, x_1^*(\\bar{s}))) \\right] + \\delta^2 V_3(g(g(\\bar{s}, x_1^*(\\bar{s})), x_2^*(g(\\bar{s}, x_1^*(\\bar{s}))))) \\\\\n", "&= \\ldots\n", "\\end{align*}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we show that $V_t$ is differentiable by $s_t$ for all $t=1, 2, \\ldots, T+1$\n", "\n", "* At $t = T+1$, $V_{T+1}(s_{T+1}) = ps_{T+1}$ so this is differentiable by $s_{T+1}$\n", "* As an induction hypothesis, assume $V_{t+1}$ is differentiable by $s_t$ ($1 \\leq t \\leq T$). Since \n", "\n", " \\begin{align*}\n", " V_t(s_t) = -\\kappa x_t^*(s_t) + \\delta V_{t+1}(g(s_t, x_t^*(s_t)))\n", " \\end{align*}\n", "\n", " and $x_t^*(s_t)$ and $V_{t+1}(s_t)$ are differentiable by $s_t$ and $g(s_t, x)$ is differentiable by both $s_t$ and $x$, $V_t(s_t)$ is also differentiable. The derivative is\n", " \n", " \\begin{align*}\n", " \\frac{\\partial}{\\partial s_t} V_t(s_t) = -\\kappa \\frac{\\partial}{\\partial s_t} x_t^*(s) + \\delta \\frac{\\partial}{\\partial s_t}V_{t+1}(g(s_t, x_t^*(s_t))) \\left\\{ g_s(s_t, x_t^*(s_t)) + g_x(s_t, x_t^*(s_t)) \\frac{\\partial}{\\partial s_t} x_t^*(s_t) \\right\\}\n", " \\end{align*}\n", " \n", "Hence by induction, $V_t$ is differentiable by $s_t$ for all $t$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next consider the optimality condition of the maximization problem in the Bellman equation: $\\underset{x_t \\geq 0}{\\max} \\{ -\\kappa x_t + \\delta V_{t+1}(g(s_t, x_t)) \\}$ \n", "\n", "Define $\\lambda_t(s_t) \\equiv V_{t}'(s_t) = \\frac{\\partial V_t}{\\partial s_t}$\n", "\n", "Using the chain rule, the FOCs are\n", "\n", "\\begin{align*}\n", "\\delta \\lambda_{t+1}(g(s_t, x_t^*))g_x(s_t, x_t^*) = \\kappa \\hspace{1em} t=1, \\ldots, T \\\\\n", "\\end{align*}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then the drivatives of the value functions by $s_t$: $\\lambda_t(s_t) = \\frac{\\partial}{\\partial s_t} V_t(s_t)$ become\n", "\n", "\\begin{align*}\n", "\\lambda_t(s) &= \\underbrace{ \\bigl\\{ -\\kappa + \\delta \\lambda_{t+1}(g(s_t, x_t^*(s_t))) g_x(s_t, x_t^*(s_t)) \\bigr\\}}_{=0 \\text{ by FOC}} \\frac{\\partial}{\\partial s_t} x_t^*(s_t) + \\delta \\lambda_{t+1}(g(s_t, x_t^*(s_t))) g_s(s_t, x_t^*(s_t)) \\\\\n", "&= \\delta \\lambda_{t+1}(g(s_t, x_t^*(s_t))) g_s(s_t, x_t^*(s_t))\n", "\\end{align*}\n", "\n", "for $t=1, \\ldots, T$ and\n", "\n", "\\begin{align*}\n", "\\lambda_{T+1}(s_{T+1}) = p\n", "\\end{align*}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In summary, the optimal path follows the following equations: \n", "\n", "\\begin{align*}\n", "\\begin{cases}\n", "\\delta \\lambda_{t+1}(g(s_t, x_t))g_x(s_t, x_t) = \\kappa \\hspace{1em} t=1, \\ldots, T \\\\\n", "\\lambda_t(s_t) = \\delta \\lambda_{t+1}(g(s_t, x_t)) g_s(s_t, x_t) \\hspace{1em} t=1, \\ldots, T \\\\\n", "\\lambda_{T+1}(s_{T+1}) = p\n", "\\end{cases}\n", "\\end{align*}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Solve the equations by hand" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How to solve the above equations and get the optimal polity $\\{x_t\\}_{t=1}^{T}$?\n", "\n", "* At $t=T$, since $\\lambda_{T+1}(s) = p$ regardless of the value of $s$, the 1st equation becomes\n", " $$\n", " g_x(s_T, x_T) = \\frac{\\kappa}{\\delta p}\n", " $$\n", " \n", " So we can get the optimal policy at $t=T$ by solving this equation for $x_T$. Then by the 2nd equation, we get $\\lambda_{T}(s_T)$\n", " \n", "* At $1 \\leq t < T$, we can get $x_t$ and $\\lambda_t(s_t)$ in the similar way\n", "\n", "* Finally we set $s_1 = \\bar{s}$ and then we get the concrete values of $\\lambda_1(s_1^*), x_1^*, \\lambda_2(s_2^*), x_2^*, \\ldots$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Concrete Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let\n", "\n", "* $T = 6$\n", "* $g(x, s) = \\alpha s + \\sqrt{x}$\n", "* $p = 1$\n", "\n", "Then\n", "\n", "* $g_x(x, s) = \\cfrac{0.5}{\\sqrt{x}}$\n", "* $g_s(x, s) = \\alpha$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At $t=6$, \n", "\n", "* $g_x(s_6, x_6) = \\cfrac{0.5}{\\sqrt{x_6}} = \\cfrac{\\kappa}{\\delta} \\hspace{2em} \\therefore x_6(s_6) = \\cfrac{\\delta^2}{4 \\kappa^2}$\n", "* $\\lambda_6(s_6) = \\delta \\alpha$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At $1 \\leq t \\leq 5$,\n", "\n", "* $g_x(s_t, x_t) = \\cfrac{0.5}{\\sqrt{x_t}} = \\cfrac{\\kappa}{\\delta^{7-t} \\alpha^{6-t}} \\hspace{2em} \\therefore x_t(s_t) = \\cfrac{(\\delta^{7-t} \\alpha^{6-t})^2}{4 \\kappa^2}$\n", "* $\\lambda_t(s_t) = \\delta^{7-t} \\alpha^{7-t}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So the optimal feeding policy is\n", "\n", "\\begin{align*}\n", "x_t^*(s_t) = \\cfrac{(\\delta^{7-t} \\alpha^{6-t})^2}{4 \\kappa^2} \\hspace{1em} t=1, \\ldots, 6\n", "\\end{align*}\n", "\n", "Note that in this special case the optimal policy $x_1, \\ldots, x_6$ does not depend on the initial weight $\\bar{s}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9.7.8 Solution by computation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to the settings of the example above, assume\n", "\n", "* $\\alpha = 0.9$\n", "* $\\kappa = 0.4$\n", "* $\\delta = 0.9$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to calculate the value function $V_t(s_t) = \\underset{x_t \\geq 0}{\\max} \\{ -\\kappa x_t + \\delta V_{t+1}(g(s_t, x_t)) \\}$ given $s_t$ computationally, we approximate $V_t(s_t)$ as\n", "\n", "\\begin{align*}\n", "V_t(s_t) \\simeq \\tilde{V_t}(s_t) = \\sum_{i=1}^n c_{it} \\phi_i(s_t)\n", "\\end{align*}\n", "\n", "where $\\{ \\phi_i \\}_{i=1}^n$ are the predetermined basis functions and $\\{ c_{it} \\}_{i=1}^n$ are coefficients of them" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also we choose $n$ sample points $\\xi_1 < \\xi_2 < \\ldots < \\xi_n$ in the state space" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The procedure of calculating optimal policy is as follows:\n", "\n", "* At $t=T$\n", " * Using optimizer, solve $V_T(\\xi_j) = \\underset{x_T \\geq 0}{\\max} \\{ -\\kappa x_T + \\delta p g(\\xi_j, x_T) \\}$ for each $\\xi_1, \\ldots, \\xi_n$ and get optimal $V_T(\\xi_j)$ and $x_T(\\xi_j)$\n", " \n", " * Solve $n$ simultaneous linear equations \n", " \n", " \\begin{align*}\n", " \\sum_{i=1}^n c_{iT} \\phi_i(\\xi_j) = V_T(\\xi_j) \\hspace{1em} j=1, \\ldots, n\n", " \\end{align*}\n", " \n", " to determine the $n$ coefficients $\\{ c_{iT} \\}_{i=1}^n$ and get $\\tilde{V_T}(s_T)$\n", "\n", "\n", "* At $1 \\leq t < T$, given $\\tilde{V_{t+1}}(\\xi_j)$, \n", " * Using optimizer, solve $V_t(\\xi_j) = \\underset{x_t \\geq 0}{\\max} \\{ -\\kappa x_t + \\delta \\tilde{V_{t+1}}(g(\\xi_j, x_t)) \\}$ for each $\\xi_1, \\ldots, \\xi_n$ and get optimal $V_t(\\xi_j)$ and $x_t(\\xi_j)$\n", " \n", " * Solve $n$ simultaneous linear equations \n", " \n", " \\begin{align*}\n", " \\sum_{i=1}^n c_{it} \\phi_i(\\xi_j) = V_t(\\xi_j) \\hspace{1em} j=1, \\ldots, n\n", " \\end{align*}\n", " \n", " to determine the $n$ coefficients $\\{ c_{it} \\}_{i=1}^n$ and get $\\tilde{V_t}(s_t)$\n", "\n", "* Finally set $s_1 = \\bar{s}$ and then we can get all optimal policies" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", "

Plotly javascript loaded.

\n", "

To load again call

init_notebook(true)

\n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Plots.PlotlyJSBackend()" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using QuantEcon\n", "using Optim\n", "using BasisMatrices\n", "using Plots\n", "plotlyjs()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "type LiveStock\n", " T::Int # ts_length(sell a livestock at period T+1)\n", " f::Function # cost function for each period\n", " g::Function # state transition function\n", " v_term::Function # value function at period T+1\n", " delta::Float64 # discount factor\n", " basis::Basis # BasisMatrix of value functions\n", "end" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1 dimensional Basis on the hypercube formed by (0.4,) × (2.0,).\n", "Basis families are Spline\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# For BasisMatrices, see https://github.com/QuantEcon/BasisMatrices.jl\n", "basis_size = 50\n", "s_min, s_max = 0.4, 2.0\n", "grid = linspace(s_min, s_max, basis_size-2)\n", "basis = Basis(SplineParams(grid, 0, 3)) # cubic spline" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "v_term (generic function with 1 method)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "T = 6\n", "delta = 0.9\n", "kappa = 0.4\n", "alpha = 0.9\n", "beta = 0.5\n", "p = 1\n", "f(s, x) = -1 * kappa .* x\n", "g(s, x) = alpha.*s + x.^beta\n", "v_term(s) = p * s" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "LiveStock(6, f, g, v_term, 0.9, 1 dimensional Basis on the hypercube formed by (0.4,) × (2.0,).\n", "Basis families are Spline\n", ")" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "live_stock = LiveStock(T, f, g, v_term, delta, basis)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "backward_induction (generic function with 3 methods)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function backward_induction(obj::LiveStock, x_min=0.01, x_max=100)\n", " grid = nodes(obj.basis)[1]\n", " grid_size = length(grid)\n", " VF_coefs = Matrix{Float64}(grid_size, obj.T)\n", " policies = similar(VF_coefs)\n", " \n", " Psi = BasisMatrix(obj.basis, Expanded(), grid, 0)\n", " values = Vector{Float64}(grid_size)\n", " \n", " # backward induction\n", " for t in obj.T:-1:1\n", " for i in 1:grid_size\n", " if t == obj.T\n", " # minimization -> maximization\n", " obj_func1(x) = -1 * ( obj.f(grid[i], x) + delta * v_term(obj.g(grid[i], x)) )\n", " result = Optim.optimize(obj_func1, x_min, x_max)\n", " else\n", " # minimization -> maximization\n", " obj_func2(x) = -1 * ( \n", " obj.f(grid[i], x) + \n", " delta * funeval(VF_coefs[:, t+1], basis, obj.g(grid[i], x))\n", " )\n", " result = Optim.optimize(obj_func2, x_min, x_max)\n", " end\n", "\n", " # optimal value\n", " values[i] = -1 * Optim.minimum(result)\n", "\n", " # optimal policy\n", " policies[i, t] = Optim.minimizer(result)\n", " end\n", "\n", " # calculate coefficients\n", " VF_coefs[:, t] = Psi.vals[1] \\ values\n", " end\n", "\n", " return VF_coefs, policies\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let $\\bar{s} = 0.6, 1.0, 1.4$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "s_init=0.6\n", " VF: [1.10697, 1.29836, 1.54685, 1.87759, 2.32835, 2.95458, 3.84596]\n", " PF: [0.15387, 0.234523, 0.35745, 0.54481, 0.826924, 1.26697]\n", " We: [0.6, 0.932263, 1.32331, 1.78885, 2.34808, 3.02263, 3.84596]\n", "s_init=1.0\n", " VF: [1.21995, 1.42388, 1.68632, 2.03256, 2.50053, 3.13976, 4.05219]\n", " PF: [0.15387, 0.234523, 0.357449, 0.544786, 0.813225, 1.26804]\n", " We: [1.0, 1.29226, 1.64731, 2.08045, 2.6105, 3.25124, 4.05219]\n", "s_init=1.4\n", " VF: [1.33292, 1.54941, 1.82579, 2.18753, 2.67192, 3.31609, 4.24875]\n", " PF: [0.15387, 0.234522, 0.357449, 0.543014, 0.78211, 1.26948]\n", " We: [1.4, 1.65226, 1.97131, 2.37205, 2.87174, 3.46894, 4.24875]\n" ] } ], "source": [ "VF_coefs, policies = backward_induction(live_stock)\n", "\n", "optimal_values = Vector{Float64}(T+1)\n", "optimal_policy = Vector{Float64}(T)\n", "optimal_livestock_weight = Vector{Float64}(T+1)\n", "\n", "initial_s = [0.6, 1.0, 1.4]\n", "\n", "for i in 1:length(initial_s)\n", " current_s = initial_s[i]\n", " for t in 1:T\n", " optimal_livestock_weight[t] = current_s\n", " optimal_policy[t] = funeval(policies[:, t], live_stock.basis, current_s)\n", " optimal_values[t] = funeval(VF_coefs[:, t], live_stock.basis, current_s)\n", " current_s = g(current_s, optimal_policy[t])\n", " end\n", " optimal_livestock_weight[T+1] = current_s\n", " optimal_values[T+1] = v_term(current_s)\n", " println(\"s_init=\", initial_s[i])\n", " println(\" VF: \", optimal_values)\n", " println(\" PF: \", optimal_policy)\n", " println(\" We: \", optimal_livestock_weight)\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "plot feeding policy and livestock weight ($\\bar{s}=0.4$)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimal_values = Vector{Float64}(T+1)\n", "optimal_policy = Vector{Float64}(T)\n", "optimal_livestock_weight = Vector{Float64}(T+1)\n", "\n", "initial_s = 0.4\n", "current_s = initial_s\n", "for t in 1:T\n", " optimal_livestock_weight[t] = current_s\n", " optimal_policy[t] = funeval(policies[:, t], live_stock.basis, current_s)\n", " optimal_values[t] = funeval(VF_coefs[:, t], live_stock.basis, current_s)\n", " current_s = g(current_s, optimal_policy[t])\n", "end\n", "optimal_livestock_weight[T+1] = current_s\n", "optimal_values[T+1] = v_term(current_s)\n", "\n", "plot(1:7, optimal_livestock_weight, xlims=(0.9, 7.1), ylim=(0, 4), label=\"(a) Optimal Stock Weight\", size=(800, 400))\n", "xlabel!(\"Month\")\n", "ylabel!(\"Stock Weight\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(1:6, optimal_policy, xlims=(0.9, 6.1), ylim=(0, 1.5), label=\"(b) Optimal Policy\", size=(800, 400))\n", "xlabel!(\"Month\")\n", "ylabel!(\"Feed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "compare to the theoretical policy" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "thoretical_policy_f(t) = (delta^(7-t) * alpha^(6-t))^2 / 4 / kappa^2\n", "theoretical_policy = [thoretical_policy_f(t) for t in 1:T]\n", "\n", "plot(1:6, optimal_policy, xlims=(0.9, 6.1), ylim=(0, 1.5), label=\"simulated OP\", size=(800, 400), lw=3)\n", "plot!(1:6, theoretical_policy, label=\"theoretical OP\", lw=2)\n", "xlabel!(\"Month\")\n", "ylabel!(\"Feed\")" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Julia 0.6.0", "language": "julia", "name": "julia-0.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "0.6.0" } }, "nbformat": 4, "nbformat_minor": 1 }