{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Solución del Modelo Neoclásico de Crecimiento usando Programación Dinámica e Iteración de la Función Valor\n", "\n", "Mauricio M. Tejada\n", "\n", "ILADES - Universidad Alberto Hurtado\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### El Problema de Opmización \n", "\n", "El problema de optimización del planificador central es el siguiente:\n", "\\begin{eqnarray*}\n", "\\max U_{0} & = & \\sum_{t=0}^{\\infty}\\beta^{t}\\ln c_{t}\\\\\n", "s.a & & c_{t}+i_{t}=Ak_{t}^{\\alpha}\\\\\n", " & & k_{t+1}=i_{t}\\\\\n", " & & k_{0}\\,dado.\n", "\\end{eqnarray*}\n", "\n", "Alternativamente:\n", "\\begin{eqnarray*}\n", "\\max U_{0} & = & \\sum_{t=0}^{\\infty}\\beta^{t}\\ln c_{t}\\\\\n", "s.a & & c_{t}+k_{t+1}=Ak_{t}^{\\alpha}\\\\\n", " & & k_{0}\\,dado.\n", "\\end{eqnarray*}\n", "\n", "La ecuación de Bellman es:\n", "$$\n", "v(k_{t})=\\max_{k_{t+1}}\\left\\{ \\log\\left(Ak_{t}^{\\alpha}-k_{t+1}\\right)+\\beta v(k_{t+1})\\right\\} \n", "$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Solución Algebraica\n", "\n", "La solución del problema funcional está dada por la función valor y la función de política:\n", "\n", "$$\n", "v(k_{k})\\,\\,y\\,\\,k_{t+1}=g(k_{t})\n", "$$\n", "\n", "Conocemos la solución de este problema:\n", "\n", "\\begin{eqnarray*}\n", "k_{t+1} & = & \\frac{\\beta F}{1+\\beta F}Ak_{t}^{\\alpha}\\\\\n", "v(k_{t}) & = & E+F\\ln(k_{t})\n", "\\end{eqnarray*}\n", "Donde:\n", "\\begin{eqnarray*}\n", "E & = & \\frac{1}{1-\\beta}\\left[\\ln\\left(A\\left(1-\\alpha\\beta\\right)\\right)+\\frac{\\alpha\\beta}{1-\\alpha\\beta}\\ln\\left(Aa\\beta\\right)\\right]\\\\\n", "F & = & \\frac{\\alpha}{1-\\alpha\\beta}\n", "\\end{eqnarray*}\n", "\n", "La idea es implementar la solución numérica en Julia y compararla con la obtenida algebraicamente." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Implementación\n", "\n", "Algoritmo:\n", "\n", "1. Definir un grid de puntos $k$ (discretización) y realizar una conjetura para $v(k)$ en cada posible punto del grid. \n", "2. Usando la conjetura evaluar el operador $Tv$ para cada punto en el grid (esto implica resolver el $\\max$).\n", "3. Evaluar si $v=Tv$ (usando algún grado de tolerancia), en tal caso terminar el proceso. Caso contrario volver al punto 2 usando la función valor resultante.\n", "\n", "En términos de la ecuación de Bellman, la iteración sería:\n", "$$\n", "v_{j+1}(k)=\\max_{k'}\\left\\{ \\ln\\left(Ak^{\\alpha}-k'\\right)+\\beta v_{j}(k')\\right\\} \n", "$$\n", "\n", "Partir con algún $v_{0}(k)$. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "text/plain": [ "500" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Discretizamos la variable de estado. Definimos primero el número de puntos en el grid de k\n", "n = 500" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Parametros del modelo:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "A = 1 # tecnologia\n", "α = 0.36 # participacion del capital \n", "β = 0.9; # factor de descuento " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Definimos el grado de tolerancia de la iteración de la función valor:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0e-6" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "crit = 1e-6 # valor critico de convergencia" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Definimos el grid de puntos de $k$ como $k_1,...,k_n \\in [0.6k^*,1.4k^*]$" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Calcular kss y definir kgrid \n", "kss = (α*β)^(1/(1-α)) # capital en EE \n", "kgrid = kss * collect(range(0.6,stop=1.4,length=n)); # n x 1 \n", "#println(kgrid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note que mientras más puntos tengamos en el grid, más precisión tendremos." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El siguiente paso es iterar la función valor partiendo de la siguiente conjetura:\n", "$$\n", "v_{0}(k)=\\left[\\begin{array}{c}\n", "0\\\\\n", "\\vdots \\\\\n", "0\n", "\\end{array}\\right]\n", "$$" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Definir valores inciales\n", "\n", "val0 = zeros(n) # Conjetura Inicial \n", "valiter = val0; # Vector donde guardamos las iteraciones" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "using Optim\n", "using Interpolations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Usamos interpolación lineal para evaluar la función entre los puntos definidos en el grid del capital." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v_interpolate = LinearInterpolation(kgrid, val0, extrapolation_bc = Line())\n", "v_interpolate(kss)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Resolvemos usando el método de iteración de la función valor:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Convergencia = 9.774898082071104e-7\n" ] } ], "source": [ "diff = 1\n", "\n", "val1 = zeros(n) # Vector para guardar la función valor\n", "kdeci = zeros(n) # Vector para guardar la función de política \n", "\n", "while diff > crit\n", " \n", " global val0, val1, valiter, kdeci, diff\n", " \n", " v_interpolate = LinearInterpolation(kgrid, val0, extrapolation_bc = Line()) \n", " Tv(k,kf) = log(A*k^α-kf) + β*v_interpolate(kf) \n", " \n", " for i in 1:n\n", " res = optimize(x -> -Tv(kgrid[i],x), 1e-10, A*kgrid[i]^α)\n", " kdeci[i] = res.minimizer\n", " val1[i] = -res.minimum\n", " end\n", " \n", " diff = abs(maximum(val1-val0)) \n", " #println(diff)\n", " valiter = [valiter val1]\n", " val0 = copy(val1) \n", "end\n", "\n", "println(\"Convergencia = $diff\");" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Solución Algebraica\n", "\n", "Para este problema particular conocemos la solución alebraica." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "# Computar los coeficiente E y F \n", "E1 = log(A*(1 - α*β))\n", "E2 = α*β/(1 - α*β) * log(A*α*β)\n", "E = 1/(1 - β)*(E1 + E2)\n", "F = α/(1 - α*β)\n", "\n", "# Evaluar en la solucion algebraica la FV y la FP en kgrid\n", "val_cs = E*ones(n) + F * log.(kgrid) # n x 1\n", "kdeci_cs = β*F/(1 + β*F)*A*kgrid.^α; # n x 1" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Gráficos" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Plots.GRBackend()" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using Plots\n", "gr()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Función de política:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(kgrid, [kdeci kdeci_cs], title = \"Función de Política\", \n", " xlabel = \"k(t)\", ylabel = \"k(t+1)\", label=[\"Sol. Num.\" \"Sol. Alg.\"], \n", " linewidth = 2, grid = true, line=[:solid :dot], color=[:red :blue])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Función valor:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(kgrid, [val1 val_cs], title = \"Función Valor\", \n", " xlabel = \"k(t)\", ylabel = \"v(k(t))\", label=[\"Sol. Num.\" \"Sol. Alg.\"], \n", " linewidth = 2, grid = true, line=[:solid :dot], color=[:red :blue])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Proceso de iteración de la función valor:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(kgrid, valiter, title = \"Iteración de la Función Valor\", \n", " xlabel = \"k(t)\", ylabel = \"v(k(t))\", legend = false, linewidth = 2, \n", " grid = true)" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.6.0", "language": "julia", "name": "julia-1.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.6.0" } }, "nbformat": 4, "nbformat_minor": 4 }