{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "
\n", " \n", " \"QuantEcon\"\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# General Purpose Packages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Contents\n", "\n", "- [General Purpose Packages](#General-Purpose-Packages) \n", " - [Overview](#Overview) \n", " - [Numerical Integration](#Numerical-Integration) \n", " - [Interpolation](#Interpolation) \n", " - [Linear Algebra](#Linear-Algebra) \n", " - [General Tools](#General-Tools) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview\n", "\n", "Julia has both a large number of useful, well written libraries and many incomplete poorly maintained proofs of concept\n", "\n", "A major advantage of Julia libraries is that, because Julia itself is sufficiently fast, there is less need to mix in low level languages like C and Fortran\n", "\n", "As a result, most Julia libraries are written exclusively in Julia\n", "\n", "Not only does this make the libraries more portable, it makes them much easier to dive into, read, learn from and modify\n", "\n", "In this lecture we introduce a few of the Julia libraries that we’ve found particularly useful for quantitative work in economics\n", "\n", "Also see [data and statistical packages](data_statistical_packages.ipynb) and [optimization, solver, and related packages](optimization_solver_packages.ipynb) for more domain specific packages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setup" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": true }, "outputs": [], "source": [ "using InstantiateFromURL\n", "github_project(\"QuantEcon/quantecon-notebooks-julia\", version = \"0.2.0\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": true }, "outputs": [], "source": [ "using LinearAlgebra, Statistics, Compat\n", "using QuantEcon, QuadGK, FastGaussQuadrature, Distributions, Expectations\n", "using Interpolations, Plots, LaTeXStrings, ProgressMeter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numerical Integration\n", "\n", "Many applications require directly calculating a numerical derivative and calculating expectations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adaptive Quadrature\n", "\n", "A high accuracy solution for calculating numerical integrals is [QuadGK](https://github.com/JuliaMath/QuadGK.jl)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using QuadGK\n", "@show value, tol = quadgk(cos, -2π, 2π);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is an adaptive Gauss-Kronrod integration technique that’s relatively accurate for smooth functions\n", "\n", "However, its adaptive implementation makes it slow and not well suited to inner loops" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gaussian Quadrature\n", "\n", "Alternatively, many integrals can be done efficiently with (non-adaptive) [Gaussian quadrature](https://en.wikipedia.org/wiki/Gaussian_quadrature)\n", "\n", "For example, using [FastGaussQuadrature.jl](https://github.com/ajt60gaibb/FastGaussQuadrature.jl)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using FastGaussQuadrature\n", "x, w = gausslegendre( 100_000 ); # i.e. find 100,000 nodes\n", "\n", "# integrates f(x) = x^2 from -1 to 1\n", "f(x) = x^2\n", "@show w ⋅ f.(x); # calculate integral" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The only problem with the `FastGaussQuadrature` package is that you will need to deal with affine transformations to the non-default domains yourself\n", "\n", "Alternatively, `QuantEcon.jl` has routines for Gaussian quadrature that translate the domains" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using QuantEcon\n", "\n", "x, w = qnwlege(65, -2π, 2π);\n", "@show w ⋅ cos.(x); # i.e. on [-2π, 2π] domain" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expectations\n", "\n", "If the calculations of the numerical integral is simply for calculating mathematical expectations of a particular distribution, then [Expectations.jl](https://github.com/QuantEcon/Expectations.jl) provides a convenient interface\n", "\n", "Under the hood, it is finding the appropriate Gaussian quadrature scheme for the distribution using `FastGaussQuadrature`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using Distributions, Expectations\n", "dist = Normal()\n", "E = expectation(dist)\n", "f(x) = x\n", "@show E(f) #i.e. identity\n", "\n", "# Or using as a linear operator\n", "f(x) = x^2\n", "x = nodes(E)\n", "w = weights(E)\n", "E * f.(x) == f.(x) ⋅ w" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpolation\n", "\n", "In economics we often wish to interpolate discrete data (i.e., build continuous functions that join discrete sequences of points)\n", "\n", "The package we usually turn to for this purpose is [Interpolations.jl](https://github.com/JuliaMath/Interpolations.jl)\n", "\n", "There are a variety of options, but we will only demonstrate the convenience notation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Univariate with a Regular Grid\n", "\n", "Let’s start with the univariate case\n", "\n", "We begin by creating some data points, using a sine function" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using Interpolations\n", "using Plots\n", "gr(fmt=:png);\n", "\n", "x = -7:7 # x points, coase grid\n", "y = sin.(x) # corresponding y points\n", "\n", "xf = -7:0.1:7 # fine grid\n", "plot(xf, sin.(xf), label = \"sin function\")\n", "scatter!(x, y, label = \"sampled data\", markersize = 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To implement linear and cubic spline interpolation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "li = LinearInterpolation(x, y)\n", "li_spline = CubicSplineInterpolation(x, y)\n", "\n", "@show li(0.3) # evaluate at a single point\n", "\n", "scatter(x, y, label = \"sampled data\", markersize = 4)\n", "plot!(xf, li.(xf), label = \"linear\")\n", "plot!(xf, li_spline.(xf), label = \"spline\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Univariate with Irregular Grid\n", "\n", "In the above, the `LinearInterpolation` function uses a specialized function\n", "for regular grids since `x` is a `Range` type\n", "\n", "For an arbitrary, irregular grid" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "x = log.(range(1, exp(4), length = 10)) .+ 1 # uneven grid\n", "y = log.(x) # corresponding y points\n", "\n", "interp = LinearInterpolation(x, y)\n", "\n", "xf = log.(range(1, exp(4), length = 100)) .+ 1 # finer grid\n", "\n", "plot(xf, interp.(xf), label = \"linear\")\n", "scatter!(x, y, label = \"sampled data\", markersize = 4, size = (800, 400))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At this point, `Interpolations.jl` does not have support for cubic splines with irregular grids, but there are plenty of other packages that do (e.g. [Dierckx.jl](https://github.com/kbarbary/Dierckx.jl) and [GridInterpolations.jl](https://github.com/sisl/GridInterpolations.jl))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multivariate Interpolation\n", "\n", "Interpolating a regular multivariate function uses the same function" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "f(x,y) = log(x+y)\n", "xs = 1:0.2:5\n", "ys = 2:0.1:5\n", "A = [f(x,y) for x in xs, y in ys]\n", "\n", "# linear interpolation\n", "interp_linear = LinearInterpolation((xs, ys), A)\n", "@show interp_linear(3, 2) # exactly log(3 + 2)\n", "@show interp_linear(3.1, 2.1) # approximately log(3.1 + 2.1)\n", "\n", "# cubic spline interpolation\n", "interp_cubic = CubicSplineInterpolation((xs, ys), A)\n", "@show interp_cubic(3, 2) # exactly log(3 + 2)\n", "@show interp_cubic(3.1, 2.1) # approximately log(3.1 + 2.1);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See [Interpolations.jl documentation](https://github.com/JuliaMath/Interpolations.jl#convenience-notation) for more details on options and settings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Linear Algebra" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Standard Library\n", "\n", "The standard library contains many useful routines for linear algebra, in\n", "addition to standard functions such as `det()`, `inv()`, `factorize()`, etc.\n", "\n", "Routines are available for\n", "\n", "- Cholesky factorization \n", "- LU decomposition \n", "- Singular value decomposition, \n", "- Schur factorization, etc. \n", "\n", "\n", "See [here](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/) for further details" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## General Tools" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### LaTeXStrings.jl\n", "\n", "When you need to properly escape latex code (e.g. for equation labels), use [LaTeXStrings.jl](https://github.com/stevengj/LaTeXStrings.jl)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using LaTeXStrings\n", "L\"an equation: $1 + \\alpha^2$\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ProgressMeter.jl\n", "\n", "For long-running operations, you can use the [ProgressMeter.jl](https://github.com/timholy/ProgressMeter.jl) package\n", "\n", "To use the package, you simply put a macro in front of `for` loops, etc.\n", "\n", "From the documentation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using ProgressMeter\n", "\n", "@showprogress 1 \"Computing...\" for i in 1:50\n", " sleep(0.1) # some computation....\n", "end" ] } ], "metadata": { "filename": "general_packages.rst", "kernelspec": { "display_name": "Julia 1.2", "language": "julia", "name": "julia-1.2" }, "title": "General Purpose Packages" }, "nbformat": 4, "nbformat_minor": 2 }