{ "cells": [ { "cell_type": "markdown", "id": "d2c383a1", "metadata": {}, "source": [ "\n", "" ] }, { "cell_type": "markdown", "id": "919b455c", "metadata": {}, "source": [ "# Univariate Time Series with Matrix Algebra" ] }, { "cell_type": "markdown", "id": "9df697bc", "metadata": {}, "source": [ "## Contents\n", "\n", "- [Univariate Time Series with Matrix Algebra](#Univariate-Time-Series-with-Matrix-Algebra) \n", " - [Overview](#Overview) \n", " - [Samuelson’s model](#Samuelson’s-model) \n", " - [Adding a random term](#Adding-a-random-term) \n", " - [A forward looking model](#A-forward-looking-model) " ] }, { "cell_type": "markdown", "id": "f8e8a881", "metadata": {}, "source": [ "## Overview\n", "\n", "This lecture uses matrices to solve some linear difference equations.\n", "\n", "As a running example, we’ll study a **second-order linear difference\n", "equation** that was the key technical tool in Paul Samuelson’s 1939\n", "article [[Sam39](https://python.quantecon.org/zreferences.html#id61)] that introduced the **multiplier-accelerator** model.\n", "\n", "This model became the workhorse that powered early econometric versions of\n", "Keynesian macroeconomic models in the United States.\n", "\n", "You can read about the details of that model in [this](https://python.quantecon.org/samuelson.html)\n", "QuantEcon lecture.\n", "\n", "(That lecture also describes some technicalities about second-order linear difference equations.)\n", "\n", "We’ll also study a “perfect foresight” model of stock prices that involves solving\n", "a “forward-looking” linear difference equation.\n", "\n", "We will use the following imports:" ] }, { "cell_type": "code", "execution_count": null, "id": "3a56609e", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import numpy as np\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.rcParams[\"figure.figsize\"] = (11, 5) #set default figure size" ] }, { "cell_type": "markdown", "id": "6f17ea73", "metadata": {}, "source": [ "## Samuelson’s model\n", "\n", "Let $t = 0, \\pm 1, \\pm 2, \\ldots$ index time.\n", "\n", "For $t = 1, 2, 3, \\ldots, T$ suppose that\n", "\n", "\n", "\n", "$$\n", "y_{t} = \\alpha_{0} + \\alpha_{1} y_{t-1} + \\alpha_{2} y_{t-2} \\tag{12.1}\n", "$$\n", "\n", "where we assume that $y_0$ and $y_{-1}$ are given numbers\n", "that we take as **initial conditions**.\n", "\n", "In Samuelson’s model, $y_t$ stood for **national income** or perhaps a different\n", "measure of aggregate activity called **gross domestic product** (GDP) at time $t$.\n", "\n", "Equation [(12.1)](#equation-tswm-1) is called a **second-order linear difference equation**.\n", "\n", "But actually, it is a collection of $T$ simultaneous linear\n", "equations in the $T$ variables $y_1, y_2, \\ldots, y_T$.\n", "\n", "**Note:** To be able to solve a second-order linear difference\n", "equation, we require two **boundary conditions** that can take the form\n", "either of two **initial conditions** or two **terminal conditions** or\n", "possibly one of each.\n", "\n", "Let’s write our equations as a stacked system\n", "\n", "$$\n", "\\underset{\\equiv A}{\\underbrace{\\left[\\begin{array}{cccccccc}\n", "1 & 0 & 0 & 0 & \\cdots & 0 & 0 & 0\\\\\n", "-\\alpha_{1} & 1 & 0 & 0 & \\cdots & 0 & 0 & 0\\\\\n", "-\\alpha_{2} & -\\alpha_{1} & 1 & 0 & \\cdots & 0 & 0 & 0\\\\\n", "0 & -\\alpha_{2} & -\\alpha_{1} & 1 & \\cdots & 0 & 0 & 0\\\\\n", "\\vdots & \\vdots & \\vdots & \\vdots & \\cdots & \\vdots & \\vdots & \\vdots\\\\\n", "0 & 0 & 0 & 0 & \\cdots & -\\alpha_{2} & -\\alpha_{1} & 1\n", "\\end{array}\\right]}}\\left[\\begin{array}{c}\n", "y_{1}\\\\\n", "y_{2}\\\\\n", "y_{3}\\\\\n", "y_{4}\\\\\n", "\\vdots\\\\\n", "y_{T}\n", "\\end{array}\\right]=\\underset{\\equiv b}{\\underbrace{\\left[\\begin{array}{c}\n", "\\alpha_{0}+\\alpha_{1}y_{0}+\\alpha_{2}y_{-1}\\\\\n", "\\alpha_{0}+\\alpha_{2}y_{0}\\\\\n", "\\alpha_{0}\\\\\n", "\\alpha_{0}\\\\\n", "\\vdots\\\\\n", "\\alpha_{0}\n", "\\end{array}\\right]}}\n", "$$\n", "\n", "or\n", "\n", "$$\n", "A y = b\n", "$$\n", "\n", "where\n", "\n", "$$\n", "y = \\begin{bmatrix} y_1 \\cr y_2 \\cr \\cdots \\cr y_T \\end{bmatrix}\n", "$$\n", "\n", "Evidently $y$ can be computed from\n", "\n", "$$\n", "y = A^{-1} b\n", "$$\n", "\n", "The vector $y$ is a complete time path $\\{y_t\\}_{t=1}^T$.\n", "\n", "Let’s put Python to work on an example that captures the flavor of\n", "Samuelson’s multiplier-accelerator model.\n", "\n", "We’ll set parameters equal to the same values we used in [this QuantEcon lecture](https://python.quantecon.org/samuelson.html)." ] }, { "cell_type": "code", "execution_count": null, "id": "6874803a", "metadata": { "hide-output": false }, "outputs": [], "source": [ "T = 80\n", "\n", "# parameters\n", "𝛼0 = 10.0\n", "𝛼1 = 1.53\n", "𝛼2 = -.9\n", "\n", "y_1 = 28. # y_{-1}\n", "y0 = 24." ] }, { "cell_type": "code", "execution_count": null, "id": "bd1d2361", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# construct A and b\n", "A = np.zeros((T, T))\n", "\n", "for i in range(T):\n", " A[i, i] = 1\n", "\n", " if i-1 >= 0:\n", " A[i, i-1] = -𝛼1\n", "\n", " if i-2 >= 0:\n", " A[i, i-2] = -𝛼2\n", "\n", "b = np.full(T, 𝛼0)\n", "b = 𝛼0 + 𝛼1 * y0 + 𝛼2 * y_1\n", "b = 𝛼0 + 𝛼2 * y0" ] }, { "cell_type": "markdown", "id": "9ff61b56", "metadata": {}, "source": [ "Let’s look at the matrix $A$ and the vector $b$ for our\n", "example." ] }, { "cell_type": "code", "execution_count": null, "id": "ffca1efa", "metadata": { "hide-output": false }, "outputs": [], "source": [ "A, b" ] }, { "cell_type": "markdown", "id": "b328b946", "metadata": {}, "source": [ "Now let’s solve for the path of $y$.\n", "\n", "If $y_t$ is GNP at time $t$, then we have a version of\n", "Samuelson’s model of the dynamics for GNP." ] }, { "cell_type": "code", "execution_count": null, "id": "eb8fbcd2", "metadata": { "hide-output": false }, "outputs": [], "source": [ "A_inv = np.linalg.inv(A)\n", "\n", "y = A_inv @ b" ] }, { "cell_type": "code", "execution_count": null, "id": "9687a520", "metadata": { "hide-output": false }, "outputs": [], "source": [ "plt.plot(np.arange(T)+1, y)\n", "plt.xlabel('t')\n", "plt.ylabel('y')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "74cb92eb", "metadata": {}, "source": [ "If we set both initial values at the **steady state** value of $y_t$, namely,\n", "\n", "$$\n", "y_{0} = y_{-1} = \\frac{\\alpha_{0}}{1 - \\alpha_{1} - \\alpha_{2}}\n", "$$\n", "\n", "then $y_{t}$ will be constant" ] }, { "cell_type": "code", "execution_count": null, "id": "70f1d789", "metadata": { "hide-output": false }, "outputs": [], "source": [ "y_1_steady = 𝛼0 / (1 - 𝛼1 - 𝛼2) # y_{-1}\n", "y0_steady = 𝛼0 / (1 - 𝛼1 - 𝛼2)\n", "\n", "b_steady = np.full(T, 𝛼0)\n", "b_steady = 𝛼0 + 𝛼1 * y0_steady + 𝛼2 * y_1_steady\n", "b_steady = 𝛼0 + 𝛼2 * y0_steady" ] }, { "cell_type": "code", "execution_count": null, "id": "02e1d0d1", "metadata": { "hide-output": false }, "outputs": [], "source": [ "y_steady = A_inv @ b_steady" ] }, { "cell_type": "code", "execution_count": null, "id": "6f4eae74", "metadata": { "hide-output": false }, "outputs": [], "source": [ "plt.plot(np.arange(T)+1, y_steady)\n", "plt.xlabel('t')\n", "plt.ylabel('y')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "82892c5d", "metadata": {}, "source": [ "## Adding a random term\n", "\n", "To generate some excitement, we’ll follow in the spirit of the great economists\n", "Eugen Slutsky and Ragnar Frisch and replace our original second-order difference\n", "equation with the following **second-order stochastic linear difference\n", "equation**:\n", "\n", "\n", "\n", "$$\n", "y_{t} = \\alpha_{0} + \\alpha_{1} y_{t-1} + \\alpha_{2} y_{t-2} + u_t \\tag{12.2}\n", "$$\n", "\n", "where $u_{t} \\sim N\\left(0, \\sigma_{u}^{2}\\right)$ and is IID,\n", "meaning **independent** and **identically** distributed.\n", "\n", "We’ll stack these $T$ equations into a system cast in terms of\n", "matrix algebra.\n", "\n", "Let’s define the random vector\n", "\n", "$$\n", "u=\\left[\\begin{array}{c}\n", "u_{1}\\\\\n", "u_{2}\\\\\n", "\\vdots\\\\\n", "u_{T}\n", "\\end{array}\\right]\n", "$$\n", "\n", "Where $A, b, y$ are defined as above, now assume that $y$ is\n", "governed by the system\n", "\n", "$$\n", "A y = b + u\n", "$$\n", "\n", "The solution for $y$ becomes\n", "\n", "$$\n", "y = A^{-1} \\left(b + u\\right)\n", "$$\n", "\n", "Let’s try it out in Python." ] }, { "cell_type": "code", "execution_count": null, "id": "9c643ed5", "metadata": { "hide-output": false }, "outputs": [], "source": [ "𝜎u = 2." ] }, { "cell_type": "code", "execution_count": null, "id": "4354e5dd", "metadata": { "hide-output": false }, "outputs": [], "source": [ "u = np.random.normal(0, 𝜎u, size=T)\n", "y = A_inv @ (b + u)" ] }, { "cell_type": "code", "execution_count": null, "id": "8e34dda4", "metadata": { "hide-output": false }, "outputs": [], "source": [ "plt.plot(np.arange(T)+1, y)\n", "plt.xlabel('t')\n", "plt.ylabel('y')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "b71fdc7f", "metadata": {}, "source": [ "The above time series looks a lot like (detrended) GDP series for a\n", "number of advanced countries in recent decades.\n", "\n", "We can simulate $N$ paths." ] }, { "cell_type": "code", "execution_count": null, "id": "6f325909", "metadata": { "hide-output": false }, "outputs": [], "source": [ "N = 100\n", "\n", "for i in range(N):\n", " u = np.random.normal(0, 𝜎u, size=T)\n", " y = A_inv @ (b + u)\n", " plt.plot(np.arange(T)+1, y, lw=0.5)\n", "\n", "plt.xlabel('t')\n", "plt.ylabel('y')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "4053cf80", "metadata": {}, "source": [ "Also consider the case when $y_{0}$ and $y_{-1}$ are at\n", "steady state." ] }, { "cell_type": "code", "execution_count": null, "id": "b3c3a5dd", "metadata": { "hide-output": false }, "outputs": [], "source": [ "N = 100\n", "\n", "for i in range(N):\n", " u = np.random.normal(0, 𝜎u, size=T)\n", " y_steady = A_inv @ (b_steady + u)\n", " plt.plot(np.arange(T)+1, y_steady, lw=0.5)\n", "\n", "plt.xlabel('t')\n", "plt.ylabel('y')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "799e19cc", "metadata": {}, "source": [ "## A forward looking model\n", "\n", "Samuelson’s model is **backwards looking** in the sense that we give it **initial conditions** and let it\n", "run.\n", "\n", "Let’s now turn to model that is **forward looking**.\n", "\n", "We apply similar linear algebra machinery to study a **perfect\n", "foresight** model widely used as a benchmark in macroeconomics and\n", "finance.\n", "\n", "As an example, we suppose that $p_t$ is the price of a stock and\n", "that $y_t$ is its dividend.\n", "\n", "We assume that $y_t$ is determined by second-order difference\n", "equation that we analyzed just above, so that\n", "\n", "$$\n", "y = A^{-1} \\left(b + u\\right)\n", "$$\n", "\n", "Our **perfect foresight** model of stock prices is\n", "\n", "$$\n", "p_{t} = \\sum_{j=0}^{T-t} \\beta^{j} y_{t+j}, \\quad \\beta \\in (0,1)\n", "$$\n", "\n", "where $\\beta$ is a discount factor.\n", "\n", "The model asserts that the price of the stock at $t$ equals the\n", "discounted present values of the (perfectly foreseen) future dividends.\n", "\n", "Form\n", "\n", "$$\n", "\\underset{\\equiv p}{\\underbrace{\\left[\\begin{array}{c}\n", "p_{1}\\\\\n", "p_{2}\\\\\n", "p_{3}\\\\\n", "\\vdots\\\\\n", "p_{T}\n", "\\end{array}\\right]}}=\\underset{\\equiv B}{\\underbrace{\\left[\\begin{array}{ccccc}\n", "1 & \\beta & \\beta^{2} & \\cdots & \\beta^{T-1}\\\\\n", "0 & 1 & \\beta & \\cdots & \\beta^{T-2}\\\\\n", "0 & 0 & 1 & \\cdots & \\beta^{T-3}\\\\\n", "\\vdots & \\vdots & \\vdots & \\vdots & \\vdots\\\\\n", "0 & 0 & 0 & \\cdots & 1\n", "\\end{array}\\right]}}\\left[\\begin{array}{c}\n", "y_{1}\\\\\n", "y_{2}\\\\\n", "y_{3}\\\\\n", "\\vdots\\\\\n", "y_{T}\n", "\\end{array}\\right]\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "id": "6e6ea553", "metadata": { "hide-output": false }, "outputs": [], "source": [ "𝛽 = .96" ] }, { "cell_type": "code", "execution_count": null, "id": "3cb91427", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# construct B\n", "B = np.zeros((T, T))\n", "\n", "for i in range(T):\n", " B[i, i:] = 𝛽 ** np.arange(0, T-i)" ] }, { "cell_type": "code", "execution_count": null, "id": "5b63aa0d", "metadata": { "hide-output": false }, "outputs": [], "source": [ "B" ] }, { "cell_type": "code", "execution_count": null, "id": "4692fdbe", "metadata": { "hide-output": false }, "outputs": [], "source": [ "𝜎u = 0.\n", "u = np.random.normal(0, 𝜎u, size=T)\n", "y = A_inv @ (b + u)\n", "y_steady = A_inv @ (b_steady + u)" ] }, { "cell_type": "code", "execution_count": null, "id": "2782e932", "metadata": { "hide-output": false }, "outputs": [], "source": [ "p = B @ y" ] }, { "cell_type": "code", "execution_count": null, "id": "bbd41787", "metadata": { "hide-output": false }, "outputs": [], "source": [ "plt.plot(np.arange(0, T)+1, y, label='y')\n", "plt.plot(np.arange(0, T)+1, p, label='p')\n", "plt.xlabel('t')\n", "plt.ylabel('y/p')\n", "plt.legend()\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "9d805704", "metadata": {}, "source": [ "Can you explain why the trend of the price is downward over time?\n", "\n", "Also consider the case when $y_{0}$ and $y_{-1}$ are at the\n", "steady state." ] }, { "cell_type": "code", "execution_count": null, "id": "99ca09c3", "metadata": { "hide-output": false }, "outputs": [], "source": [ "p_steady = B @ y_steady\n", "\n", "plt.plot(np.arange(0, T)+1, y_steady, label='y')\n", "plt.plot(np.arange(0, T)+1, p_steady, label='p')\n", "plt.xlabel('t')\n", "plt.ylabel('y/p')\n", "plt.legend()\n", "\n", "plt.show()" ] } ], "metadata": { "date": 1643278497.330684, "filename": "time_series_with_matrices.md", "kernelspec": { "display_name": "Python", "language": "python3", "name": "python3" }, "title": "Univariate Time Series with Matrix Algebra" }, "nbformat": 4, "nbformat_minor": 5 }