├── README.md
├── about_lectures.ipynb
├── about_py.ipynb
├── additive_functionals.ipynb
├── aiyagari.ipynb
├── amss.ipynb
├── amss2.ipynb
├── amss3.ipynb
├── ar1_processes.ipynb
├── arellano.ipynb
├── arma.ipynb
├── black_litterman.ipynb
├── calvo.ipynb
├── career.ipynb
├── cass_koopmans.ipynb
├── cattle_cycles.ipynb
├── chang_credible.ipynb
├── chang_ramsey.ipynb
├── classical_filtering.ipynb
├── coase.ipynb
├── coleman_policy_iter.ipynb
├── complex_and_trig.ipynb
├── cons_news.ipynb
├── debugging.ipynb
├── discrete_dp.ipynb
├── dyn_stack.ipynb
├── egm_policy_iter.ipynb
├── estspec.ipynb
├── exchangeable.ipynb
├── finite_markov.ipynb
├── functions.ipynb
├── geom_series.ipynb
├── getting_started.ipynb
├── growth_in_dles.ipynb
├── harrison_kreps.ipynb
├── heavy_tails.ipynb
├── hs_invertibility_example.ipynb
├── hs_recursive_models.ipynb
├── ifp.ipynb
├── inventory_dynamics.ipynb
├── irfs_in_hall_model.ipynb
├── jv.ipynb
├── kalman.ipynb
├── kesten_processes.ipynb
├── lake_model.ipynb
├── likelihood_ratio_process.ipynb
├── linear_algebra.ipynb
├── linear_models.ipynb
├── lln_clt.ipynb
├── lq_inventories.ipynb
├── lqcontrol.ipynb
├── lqramsey.ipynb
├── lu_tricks.ipynb
├── lucas_asset_pricing_dles.ipynb
├── lucas_model.ipynb
├── markov_asset.ipynb
├── markov_jump_lq.ipynb
├── markov_perf.ipynb
├── matplotlib.ipynb
├── matsuyama.ipynb
├── mccall_correlated.ipynb
├── mccall_fitted_vfi.ipynb
├── mccall_model.ipynb
├── mccall_model_with_separation.ipynb
├── mle.ipynb
├── multiplicative_functionals.ipynb
├── muth_kalman.ipynb
├── need_for_speed.ipynb
├── numba.ipynb
├── numpy.ipynb
├── odu.ipynb
├── ols.ipynb
├── oop_intro.ipynb
├── opt_tax_recur.ipynb
├── optgrowth.ipynb
├── optgrowth_fast.ipynb
├── orth_proj.ipynb
├── pandas.ipynb
├── pandas_panel.ipynb
├── parallelization.ipynb
├── perm_income.ipynb
├── perm_income_cons.ipynb
├── permanent_income_dles.ipynb
├── python_advanced_features.ipynb
├── python_by_example.ipynb
├── python_essentials.ipynb
├── python_oop.ipynb
├── rational_expectations.ipynb
├── re_with_feedback.ipynb
├── rob_markov_perf.ipynb
├── robustness.ipynb
├── rosen_schooling_model.ipynb
├── samuelson.ipynb
├── scalar_dynam.ipynb
├── schelling.ipynb
├── sci_libs.ipynb
├── scipy.ipynb
├── short_path.ipynb
├── smoothing.ipynb
├── smoothing_tax.ipynb
├── stationary_densities.ipynb
├── tax_smoothing_1.ipynb
├── tax_smoothing_2.ipynb
├── tax_smoothing_3.ipynb
├── troubleshooting.ipynb
├── uncertainty_traps.ipynb
├── von_neumann_model.ipynb
├── wald_friedman.ipynb
├── wealth_dynamics.ipynb
├── writing_good_code.ipynb
└── zreferences.ipynb
/README.md:
--------------------------------------------------------------------------------
1 | # lecture-py-notebooks
2 |
3 | A Repository of Notebooks for the QuantEcon Python Lecture Site
4 |
5 | These files are generated and sources are at https://github.com/QuantEcon/lecture-source-py
6 |
--------------------------------------------------------------------------------
/about_lectures.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "
"
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# About these Lectures"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "## Contents\n",
28 | "\n",
29 | "- [About these Lectures](#About-these-Lectures) \n",
30 | " - [Overview](#Overview) \n",
31 | " - [Python](#Python) \n",
32 | " - [Open Source](#Open-Source) \n",
33 | " - [How about Other Languages?](#How-about-Other-Languages?) \n",
34 | " - [Credits](#Credits) "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | ""
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "## Overview\n",
49 | "\n",
50 | "Programming, mathematics and statistics are powerful tools for analyzing the functioning of economies.\n",
51 | "\n",
52 | "This lecture series provides a hands-on instruction manual.\n",
53 | "\n",
54 | "Topics include\n",
55 | "\n",
56 | "- algorithms and numerical methods for studying economic problems, \n",
57 | "- related mathematical and statistical concepts, and \n",
58 | "- basics of coding skills and software engineering. \n",
59 | "\n",
60 | "\n",
61 | "The intended audience is undergraduate students, graduate students and\n",
62 | "researchers in economics, finance and related fields."
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Python\n",
70 | "\n",
71 | "The coding language for this lecture series is Python.\n",
72 | "\n",
73 | "Note that there’s also a related set of Julia lectures .\n",
74 | "\n",
75 | "In terms of the differences,\n",
76 | "\n",
77 | "- Python is a general-purpose language featuring a massive user community in the sciences and an outstanding scientific ecosystem. \n",
78 | "- Julia is a more recent language with many exciting features. \n",
79 | "\n",
80 | "\n",
81 | "Both are modern, open-source, high productivity languages with all the key features needed for\n",
82 | "high-performance computing.\n",
83 | "\n",
84 | "Julia has the advantage that third party libraries are often written entirely in Julia itself.\n",
85 | "\n",
86 | "Python has the advantage of being supported by a vast collection of scientific libraries (and being a highly marketable skill)."
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "## Open Source\n",
94 | "\n",
95 | "All the computing environments we work with are free and open-source.\n",
96 | "\n",
97 | "This means that you, your coauthors and your students can install them and their libraries on all of your computers without cost or concern about licenses.\n",
98 | "\n",
99 | "Another advantage of open source libraries is that you can read them and learn\n",
100 | "how they work.\n",
101 | "\n",
102 | "For example, let’s say you want to know exactly how [statsmodels](https://github.com/statsmodels/statsmodels) computes Newey-West covariance matrices.\n",
103 | "\n",
104 | "No problem: You can go ahead and [read the code](https://github.com/statsmodels/statsmodels/blob/master/statsmodels/stats/sandwich_covariance.py).\n",
105 | "\n",
106 | "While dipping into external code libraries takes a bit of coding maturity, it’s very useful for\n",
107 | "\n",
108 | "1. helping you understand the details of a particular implementation, and \n",
109 | "1. building your programming skills by showing you code written by first-rate programmers. \n",
110 | "\n",
111 | "\n",
112 | "Also, you can modify the library to suit your needs: if the functionality provided is not exactly what you want, you are free to change it.\n",
113 | "\n",
114 | "Another, a more philosophical advantage of open-source software is that it conforms to the [scientific ideal of reproducibility](https://en.wikipedia.org/wiki/Scientific_method)."
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "## How about Other Languages?\n",
122 | "\n",
123 | "But why don’t you use language XYZ?"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "### MATLAB\n",
131 | "\n",
132 | "While MATLAB has many nice features, it’s starting to show its age.\n",
133 | "\n",
134 | "It can no longer match Python or Julia in terms of performance and design.\n",
135 | "\n",
136 | "MATLAB is also proprietary, which comes with its own set of disadvantages.\n",
137 | "\n",
138 | "Given what’s available now, it’s hard to find any good reason to invest in MATLAB.\n",
139 | "\n",
140 | "Incidentally, if you decide to jump from MATLAB to Python, [this cheat-sheet](http://cheatsheets.quantecon.org/) will be useful."
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "### R\n",
148 | "\n",
149 | "[R](https://cran.r-project.org/) is a very useful open source statistical environment and programming language\n",
150 | "\n",
151 | "Its primary strength is its [vast collection](https://cran.r-project.org/web/packages) of extension packages\n",
152 | "\n",
153 | "Python is more general-purpose than R and hence a better fit for this course\n",
154 | "\n",
155 | "Moreover, if there are R libraries you find you want to use, you can now call them from within Python or Julia"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "### C / C++ / Fortran?\n",
163 | "\n",
164 | "Isn’t Fortran / C / C++ faster than Python? In which case it must be better, right?\n",
165 | "\n",
166 | "This is an outdated view.\n",
167 | "\n",
168 | "First, you can achieve speeds equal to or faster than those of compiled languages in Python through features like a just-in-time compilation — we’ll talk about how later on.\n",
169 | "\n",
170 | "Second, remember that the correct objective function to minimize is"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {
176 | "hide-output": false
177 | },
178 | "source": [
179 | "```python\n",
180 | "total time = development time + execution time\n",
181 | "```\n"
182 | ]
183 | },
184 | {
185 | "cell_type": "markdown",
186 | "metadata": {},
187 | "source": [
188 | "In assessing this trade off, it’s necessary to bear in mind that\n",
189 | "\n",
190 | "- Your time is a far more valuable resource than the computer’s time. \n",
191 | "- Languages like Python are much faster to write and debug in. \n",
192 | "- In any one program, the vast majority of CPU time will be spent iterating over just a few lines of your code. "
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "#### Last Word\n",
200 | "\n",
201 | "Writing your entire program in Fortran / C / C++ is best thought of as “premature optimization”\n",
202 | "\n",
203 | "On this topic we quote the godfather:\n",
204 | "\n",
205 | "> We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. – [Donald Knuth](https://en.wikipedia.org/wiki/Donald_Knuth)"
206 | ]
207 | },
208 | {
209 | "cell_type": "markdown",
210 | "metadata": {},
211 | "source": [
212 | "## Credits\n",
213 | "\n",
214 | "These lectures have benefited greatly from comments and suggestions from our\n",
215 | "colleagues, students and friends. Special thanks are due to our sponsoring\n",
216 | "organization the Alfred P. Sloan Foundation and our research assistants Chase\n",
217 | "Coleman, Spencer Lyon and Matthew McKay for innumerable contributions to the\n",
218 | "code library and functioning of the website.\n",
219 | "\n",
220 | "We also thank [Andrij Stachurski](http://drdrij.com/) for his great web\n",
221 | "skills, and the many others who have contributed suggestions, bug fixes or\n",
222 | "improvements. They include but are not limited to Anmol Bhandari, Long Bui,\n",
223 | "Jeong-Hun Choi, David Evans, Shunsuke Hori, Chenghan Hou, Doc-Jin Jang,\n",
224 | "Qingyin Ma, Akira Matsushita, Tomohito Okabe, Daisuke Oyama, David Pugh, Alex\n",
225 | "Olssen, Nathan Palmer, Bill Tubbs, Natasha Watkins, Pablo Winant and Yixiao\n",
226 | "Zhou."
227 | ]
228 | }
229 | ],
230 | "metadata": {
231 | "date": 1584334732.3616617,
232 | "filename": "about_lectures.rst",
233 | "kernelspec": {
234 | "display_name": "Python",
235 | "language": "python3",
236 | "name": "python3"
237 | },
238 | "title": "About these Lectures"
239 | },
240 | "nbformat": 4,
241 | "nbformat_minor": 2
242 | }
--------------------------------------------------------------------------------
/cattle_cycles.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Cattle Cycles"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Cattle Cycles](#Cattle-Cycles) \n",
33 | " - [The Model](#The-Model) \n",
34 | " - [Mapping into HS2013 Framework](#Mapping-into-HS2013-Framework) "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "This is another member of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
42 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
43 | "\n",
44 | "In addition to what’s in Anaconda, this lecture uses the quantecon library."
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "hide-output": true
52 | },
53 | "outputs": [],
54 | "source": [
55 | "!pip install --upgrade quantecon"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "This lecture uses the DLE class to construct instances of the “Cattle Cycles” model\n",
63 | "of Rosen, Murphy and Scheinkman (1994) [[RMS94]](https://python.quantecon.org/zreferences.html#rosen1994cattle).\n",
64 | "\n",
65 | "That paper constructs a rational expectations equilibrium model to\n",
66 | "understand sources of recurrent cycles in US cattle stocks and prices.\n",
67 | "\n",
68 | "We make the following imports:"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "metadata": {
75 | "hide-output": false
76 | },
77 | "outputs": [],
78 | "source": [
79 | "import numpy as np\n",
80 | "import matplotlib.pyplot as plt\n",
81 | "from quantecon import LQ\n",
82 | "from collections import namedtuple\n",
83 | "from quantecon import DLE\n",
84 | "from math import sqrt\n",
85 | "%matplotlib inline"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "## The Model\n",
93 | "\n",
94 | "The model features a static linear demand curve and a “time-to-grow”\n",
95 | "structure for cattle.\n",
96 | "\n",
97 | "Let $ p_t $ be the price of slaughtered beef, $ m_t $ the cost\n",
98 | "of preparing an animal for slaughter, $ h_t $ the holding cost for a\n",
99 | "mature animal, $ \\gamma_1 h_t $ the holding cost for a yearling, and\n",
100 | "$ \\gamma_0 h_t $ the holding cost for a calf.\n",
101 | "\n",
102 | "The cost processes $ \\{h_t, m_t \\}_{t=0}^\\infty $ are exogenous,\n",
103 | "while the price process $ \\{p_t \\}_{t=0}^\\infty $ is determined\n",
104 | "within a rational expectations equilibrium.\n",
105 | "\n",
106 | "Let $ x_t $ be the breeding stock, and $ y_t $ be the total\n",
107 | "stock of cattle.\n",
108 | "\n",
109 | "The law of motion for the breeding stock is\n",
110 | "\n",
111 | "$$\n",
112 | "x_t = (1-\\delta)x_{t-1} + gx_{t-3} - c_t\n",
113 | "$$\n",
114 | "\n",
115 | "where $ g < 1 $ is the number of calves that each member of the\n",
116 | "breeding stock has each year, and $ c_t $ is the number of cattle\n",
117 | "slaughtered.\n",
118 | "\n",
119 | "The total headcount of cattle is\n",
120 | "\n",
121 | "$$\n",
122 | "y_t = x_t + gx_{t-1} + gx_{t-2}\n",
123 | "$$\n",
124 | "\n",
125 | "This equation states that the total number of cattle equals the sum of\n",
126 | "adults, calves and yearlings, respectively.\n",
127 | "\n",
128 | "A representative farmer chooses $ \\{c_t, x_t\\} $ to maximize:\n",
129 | "\n",
130 | "$$\n",
131 | "\\mathbb{E}_0 \\sum_{t=0}^\\infty \\beta^t \\{p_tc_t - h_tx_t - \\gamma_0 h_t(gx_{t-1}) - \\gamma_1 h_t(gx_{t-2}) - m_tc_t - \\frac{\\psi_1}{2}x_t^2 - \\frac{\\psi_2}{2}x_{t-1}^2 - \\frac{\\psi_3}{2}x_{t-3}^2 - \\frac{\\psi_4}{2}c_t^2 \\}\n",
132 | "$$\n",
133 | "\n",
134 | "subject to the law of motion for $ x_t $, taking as given the\n",
135 | "stochastic laws of motion for the exogenous processes, the equilibrium\n",
136 | "price process, and the initial state [$ x_{-1},x_{-2},x_{-3} $].\n",
137 | "\n",
138 | "**Remark** The $ \\psi_j $ parameters are very small quadratic costs\n",
139 | "that are included for technical reasons to make well posed and well\n",
140 | "behaved the linear quadratic dynamic programming problem solved by the\n",
141 | "fictitious planner who in effect chooses equilibrium quantities and shadow\n",
142 | "prices.\n",
143 | "\n",
144 | "Demand for beef is government by $ c_t = a_0 - a_1p_t + \\tilde d_t $\n",
145 | "where $ \\tilde d_t $ is a stochastic process with mean zero,\n",
146 | "representing a demand shifter."
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "## Mapping into HS2013 Framework"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "### Preferences\n",
161 | "\n",
162 | "We set\n",
163 | "$ \\Lambda = 0, \\Delta_h = 0, \\Theta_h = 0, \\Pi = \\alpha_1^{-\\frac{1}{2}} $\n",
164 | "and $ b_t = \\Pi \\tilde d_t + \\Pi \\alpha_0 $.\n",
165 | "\n",
166 | "With these settings, the FOC for the household’s problem becomes the\n",
167 | "demand curve of the “Cattle Cycles” model."
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {},
173 | "source": [
174 | "### Technology\n",
175 | "\n",
176 | "To capture the law of motion for cattle, we set\n",
177 | "\n",
178 | "$$\n",
179 | "\\Delta_k =\n",
180 | "\\left[ {\\begin{array}{ccc}\n",
181 | " (1-\\delta) & 0 & g \\\\ 1 & 0 & 0 \\\\ 0 & 1 & 0\n",
182 | " \\end{array} }\n",
183 | " \\right] , \\\n",
184 | " \\Theta_k =\n",
185 | "\\left[ {\\begin{array}{c}\n",
186 | " 1 \\\\ 0 \\\\ 0\n",
187 | " \\end{array} }\n",
188 | " \\right]\n",
189 | "$$\n",
190 | "\n",
191 | "(where $ i_t = - c_t $).\n",
192 | "\n",
193 | "To capture the production of cattle, we set\n",
194 | "\n",
195 | "$$\n",
196 | "\\Phi_c =\n",
197 | "\\left[ {\\begin{array}{c}\n",
198 | " 1 \\\\ f_1 \\\\ 0 \\\\ 0 \\\\ -f_7\n",
199 | " \\end{array} }\n",
200 | " \\right] , \\\n",
201 | " \\Phi_g =\n",
202 | "\\left[ {\\begin{array}{cccc}\n",
203 | " 0 & 0 & 0 & 0 \\\\ 1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1\n",
204 | " \\end{array} }\n",
205 | " \\right] , \\\n",
206 | " \\Phi_i =\n",
207 | "\\left[ {\\begin{array}{c}\n",
208 | " 1 \\\\ 0 \\\\ 0 \\\\ 0 \\\\ 0\n",
209 | " \\end{array} }\n",
210 | " \\right] , \\\n",
211 | " \\Gamma =\n",
212 | "\\left[ {\\begin{array}{ccc}\n",
213 | " 0 & 0 & 0 \\\\ f_1(1-\\delta) & 0 & g f_1 \\\\ f_3 & 0 & 0 \\\\ 0 & f_5 & 0 \\\\ 0 & 0 & 0\n",
214 | " \\end{array} }\n",
215 | " \\right]\n",
216 | "$$"
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {},
222 | "source": [
223 | "### Information\n",
224 | "\n",
225 | "We set\n",
226 | "\n",
227 | "$$\n",
228 | "A_{22} =\n",
229 | "\\left[ {\\begin{array}{cccc}\n",
230 | " 1 & 0 & 0 & 0\\\\ 0 & \\rho_1 & 0 & 0 \\\\ 0 & 0 & \\rho_2 & 0 \\\\ 0 & 0 & 0 & \\rho_3\n",
231 | " \\end{array} }\n",
232 | " \\right] \\\n",
233 | ", C_2 =\n",
234 | "\\left[ {\\begin{array}{ccc}\n",
235 | " 0 & 0 & 0\\\\ 1 & 0 & 0 \\\\ 0 & 1 & 0 \\\\ 0 & 0 & 15\n",
236 | " \\end{array} }\n",
237 | " \\right] \\\n",
238 | ", U_b =\n",
239 | "\\left[ {\\begin{array}{cccc}\n",
240 | " \\Pi \\alpha_0 & 0 & 0 & \\Pi\n",
241 | " \\end{array} }\n",
242 | " \\right] \\\n",
243 | ", U_d =\n",
244 | "\\left[ {\\begin{array}{c}\n",
245 | " 0 \\\\ f_2 U_h \\\\ f_4 U_h \\\\ f_6 U_h \\\\ f_8 U_h\n",
246 | " \\end{array} }\n",
247 | " \\right]\n",
248 | "$$\n",
249 | "\n",
250 | "To map this into our class, we set $ f_1^2 = \\frac{\\Psi_1}{2} $,\n",
251 | "$ f_2^2 = \\frac{\\Psi_2}{2} $, $ f_3^2 = \\frac{\\Psi_3}{2} $,\n",
252 | "$ 2f_1f_2 = 1 $, $ 2f_3f_4 = \\gamma_0g $,\n",
253 | "$ 2f_5f_6 = \\gamma_1g $."
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {
260 | "hide-output": false
261 | },
262 | "outputs": [],
263 | "source": [
264 | "# We define namedtuples in this way as it allows us to check, for example,\n",
265 | "# what matrices are associated with a particular technology.\n",
266 | "\n",
267 | "Information = namedtuple('Information', ['a22', 'c2', 'ub', 'ud'])\n",
268 | "Technology = namedtuple('Technology', ['ϕ_c', 'ϕ_g', 'ϕ_i', 'γ', 'δ_k', 'θ_k'])\n",
269 | "Preferences = namedtuple('Preferences', ['β', 'l_λ', 'π_h', 'δ_h', 'θ_h'])"
270 | ]
271 | },
272 | {
273 | "cell_type": "markdown",
274 | "metadata": {},
275 | "source": [
276 | "We set parameters to those used by [[RMS94]](https://python.quantecon.org/zreferences.html#rosen1994cattle)"
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {
283 | "hide-output": false
284 | },
285 | "outputs": [],
286 | "source": [
287 | "β = np.array([[0.909]])\n",
288 | "lλ = np.array([[0]])\n",
289 | "\n",
290 | "a1 = 0.5\n",
291 | "πh = np.array([[1 / (sqrt(a1))]])\n",
292 | "δh = np.array([[0]])\n",
293 | "θh = np.array([[0]])\n",
294 | "\n",
295 | "δ = 0.1\n",
296 | "g = 0.85\n",
297 | "f1 = 0.001\n",
298 | "f3 = 0.001\n",
299 | "f5 = 0.001\n",
300 | "f7 = 0.001\n",
301 | "\n",
302 | "ϕc = np.array([[1], [f1], [0], [0], [-f7]])\n",
303 | "\n",
304 | "ϕg = np.array([[0, 0, 0, 0],\n",
305 | " [1, 0, 0, 0],\n",
306 | " [0, 1, 0, 0],\n",
307 | " [0, 0, 1,0],\n",
308 | " [0, 0, 0, 1]])\n",
309 | "\n",
310 | "ϕi = np.array([[1], [0], [0], [0], [0]])\n",
311 | "\n",
312 | "γ = np.array([[ 0, 0, 0],\n",
313 | " [f1 * (1 - δ), 0, g * f1],\n",
314 | " [ f3, 0, 0],\n",
315 | " [ 0, f5, 0],\n",
316 | " [ 0, 0, 0]])\n",
317 | "\n",
318 | "δk = np.array([[1 - δ, 0, g],\n",
319 | " [ 1, 0, 0],\n",
320 | " [ 0, 1, 0]])\n",
321 | "\n",
322 | "θk = np.array([[1], [0], [0]])\n",
323 | "\n",
324 | "ρ1 = 0\n",
325 | "ρ2 = 0\n",
326 | "ρ3 = 0.6\n",
327 | "a0 = 500\n",
328 | "γ0 = 0.4\n",
329 | "γ1 = 0.7\n",
330 | "f2 = 1 / (2 * f1)\n",
331 | "f4 = γ0 * g / (2 * f3)\n",
332 | "f6 = γ1 * g / (2 * f5)\n",
333 | "f8 = 1 / (2 * f7)\n",
334 | "\n",
335 | "a22 = np.array([[1, 0, 0, 0],\n",
336 | " [0, ρ1, 0, 0],\n",
337 | " [0, 0, ρ2, 0],\n",
338 | " [0, 0, 0, ρ3]])\n",
339 | "\n",
340 | "c2 = np.array([[0, 0, 0],\n",
341 | " [1, 0, 0],\n",
342 | " [0, 1, 0],\n",
343 | " [0, 0, 15]])\n",
344 | "\n",
345 | "ub = np.array([[πh * a0, 0, 0, πh]])\n",
346 | "uh = np.array([[50, 1, 0, 0]])\n",
347 | "um = np.array([[100, 0, 1, 0]])\n",
348 | "ud = np.vstack(([0, 0, 0, 0],\n",
349 | " f2 * uh, f4 * uh, f6 * uh, f8 * um))"
350 | ]
351 | },
352 | {
353 | "cell_type": "markdown",
354 | "metadata": {},
355 | "source": [
356 | "Notice that we have set $ \\rho_1 = \\rho_2 = 0 $, so $ h_t $ and\n",
357 | "$ m_t $ consist of a constant and a white noise component.\n",
358 | "\n",
359 | "We set up the economy using tuples for information, technology and\n",
360 | "preference matrices below.\n",
361 | "\n",
362 | "We also construct two extra information matrices, corresponding to cases\n",
363 | "when $ \\rho_3 = 1 $ and $ \\rho_3 = 0 $ (as opposed to the\n",
364 | "baseline case of $ \\rho_3 = 0.6 $)."
365 | ]
366 | },
367 | {
368 | "cell_type": "code",
369 | "execution_count": null,
370 | "metadata": {
371 | "hide-output": false
372 | },
373 | "outputs": [],
374 | "source": [
375 | "info1 = Information(a22, c2, ub, ud)\n",
376 | "tech1 = Technology(ϕc, ϕg, ϕi, γ, δk, θk)\n",
377 | "pref1 = Preferences(β, lλ, πh, δh, θh)\n",
378 | "\n",
379 | "ρ3_2 = 1\n",
380 | "a22_2 = np.array([[1, 0, 0, 0],\n",
381 | " [0, ρ1, 0, 0],\n",
382 | " [0, 0, ρ2, 0],\n",
383 | " [0, 0, 0, ρ3_2]])\n",
384 | "\n",
385 | "info2 = Information(a22_2, c2, ub, ud)\n",
386 | "\n",
387 | "ρ3_3 = 0\n",
388 | "a22_3 = np.array([[1, 0, 0, 0],\n",
389 | " [0, ρ1, 0, 0],\n",
390 | " [0, 0, ρ2, 0],\n",
391 | " [0, 0, 0, ρ3_3]])\n",
392 | "\n",
393 | "info3 = Information(a22_3, c2, ub, ud)\n",
394 | "\n",
395 | "# Example of how we can look at the matrices associated with a given namedtuple\n",
396 | "info1.a22"
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": null,
402 | "metadata": {
403 | "hide-output": false
404 | },
405 | "outputs": [],
406 | "source": [
407 | "# Use tuples to define DLE class\n",
408 | "econ1 = DLE(info1, tech1, pref1)\n",
409 | "econ2 = DLE(info2, tech1, pref1)\n",
410 | "econ3 = DLE(info3, tech1, pref1)\n",
411 | "\n",
412 | "# Calculate steady-state in baseline case and use to set the initial condition\n",
413 | "econ1.compute_steadystate(nnc=4)\n",
414 | "x0 = econ1.zz"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": null,
420 | "metadata": {
421 | "hide-output": false
422 | },
423 | "outputs": [],
424 | "source": [
425 | "econ1.compute_sequence(x0, ts_length=100)"
426 | ]
427 | },
428 | {
429 | "cell_type": "markdown",
430 | "metadata": {},
431 | "source": [
432 | "[[RMS94]](https://python.quantecon.org/zreferences.html#rosen1994cattle) use the model to understand the\n",
433 | "sources of recurrent cycles in total cattle stocks.\n",
434 | "\n",
435 | "Plotting $ y_t $ for a simulation of their model shows its ability\n",
436 | "to generate cycles in quantities"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "execution_count": null,
442 | "metadata": {
443 | "hide-output": false
444 | },
445 | "outputs": [],
446 | "source": [
447 | "# Calculation of y_t\n",
448 | "totalstock = econ1.k[0] + g * econ1.k[1] + g * econ1.k[2]\n",
449 | "fig, ax = plt.subplots()\n",
450 | "ax.plot(totalstock)\n",
451 | "ax.set_xlim((-1, 100))\n",
452 | "ax.set_title('Total number of cattle')\n",
453 | "plt.show()"
454 | ]
455 | },
456 | {
457 | "cell_type": "markdown",
458 | "metadata": {},
459 | "source": [
460 | "In their Figure 3, [[RMS94]](https://python.quantecon.org/zreferences.html#rosen1994cattle) plot the impulse response functions\n",
461 | "of consumption and the breeding stock of cattle to the demand shock,\n",
462 | "$ \\tilde d_t $, under the three different values of $ \\rho_3 $.\n",
463 | "\n",
464 | "We replicate their Figure 3 below"
465 | ]
466 | },
467 | {
468 | "cell_type": "code",
469 | "execution_count": null,
470 | "metadata": {
471 | "hide-output": false
472 | },
473 | "outputs": [],
474 | "source": [
475 | "shock_demand = np.array([[0], [0], [1]])\n",
476 | "\n",
477 | "econ1.irf(ts_length=25, shock=shock_demand)\n",
478 | "econ2.irf(ts_length=25, shock=shock_demand)\n",
479 | "econ3.irf(ts_length=25, shock=shock_demand)\n",
480 | "\n",
481 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
482 | "ax1.plot(econ1.c_irf, label='$\\\\rho=0.6$')\n",
483 | "ax1.plot(econ2.c_irf, label='$\\\\rho=1$')\n",
484 | "ax1.plot(econ3.c_irf, label='$\\\\rho=0$')\n",
485 | "ax1.set_title('Consumption response to demand shock')\n",
486 | "ax1.legend()\n",
487 | "\n",
488 | "ax2.plot(econ1.k_irf[:, 0], label='$\\\\rho=0.6$')\n",
489 | "ax2.plot(econ2.k_irf[:, 0], label='$\\\\rho=1$')\n",
490 | "ax2.plot(econ3.k_irf[:, 0], label='$\\\\rho=0$')\n",
491 | "ax2.set_title('Breeding stock response to demand shock')\n",
492 | "ax2.legend()\n",
493 | "plt.show()"
494 | ]
495 | },
496 | {
497 | "cell_type": "markdown",
498 | "metadata": {},
499 | "source": [
500 | "The above figures show how consumption patterns differ markedly,\n",
501 | "depending on the persistence of the demand shock:\n",
502 | "\n",
503 | "- If it is purely transitory ($ \\rho_3 = 0 $) then consumption\n",
504 | " rises immediately but is later reduced to build stocks up again. \n",
505 | "- If it is permanent ($ \\rho_3 = 1 $), then consumption falls\n",
506 | " immediately, in order to build up stocks to satisfy the permanent\n",
507 | " rise in future demand. \n",
508 | "\n",
509 | "\n",
510 | "In Figure 4 of their paper, [[RMS94]](https://python.quantecon.org/zreferences.html#rosen1994cattle) plot the response to a demand shock\n",
511 | "of the breeding stock *and* the total stock, for $ \\rho_3 = 0 $ and\n",
512 | "$ \\rho_3 = 0.6 $.\n",
513 | "\n",
514 | "We replicate their Figure 4 below"
515 | ]
516 | },
517 | {
518 | "cell_type": "code",
519 | "execution_count": null,
520 | "metadata": {
521 | "hide-output": false
522 | },
523 | "outputs": [],
524 | "source": [
525 | "total1_irf = econ1.k_irf[:, 0] + g * econ1.k_irf[:, 1] + g * econ1.k_irf[:, 2]\n",
526 | "total3_irf = econ3.k_irf[:, 0] + g * econ3.k_irf[:, 1] + g * econ3.k_irf[:, 2]\n",
527 | "\n",
528 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
529 | "ax1.plot(econ1.k_irf[:, 0], label='Breeding Stock')\n",
530 | "ax1.plot(total1_irf, label='Total Stock')\n",
531 | "ax1.set_title('$\\\\rho=0.6$')\n",
532 | "\n",
533 | "ax2.plot(econ3.k_irf[:, 0], label='Breeding Stock')\n",
534 | "ax2.plot(total3_irf, label='Total Stock')\n",
535 | "ax2.set_title('$\\\\rho=0$')\n",
536 | "plt.show()"
537 | ]
538 | },
539 | {
540 | "cell_type": "markdown",
541 | "metadata": {},
542 | "source": [
543 | "The fact that $ y_t $ is a weighted moving average of $ x_t $\n",
544 | "creates a humped shape response of the total stock in response to demand\n",
545 | "shocks, contributing to the cyclicality seen in the first graph of this\n",
546 | "lecture."
547 | ]
548 | }
549 | ],
550 | "metadata": {
551 | "date": 1584334734.8176475,
552 | "filename": "cattle_cycles.rst",
553 | "kernelspec": {
554 | "display_name": "Python",
555 | "language": "python3",
556 | "name": "python3"
557 | },
558 | "title": "Cattle Cycles"
559 | },
560 | "nbformat": 4,
561 | "nbformat_minor": 2
562 | }
--------------------------------------------------------------------------------
/debugging.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# Debugging\n",
21 | "\n",
22 | "\n",
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Debugging](#Debugging) \n",
33 | " - [Overview](#Overview) \n",
34 | " - [Debugging](#Debugging) \n",
35 | " - [Other Useful Magics](#Other-Useful-Magics) "
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "> “Debugging is twice as hard as writing the code in the first place.\n",
43 | "> Therefore, if you write the code as cleverly as possible, you are, by definition,\n",
44 | "> not smart enough to debug it.” – Brian Kernighan"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "## Overview\n",
52 | "\n",
53 | "Are you one of those programmers who fills their code with `print` statements when trying to debug their programs?\n",
54 | "\n",
55 | "Hey, we all used to do that.\n",
56 | "\n",
57 | "(OK, sometimes we still do that…)\n",
58 | "\n",
59 | "But once you start writing larger programs you’ll need a better system.\n",
60 | "\n",
61 | "Debugging tools for Python vary across platforms, IDEs and editors.\n",
62 | "\n",
63 | "Here we’ll focus on Jupyter and leave you to explore other settings.\n",
64 | "\n",
65 | "We’ll need the following imports"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {
72 | "hide-output": false
73 | },
74 | "outputs": [],
75 | "source": [
76 | "import numpy as np\n",
77 | "import matplotlib.pyplot as plt\n",
78 | "%matplotlib inline"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "## Debugging\n",
86 | "\n",
87 | "\n",
88 | ""
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "### The `debug` Magic\n",
96 | "\n",
97 | "Let’s consider a simple (and rather contrived) example"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {
104 | "hide-output": false
105 | },
106 | "outputs": [],
107 | "source": [
108 | "def plot_log():\n",
109 | " fig, ax = plt.subplots(2, 1)\n",
110 | " x = np.linspace(1, 2, 10)\n",
111 | " ax.plot(x, np.log(x))\n",
112 | " plt.show()\n",
113 | "\n",
114 | "plot_log() # Call the function, generate plot"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "This code is intended to plot the `log` function over the interval $ [1, 2] $.\n",
122 | "\n",
123 | "But there’s an error here: `plt.subplots(2, 1)` should be just `plt.subplots()`.\n",
124 | "\n",
125 | "(The call `plt.subplots(2, 1)` returns a NumPy array containing two axes objects, suitable for having two subplots on the same figure)\n",
126 | "\n",
127 | "The traceback shows that the error occurs at the method call `ax.plot(x, np.log(x))`.\n",
128 | "\n",
129 | "The error occurs because we have mistakenly made `ax` a NumPy array, and a NumPy array has no `plot` method.\n",
130 | "\n",
131 | "But let’s pretend that we don’t understand this for the moment.\n",
132 | "\n",
133 | "We might suspect there’s something wrong with `ax` but when we try to investigate this object, we get the following exception:"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": null,
139 | "metadata": {
140 | "hide-output": false
141 | },
142 | "outputs": [],
143 | "source": [
144 | "ax"
145 | ]
146 | },
147 | {
148 | "cell_type": "markdown",
149 | "metadata": {},
150 | "source": [
151 | "The problem is that `ax` was defined inside `plot_log()`, and the name is\n",
152 | "lost once that function terminates.\n",
153 | "\n",
154 | "Let’s try doing it a different way.\n",
155 | "\n",
156 | "We run the first cell block again, generating the same error"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {
163 | "hide-output": false
164 | },
165 | "outputs": [],
166 | "source": [
167 | "def plot_log():\n",
168 | " fig, ax = plt.subplots(2, 1)\n",
169 | " x = np.linspace(1, 2, 10)\n",
170 | " ax.plot(x, np.log(x))\n",
171 | " plt.show()\n",
172 | "\n",
173 | "plot_log() # Call the function, generate plot"
174 | ]
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "metadata": {},
179 | "source": [
180 | "But this time we type in the following cell block"
181 | ]
182 | },
183 | {
184 | "cell_type": "markdown",
185 | "metadata": {
186 | "hide-output": false
187 | },
188 | "source": [
189 | "```ipython\n",
190 | "%debug\n",
191 | "```\n"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "You should be dropped into a new prompt that looks something like this"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {
204 | "hide-output": false
205 | },
206 | "source": [
207 | "```ipython\n",
208 | "ipdb>\n",
209 | "```\n"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "(You might see pdb> instead)\n",
217 | "\n",
218 | "Now we can investigate the value of our variables at this point in the program, step forward through the code, etc.\n",
219 | "\n",
220 | "For example, here we simply type the name `ax` to see what’s happening with\n",
221 | "this object:"
222 | ]
223 | },
224 | {
225 | "cell_type": "markdown",
226 | "metadata": {
227 | "hide-output": false
228 | },
229 | "source": [
230 | "```ipython\n",
231 | "ipdb> ax\n",
232 | "array([,\n",
233 | " ], dtype=object)\n",
234 | "```\n"
235 | ]
236 | },
237 | {
238 | "cell_type": "markdown",
239 | "metadata": {},
240 | "source": [
241 | "It’s now very clear that `ax` is an array, which clarifies the source of the\n",
242 | "problem.\n",
243 | "\n",
244 | "To find out what else you can do from inside `ipdb` (or `pdb`), use the\n",
245 | "online help"
246 | ]
247 | },
248 | {
249 | "cell_type": "markdown",
250 | "metadata": {
251 | "hide-output": false
252 | },
253 | "source": [
254 | "```ipython\n",
255 | "ipdb> h\n",
256 | "\n",
257 | "Documented commands (type help ):\n",
258 | "========================================\n",
259 | "EOF bt cont enable jump pdef r tbreak w\n",
260 | "a c continue exit l pdoc restart u whatis\n",
261 | "alias cl d h list pinfo return unalias where\n",
262 | "args clear debug help n pp run unt\n",
263 | "b commands disable ignore next q s until\n",
264 | "break condition down j p quit step up\n",
265 | "\n",
266 | "Miscellaneous help topics:\n",
267 | "==========================\n",
268 | "exec pdb\n",
269 | "\n",
270 | "Undocumented commands:\n",
271 | "======================\n",
272 | "retval rv\n",
273 | "\n",
274 | "ipdb> h c\n",
275 | "c(ont(inue))\n",
276 | "Continue execution, only stop when a breakpoint is encountered.\n",
277 | "```\n"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "### Setting a Break Point\n",
285 | "\n",
286 | "The preceding approach is handy but sometimes insufficient.\n",
287 | "\n",
288 | "Consider the following modified version of our function above"
289 | ]
290 | },
291 | {
292 | "cell_type": "code",
293 | "execution_count": null,
294 | "metadata": {
295 | "hide-output": false
296 | },
297 | "outputs": [],
298 | "source": [
299 | "def plot_log():\n",
300 | " fig, ax = plt.subplots()\n",
301 | " x = np.logspace(1, 2, 10)\n",
302 | " ax.plot(x, np.log(x))\n",
303 | " plt.show()\n",
304 | "\n",
305 | "plot_log()"
306 | ]
307 | },
308 | {
309 | "cell_type": "markdown",
310 | "metadata": {},
311 | "source": [
312 | "Here the original problem is fixed, but we’ve accidentally written\n",
313 | "`np.logspace(1, 2, 10)` instead of `np.linspace(1, 2, 10)`.\n",
314 | "\n",
315 | "Now there won’t be any exception, but the plot won’t look right.\n",
316 | "\n",
317 | "To investigate, it would be helpful if we could inspect variables like `x` during execution of the function.\n",
318 | "\n",
319 | "To this end, we add a “break point” by inserting `breakpoint()` inside the function code block"
320 | ]
321 | },
322 | {
323 | "cell_type": "markdown",
324 | "metadata": {
325 | "hide-output": false
326 | },
327 | "source": [
328 | "```python3\n",
329 | "def plot_log():\n",
330 | " breakpoint()\n",
331 | " fig, ax = plt.subplots()\n",
332 | " x = np.logspace(1, 2, 10)\n",
333 | " ax.plot(x, np.log(x))\n",
334 | " plt.show()\n",
335 | "\n",
336 | "plot_log()\n",
337 | "```\n"
338 | ]
339 | },
340 | {
341 | "cell_type": "markdown",
342 | "metadata": {},
343 | "source": [
344 | "Now let’s run the script, and investigate via the debugger"
345 | ]
346 | },
347 | {
348 | "cell_type": "markdown",
349 | "metadata": {
350 | "hide-output": false
351 | },
352 | "source": [
353 | "```ipython\n",
354 | "> (6)plot_log()\n",
355 | "-> fig, ax = plt.subplots()\n",
356 | "(Pdb) n\n",
357 | "> (7)plot_log()\n",
358 | "-> x = np.logspace(1, 2, 10)\n",
359 | "(Pdb) n\n",
360 | "> (8)plot_log()\n",
361 | "-> ax.plot(x, np.log(x))\n",
362 | "(Pdb) x\n",
363 | "array([ 10. , 12.91549665, 16.68100537, 21.5443469 ,\n",
364 | " 27.82559402, 35.93813664, 46.41588834, 59.94842503,\n",
365 | " 77.42636827, 100. ])\n",
366 | "```\n"
367 | ]
368 | },
369 | {
370 | "cell_type": "markdown",
371 | "metadata": {},
372 | "source": [
373 | "We used `n` twice to step forward through the code (one line at a time).\n",
374 | "\n",
375 | "Then we printed the value of `x` to see what was happening with that variable.\n",
376 | "\n",
377 | "To exit from the debugger, use `q`."
378 | ]
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "metadata": {},
383 | "source": [
384 | "## Other Useful Magics\n",
385 | "\n",
386 | "In this lecture, we used the `%debug` IPython magic.\n",
387 | "\n",
388 | "There are many other useful magics:\n",
389 | "\n",
390 | "- `%precision 4` sets printed precision for floats to 4 decimal places \n",
391 | "- `%whos` gives a list of variables and their values \n",
392 | "- `%quickref` gives a list of magics \n",
393 | "\n",
394 | "\n",
395 | "The full list of magics is [here](http://ipython.readthedocs.org/en/stable/interactive/magics.html)."
396 | ]
397 | }
398 | ],
399 | "metadata": {
400 | "date": 1584334736.3417926,
401 | "filename": "debugging.rst",
402 | "kernelspec": {
403 | "display_name": "Python",
404 | "language": "python3",
405 | "name": "python3"
406 | },
407 | "title": "Debugging"
408 | },
409 | "nbformat": 4,
410 | "nbformat_minor": 2
411 | }
--------------------------------------------------------------------------------
/hs_invertibility_example.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Shock Non Invertibility"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Shock Non Invertibility](#Shock-Non-Invertibility) \n",
33 | " - [Overview](#Overview) \n",
34 | " - [Model](#Model) \n",
35 | " - [Code](#Code) "
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "## Overview\n",
43 | "\n",
44 | "This is another member of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
45 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
46 | "\n",
47 | "In addition to what’s in Anaconda, this lecture uses the quantecon library."
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "metadata": {
54 | "hide-output": true
55 | },
56 | "outputs": [],
57 | "source": [
58 | "!pip install --upgrade quantecon"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {},
64 | "source": [
65 | "We’ll make these imports:"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {
72 | "hide-output": false
73 | },
74 | "outputs": [],
75 | "source": [
76 | "import numpy as np\n",
77 | "import quantecon as qe\n",
78 | "import matplotlib.pyplot as plt\n",
79 | "from quantecon import LQ\n",
80 | "from quantecon import DLE\n",
81 | "from math import sqrt\n",
82 | "%matplotlib inline"
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "This lecture can be viewed as introducing an early contribution to what is now often called\n",
90 | "a **news and noise** issue.\n",
91 | "\n",
92 | "In particular, it analyzes a **shock-invertibility** issue that is\n",
93 | "endemic within a class of permanent income models.\n",
94 | "\n",
95 | "Technically, the invertibility problem indicates a situation in which\n",
96 | "histories of the shocks in an econometrician’s autoregressive or Wold\n",
97 | "moving average representation span a smaller information space than do\n",
98 | "the shocks that are seen by the agents inside the econometrician’s model.\n",
99 | "\n",
100 | "This situation sets the stage for an econometrician who is unaware of the\n",
101 | "problem and consequently misinterprets shocks and likely responses to them.\n",
102 | "\n",
103 | "A shock-invertibility that is technically close to the one studied here is discussed by\n",
104 | "Eric Leeper, Todd Walker, and Susan Yang [[LWY13]](https://python.quantecon.org/zreferences.html#leeper-walker-yang) in their analysis of **fiscal foresight**.\n",
105 | "\n",
106 | "A distinct shock-invertibility issue is present in the special LQ consumption smoothing model\n",
107 | "in [quantecon lecture](https://python.quantecon.org/cons_news.html)."
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "## Model\n",
115 | "\n",
116 | "We consider the following modification of Robert Hall’s (1978) model [[Hal78]](https://python.quantecon.org/zreferences.html#hall1978) in which the endowment process is the sum of two orthogonal autoregressive processes:\n",
117 | "\n",
118 | "**Preferences**\n",
119 | "\n",
120 | "$$\n",
121 | "-\\frac{1}{2}\\mathbb{E}\\sum_{t=0}^\\infty \\beta^t[(c_t - b_t)^2 + l_t^2]|J_0\n",
122 | "$$\n",
123 | "\n",
124 | "$$\n",
125 | "s_t = c_t\n",
126 | "$$\n",
127 | "\n",
128 | "$$\n",
129 | "b_t = U_bz_t\n",
130 | "$$\n",
131 | "\n",
132 | "**Technology**\n",
133 | "\n",
134 | "$$\n",
135 | "c_t + i_t = \\gamma k_{t-1} + d_t\n",
136 | "$$\n",
137 | "\n",
138 | "$$\n",
139 | "k_t = \\delta_k k_{t-1} + i_t\n",
140 | "$$\n",
141 | "\n",
142 | "$$\n",
143 | "g_t = \\phi_1 i_t \\, , \\phi_1 > 0\n",
144 | "$$\n",
145 | "\n",
146 | "$$\n",
147 | "g_t \\cdot g_t = l_t^2\n",
148 | "$$\n",
149 | "\n",
150 | "**Information**\n",
151 | "\n",
152 | "$$\n",
153 | "z_{t+1} =\n",
154 | "\\left[ {\\begin{array}{cccccc}\n",
155 | " 1 & 0 & 0 & 0 & 0 & 0 \\\\ 0 & 0.9 & 0 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 0 & 0 & 0 \\\\ 0 & 0 & 1 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 0 & 1 & 0\n",
156 | " \\end{array} }\n",
157 | " \\right]\n",
158 | " z_t +\n",
159 | " \\left[ {\\begin{array}{cc}\n",
160 | " 0 & 0 \\\\ 1 & 0 \\\\ 0 & 4 \\\\ 0 & 0 \\\\ 0 & 0 \\\\ 0 & 0\n",
161 | " \\end{array} }\n",
162 | " \\right]\n",
163 | " w_{t+1}\n",
164 | "$$\n",
165 | "\n",
166 | "$$\n",
167 | "U_b =\n",
168 | " \\left[ {\\begin{array}{cccccc}\n",
169 | " 30 & 0 & 0 & 0 & 0 & 0\n",
170 | " \\end{array} }\n",
171 | " \\right]\n",
172 | "$$\n",
173 | "\n",
174 | "$$\n",
175 | "U_d =\n",
176 | " \\left[ {\\begin{array}{cccccc}\n",
177 | " 5 & 1 & 1 & 0.8 & 0.6 & 0.4 \\\\ 0 & 0 & 0 & 0 & 0 & 0\n",
178 | " \\end{array} }\n",
179 | " \\right]\n",
180 | "$$\n",
181 | "\n",
182 | "The preference shock is constant at 30, while the endowment process is\n",
183 | "the sum of a constant and two orthogonal processes.\n",
184 | "\n",
185 | "Specifically:\n",
186 | "\n",
187 | "$$\n",
188 | "d_t = 5 + d_{1t} + d_{2t}\n",
189 | "$$\n",
190 | "\n",
191 | "$$\n",
192 | "d_{1t} = 0.9d_{1t-1} + w_{1t}\n",
193 | "$$\n",
194 | "\n",
195 | "$$\n",
196 | "d_{2t} = 4w_{2t} + 0.8(4w_{2t-1})+ 0.6(4w_{2t-2})+ 0.4(4w_{2t-3})\n",
197 | "$$\n",
198 | "\n",
199 | "$ d_{1t} $ is a first-order AR process, while $ d_{2t} $ is a\n",
200 | "third-order pure moving average process."
201 | ]
202 | },
203 | {
204 | "cell_type": "code",
205 | "execution_count": null,
206 | "metadata": {
207 | "hide-output": false
208 | },
209 | "outputs": [],
210 | "source": [
211 | "γ_1 = 0.05\n",
212 | "γ = np.array([[γ_1], [0]])\n",
213 | "ϕ_c = np.array([[1], [0]])\n",
214 | "ϕ_g = np.array([[0], [1]])\n",
215 | "ϕ_1 = 0.00001\n",
216 | "ϕ_i = np.array([[1], [-ϕ_1]])\n",
217 | "δ_k = np.array([[1]])\n",
218 | "θ_k = np.array([[1]])\n",
219 | "β = np.array([[1 / 1.05]])\n",
220 | "l_λ = np.array([[0]])\n",
221 | "π_h = np.array([[1]])\n",
222 | "δ_h = np.array([[.9]])\n",
223 | "θ_h = np.array([[1]]) - δ_h\n",
224 | "ud = np.array([[5, 1, 1, 0.8, 0.6, 0.4],\n",
225 | " [0, 0, 0, 0, 0, 0]])\n",
226 | "a22 = np.zeros((6, 6))\n",
227 | "# Chase's great trick\n",
228 | "a22[[0, 1, 3, 4, 5], [0, 1, 2, 3, 4]] = np.array([1.0, 0.9, 1.0, 1.0, 1.0])\n",
229 | "c2 = np.zeros((6, 2))\n",
230 | "c2[[1, 2], [0, 1]] = np.array([1.0, 4.0])\n",
231 | "ub = np.array([[30, 0, 0, 0, 0, 0]])\n",
232 | "x0 = np.array([[5], [150], [1], [0], [0], [0], [0], [0]])\n",
233 | "\n",
234 | "info1 = (a22, c2, ub, ud)\n",
235 | "tech1 = (ϕ_c, ϕ_g, ϕ_i, γ, δ_k, θ_k)\n",
236 | "pref1 = (β, l_λ, π_h, δ_h, θ_h)\n",
237 | "\n",
238 | "econ1 = DLE(info1, tech1, pref1)"
239 | ]
240 | },
241 | {
242 | "cell_type": "markdown",
243 | "metadata": {},
244 | "source": [
245 | "We define the household’s net of interest deficit as $ c_t - d_t $.\n",
246 | "\n",
247 | "Hall’s model imposes “expected present-value budget balance” in the\n",
248 | "sense that\n",
249 | "\n",
250 | "$$\n",
251 | "\\mathbb{E}\\sum_{j=0}^\\infty \\beta^j (c_{t+j} - d_{t+j})|J_t = \\beta^{-1}k_{t-1} \\, \\forall t\n",
252 | "$$\n",
253 | "\n",
254 | "If we define the moving average representation of\n",
255 | "$ (c_t, c_t - d_t) $ in terms of the $ w_t $s to be:\n",
256 | "\n",
257 | "$$\n",
258 | "\\left[ {\\begin{array}{c}\n",
259 | " c_t \\\\ c_t - d_t\n",
260 | " \\end{array} }\n",
261 | " \\right] = \\left[ {\\begin{array}{c}\n",
262 | " \\sigma_1(L) \\\\ \\sigma_2(L)\n",
263 | " \\end{array} }\n",
264 | " \\right] w_t\n",
265 | "$$\n",
266 | "\n",
267 | "then Hall’s model imposes the restriction\n",
268 | "$ \\sigma_2(\\beta) = [0\\,\\,\\,0] $.\n",
269 | "\n",
270 | "The agent inside this model sees histories of both components of the\n",
271 | "endowment process $ d_{1t} $ and $ d_{2t} $.\n",
272 | "\n",
273 | "The econometrician has data on the history of the pair\n",
274 | "$ [c_t,d_t] $, but not directly on the history of $ w_t $.\n",
275 | "\n",
276 | "The econometrician obtains a Wold representation for the process\n",
277 | "$ [c_t,c_t-d_t] $:\n",
278 | "\n",
279 | "$$\n",
280 | "\\left[ {\\begin{array}{c}\n",
281 | " c_t \\\\ c_t - d_t\n",
282 | " \\end{array} }\n",
283 | " \\right] = \\left[ {\\begin{array}{c}\n",
284 | " \\sigma_1^*(L) \\\\ \\sigma_2^*(L)\n",
285 | " \\end{array} }\n",
286 | " \\right] u_t\n",
287 | "$$\n",
288 | "\n",
289 | "The Appendix of chapter 8 of [[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) explains why the impulse\n",
290 | "response functions in the Wold representation estimated by the\n",
291 | "econometrician do not resemble the impulse response functions that\n",
292 | "depict the response of consumption and the deficit to innovations to\n",
293 | "agents’ information.\n",
294 | "\n",
295 | "Technically, $ \\sigma_2(\\beta) = [0\\,\\,\\,0] $ implies that the\n",
296 | "history of $ u_t $s spans a *smaller* linear space than does the\n",
297 | "history of $ w_t $s.\n",
298 | "\n",
299 | "This means that $ u_t $ will typically be a distributed lag of\n",
300 | "$ w_t $ that is not concentrated at zero lag:\n",
301 | "\n",
302 | "$$\n",
303 | "u_t = \\sum_{j=0}^\\infty \\alpha_j w_{t-j}\n",
304 | "$$\n",
305 | "\n",
306 | "Thus, the econometrician’s news $ u_t $ potentially responds\n",
307 | "belatedly to agents’ news $ w_t $."
308 | ]
309 | },
310 | {
311 | "cell_type": "markdown",
312 | "metadata": {},
313 | "source": [
314 | "## Code\n",
315 | "\n",
316 | "We will construct Figures from Chapter 8 Appendix E of [[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) to\n",
317 | "illustrate these ideas:"
318 | ]
319 | },
320 | {
321 | "cell_type": "code",
322 | "execution_count": null,
323 | "metadata": {
324 | "hide-output": false
325 | },
326 | "outputs": [],
327 | "source": [
328 | "# This is Fig 8.E.1 from p.188 of HS2013\n",
329 | "\n",
330 | "econ1.irf(ts_length=40, shock=None)\n",
331 | "\n",
332 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
333 | "ax1.plot(econ1.c_irf, label='Consumption')\n",
334 | "ax1.plot(econ1.c_irf - econ1.d_irf[:,0].reshape(40,1), label='Deficit')\n",
335 | "ax1.legend()\n",
336 | "ax1.set_title('Response to $w_{1t}$')\n",
337 | "\n",
338 | "shock2 = np.array([[0], [1]])\n",
339 | "econ1.irf(ts_length=40, shock=shock2)\n",
340 | "\n",
341 | "ax2.plot(econ1.c_irf, label='Consumption')\n",
342 | "ax2.plot(econ1.c_irf - econ1.d_irf[:,0].reshape(40, 1), label='Deficit')\n",
343 | "ax2.legend()\n",
344 | "ax2.set_title('Response to $w_{2t}$')\n",
345 | "plt.show()"
346 | ]
347 | },
348 | {
349 | "cell_type": "markdown",
350 | "metadata": {},
351 | "source": [
352 | "The above figure displays the impulse response of consumption and the\n",
353 | "deficit to the endowment innovations.\n",
354 | "\n",
355 | "Consumption displays the characteristic “random walk” response with\n",
356 | "respect to each innovation.\n",
357 | "\n",
358 | "Each endowment innovation leads to a\n",
359 | "temporary surplus followed by a permanent net-of-interest deficit.\n",
360 | "\n",
361 | "The temporary surplus just offsets the permanent deficit in terms of\n",
362 | "expected present value."
363 | ]
364 | },
365 | {
366 | "cell_type": "code",
367 | "execution_count": null,
368 | "metadata": {
369 | "hide-output": false
370 | },
371 | "outputs": [],
372 | "source": [
373 | "G_HS = np.vstack([econ1.Sc, econ1.Sc-econ1.Sd[0, :].reshape(1, 8)])\n",
374 | "H_HS = 1e-8 * np.eye(2) # Set very small so there is no measurement error\n",
375 | "lss_hs = qe.LinearStateSpace(econ1.A0, econ1.C, G_HS, H_HS)\n",
376 | "\n",
377 | "hs_kal = qe.Kalman(lss_hs)\n",
378 | "w_lss = hs_kal.whitener_lss()\n",
379 | "ma_coefs = hs_kal.stationary_coefficients(50, 'ma')\n",
380 | "\n",
381 | "# This is Fig 8.E.2 from p.189 of HS2013\n",
382 | "\n",
383 | "ma_coefs = ma_coefs\n",
384 | "jj = 50\n",
385 | "y1_w1 = np.empty(jj)\n",
386 | "y2_w1 = np.empty(jj)\n",
387 | "y1_w2 = np.empty(jj)\n",
388 | "y2_w2 = np.empty(jj)\n",
389 | "\n",
390 | "for t in range(jj):\n",
391 | " y1_w1[t] = ma_coefs[t][0, 0]\n",
392 | " y1_w2[t] = ma_coefs[t][0, 1]\n",
393 | " y2_w1[t] = ma_coefs[t][1, 0]\n",
394 | " y2_w2[t] = ma_coefs[t][1, 1]\n",
395 | "\n",
396 | "# This scales the impulse responses to match those in the book\n",
397 | "y1_w1 = sqrt(hs_kal.stationary_innovation_covar()[0, 0]) * y1_w1\n",
398 | "y2_w1 = sqrt(hs_kal.stationary_innovation_covar()[0, 0]) * y2_w1\n",
399 | "y1_w2 = sqrt(hs_kal.stationary_innovation_covar()[1, 1]) * y1_w2\n",
400 | "y2_w2 = sqrt(hs_kal.stationary_innovation_covar()[1, 1]) * y2_w2\n",
401 | "\n",
402 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
403 | "ax1.plot(y1_w1, label='Consumption')\n",
404 | "ax1.plot(y2_w1, label='Deficit')\n",
405 | "ax1.legend()\n",
406 | "ax1.set_title('Response to $u_{1t}$')\n",
407 | "\n",
408 | "ax2.plot(y1_w2, label='Consumption')\n",
409 | "ax2.plot(y2_w2, label='Deficit')\n",
410 | "ax2.legend()\n",
411 | "ax2.set_title('Response to $u_{2t}$')\n",
412 | "plt.show()"
413 | ]
414 | },
415 | {
416 | "cell_type": "markdown",
417 | "metadata": {},
418 | "source": [
419 | "The above figure displays the impulse response of consumption and the\n",
420 | "deficit to the innovations in the econometrician’s Wold representation\n",
421 | "\n",
422 | "- this is the object that would be recovered from a high order vector\n",
423 | " autoregression on the econometrician’s observations. \n",
424 | "\n",
425 | "\n",
426 | "Consumption responds only to the first innovation\n",
427 | "\n",
428 | "- this is indicative of the Granger causality imposed on the\n",
429 | " $ [c_t, c_t - d_t] $ process by Hall’s model: consumption Granger\n",
430 | " causes $ c_t - d_t $, with no reverse causality. "
431 | ]
432 | },
433 | {
434 | "cell_type": "code",
435 | "execution_count": null,
436 | "metadata": {
437 | "hide-output": false
438 | },
439 | "outputs": [],
440 | "source": [
441 | "# This is Fig 8.E.3 from p.189 of HS2013\n",
442 | "\n",
443 | "jj = 20\n",
444 | "irf_wlss = w_lss.impulse_response(jj)\n",
445 | "ycoefs = irf_wlss[1]\n",
446 | "# Pull out the shocks\n",
447 | "a1_w1 = np.empty(jj)\n",
448 | "a1_w2 = np.empty(jj)\n",
449 | "a2_w1 = np.empty(jj)\n",
450 | "a2_w2 = np.empty(jj)\n",
451 | "\n",
452 | "for t in range(jj):\n",
453 | " a1_w1[t] = ycoefs[t][0, 0]\n",
454 | " a1_w2[t] = ycoefs[t][0, 1]\n",
455 | " a2_w1[t] = ycoefs[t][1, 0]\n",
456 | " a2_w2[t] = ycoefs[t][1, 1]\n",
457 | "\n",
458 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
459 | "ax1.plot(a1_w1, label='Consumption innov.')\n",
460 | "ax1.plot(a2_w1, label='Deficit innov.')\n",
461 | "ax1.set_title('Response to $w_{1t}$')\n",
462 | "ax1.legend()\n",
463 | "ax2.plot(a1_w2, label='Consumption innov.')\n",
464 | "ax2.plot(a2_w2, label='Deficit innov.')\n",
465 | "ax2.legend()\n",
466 | "ax2.set_title('Response to $w_{2t}$')\n",
467 | "plt.show()"
468 | ]
469 | },
470 | {
471 | "cell_type": "markdown",
472 | "metadata": {},
473 | "source": [
474 | "The above figure displays the impulse responses of $ u_t $ to\n",
475 | "$ w_t $, as depicted in:\n",
476 | "\n",
477 | "$$\n",
478 | "u_t = \\sum_{j=0}^\\infty \\alpha_j w_{t-j}\n",
479 | "$$\n",
480 | "\n",
481 | "While the responses of the innovations to consumption are concentrated\n",
482 | "at lag zero for both components of $ w_t $, the responses of the\n",
483 | "innovations to $ (c_t - d_t) $ are spread over time (especially in\n",
484 | "response to $ w_{1t} $).\n",
485 | "\n",
486 | "Thus, the innovations to $ (c_t - d_t) $ as revealed by the vector\n",
487 | "autoregression depend on what the economic agent views as “old news”."
488 | ]
489 | }
490 | ],
491 | "metadata": {
492 | "date": 1584334739.209215,
493 | "filename": "hs_invertibility_example.rst",
494 | "kernelspec": {
495 | "display_name": "Python",
496 | "language": "python3",
497 | "name": "python3"
498 | },
499 | "title": "Shock Non Invertibility"
500 | },
501 | "nbformat": 4,
502 | "nbformat_minor": 2
503 | }
--------------------------------------------------------------------------------
/irfs_in_hall_model.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# IRFs in Hall Models"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [IRFs in Hall Models](#IRFs-in-Hall-Models) \n",
33 | " - [Example 1: Hall (1978)](#Example-1:-Hall-%281978%29) \n",
34 | " - [Example 2: Higher Adjustment Costs](#Example-2:-Higher-Adjustment-Costs) \n",
35 | " - [Example 3: Durable Consumption Goods](#Example-3:-Durable-Consumption-Goods) "
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "This is another member of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
43 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
44 | "\n",
45 | "In addition to what’s in Anaconda, this lecture uses the quantecon library."
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {
52 | "hide-output": true
53 | },
54 | "outputs": [],
55 | "source": [
56 | "!pip install --upgrade quantecon"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "We’ll make these imports:"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {
70 | "hide-output": false
71 | },
72 | "outputs": [],
73 | "source": [
74 | "import numpy as np\n",
75 | "import matplotlib.pyplot as plt\n",
76 | "%matplotlib inline\n",
77 | "from quantecon import LQ\n",
78 | "from quantecon import DLE"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "This lecture shows how the DLE class can be used to create impulse\n",
86 | "response functions for three related economies, starting from\n",
87 | "Hall (1978) [[Hal78]](https://python.quantecon.org/zreferences.html#hall1978).\n",
88 | "\n",
89 | "Knowledge of the basic economic environment is assumed.\n",
90 | "\n",
91 | "See the lecture “Growth in Dynamic Linear Economies” for more details."
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "## Example 1: Hall (1978)\n",
99 | "\n",
100 | "First, we set parameters to make consumption (almost) follow a random\n",
101 | "walk.\n",
102 | "\n",
103 | "We set\n",
104 | "\n",
105 | "$$\n",
106 | "\\lambda = 0, \\pi = 1, \\gamma_1 = 0.1, \\phi_1 = 0.00001, \\delta_k = 0.95, \\beta = \\frac{1}{1.05}\n",
107 | "$$\n",
108 | "\n",
109 | "(In this example $ \\delta_h $ and $ \\theta_h $ are arbitrary as\n",
110 | "household capital does not enter the equation for consumption services.\n",
111 | "\n",
112 | "We set them to values that will become useful in Example 3)\n",
113 | "\n",
114 | "It is worth noting that this choice of parameter values ensures that\n",
115 | "$ \\beta(\\gamma_1 + \\delta_k) = 1 $.\n",
116 | "\n",
117 | "For simulations of this economy, we choose an initial condition of:\n",
118 | "\n",
119 | "$$\n",
120 | "x_0 =\n",
121 | " \\left[ {\\begin{array}{ccccc}\n",
122 | " 5 & 150 & 1 & 0 & 0\n",
123 | " \\end{array} }\n",
124 | " \\right]'\n",
125 | "$$"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": null,
131 | "metadata": {
132 | "hide-output": false
133 | },
134 | "outputs": [],
135 | "source": [
136 | "γ_1 = 0.1\n",
137 | "γ = np.array([[γ_1], [0]])\n",
138 | "ϕ_c = np.array([[1], [0]])\n",
139 | "ϕ_g = np.array([[0], [1]])\n",
140 | "ϕ_1 = 1e-5\n",
141 | "ϕ_i = np.array([[1], [-ϕ_1]])\n",
142 | "δ_k = np.array([[.95]])\n",
143 | "θ_k = np.array([[1]])\n",
144 | "β = np.array([[1 / 1.05]])\n",
145 | "l_λ = np.array([[0]])\n",
146 | "π_h = np.array([[1]])\n",
147 | "δ_h = np.array([[.9]])\n",
148 | "θ_h = np.array([[1]])\n",
149 | "a22 = np.array([[1, 0, 0],\n",
150 | " [0, 0.8, 0],\n",
151 | " [0, 0, 0.5]])\n",
152 | "c2 = np.array([[0, 0],\n",
153 | " [1, 0],\n",
154 | " [0, 1]])\n",
155 | "ud = np.array([[5, 1, 0],\n",
156 | " [0, 0, 0]])\n",
157 | "ub = np.array([[30, 0, 0]])\n",
158 | "x0 = np.array([[5], [150], [1], [0], [0]])\n",
159 | "\n",
160 | "info1 = (a22, c2, ub, ud)\n",
161 | "tech1 = (ϕ_c, ϕ_g, ϕ_i, γ, δ_k, θ_k)\n",
162 | "pref1 = (β, l_λ, π_h, δ_h, θ_h)"
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "These parameter values are used to define an economy of the DLE class.\n",
170 | "\n",
171 | "We can then simulate the economy for a chosen length of time, from our\n",
172 | "initial state vector $ x_0 $.\n",
173 | "\n",
174 | "The economy stores the simulated values for each variable. Below we plot\n",
175 | "consumption and investment:"
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {
182 | "hide-output": false
183 | },
184 | "outputs": [],
185 | "source": [
186 | "econ1 = DLE(info1, tech1, pref1)\n",
187 | "econ1.compute_sequence(x0, ts_length=300)\n",
188 | "\n",
189 | "# This is the right panel of Fig 5.7.1 from p.105 of HS2013\n",
190 | "plt.plot(econ1.c[0], label='Cons.')\n",
191 | "plt.plot(econ1.i[0], label='Inv.')\n",
192 | "plt.legend()\n",
193 | "plt.show()"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "The DLE class can be used to create impulse response functions for each\n",
201 | "of the endogenous variables: $ \\{c_t,s_t,h_t,i_t,k_t,g_t\\} $.\n",
202 | "\n",
203 | "If no selector vector for the shock is specified, the default choice is\n",
204 | "to give IRFs to the first shock in $ w_{t+1} $.\n",
205 | "\n",
206 | "Below we plot the impulse response functions of investment and\n",
207 | "consumption to an endowment innovation (the first shock) in the Hall\n",
208 | "model:"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": null,
214 | "metadata": {
215 | "hide-output": false
216 | },
217 | "outputs": [],
218 | "source": [
219 | "econ1.irf(ts_length=40, shock=None)\n",
220 | "# This is the left panel of Fig 5.7.1 from p.105 of HS2013\n",
221 | "plt.plot(econ1.c_irf, label='Cons.')\n",
222 | "plt.plot(econ1.i_irf, label='Inv.')\n",
223 | "plt.legend()\n",
224 | "plt.show()"
225 | ]
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "It can be seen that the endowment shock has permanent effects on the\n",
232 | "level of both consumption and investment, consistent with the endogenous\n",
233 | "unit eigenvalue in this economy.\n",
234 | "\n",
235 | "Investment is much more responsive to the endowment shock at shorter time\n",
236 | "horizons."
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {},
242 | "source": [
243 | "## Example 2: Higher Adjustment Costs\n",
244 | "\n",
245 | "We generate our next economy by making only one change to the parameters\n",
246 | "of Example 1: we raise the parameter associated with the cost of\n",
247 | "adjusting capital,$ \\phi_1 $, from 0.00001 to 0.2.\n",
248 | "\n",
249 | "This will lower the endogenous eigenvalue that is unity in Example 1 to\n",
250 | "a value slightly below 1."
251 | ]
252 | },
253 | {
254 | "cell_type": "code",
255 | "execution_count": null,
256 | "metadata": {
257 | "hide-output": false
258 | },
259 | "outputs": [],
260 | "source": [
261 | "ϕ_12 = 0.2\n",
262 | "ϕ_i2 = np.array([[1], [-ϕ_12]])\n",
263 | "tech2 = (ϕ_c, ϕ_g, ϕ_i2, γ, δ_k, θ_k)\n",
264 | "\n",
265 | "econ2 = DLE(info1, tech2, pref1)\n",
266 | "econ2.compute_sequence(x0, ts_length = 300)\n",
267 | "\n",
268 | "# This is the right panel of Fig 5.8.1 from p.106 of HS2013\n",
269 | "plt.plot(econ2.c[0], label='Cons.')\n",
270 | "plt.plot(econ2.i[0], label='Inv.')\n",
271 | "plt.legend()\n",
272 | "plt.show()"
273 | ]
274 | },
275 | {
276 | "cell_type": "code",
277 | "execution_count": null,
278 | "metadata": {
279 | "hide-output": false
280 | },
281 | "outputs": [],
282 | "source": [
283 | "econ2.irf(ts_length=40,shock=None)\n",
284 | "# This is the left panel of Fig 5.8.1 from p.106 of HS2013\n",
285 | "plt.plot(econ2.c_irf,label='Cons.')\n",
286 | "plt.plot(econ2.i_irf,label='Inv.')\n",
287 | "plt.legend()\n",
288 | "plt.show()"
289 | ]
290 | },
291 | {
292 | "cell_type": "code",
293 | "execution_count": null,
294 | "metadata": {
295 | "hide-output": false
296 | },
297 | "outputs": [],
298 | "source": [
299 | "econ2.endo"
300 | ]
301 | },
302 | {
303 | "cell_type": "code",
304 | "execution_count": null,
305 | "metadata": {
306 | "hide-output": false
307 | },
308 | "outputs": [],
309 | "source": [
310 | "econ2.compute_steadystate()\n",
311 | "print(econ2.css, econ2.iss, econ2.kss)"
312 | ]
313 | },
314 | {
315 | "cell_type": "markdown",
316 | "metadata": {},
317 | "source": [
318 | "The first graph shows that there seems to be a downward trend in both\n",
319 | "consumption and investment.\n",
320 | "\n",
321 | "his is a consequence of the decrease in the largest endogenous\n",
322 | "eigenvalue from unity in the earlier economy, caused by the higher\n",
323 | "adjustment cost.\n",
324 | "\n",
325 | "The present economy has a nonstochastic steady state value of 5 for\n",
326 | "consumption and 0 for both capital and investment.\n",
327 | "\n",
328 | "Because the largest endogenous eigenvalue is still close to 1, the\n",
329 | "economy heads only slowly towards these mean values.\n",
330 | "\n",
331 | "The impulse response functions now show that an endowment shock does not\n",
332 | "have a permanent effect on the levels of either consumption or\n",
333 | "investment."
334 | ]
335 | },
336 | {
337 | "cell_type": "markdown",
338 | "metadata": {},
339 | "source": [
340 | "## Example 3: Durable Consumption Goods\n",
341 | "\n",
342 | "We generate our third economy by raising $ \\phi_1 $ further, to 1.0.\n",
343 | "We also raise the production function parameter from 0.1 to 0.15 (which\n",
344 | "raises the non-stochastic steady state value of capital above zero).\n",
345 | "\n",
346 | "We also change the specification of preferences to make the consumption\n",
347 | "good *durable*.\n",
348 | "\n",
349 | "Specifically, we allow for a single durable household good obeying:\n",
350 | "\n",
351 | "$$\n",
352 | "h_t = \\delta_h h_{t-1} + c_t \\, , 0<\\delta_h<1\n",
353 | "$$\n",
354 | "\n",
355 | "Services are related to the stock of durables at the beginning of the\n",
356 | "period:\n",
357 | "\n",
358 | "$$\n",
359 | "s_t = \\lambda h_{t-1} \\, , \\lambda > 0\n",
360 | "$$\n",
361 | "\n",
362 | "And preferences are ordered by:\n",
363 | "\n",
364 | "$$\n",
365 | "- \\frac{1}{2} \\mathbb{E} \\sum_{t=0}^\\infty \\beta^t [(\\lambda h_{t-1} - b_t)^2 + l_t^2]|J_0\n",
366 | "$$\n",
367 | "\n",
368 | "To implement this, we set $ \\lambda=0.1 $ and $ \\pi = 0 $ (we\n",
369 | "have already set $ \\theta_h = 1 $ and $ \\delta_h = 0.9 $).\n",
370 | "\n",
371 | "We start from an initial condition that makes consumption begin near\n",
372 | "around its non-stochastic steady state."
373 | ]
374 | },
375 | {
376 | "cell_type": "code",
377 | "execution_count": null,
378 | "metadata": {
379 | "hide-output": false
380 | },
381 | "outputs": [],
382 | "source": [
383 | "ϕ_13 = 1\n",
384 | "ϕ_i3 = np.array([[1], [-ϕ_13]])\n",
385 | "\n",
386 | "γ_12 = 0.15\n",
387 | "γ_2 = np.array([[γ_12], [0]])\n",
388 | "\n",
389 | "l_λ2 = np.array([[0.1]])\n",
390 | "π_h2 = np.array([[0]])\n",
391 | "\n",
392 | "x01 = np.array([[150], [100], [1], [0], [0]])\n",
393 | "\n",
394 | "tech3 = (ϕ_c, ϕ_g, ϕ_i3, γ_2, δ_k, θ_k)\n",
395 | "pref2 = (β, l_λ2, π_h2, δ_h, θ_h)\n",
396 | "\n",
397 | "econ3 = DLE(info1, tech3, pref2)\n",
398 | "econ3.compute_sequence(x01, ts_length=300)\n",
399 | "\n",
400 | "# This is the right panel of Fig 5.11.1 from p.111 of HS2013\n",
401 | "plt.plot(econ3.c[0], label='Cons.')\n",
402 | "plt.plot(econ3.i[0], label='Inv.')\n",
403 | "plt.legend()\n",
404 | "plt.show()"
405 | ]
406 | },
407 | {
408 | "cell_type": "markdown",
409 | "metadata": {},
410 | "source": [
411 | "In contrast to Hall’s original model of Example 1, it is now investment\n",
412 | "that is much smoother than consumption.\n",
413 | "\n",
414 | "This illustrates how making consumption goods durable tends to undo the\n",
415 | "strong consumption smoothing result that Hall obtained."
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": null,
421 | "metadata": {
422 | "hide-output": false
423 | },
424 | "outputs": [],
425 | "source": [
426 | "econ3.irf(ts_length=40, shock=None)\n",
427 | "# This is the left panel of Fig 5.11.1 from p.111 of HS2013\n",
428 | "plt.plot(econ3.c_irf, label='Cons.')\n",
429 | "plt.plot(econ3.i_irf, label='Inv.')\n",
430 | "plt.legend()\n",
431 | "plt.show()"
432 | ]
433 | },
434 | {
435 | "cell_type": "markdown",
436 | "metadata": {},
437 | "source": [
438 | "The impulse response functions confirm that consumption is now much more\n",
439 | "responsive to an endowment shock (and investment less so) than in\n",
440 | "Example 1.\n",
441 | "\n",
442 | "As in Example 2, the endowment shock has permanent effects on\n",
443 | "neither variable."
444 | ]
445 | }
446 | ],
447 | "metadata": {
448 | "date": 1584334741.572115,
449 | "filename": "irfs_in_hall_model.rst",
450 | "kernelspec": {
451 | "display_name": "Python",
452 | "language": "python3",
453 | "name": "python3"
454 | },
455 | "title": "IRFs in Hall Models"
456 | },
457 | "nbformat": 4,
458 | "nbformat_minor": 2
459 | }
--------------------------------------------------------------------------------
/lucas_asset_pricing_dles.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Lucas Asset Pricing Using DLE"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Lucas Asset Pricing Using DLE](#Lucas-Asset-Pricing-Using-DLE) \n",
33 | " - [Asset Pricing Equations](#Asset-Pricing-Equations) \n",
34 | " - [Asset Pricing Simulations](#Asset-Pricing-Simulations) "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "This is one of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
42 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
43 | "\n",
44 | "In addition to what’s in Anaconda, this lecture uses the quantecon library"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "hide-output": true
52 | },
53 | "outputs": [],
54 | "source": [
55 | "!pip install --upgrade quantecon"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "This lecture uses the DLE class to price payout\n",
63 | "streams that are linear functions of the economy’s state vector, as well\n",
64 | "as risk-free assets that pay out one unit of the first consumption good\n",
65 | "with certainty.\n",
66 | "\n",
67 | "We assume basic knowledge of the class of economic environments that fall within the domain of the\n",
68 | "DLE class.\n",
69 | "\n",
70 | "Many details about the basic environment are contained in the lecture\n",
71 | "[Growth in Dynamic Linear Economies](https://python.quantecon.org/growth_in_dles.html).\n",
72 | "\n",
73 | "We’ll also need the following imports"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {
80 | "hide-output": false
81 | },
82 | "outputs": [],
83 | "source": [
84 | "import numpy as np\n",
85 | "import matplotlib.pyplot as plt\n",
86 | "from quantecon import LQ\n",
87 | "from quantecon import DLE\n",
88 | "%matplotlib inline"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "We use a linear-quadratic version of an economy that Lucas (1978) [[Luc78]](https://python.quantecon.org/zreferences.html#lucas1978) used\n",
96 | "to develop an equilibrium theory of asset prices:\n",
97 | "\n",
98 | "**Preferences**\n",
99 | "\n",
100 | "$$\n",
101 | "-\\frac{1}{2}\\mathbb{E}\\sum_{t=0}^\\infty \\beta^t[(c_t - b_t)^2 + l_t^2]|J_0\n",
102 | "$$\n",
103 | "\n",
104 | "$$\n",
105 | "s_t = c_t\n",
106 | "$$\n",
107 | "\n",
108 | "$$\n",
109 | "b_t = U_bz_t\n",
110 | "$$\n",
111 | "\n",
112 | "**Technology**\n",
113 | "\n",
114 | "$$\n",
115 | "c_t = d_{1t}\n",
116 | "$$\n",
117 | "\n",
118 | "$$\n",
119 | "k_t = \\delta_k k_{t-1} + i_t\n",
120 | "$$\n",
121 | "\n",
122 | "$$\n",
123 | "g_t = \\phi_1 i_t \\, , \\phi_1 > 0\n",
124 | "$$\n",
125 | "\n",
126 | "$$\n",
127 | "\\left[ {\\begin{array}{c}\n",
128 | " d_{1t} \\\\ 0\n",
129 | " \\end{array} }\n",
130 | " \\right] = U_dz_t\n",
131 | "$$\n",
132 | "\n",
133 | "**Information**\n",
134 | "\n",
135 | "$$\n",
136 | "z_{t+1} =\n",
137 | "\\left[ {\\begin{array}{ccc}\n",
138 | " 1 & 0 & 0 \\\\ 0 & 0.8 & 0 \\\\ 0 & 0 & 0.5\n",
139 | " \\end{array} }\n",
140 | " \\right]\n",
141 | " z_t +\n",
142 | " \\left[ {\\begin{array}{cc}\n",
143 | " 0 & 0 \\\\ 1 & 0 \\\\ 0 & 1\n",
144 | " \\end{array} }\n",
145 | " \\right]\n",
146 | " w_{t+1}\n",
147 | "$$\n",
148 | "\n",
149 | "$$\n",
150 | "U_b =\n",
151 | " \\left[ {\\begin{array}{ccc}\n",
152 | " 30 & 0 & 0\n",
153 | " \\end{array} }\n",
154 | " \\right]\n",
155 | "$$\n",
156 | "\n",
157 | "$$\n",
158 | "U_d =\n",
159 | " \\left[ {\\begin{array}{ccc}\n",
160 | " 5 & 1 & 0 \\\\ 0 & 0 & 0\n",
161 | " \\end{array} }\n",
162 | " \\right]\n",
163 | "$$\n",
164 | "\n",
165 | "$$\n",
166 | "x_0 =\n",
167 | " \\left[ {\\begin{array}{ccccc}\n",
168 | " 5 & 150 & 1 & 0 & 0\n",
169 | " \\end{array} }\n",
170 | " \\right]'\n",
171 | "$$"
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "metadata": {},
177 | "source": [
178 | "## Asset Pricing Equations\n",
179 | "\n",
180 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) show that the time t value of a permanent claim to a stream\n",
181 | "$ y_s = U_ax_s \\, , s \\geq t $ is:\n",
182 | "\n",
183 | "$$\n",
184 | "a_t = (x_t'\\mu_ax_t + \\sigma_a)/(\\bar e _1M_cx_t)\n",
185 | "$$\n",
186 | "\n",
187 | "with\n",
188 | "\n",
189 | "$$\n",
190 | "\\mu_a = \\sum_{\\tau = 0}^\\infty \\beta^\\tau(A^{o'})^\\tau Z_a A^{o\\tau}\n",
191 | "$$\n",
192 | "\n",
193 | "$$\n",
194 | "\\sigma_a = \\frac{\\beta}{1-\\beta} \\text{trace} (Z_a \\sum_{\\tau = 0}^\\infty \\beta^\\tau (A^{o})^\\tau C C^{'} (A^{o'})^\\tau)\n",
195 | "$$\n",
196 | "\n",
197 | "where\n",
198 | "\n",
199 | "$$\n",
200 | "Z_a = U_a^{'}M_c\n",
201 | "$$\n",
202 | "\n",
203 | "The use of $ \\bar e _1 $ indicates that the first consumption good\n",
204 | "is the numeraire."
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "## Asset Pricing Simulations"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {
218 | "hide-output": false
219 | },
220 | "outputs": [],
221 | "source": [
222 | "gam = 0\n",
223 | "γ = np.array([[gam], [0]])\n",
224 | "ϕ_c = np.array([[1], [0]])\n",
225 | "ϕ_g = np.array([[0], [1]])\n",
226 | "ϕ_1 = 1e-4\n",
227 | "ϕ_i = np.array([[0], [-ϕ_1]])\n",
228 | "δ_k = np.array([[.95]])\n",
229 | "θ_k = np.array([[1]])\n",
230 | "β = np.array([[1 / 1.05]])\n",
231 | "ud = np.array([[5, 1, 0],\n",
232 | " [0, 0, 0]])\n",
233 | "a22 = np.array([[1, 0, 0],\n",
234 | " [0, 0.8, 0],\n",
235 | " [0, 0, 0.5]])\n",
236 | "c2 = np.array([[0, 1, 0],\n",
237 | " [0, 0, 1]]).T\n",
238 | "l_λ = np.array([[0]])\n",
239 | "π_h = np.array([[1]])\n",
240 | "δ_h = np.array([[.9]])\n",
241 | "θ_h = np.array([[1]]) - δ_h\n",
242 | "ub = np.array([[30, 0, 0]])\n",
243 | "x0 = np.array([[5, 150, 1, 0, 0]]).T\n",
244 | "\n",
245 | "info1 = (a22, c2, ub, ud)\n",
246 | "tech1 = (ϕ_c, ϕ_g, ϕ_i, γ, δ_k, θ_k)\n",
247 | "pref1 = (β, l_λ, π_h, δ_h, θ_h)"
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": null,
253 | "metadata": {
254 | "hide-output": false
255 | },
256 | "outputs": [],
257 | "source": [
258 | "econ1 = DLE(info1, tech1, pref1)"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {},
264 | "source": [
265 | "After specifying a “Pay” matrix, we simulate the economy.\n",
266 | "\n",
267 | "The particular choice of “Pay” used below means that we are pricing a\n",
268 | "perpetual claim on the endowment process $ d_{1t} $"
269 | ]
270 | },
271 | {
272 | "cell_type": "code",
273 | "execution_count": null,
274 | "metadata": {
275 | "hide-output": false
276 | },
277 | "outputs": [],
278 | "source": [
279 | "econ1.compute_sequence(x0, ts_length=100, Pay=np.array([econ1.Sd[0, :]]))"
280 | ]
281 | },
282 | {
283 | "cell_type": "markdown",
284 | "metadata": {},
285 | "source": [
286 | "The graph below plots the price of this claim over time:"
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "hide-output": false
294 | },
295 | "outputs": [],
296 | "source": [
297 | "### Fig 7.12.1 from p.147 of HS2013\n",
298 | "plt.plot(econ1.Pay_Price, label='Price of Tree')\n",
299 | "plt.legend()\n",
300 | "plt.show()"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "The next plot displays the realized gross rate of return on this “Lucas\n",
308 | "tree” as well as on a risk-free one-period bond:"
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": null,
314 | "metadata": {
315 | "hide-output": false
316 | },
317 | "outputs": [],
318 | "source": [
319 | "### Left panel of Fig 7.12.2 from p.148 of HS2013\n",
320 | "plt.plot(econ1.Pay_Gross, label='Tree')\n",
321 | "plt.plot(econ1.R1_Gross, label='Risk-Free')\n",
322 | "plt.legend()\n",
323 | "plt.show()"
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": null,
329 | "metadata": {
330 | "hide-output": false
331 | },
332 | "outputs": [],
333 | "source": [
334 | "np.corrcoef(econ1.Pay_Gross[1:, 0], econ1.R1_Gross[1:, 0])"
335 | ]
336 | },
337 | {
338 | "cell_type": "markdown",
339 | "metadata": {},
340 | "source": [
341 | "Above we have also calculated the correlation coefficient between these\n",
342 | "two returns.\n",
343 | "\n",
344 | "To give an idea of how the term structure of interest rates moves in\n",
345 | "this economy, the next plot displays the *net* rates of return on\n",
346 | "one-period and five-period risk-free bonds:"
347 | ]
348 | },
349 | {
350 | "cell_type": "code",
351 | "execution_count": null,
352 | "metadata": {
353 | "hide-output": false
354 | },
355 | "outputs": [],
356 | "source": [
357 | "### Right panel of Fig 7.12.2 from p.148 of HS2013\n",
358 | "plt.plot(econ1.R1_Net, label='One-Period')\n",
359 | "plt.plot(econ1.R5_Net, label='Five-Period')\n",
360 | "plt.legend()\n",
361 | "plt.show()"
362 | ]
363 | },
364 | {
365 | "cell_type": "markdown",
366 | "metadata": {},
367 | "source": [
368 | "From the above plot, we can see the tendency of the term structure to\n",
369 | "slope up when rates are low and to slope down when rates are high.\n",
370 | "\n",
371 | "Comparing it to the previous plot of the price of the “Lucas tree”, we\n",
372 | "can also see that net rates of return are low when the price of the tree\n",
373 | "is high, and vice versa.\n",
374 | "\n",
375 | "We now plot the realized gross rate of return on a “Lucas tree” as well\n",
376 | "as on a risk-free one-period bond when the autoregressive parameter for\n",
377 | "the endowment process is reduced to 0.4:"
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": null,
383 | "metadata": {
384 | "hide-output": false
385 | },
386 | "outputs": [],
387 | "source": [
388 | "a22_2 = np.array([[1, 0, 0],\n",
389 | " [0, 0.4, 0],\n",
390 | " [0, 0, 0.5]])\n",
391 | "info2 = (a22_2, c2, ub, ud)\n",
392 | "\n",
393 | "econ2 = DLE(info2, tech1, pref1)\n",
394 | "econ2.compute_sequence(x0, ts_length=100, Pay=np.array([econ2.Sd[0, :]]))"
395 | ]
396 | },
397 | {
398 | "cell_type": "code",
399 | "execution_count": null,
400 | "metadata": {
401 | "hide-output": false
402 | },
403 | "outputs": [],
404 | "source": [
405 | "### Left panel of Fig 7.12.3 from p.148 of HS2013\n",
406 | "plt.plot(econ2.Pay_Gross, label='Tree')\n",
407 | "plt.plot(econ2.R1_Gross, label='Risk-Free')\n",
408 | "plt.legend()\n",
409 | "plt.show()"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": null,
415 | "metadata": {
416 | "hide-output": false
417 | },
418 | "outputs": [],
419 | "source": [
420 | "np.corrcoef(econ2.Pay_Gross[1:, 0], econ2.R1_Gross[1:, 0])"
421 | ]
422 | },
423 | {
424 | "cell_type": "markdown",
425 | "metadata": {},
426 | "source": [
427 | "The correlation between these two gross rates is now more negative.\n",
428 | "\n",
429 | "Next, we again plot the *net* rates of return on one-period and\n",
430 | "five-period risk-free bonds:"
431 | ]
432 | },
433 | {
434 | "cell_type": "code",
435 | "execution_count": null,
436 | "metadata": {
437 | "hide-output": false
438 | },
439 | "outputs": [],
440 | "source": [
441 | "### Right panel of Fig 7.12.3 from p.148 of HS2013\n",
442 | "plt.plot(econ2.R1_Net, label='One-Period')\n",
443 | "plt.plot(econ2.R5_Net, label='Five-Period')\n",
444 | "plt.legend()\n",
445 | "plt.show()"
446 | ]
447 | },
448 | {
449 | "cell_type": "markdown",
450 | "metadata": {},
451 | "source": [
452 | "We can see the tendency of the term structure to slope up when rates are\n",
453 | "low (and down when rates are high) has been accentuated relative to the\n",
454 | "first instance of our economy."
455 | ]
456 | }
457 | ],
458 | "metadata": {
459 | "date": 1584334744.7887528,
460 | "filename": "lucas_asset_pricing_dles.rst",
461 | "kernelspec": {
462 | "display_name": "Python",
463 | "language": "python3",
464 | "name": "python3"
465 | },
466 | "title": "Lucas Asset Pricing Using DLE"
467 | },
468 | "nbformat": 4,
469 | "nbformat_minor": 2
470 | }
--------------------------------------------------------------------------------
/matplotlib.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# Matplotlib\n",
21 | "\n",
22 | "\n",
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Matplotlib](#Matplotlib) \n",
33 | " - [Overview](#Overview) \n",
34 | " - [The APIs](#The-APIs) \n",
35 | " - [More Features](#More-Features) \n",
36 | " - [Further Reading](#Further-Reading) \n",
37 | " - [Exercises](#Exercises) \n",
38 | " - [Solutions](#Solutions) "
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Overview\n",
46 | "\n",
47 | "We’ve already generated quite a few figures in these lectures using [Matplotlib](http://matplotlib.org/).\n",
48 | "\n",
49 | "Matplotlib is an outstanding graphics library, designed for scientific computing, with\n",
50 | "\n",
51 | "- high-quality 2D and 3D plots \n",
52 | "- output in all the usual formats (PDF, PNG, etc.) \n",
53 | "- LaTeX integration \n",
54 | "- fine-grained control over all aspects of presentation \n",
55 | "- animation, etc. "
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "### Matplotlib’s Split Personality\n",
63 | "\n",
64 | "Matplotlib is unusual in that it offers two different interfaces to plotting.\n",
65 | "\n",
66 | "One is a simple MATLAB-style API (Application Programming Interface) that was written to help MATLAB refugees find a ready home.\n",
67 | "\n",
68 | "The other is a more “Pythonic” object-oriented API.\n",
69 | "\n",
70 | "For reasons described below, we recommend that you use the second API.\n",
71 | "\n",
72 | "But first, let’s discuss the difference."
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## The APIs\n",
80 | "\n",
81 | "\n",
82 | ""
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "### The MATLAB-style API\n",
90 | "\n",
91 | "Here’s the kind of easy example you might find in introductory treatments"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {
98 | "hide-output": false
99 | },
100 | "outputs": [],
101 | "source": [
102 | "import matplotlib.pyplot as plt\n",
103 | "%matplotlib inline\n",
104 | "import numpy as np\n",
105 | "\n",
106 | "x = np.linspace(0, 10, 200)\n",
107 | "y = np.sin(x)\n",
108 | "\n",
109 | "plt.plot(x, y, 'b-', linewidth=2)\n",
110 | "plt.show()"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "This is simple and convenient, but also somewhat limited and un-Pythonic.\n",
118 | "\n",
119 | "For example, in the function calls, a lot of objects get created and passed around without making themselves known to the programmer.\n",
120 | "\n",
121 | "Python programmers tend to prefer a more explicit style of programming (run `import this` in a code block and look at the second line).\n",
122 | "\n",
123 | "This leads us to the alternative, object-oriented Matplotlib API."
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "### The Object-Oriented API\n",
131 | "\n",
132 | "Here’s the code corresponding to the preceding figure using the object-oriented API"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {
139 | "hide-output": false
140 | },
141 | "outputs": [],
142 | "source": [
143 | "fig, ax = plt.subplots()\n",
144 | "ax.plot(x, y, 'b-', linewidth=2)\n",
145 | "plt.show()"
146 | ]
147 | },
148 | {
149 | "cell_type": "markdown",
150 | "metadata": {},
151 | "source": [
152 | "Here the call `fig, ax = plt.subplots()` returns a pair, where\n",
153 | "\n",
154 | "- `fig` is a `Figure` instance—like a blank canvas. \n",
155 | "- `ax` is an `AxesSubplot` instance—think of a frame for plotting in. \n",
156 | "\n",
157 | "\n",
158 | "The `plot()` function is actually a method of `ax`.\n",
159 | "\n",
160 | "While there’s a bit more typing, the more explicit use of objects gives us better control.\n",
161 | "\n",
162 | "This will become more clear as we go along."
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "### Tweaks\n",
170 | "\n",
171 | "Here we’ve changed the line to red and added a legend"
172 | ]
173 | },
174 | {
175 | "cell_type": "code",
176 | "execution_count": null,
177 | "metadata": {
178 | "hide-output": false
179 | },
180 | "outputs": [],
181 | "source": [
182 | "fig, ax = plt.subplots()\n",
183 | "ax.plot(x, y, 'r-', linewidth=2, label='sine function', alpha=0.6)\n",
184 | "ax.legend()\n",
185 | "plt.show()"
186 | ]
187 | },
188 | {
189 | "cell_type": "markdown",
190 | "metadata": {},
191 | "source": [
192 | "We’ve also used `alpha` to make the line slightly transparent—which makes it look smoother.\n",
193 | "\n",
194 | "The location of the legend can be changed by replacing `ax.legend()` with `ax.legend(loc='upper center')`."
195 | ]
196 | },
197 | {
198 | "cell_type": "code",
199 | "execution_count": null,
200 | "metadata": {
201 | "hide-output": false
202 | },
203 | "outputs": [],
204 | "source": [
205 | "fig, ax = plt.subplots()\n",
206 | "ax.plot(x, y, 'r-', linewidth=2, label='sine function', alpha=0.6)\n",
207 | "ax.legend(loc='upper center')\n",
208 | "plt.show()"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "If everything is properly configured, then adding LaTeX is trivial"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "metadata": {
222 | "hide-output": false
223 | },
224 | "outputs": [],
225 | "source": [
226 | "fig, ax = plt.subplots()\n",
227 | "ax.plot(x, y, 'r-', linewidth=2, label='$y=\\sin(x)$', alpha=0.6)\n",
228 | "ax.legend(loc='upper center')\n",
229 | "plt.show()"
230 | ]
231 | },
232 | {
233 | "cell_type": "markdown",
234 | "metadata": {},
235 | "source": [
236 | "Controlling the ticks, adding titles and so on is also straightforward"
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": null,
242 | "metadata": {
243 | "hide-output": false
244 | },
245 | "outputs": [],
246 | "source": [
247 | "fig, ax = plt.subplots()\n",
248 | "ax.plot(x, y, 'r-', linewidth=2, label='$y=\\sin(x)$', alpha=0.6)\n",
249 | "ax.legend(loc='upper center')\n",
250 | "ax.set_yticks([-1, 0, 1])\n",
251 | "ax.set_title('Test plot')\n",
252 | "plt.show()"
253 | ]
254 | },
255 | {
256 | "cell_type": "markdown",
257 | "metadata": {},
258 | "source": [
259 | "## More Features\n",
260 | "\n",
261 | "Matplotlib has a huge array of functions and features, which you can discover\n",
262 | "over time as you have need for them.\n",
263 | "\n",
264 | "We mention just a few."
265 | ]
266 | },
267 | {
268 | "cell_type": "markdown",
269 | "metadata": {},
270 | "source": [
271 | "### Multiple Plots on One Axis\n",
272 | "\n",
273 | "\n",
274 | "\n",
275 | "It’s straightforward to generate multiple plots on the same axes.\n",
276 | "\n",
277 | "Here’s an example that randomly generates three normal densities and adds a label with their mean"
278 | ]
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {
284 | "hide-output": false
285 | },
286 | "outputs": [],
287 | "source": [
288 | "from scipy.stats import norm\n",
289 | "from random import uniform\n",
290 | "\n",
291 | "fig, ax = plt.subplots()\n",
292 | "x = np.linspace(-4, 4, 150)\n",
293 | "for i in range(3):\n",
294 | " m, s = uniform(-1, 1), uniform(1, 2)\n",
295 | " y = norm.pdf(x, loc=m, scale=s)\n",
296 | " current_label = f'$\\mu = {m:.2}$'\n",
297 | " ax.plot(x, y, linewidth=2, alpha=0.6, label=current_label)\n",
298 | "ax.legend()\n",
299 | "plt.show()"
300 | ]
301 | },
302 | {
303 | "cell_type": "markdown",
304 | "metadata": {},
305 | "source": [
306 | "### Multiple Subplots\n",
307 | "\n",
308 | "\n",
309 | "\n",
310 | "Sometimes we want multiple subplots in one figure.\n",
311 | "\n",
312 | "Here’s an example that generates 6 histograms"
313 | ]
314 | },
315 | {
316 | "cell_type": "code",
317 | "execution_count": null,
318 | "metadata": {
319 | "hide-output": false
320 | },
321 | "outputs": [],
322 | "source": [
323 | "num_rows, num_cols = 3, 2\n",
324 | "fig, axes = plt.subplots(num_rows, num_cols, figsize=(10, 12))\n",
325 | "for i in range(num_rows):\n",
326 | " for j in range(num_cols):\n",
327 | " m, s = uniform(-1, 1), uniform(1, 2)\n",
328 | " x = norm.rvs(loc=m, scale=s, size=100)\n",
329 | " axes[i, j].hist(x, alpha=0.6, bins=20)\n",
330 | " t = f'$\\mu = {m:.2}, \\quad \\sigma = {s:.2}$'\n",
331 | " axes[i, j].set(title=t, xticks=[-4, 0, 4], yticks=[])\n",
332 | "plt.show()"
333 | ]
334 | },
335 | {
336 | "cell_type": "markdown",
337 | "metadata": {},
338 | "source": [
339 | "### 3D Plots\n",
340 | "\n",
341 | "\n",
342 | "\n",
343 | "Matplotlib does a nice job of 3D plots — here is one example"
344 | ]
345 | },
346 | {
347 | "cell_type": "code",
348 | "execution_count": null,
349 | "metadata": {
350 | "hide-output": false
351 | },
352 | "outputs": [],
353 | "source": [
354 | "from mpl_toolkits.mplot3d.axes3d import Axes3D\n",
355 | "from matplotlib import cm\n",
356 | "\n",
357 | "\n",
358 | "def f(x, y):\n",
359 | " return np.cos(x**2 + y**2) / (1 + x**2 + y**2)\n",
360 | "\n",
361 | "xgrid = np.linspace(-3, 3, 50)\n",
362 | "ygrid = xgrid\n",
363 | "x, y = np.meshgrid(xgrid, ygrid)\n",
364 | "\n",
365 | "fig = plt.figure(figsize=(8, 6))\n",
366 | "ax = fig.add_subplot(111, projection='3d')\n",
367 | "ax.plot_surface(x,\n",
368 | " y,\n",
369 | " f(x, y),\n",
370 | " rstride=2, cstride=2,\n",
371 | " cmap=cm.jet,\n",
372 | " alpha=0.7,\n",
373 | " linewidth=0.25)\n",
374 | "ax.set_zlim(-0.5, 1.0)\n",
375 | "plt.show()"
376 | ]
377 | },
378 | {
379 | "cell_type": "markdown",
380 | "metadata": {},
381 | "source": [
382 | "### A Customizing Function\n",
383 | "\n",
384 | "Perhaps you will find a set of customizations that you regularly use.\n",
385 | "\n",
386 | "Suppose we usually prefer our axes to go through the origin, and to have a grid.\n",
387 | "\n",
388 | "Here’s a nice example from [Matthew Doty](https://github.com/xcthulhu) of how the object-oriented API can be used to build a custom `subplots` function that implements these changes.\n",
389 | "\n",
390 | "Read carefully through the code and see if you can follow what’s going on"
391 | ]
392 | },
393 | {
394 | "cell_type": "code",
395 | "execution_count": null,
396 | "metadata": {
397 | "hide-output": false
398 | },
399 | "outputs": [],
400 | "source": [
401 | "def subplots():\n",
402 | " \"Custom subplots with axes through the origin\"\n",
403 | " fig, ax = plt.subplots()\n",
404 | "\n",
405 | " # Set the axes through the origin\n",
406 | " for spine in ['left', 'bottom']:\n",
407 | " ax.spines[spine].set_position('zero')\n",
408 | " for spine in ['right', 'top']:\n",
409 | " ax.spines[spine].set_color('none')\n",
410 | "\n",
411 | " ax.grid()\n",
412 | " return fig, ax\n",
413 | "\n",
414 | "\n",
415 | "fig, ax = subplots() # Call the local version, not plt.subplots()\n",
416 | "x = np.linspace(-2, 10, 200)\n",
417 | "y = np.sin(x)\n",
418 | "ax.plot(x, y, 'r-', linewidth=2, label='sine function', alpha=0.6)\n",
419 | "ax.legend(loc='lower right')\n",
420 | "plt.show()"
421 | ]
422 | },
423 | {
424 | "cell_type": "markdown",
425 | "metadata": {},
426 | "source": [
427 | "The custom `subplots` function\n",
428 | "\n",
429 | "1. calls the standard `plt.subplots` function internally to generate the `fig, ax` pair, \n",
430 | "1. makes the desired customizations to `ax`, and \n",
431 | "1. passes the `fig, ax` pair back to the calling code. "
432 | ]
433 | },
434 | {
435 | "cell_type": "markdown",
436 | "metadata": {},
437 | "source": [
438 | "## Further Reading\n",
439 | "\n",
440 | "- The [Matplotlib gallery](http://matplotlib.org/gallery.html) provides many examples. \n",
441 | "- A nice [Matplotlib tutorial](http://scipy-lectures.org/intro/matplotlib/index.html) by Nicolas Rougier, Mike Muller and Gael Varoquaux. \n",
442 | "- [mpltools](http://tonysyu.github.io/mpltools/index.html) allows easy\n",
443 | " switching between plot styles. \n",
444 | "- [Seaborn](https://github.com/mwaskom/seaborn) facilitates common statistics plots in Matplotlib. "
445 | ]
446 | },
447 | {
448 | "cell_type": "markdown",
449 | "metadata": {},
450 | "source": [
451 | "## Exercises"
452 | ]
453 | },
454 | {
455 | "cell_type": "markdown",
456 | "metadata": {},
457 | "source": [
458 | "### Exercise 1\n",
459 | "\n",
460 | "Plot the function\n",
461 | "\n",
462 | "$$\n",
463 | "f(x) = \\cos(\\pi \\theta x) \\exp(-x)\n",
464 | "$$\n",
465 | "\n",
466 | "over the interval $ [0, 5] $ for each $ \\theta $ in `np.linspace(0, 2, 10)`.\n",
467 | "\n",
468 | "Place all the curves in the same figure.\n",
469 | "\n",
470 | "The output should look like this\n",
471 | "\n",
472 | "
"
473 | ]
474 | },
475 | {
476 | "cell_type": "markdown",
477 | "metadata": {},
478 | "source": [
479 | "## Solutions"
480 | ]
481 | },
482 | {
483 | "cell_type": "markdown",
484 | "metadata": {},
485 | "source": [
486 | "### Exercise 1\n",
487 | "\n",
488 | "Here’s one solution"
489 | ]
490 | },
491 | {
492 | "cell_type": "code",
493 | "execution_count": null,
494 | "metadata": {
495 | "hide-output": false
496 | },
497 | "outputs": [],
498 | "source": [
499 | "def f(x, θ):\n",
500 | " return np.cos(np.pi * θ * x ) * np.exp(- x)\n",
501 | "\n",
502 | "θ_vals = np.linspace(0, 2, 10)\n",
503 | "x = np.linspace(0, 5, 200)\n",
504 | "fig, ax = plt.subplots()\n",
505 | "\n",
506 | "for θ in θ_vals:\n",
507 | " ax.plot(x, f(x, θ))\n",
508 | "\n",
509 | "plt.show()"
510 | ]
511 | }
512 | ],
513 | "metadata": {
514 | "date": 1584334745.8795545,
515 | "filename": "matplotlib.rst",
516 | "kernelspec": {
517 | "display_name": "Python",
518 | "language": "python3",
519 | "name": "python3"
520 | },
521 | "title": "Matplotlib"
522 | },
523 | "nbformat": 4,
524 | "nbformat_minor": 2
525 | }
--------------------------------------------------------------------------------
/muth_kalman.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Reverse Engineering a la Muth"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Reverse Engineering a la Muth](#Reverse-Engineering-a-la-Muth) \n",
33 | " - [Friedman (1956) and Muth (1960)](#Friedman-%281956%29-and-Muth-%281960%29) "
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "In addition to what’s in Anaconda, this lecture uses the quantecon library."
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {
47 | "hide-output": true
48 | },
49 | "outputs": [],
50 | "source": [
51 | "!pip install --upgrade quantecon"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "We’ll also need the following imports:"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "hide-output": false
66 | },
67 | "outputs": [],
68 | "source": [
69 | "import matplotlib.pyplot as plt\n",
70 | "%matplotlib inline\n",
71 | "import numpy as np\n",
72 | "import scipy.linalg as la\n",
73 | "\n",
74 | "from quantecon import Kalman\n",
75 | "from quantecon import LinearStateSpace\n",
76 | "from scipy.stats import norm\n",
77 | "np.set_printoptions(linewidth=120, precision=4, suppress=True)"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "This lecture uses the Kalman filter to reformulate John F. Muth’s first\n",
85 | "paper [[Mut60]](https://python.quantecon.org/zreferences.html#muth1960) about rational expectations.\n",
86 | "\n",
87 | "Muth used *classical* prediction methods to reverse engineer a\n",
88 | "stochastic process that renders optimal Milton Friedman’s [[Fri56]](https://python.quantecon.org/zreferences.html#friedman1956) “adaptive\n",
89 | "expectations” scheme."
90 | ]
91 | },
92 | {
93 | "cell_type": "markdown",
94 | "metadata": {},
95 | "source": [
96 | "## Friedman (1956) and Muth (1960)\n",
97 | "\n",
98 | "Milton Friedman [[Fri56]](https://python.quantecon.org/zreferences.html#friedman1956) (1956) posited that\n",
99 | "consumer’s forecast their future disposable income with the adaptive\n",
100 | "expectations scheme\n",
101 | "\n",
102 | "\n",
103 | "\n",
104 | "$$\n",
105 | "y_{t+i,t}^* = K \\sum_{j=0}^\\infty (1 - K)^j y_{t-j} \\tag{1}\n",
106 | "$$\n",
107 | "\n",
108 | "where $ K \\in (0,1) $ and $ y_{t+i,t}^* $ is a forecast of\n",
109 | "future $ y $ over horizon $ i $.\n",
110 | "\n",
111 | "Milton Friedman justified the **exponential smoothing** forecasting\n",
112 | "scheme [(1)](#equation-expectations) informally, noting that it seemed a plausible way to use\n",
113 | "past income to forecast future income.\n",
114 | "\n",
115 | "In his first paper about rational expectations, John F. Muth [[Mut60]](https://python.quantecon.org/zreferences.html#muth1960)\n",
116 | "reverse-engineered a univariate stochastic process\n",
117 | "$ \\{y_t\\}_{t=- \\infty}^\\infty $ for which Milton Friedman’s adaptive\n",
118 | "expectations scheme gives linear least forecasts of $ y_{t+j} $ for\n",
119 | "any horizon $ i $.\n",
120 | "\n",
121 | "Muth sought a setting and a sense in which Friedman’s forecasting scheme\n",
122 | "is optimal.\n",
123 | "\n",
124 | "That is, Muth asked for what optimal forecasting **question** is Milton\n",
125 | "Friedman’s adaptive expectation scheme the **answer**.\n",
126 | "\n",
127 | "Muth (1960) used classical prediction methods based on lag-operators and\n",
128 | "$ z $-transforms to find the answer to his question.\n",
129 | "\n",
130 | "Please see lectures [Classical Control with Linear Algebra](https://python.quantecon.org/lu_tricks.html) and\n",
131 | "[Classical Filtering and Prediction with Linear Algebra](https://python.quantecon.org/classical_filtering.html) for an introduction to the classical\n",
132 | "tools that Muth used.\n",
133 | "\n",
134 | "Rather than using those classical tools, in this lecture we apply the\n",
135 | "Kalman filter to express the heart of Muth’s analysis concisely.\n",
136 | "\n",
137 | "The lecture [First Look at Kalman Filter](https://python.quantecon.org/kalman.html) describes the Kalman filter.\n",
138 | "\n",
139 | "We’ll use limiting versions of the Kalman filter corresponding to what are called **stationary values** in that lecture."
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "### A Process for Which Adaptive Expectations are Optimal\n",
147 | "\n",
148 | "Suppose that an observable $ y_t $ is the sum of an unobserved\n",
149 | "random walk $ x_t $ and an IID shock $ \\epsilon_{2,t} $:\n",
150 | "\n",
151 | "\n",
152 | "\n",
153 | "$$\n",
154 | "\\begin{aligned} x_{t+1} & = x_t + \\sigma_x \\epsilon_{1,t+1} \\cr\n",
155 | " y_t & = x_t + \\sigma_y \\epsilon_{2,t} \\end{aligned} \\tag{2}\n",
156 | "$$\n",
157 | "\n",
158 | "where\n",
159 | "\n",
160 | "$$\n",
161 | "\\begin{bmatrix} \\epsilon_{1,t+1} \\cr \\epsilon_{2,t} \\end{bmatrix} \\sim {\\mathcal N} (0, I)\n",
162 | "$$\n",
163 | "\n",
164 | "is an IID process.\n",
165 | "\n",
166 | "**Note:** A property of the state-space representation [(2)](#equation-state-space) is that in\n",
167 | "general neither $ \\epsilon_{1,t} $ nor $ \\epsilon_{2,t} $ is in\n",
168 | "the space spanned by square-summable linear combinations of\n",
169 | "$ y_t, y_{t-1}, \\ldots $.\n",
170 | "\n",
171 | "In general\n",
172 | "$ \\begin{bmatrix} \\epsilon_{1,t} \\cr \\epsilon_{2t} \\end{bmatrix} $\n",
173 | "has more information about future $ y_{t+j} $’s than is contained\n",
174 | "in $ y_t, y_{t-1}, \\ldots $.\n",
175 | "\n",
176 | "We can use the asymptotic or stationary values of the Kalman gain and\n",
177 | "the one-step-ahead conditional state covariance matrix to compute a\n",
178 | "time-invariant *innovations representation*\n",
179 | "\n",
180 | "\n",
181 | "\n",
182 | "$$\n",
183 | "\\begin{aligned} \\hat x_{t+1} & = \\hat x_t + K a_t \\cr\n",
184 | " y_t & = \\hat x_t + a_t \\end{aligned} \\tag{3}\n",
185 | "$$\n",
186 | "\n",
187 | "where $ \\hat x_t = E [x_t | y_{t-1}, y_{t-2}, \\ldots ] $ and\n",
188 | "$ a_t = y_t - E[y_t |y_{t-1}, y_{t-2}, \\ldots ] $.\n",
189 | "\n",
190 | "**Note:** A key property about an *innovations representation* is that\n",
191 | "$ a_t $ is in the space spanned by square summable linear\n",
192 | "combinations of $ y_t, y_{t-1}, \\ldots $.\n",
193 | "\n",
194 | "For more ramifications of this property, see the lectures [Shock Non-Invertibility](https://python.quantecon.org/hs_invertibility_example.html) and\n",
195 | "[Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
196 | "\n",
197 | "Later we’ll stack these state-space systems [(2)](#equation-state-space) and [(3)](#equation-innovations) to display some\n",
198 | "classic findings of Muth.\n",
199 | "\n",
200 | "But first, let’s create an instance of the state-space system [(2)](#equation-state-space) then\n",
201 | "apply the quantecon `Kalman` class, then uses it to construct the associated “innovations representation”"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {
208 | "hide-output": false
209 | },
210 | "outputs": [],
211 | "source": [
212 | "# Make some parameter choices\n",
213 | "# sigx/sigy are state noise std err and measurement noise std err\n",
214 | "μ_0, σ_x, σ_y = 10, 1, 5\n",
215 | "\n",
216 | "# Create a LinearStateSpace object\n",
217 | "A, C, G, H = 1, σ_x, 1, σ_y\n",
218 | "ss = LinearStateSpace(A, C, G, H, mu_0=μ_0)\n",
219 | "\n",
220 | "# Set prior and initialize the Kalman type\n",
221 | "x_hat_0, Σ_0 = 10, 1\n",
222 | "kmuth = Kalman(ss, x_hat_0, Σ_0)\n",
223 | "\n",
224 | "# Computes stationary values which we need for the innovation\n",
225 | "# representation\n",
226 | "S1, K1 = kmuth.stationary_values()\n",
227 | "\n",
228 | "# Form innovation representation state-space\n",
229 | "Ak, Ck, Gk, Hk = A, K1, G, 1\n",
230 | "\n",
231 | "ssk = LinearStateSpace(Ak, Ck, Gk, Hk, mu_0=x_hat_0)"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "### Some Useful State-Space Math\n",
239 | "\n",
240 | "Now we want to map the time-invariant innovations representation [(3)](#equation-innovations) and\n",
241 | "the original state-space system [(2)](#equation-state-space) into a convenient form for deducing\n",
242 | "the impulse responses from the original shocks to the $ x_t $ and\n",
243 | "$ \\hat x_t $.\n",
244 | "\n",
245 | "Putting both of these representations into a single state-space system\n",
246 | "is yet another application of the insight that “finding the state is an\n",
247 | "art”.\n",
248 | "\n",
249 | "We’ll define a state vector and appropriate state-space matrices that\n",
250 | "allow us to represent both systems in one fell swoop.\n",
251 | "\n",
252 | "Note that\n",
253 | "\n",
254 | "$$\n",
255 | "a_t = x_t + \\sigma_y \\epsilon_{2,t} - \\hat x_t\n",
256 | "$$\n",
257 | "\n",
258 | "so that\n",
259 | "\n",
260 | "$$\n",
261 | "\\begin{aligned} \\hat x_{t+1} & = \\hat x_t + K (x_t + \\sigma_y \\epsilon_{2,t} - \\hat x_t) \\cr\n",
262 | " & = (1-K) \\hat x_t + K x_t + K \\sigma_y \\epsilon_{2,t} \\end{aligned}\n",
263 | "$$\n",
264 | "\n",
265 | "The stacked system\n",
266 | "\n",
267 | "$$\n",
268 | "\\begin{bmatrix} x_{t+1} \\cr \\hat x_{t+1} \\cr \\epsilon_{2,t+1} \\end{bmatrix} =\n",
269 | "\\begin{bmatrix} 1 & 0 & 0 \\cr K & (1-K) & K \\sigma_y \\cr 0 & 0 & 0 \\end{bmatrix}\n",
270 | "\\begin{bmatrix} x_{t} \\cr \\hat x_t \\cr \\epsilon_{2,t} \\end{bmatrix}+\n",
271 | "\\begin{bmatrix} \\sigma_x & 0 \\cr 0 & 0 \\cr 0 & 1 \\end{bmatrix}\n",
272 | "\\begin{bmatrix} \\epsilon_{1,t+1} \\cr \\epsilon_{2,t+1} \\end{bmatrix}\n",
273 | "$$\n",
274 | "\n",
275 | "$$\n",
276 | "\\begin{bmatrix} y_t \\cr a_t \\end{bmatrix} = \\begin{bmatrix} 1 & 0 & \\sigma_y \\cr\n",
277 | " 1 & -1 & \\sigma_y \\end{bmatrix} \\begin{bmatrix} x_{t} \\cr \\hat x_t \\cr \\epsilon_{2,t} \\end{bmatrix}\n",
278 | "$$\n",
279 | "\n",
280 | "is a state-space system that tells us how the shocks\n",
281 | "$ \\begin{bmatrix} \\epsilon_{1,t+1} \\cr \\epsilon_{2,t+1} \\end{bmatrix} $\n",
282 | "affect states $ \\hat x_{t+1}, x_t $, the observable $ y_t $, and\n",
283 | "the innovation $ a_t $.\n",
284 | "\n",
285 | "With this tool at our disposal, let’s form the composite system and\n",
286 | "simulate it"
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "hide-output": false
294 | },
295 | "outputs": [],
296 | "source": [
297 | "# Create grand state-space for y_t, a_t as observed vars -- Use\n",
298 | "# stacking trick above\n",
299 | "Af = np.array([[ 1, 0, 0],\n",
300 | " [K1, 1 - K1, K1 * σ_y],\n",
301 | " [ 0, 0, 0]])\n",
302 | "Cf = np.array([[σ_x, 0],\n",
303 | " [ 0, K1 * σ_y],\n",
304 | " [ 0, 1]])\n",
305 | "Gf = np.array([[1, 0, σ_y],\n",
306 | " [1, -1, σ_y]])\n",
307 | "\n",
308 | "μ_true, μ_prior = 10, 10\n",
309 | "μ_f = np.array([μ_true, μ_prior, 0]).reshape(3, 1)\n",
310 | "\n",
311 | "# Create the state-space\n",
312 | "ssf = LinearStateSpace(Af, Cf, Gf, mu_0=μ_f)\n",
313 | "\n",
314 | "# Draw observations of y from the state-space model\n",
315 | "N = 50\n",
316 | "xf, yf = ssf.simulate(N)\n",
317 | "\n",
318 | "print(f\"Kalman gain = {K1}\")\n",
319 | "print(f\"Conditional variance = {S1}\")"
320 | ]
321 | },
322 | {
323 | "cell_type": "markdown",
324 | "metadata": {},
325 | "source": [
326 | "Now that we have simulated our joint system, we have $ x_t $,\n",
327 | "$ \\hat{x_t} $, and $ y_t $.\n",
328 | "\n",
329 | "We can now investigate how these\n",
330 | "variables are related by plotting some key objects."
331 | ]
332 | },
333 | {
334 | "cell_type": "markdown",
335 | "metadata": {},
336 | "source": [
337 | "### Estimates of Unobservables\n",
338 | "\n",
339 | "First, let’s plot the hidden state $ x_t $ and the filtered version\n",
340 | "$ \\hat x_t $ that is linear-least squares projection of $ x_t $\n",
341 | "on the history $ y_{t-1}, y_{t-2}, \\ldots $"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {
348 | "hide-output": false
349 | },
350 | "outputs": [],
351 | "source": [
352 | "fig, ax = plt.subplots()\n",
353 | "ax.plot(xf[0, :], label=\"$x_t$\")\n",
354 | "ax.plot(xf[1, :], label=\"Filtered $x_t$\")\n",
355 | "ax.legend()\n",
356 | "ax.set_xlabel(\"Time\")\n",
357 | "ax.set_title(r\"$x$ vs $\\hat{x}$\")\n",
358 | "plt.show()"
359 | ]
360 | },
361 | {
362 | "cell_type": "markdown",
363 | "metadata": {},
364 | "source": [
365 | "Note how $ x_t $ and $ \\hat{x_t} $ differ.\n",
366 | "\n",
367 | "For Friedman, $ \\hat x_t $ and not $ x_t $ is the consumer’s\n",
368 | "idea about her/his *permanent income*."
369 | ]
370 | },
371 | {
372 | "cell_type": "markdown",
373 | "metadata": {},
374 | "source": [
375 | "### Relation between Unobservable and Observable\n",
376 | "\n",
377 | "Now let’s plot $ x_t $ and $ y_t $.\n",
378 | "\n",
379 | "Recall that $ y_t $ is just $ x_t $ plus white noise"
380 | ]
381 | },
382 | {
383 | "cell_type": "code",
384 | "execution_count": null,
385 | "metadata": {
386 | "hide-output": false
387 | },
388 | "outputs": [],
389 | "source": [
390 | "fig, ax = plt.subplots()\n",
391 | "ax.plot(yf[0, :], label=\"y\")\n",
392 | "ax.plot(xf[0, :], label=\"x\")\n",
393 | "ax.legend()\n",
394 | "ax.set_title(r\"$x$ and $y$\")\n",
395 | "ax.set_xlabel(\"Time\")\n",
396 | "plt.show()"
397 | ]
398 | },
399 | {
400 | "cell_type": "markdown",
401 | "metadata": {},
402 | "source": [
403 | "We see above that $ y $ seems to look like white noise around the\n",
404 | "values of $ x $."
405 | ]
406 | },
407 | {
408 | "cell_type": "markdown",
409 | "metadata": {},
410 | "source": [
411 | "### Innovations\n",
412 | "\n",
413 | "Recall that we wrote down the innovation representation that depended on\n",
414 | "$ a_t $. We now plot the innovations $ \\{a_t\\} $:"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": null,
420 | "metadata": {
421 | "hide-output": false
422 | },
423 | "outputs": [],
424 | "source": [
425 | "fig, ax = plt.subplots()\n",
426 | "ax.plot(yf[1, :], label=\"a\")\n",
427 | "ax.legend()\n",
428 | "ax.set_title(r\"Innovation $a_t$\")\n",
429 | "ax.set_xlabel(\"Time\")\n",
430 | "plt.show()"
431 | ]
432 | },
433 | {
434 | "cell_type": "markdown",
435 | "metadata": {},
436 | "source": [
437 | "### MA and AR Representations\n",
438 | "\n",
439 | "Now we shall extract from the `Kalman` instance `kmuth` coefficients of\n",
440 | "\n",
441 | "- a fundamental moving average representation that represents\n",
442 | " $ y_t $ as a one-sided moving sum of current and past\n",
443 | " $ a_t $s that are square summable linear combinations of $ y_t, y_{t-1}, \\ldots $. \n",
444 | "- a univariate autoregression representation that depicts the\n",
445 | " coefficients in a linear least square projection of $ y_t $ on\n",
446 | " the semi-infinite history $ y_{t-1}, y_{t-2}, \\ldots $. \n",
447 | "\n",
448 | "\n",
449 | "Then we’ll plot each of them"
450 | ]
451 | },
452 | {
453 | "cell_type": "code",
454 | "execution_count": null,
455 | "metadata": {
456 | "hide-output": false
457 | },
458 | "outputs": [],
459 | "source": [
460 | "# Kalman Methods for MA and VAR\n",
461 | "coefs_ma = kmuth.stationary_coefficients(5, \"ma\")\n",
462 | "coefs_var = kmuth.stationary_coefficients(5, \"var\")\n",
463 | "\n",
464 | "# Coefficients come in a list of arrays, but we\n",
465 | "# want to plot them and so need to stack into an array\n",
466 | "coefs_ma_array = np.vstack(coefs_ma)\n",
467 | "coefs_var_array = np.vstack(coefs_var)\n",
468 | "\n",
469 | "fig, ax = plt.subplots(2)\n",
470 | "ax[0].plot(coefs_ma_array, label=\"MA\")\n",
471 | "ax[0].legend()\n",
472 | "ax[1].plot(coefs_var_array, label=\"VAR\")\n",
473 | "ax[1].legend()\n",
474 | "\n",
475 | "plt.show()"
476 | ]
477 | },
478 | {
479 | "cell_type": "markdown",
480 | "metadata": {},
481 | "source": [
482 | "The **moving average** coefficients in the top panel show tell-tale\n",
483 | "signs of $ y_t $ being a process whose first difference is a first-order\n",
484 | "autoregression.\n",
485 | "\n",
486 | "The **autoregressive coefficients** decline geometrically with decay\n",
487 | "rate $ (1-K) $.\n",
488 | "\n",
489 | "These are exactly the target outcomes that Muth (1960) aimed to reverse\n",
490 | "engineer"
491 | ]
492 | },
493 | {
494 | "cell_type": "code",
495 | "execution_count": null,
496 | "metadata": {
497 | "hide-output": false
498 | },
499 | "outputs": [],
500 | "source": [
501 | "print(f'decay parameter 1 - K1 = {1 - K1}')"
502 | ]
503 | }
504 | ],
505 | "metadata": {
506 | "date": 1584334747.4248579,
507 | "filename": "muth_kalman.rst",
508 | "kernelspec": {
509 | "display_name": "Python",
510 | "language": "python3",
511 | "name": "python3"
512 | },
513 | "title": "Reverse Engineering a la Muth"
514 | },
515 | "nbformat": 4,
516 | "nbformat_minor": 2
517 | }
--------------------------------------------------------------------------------
/oop_intro.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# OOP I: Introduction to Object Oriented Programming"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "## Contents\n",
28 | "\n",
29 | "- [OOP I: Introduction to Object Oriented Programming](#OOP-I:-Introduction-to-Object-Oriented-Programming) \n",
30 | " - [Overview](#Overview) \n",
31 | " - [Objects](#Objects) \n",
32 | " - [Summary](#Summary) "
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "## Overview\n",
40 | "\n",
41 | "[OOP](https://en.wikipedia.org/wiki/Object-oriented_programming) is one of the major paradigms in programming.\n",
42 | "\n",
43 | "The traditional programming paradigm (think Fortran, C, MATLAB, etc.) is called *procedural*.\n",
44 | "\n",
45 | "It works as follows\n",
46 | "\n",
47 | "- The program has a state corresponding to the values of its variables. \n",
48 | "- Functions are called to act on these data. \n",
49 | "- Data are passed back and forth via function calls. \n",
50 | "\n",
51 | "\n",
52 | "In contrast, in the OOP paradigm\n",
53 | "\n",
54 | "- data and functions are “bundled together” into “objects” \n",
55 | "\n",
56 | "\n",
57 | "(Functions in this context are referred to as **methods**)"
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "metadata": {},
63 | "source": [
64 | "### Python and OOP\n",
65 | "\n",
66 | "Python is a pragmatic language that blends object-oriented and procedural styles, rather than taking a purist approach.\n",
67 | "\n",
68 | "However, at a foundational level, Python *is* object-oriented.\n",
69 | "\n",
70 | "In particular, in Python, *everything is an object*.\n",
71 | "\n",
72 | "In this lecture, we explain what that statement means and why it matters."
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## Objects\n",
80 | "\n",
81 | "\n",
82 | "\n",
83 | "In Python, an *object* is a collection of data and instructions held in computer memory that consists of\n",
84 | "\n",
85 | "1. a type \n",
86 | "1. a unique identity \n",
87 | "1. data (i.e., content) \n",
88 | "1. methods \n",
89 | "\n",
90 | "\n",
91 | "These concepts are defined and discussed sequentially below.\n",
92 | "\n",
93 | "\n",
94 | ""
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "### Type\n",
102 | "\n",
103 | "\n",
104 | "\n",
105 | "Python provides for different types of objects, to accommodate different categories of data.\n",
106 | "\n",
107 | "For example"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {
114 | "hide-output": false
115 | },
116 | "outputs": [],
117 | "source": [
118 | "s = 'This is a string'\n",
119 | "type(s)"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": null,
125 | "metadata": {
126 | "hide-output": false
127 | },
128 | "outputs": [],
129 | "source": [
130 | "x = 42 # Now let's create an integer\n",
131 | "type(x)"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "metadata": {},
137 | "source": [
138 | "The type of an object matters for many expressions.\n",
139 | "\n",
140 | "For example, the addition operator between two strings means concatenation"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "hide-output": false
148 | },
149 | "outputs": [],
150 | "source": [
151 | "'300' + 'cc'"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "On the other hand, between two numbers it means ordinary addition"
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {
165 | "hide-output": false
166 | },
167 | "outputs": [],
168 | "source": [
169 | "300 + 400"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "Consider the following expression"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "hide-output": false
184 | },
185 | "outputs": [],
186 | "source": [
187 | "'300' + 400"
188 | ]
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {},
193 | "source": [
194 | "Here we are mixing types, and it’s unclear to Python whether the user wants to\n",
195 | "\n",
196 | "- convert `'300'` to an integer and then add it to `400`, or \n",
197 | "- convert `400` to string and then concatenate it with `'300'` \n",
198 | "\n",
199 | "\n",
200 | "Some languages might try to guess but Python is *strongly typed*\n",
201 | "\n",
202 | "- Type is important, and implicit type conversion is rare. \n",
203 | "- Python will respond instead by raising a `TypeError`. \n",
204 | "\n",
205 | "\n",
206 | "To avoid the error, you need to clarify by changing the relevant type.\n",
207 | "\n",
208 | "For example,"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": null,
214 | "metadata": {
215 | "hide-output": false
216 | },
217 | "outputs": [],
218 | "source": [
219 | "int('300') + 400 # To add as numbers, change the string to an integer"
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {},
225 | "source": [
226 | "\n",
227 | ""
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {},
233 | "source": [
234 | "### Identity\n",
235 | "\n",
236 | "\n",
237 | "\n",
238 | "In Python, each object has a unique identifier, which helps Python (and us) keep track of the object.\n",
239 | "\n",
240 | "The identity of an object can be obtained via the `id()` function"
241 | ]
242 | },
243 | {
244 | "cell_type": "code",
245 | "execution_count": null,
246 | "metadata": {
247 | "hide-output": false
248 | },
249 | "outputs": [],
250 | "source": [
251 | "y = 2.5\n",
252 | "z = 2.5\n",
253 | "id(y)"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {
260 | "hide-output": false
261 | },
262 | "outputs": [],
263 | "source": [
264 | "id(z)"
265 | ]
266 | },
267 | {
268 | "cell_type": "markdown",
269 | "metadata": {},
270 | "source": [
271 | "In this example, `y` and `z` happen to have the same value (i.e., `2.5`), but they are not the same object.\n",
272 | "\n",
273 | "The identity of an object is in fact just the address of the object in memory."
274 | ]
275 | },
276 | {
277 | "cell_type": "markdown",
278 | "metadata": {},
279 | "source": [
280 | "### Object Content: Data and Attributes\n",
281 | "\n",
282 | "\n",
283 | "\n",
284 | "If we set `x = 42` then we create an object of type `int` that contains\n",
285 | "the data `42`.\n",
286 | "\n",
287 | "In fact, it contains more, as the following example shows"
288 | ]
289 | },
290 | {
291 | "cell_type": "code",
292 | "execution_count": null,
293 | "metadata": {
294 | "hide-output": false
295 | },
296 | "outputs": [],
297 | "source": [
298 | "x = 42\n",
299 | "x"
300 | ]
301 | },
302 | {
303 | "cell_type": "code",
304 | "execution_count": null,
305 | "metadata": {
306 | "hide-output": false
307 | },
308 | "outputs": [],
309 | "source": [
310 | "x.imag"
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": null,
316 | "metadata": {
317 | "hide-output": false
318 | },
319 | "outputs": [],
320 | "source": [
321 | "x.__class__"
322 | ]
323 | },
324 | {
325 | "cell_type": "markdown",
326 | "metadata": {},
327 | "source": [
328 | "When Python creates this integer object, it stores with it various auxiliary information, such as the imaginary part, and the type.\n",
329 | "\n",
330 | "Any name following a dot is called an *attribute* of the object to the left of the dot.\n",
331 | "\n",
332 | "- e.g.,``imag`` and `__class__` are attributes of `x`. \n",
333 | "\n",
334 | "\n",
335 | "We see from this example that objects have attributes that contain auxiliary information.\n",
336 | "\n",
337 | "They also have attributes that act like functions, called *methods*.\n",
338 | "\n",
339 | "These attributes are important, so let’s discuss them in-depth.\n",
340 | "\n",
341 | "\n",
342 | ""
343 | ]
344 | },
345 | {
346 | "cell_type": "markdown",
347 | "metadata": {},
348 | "source": [
349 | "### Methods\n",
350 | "\n",
351 | "\n",
352 | "\n",
353 | "Methods are *functions that are bundled with objects*.\n",
354 | "\n",
355 | "Formally, methods are attributes of objects that are callable (i.e., can be called as functions)"
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {
362 | "hide-output": false
363 | },
364 | "outputs": [],
365 | "source": [
366 | "x = ['foo', 'bar']\n",
367 | "callable(x.append)"
368 | ]
369 | },
370 | {
371 | "cell_type": "code",
372 | "execution_count": null,
373 | "metadata": {
374 | "hide-output": false
375 | },
376 | "outputs": [],
377 | "source": [
378 | "callable(x.__doc__)"
379 | ]
380 | },
381 | {
382 | "cell_type": "markdown",
383 | "metadata": {},
384 | "source": [
385 | "Methods typically act on the data contained in the object they belong to, or combine that data with other data"
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {
392 | "hide-output": false
393 | },
394 | "outputs": [],
395 | "source": [
396 | "x = ['a', 'b']\n",
397 | "x.append('c')\n",
398 | "s = 'This is a string'\n",
399 | "s.upper()"
400 | ]
401 | },
402 | {
403 | "cell_type": "code",
404 | "execution_count": null,
405 | "metadata": {
406 | "hide-output": false
407 | },
408 | "outputs": [],
409 | "source": [
410 | "s.lower()"
411 | ]
412 | },
413 | {
414 | "cell_type": "code",
415 | "execution_count": null,
416 | "metadata": {
417 | "hide-output": false
418 | },
419 | "outputs": [],
420 | "source": [
421 | "s.replace('This', 'That')"
422 | ]
423 | },
424 | {
425 | "cell_type": "markdown",
426 | "metadata": {},
427 | "source": [
428 | "A great deal of Python functionality is organized around method calls.\n",
429 | "\n",
430 | "For example, consider the following piece of code"
431 | ]
432 | },
433 | {
434 | "cell_type": "code",
435 | "execution_count": null,
436 | "metadata": {
437 | "hide-output": false
438 | },
439 | "outputs": [],
440 | "source": [
441 | "x = ['a', 'b']\n",
442 | "x[0] = 'aa' # Item assignment using square bracket notation\n",
443 | "x"
444 | ]
445 | },
446 | {
447 | "cell_type": "markdown",
448 | "metadata": {},
449 | "source": [
450 | "It doesn’t look like there are any methods used here, but in fact the square bracket assignment notation is just a convenient interface to a method call.\n",
451 | "\n",
452 | "What actually happens is that Python calls the `__setitem__` method, as follows"
453 | ]
454 | },
455 | {
456 | "cell_type": "code",
457 | "execution_count": null,
458 | "metadata": {
459 | "hide-output": false
460 | },
461 | "outputs": [],
462 | "source": [
463 | "x = ['a', 'b']\n",
464 | "x.__setitem__(0, 'aa') # Equivalent to x[0] = 'aa'\n",
465 | "x"
466 | ]
467 | },
468 | {
469 | "cell_type": "markdown",
470 | "metadata": {},
471 | "source": [
472 | "(If you wanted to you could modify the `__setitem__` method, so that square bracket assignment does something totally different)"
473 | ]
474 | },
475 | {
476 | "cell_type": "markdown",
477 | "metadata": {},
478 | "source": [
479 | "## Summary\n",
480 | "\n",
481 | "In Python, *everything in memory is treated as an object*.\n",
482 | "\n",
483 | "This includes not just lists, strings, etc., but also less obvious things, such as\n",
484 | "\n",
485 | "- functions (once they have been read into memory) \n",
486 | "- modules (ditto) \n",
487 | "- files opened for reading or writing \n",
488 | "- integers, etc. \n",
489 | "\n",
490 | "\n",
491 | "Consider, for example, functions.\n",
492 | "\n",
493 | "When Python reads a function definition, it creates a **function object** and stores it in memory.\n",
494 | "\n",
495 | "The following code illustrates"
496 | ]
497 | },
498 | {
499 | "cell_type": "code",
500 | "execution_count": null,
501 | "metadata": {
502 | "hide-output": false
503 | },
504 | "outputs": [],
505 | "source": [
506 | "def f(x): return x**2\n",
507 | "f"
508 | ]
509 | },
510 | {
511 | "cell_type": "code",
512 | "execution_count": null,
513 | "metadata": {
514 | "hide-output": false
515 | },
516 | "outputs": [],
517 | "source": [
518 | "type(f)"
519 | ]
520 | },
521 | {
522 | "cell_type": "code",
523 | "execution_count": null,
524 | "metadata": {
525 | "hide-output": false
526 | },
527 | "outputs": [],
528 | "source": [
529 | "id(f)"
530 | ]
531 | },
532 | {
533 | "cell_type": "code",
534 | "execution_count": null,
535 | "metadata": {
536 | "hide-output": false
537 | },
538 | "outputs": [],
539 | "source": [
540 | "f.__name__"
541 | ]
542 | },
543 | {
544 | "cell_type": "markdown",
545 | "metadata": {},
546 | "source": [
547 | "We can see that `f` has type, identity, attributes and so on—just like any other object.\n",
548 | "\n",
549 | "It also has methods.\n",
550 | "\n",
551 | "One example is the `__call__` method, which just evaluates the function"
552 | ]
553 | },
554 | {
555 | "cell_type": "code",
556 | "execution_count": null,
557 | "metadata": {
558 | "hide-output": false
559 | },
560 | "outputs": [],
561 | "source": [
562 | "f.__call__(3)"
563 | ]
564 | },
565 | {
566 | "cell_type": "markdown",
567 | "metadata": {},
568 | "source": [
569 | "Another is the `__dir__` method, which returns a list of attributes.\n",
570 | "\n",
571 | "Modules loaded into memory are also treated as objects"
572 | ]
573 | },
574 | {
575 | "cell_type": "code",
576 | "execution_count": null,
577 | "metadata": {
578 | "hide-output": false
579 | },
580 | "outputs": [],
581 | "source": [
582 | "import math\n",
583 | "\n",
584 | "id(math)"
585 | ]
586 | },
587 | {
588 | "cell_type": "markdown",
589 | "metadata": {},
590 | "source": [
591 | "This uniform treatment of data in Python (everything is an object) helps keep the language simple and consistent."
592 | ]
593 | }
594 | ],
595 | "metadata": {
596 | "date": 1584334749.33412,
597 | "filename": "oop_intro.rst",
598 | "kernelspec": {
599 | "display_name": "Python",
600 | "language": "python3",
601 | "name": "python3"
602 | },
603 | "title": "OOP I: Introduction to Object Oriented Programming"
604 | },
605 | "nbformat": 4,
606 | "nbformat_minor": 2
607 | }
--------------------------------------------------------------------------------
/optgrowth_fast.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# Optimal Growth II: Accelerating the Code with Numba"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "## Contents\n",
28 | "\n",
29 | "- [Optimal Growth II: Accelerating the Code with Numba](#Optimal-Growth-II:-Accelerating-the-Code-with-Numba) \n",
30 | " - [Overview](#Overview) \n",
31 | " - [The Model](#The-Model) \n",
32 | " - [Computation](#Computation) \n",
33 | " - [Exercises](#Exercises) \n",
34 | " - [Solutions](#Solutions) "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "In addition to what’s in Anaconda, this lecture will need the following libraries:"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {
48 | "hide-output": true
49 | },
50 | "outputs": [],
51 | "source": [
52 | "!pip install --upgrade quantecon\n",
53 | "!pip install --upgrade interpolation"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "## Overview\n",
61 | "\n",
62 | "In a [previous lecture](https://python.quantecon.org/optgrowth.html), we studied a stochastic optimal\n",
63 | "growth model with one representative agent.\n",
64 | "\n",
65 | "We solved the model using dynamic programming.\n",
66 | "\n",
67 | "In writing our code, we focused on clarity and flexibility.\n",
68 | "\n",
69 | "These are important, but there’s often a trade-off between flexibility and\n",
70 | "speed.\n",
71 | "\n",
72 | "The reason is that, when code is less flexible, we can exploit structure more\n",
73 | "easily.\n",
74 | "\n",
75 | "(This is true about algorithms and mathematical problems more generally:\n",
76 | "more specific problems have more structure, which, with some thought, can be\n",
77 | "exploited for better results.)\n",
78 | "\n",
79 | "So, in this lecture, we are going to accept less flexibility while gaining\n",
80 | "speed, using just-in-time (JIT) compilation to\n",
81 | "accelerate our code.\n",
82 | "\n",
83 | "Let’s start with some imports:"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {
90 | "hide-output": false
91 | },
92 | "outputs": [],
93 | "source": [
94 | "import numpy as np\n",
95 | "import matplotlib.pyplot as plt\n",
96 | "from interpolation import interp\n",
97 | "from numba import jit, njit, jitclass, prange, float64, int32\n",
98 | "from quantecon.optimize.scalar_maximization import brent_max\n",
99 | "\n",
100 | "%matplotlib inline"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "We are using an interpolation function from\n",
108 | "[interpolation.py](https://github.com/EconForge/interpolation.py) because it\n",
109 | "helps us JIT-compile our code.\n",
110 | "\n",
111 | "The function brent_max is also designed for embedding in JIT-compiled code.\n",
112 | "\n",
113 | "These are alternatives to similar functions in SciPy (which, unfortunately, are not JIT-aware)."
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "## The Model\n",
121 | "\n",
122 | "\n",
123 | "\n",
124 | "The model is the same as discussed in [this lecture](https://python.quantecon.org/optgrowth.html).\n",
125 | "\n",
126 | "We will use the same algorithm to solve it—the only difference is in the\n",
127 | "implementation itself.\n",
128 | "\n",
129 | "We will use the CRRA utility specification\n",
130 | "\n",
131 | "$$\n",
132 | "u(c) = \\frac{c^{1 - γ} - 1} {1 - γ}\n",
133 | "$$\n",
134 | "\n",
135 | "We continue to assume that\n",
136 | "\n",
137 | "- $ f(k) = k^{\\alpha} $ \n",
138 | "- $ \\phi $ is the distribution of $ \\exp(\\mu + s \\zeta) $ when $ \\zeta $ is standard normal "
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {},
144 | "source": [
145 | "## Computation\n",
146 | "\n",
147 | "\n",
148 | "\n",
149 | "As before, we will store the primitives of the optimal growth model in a class.\n",
150 | "\n",
151 | "But now we are going to use [Numba’s](https://python.quantecon.org/numba.html) `@jitclass` decorator to\n",
152 | "target our class for JIT compilation.\n",
153 | "\n",
154 | "Because we are going to use Numba to compile our class, we need to specify the\n",
155 | "types of the data:"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {
162 | "hide-output": false
163 | },
164 | "outputs": [],
165 | "source": [
166 | "opt_growth_data = [\n",
167 | " ('α', float64), # Production parameter\n",
168 | " ('β', float64), # Discount factor\n",
169 | " ('μ', float64), # Shock location parameter\n",
170 | " ('γ', float64), # Preference parameter\n",
171 | " ('s', float64), # Shock scale parameter\n",
172 | " ('grid', float64[:]), # Grid (array)\n",
173 | " ('shocks', float64[:]) # Shock draws (array)\n",
174 | "]"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "Note the convention for specifying the types of each argument.\n",
182 | "\n",
183 | "Now we’re ready to create our class, which will combine parameters and a\n",
184 | "method that realizes the right hand side of the Bellman equation [(9)](https://python.quantecon.org/optgrowth.html#equation-fpb30).\n",
185 | "\n",
186 | "You will notice that, unlike in the [previous lecture](https://python.quantecon.org/optgrowth.html), we\n",
187 | "hardwire the Cobb-Douglas production and CRRA utility specifications into the\n",
188 | "class.\n",
189 | "\n",
190 | "Thus, we are losing flexibility, but we will gain substantial speed."
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "metadata": {
197 | "hide-output": false
198 | },
199 | "outputs": [],
200 | "source": [
201 | "@jitclass(opt_growth_data)\n",
202 | "class OptimalGrowthModel:\n",
203 | "\n",
204 | " def __init__(self,\n",
205 | " α=0.4,\n",
206 | " β=0.96,\n",
207 | " μ=0,\n",
208 | " s=0.1,\n",
209 | " γ=1.5,\n",
210 | " grid_max=4,\n",
211 | " grid_size=120,\n",
212 | " shock_size=250,\n",
213 | " seed=1234):\n",
214 | "\n",
215 | " self.α, self.β, self.γ, self.μ, self.s = α, β, γ, μ, s\n",
216 | "\n",
217 | " # Set up grid\n",
218 | " self.grid = np.linspace(1e-5, grid_max, grid_size)\n",
219 | "\n",
220 | " # Store shocks (with a seed, so results are reproducible)\n",
221 | " np.random.seed(seed)\n",
222 | " self.shocks = np.exp(μ + s * np.random.randn(shock_size))\n",
223 | "\n",
224 | " def f(self, k):\n",
225 | " return k**self.α\n",
226 | "\n",
227 | " def u(self, c):\n",
228 | " return (c**(1 - self.γ) - 1) / (1 - self.γ)\n",
229 | "\n",
230 | " def objective(self, c, y, v_array):\n",
231 | " \"\"\"\n",
232 | " Right hand side of the Bellman equation.\n",
233 | " \"\"\"\n",
234 | "\n",
235 | " u, f, β, shocks = self.u, self.f, self.β, self.shocks\n",
236 | "\n",
237 | " v = lambda x: interp(self.grid, v_array, x)\n",
238 | "\n",
239 | " return u(c) + β * np.mean(v(f(y - c) * shocks))"
240 | ]
241 | },
242 | {
243 | "cell_type": "markdown",
244 | "metadata": {},
245 | "source": [
246 | "### The Bellman Operator\n",
247 | "\n",
248 | "Here’s a function that uses JIT compilation to accelerate the Bellman operator"
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": null,
254 | "metadata": {
255 | "hide-output": false
256 | },
257 | "outputs": [],
258 | "source": [
259 | "@jit(nopython=True)\n",
260 | "def T(og, v):\n",
261 | " \"\"\"\n",
262 | " The Bellman operator.\n",
263 | "\n",
264 | " * og is an instance of OptimalGrowthModel\n",
265 | " * v is an array representing a guess of the value function\n",
266 | " \"\"\"\n",
267 | " v_new = np.empty_like(v)\n",
268 | "\n",
269 | " for i in range(len(og.grid)):\n",
270 | " y = og.grid[i]\n",
271 | "\n",
272 | " # Maximize RHS of Bellman equation at state y\n",
273 | " v_max = brent_max(og.objective, 1e-10, y, args=(y, v))[1]\n",
274 | " v_new[i] = v_max\n",
275 | "\n",
276 | " return v_new"
277 | ]
278 | },
279 | {
280 | "cell_type": "markdown",
281 | "metadata": {},
282 | "source": [
283 | "Here’s another function, very similar to the last, that computes a $ v $-greedy\n",
284 | "policy:"
285 | ]
286 | },
287 | {
288 | "cell_type": "code",
289 | "execution_count": null,
290 | "metadata": {
291 | "hide-output": false
292 | },
293 | "outputs": [],
294 | "source": [
295 | "@jit(nopython=True)\n",
296 | "def get_greedy(og, v):\n",
297 | " \"\"\"\n",
298 | " Compute a v-greedy policy.\n",
299 | "\n",
300 | " * og is an instance of OptimalGrowthModel\n",
301 | " * v is an array representing a guess of the value function\n",
302 | " \"\"\"\n",
303 | " v_greedy = np.empty_like(v)\n",
304 | "\n",
305 | " for i in range(len(og.grid)):\n",
306 | " y = og.grid[i]\n",
307 | "\n",
308 | " # Find maximizer of RHS of Bellman equation at state y\n",
309 | " c_star = brent_max(og.objective, 1e-10, y, args=(y, v))[0]\n",
310 | " v_greedy[i] = c_star\n",
311 | "\n",
312 | " return v_greedy"
313 | ]
314 | },
315 | {
316 | "cell_type": "markdown",
317 | "metadata": {},
318 | "source": [
319 | "The last two functions could be merged, as they were in our [previous implementation](https://python.quantecon.org/optgrowth.html), but we resisted doing so to increase efficiency.\n",
320 | "\n",
321 | "Here’s a function that iterates from a starting guess of the value function until the difference between successive iterates is below a particular tolerance level."
322 | ]
323 | },
324 | {
325 | "cell_type": "code",
326 | "execution_count": null,
327 | "metadata": {
328 | "hide-output": false
329 | },
330 | "outputs": [],
331 | "source": [
332 | "def solve_model(og,\n",
333 | " tol=1e-4,\n",
334 | " max_iter=1000,\n",
335 | " verbose=True,\n",
336 | " print_skip=25):\n",
337 | "\n",
338 | " # Set up loop\n",
339 | " v = np.log(og.grid) # Initial condition\n",
340 | " i = 0\n",
341 | " error = tol + 1\n",
342 | "\n",
343 | " while i < max_iter and error > tol:\n",
344 | " v_new = T(og, v)\n",
345 | " error = np.max(np.abs(v - v_new))\n",
346 | " i += 1\n",
347 | " if verbose and i % print_skip == 0:\n",
348 | " print(f\"Error at iteration {i} is {error}.\")\n",
349 | " v = v_new\n",
350 | "\n",
351 | " if i == max_iter:\n",
352 | " print(\"Failed to converge!\")\n",
353 | "\n",
354 | " if verbose and i < max_iter:\n",
355 | " print(f\"\\nConverged in {i} iterations.\")\n",
356 | "\n",
357 | " return v_new"
358 | ]
359 | },
360 | {
361 | "cell_type": "markdown",
362 | "metadata": {},
363 | "source": [
364 | "Let’s compute the approximate solution at the default parameters.\n",
365 | "\n",
366 | "First we create an instance:"
367 | ]
368 | },
369 | {
370 | "cell_type": "code",
371 | "execution_count": null,
372 | "metadata": {
373 | "hide-output": false
374 | },
375 | "outputs": [],
376 | "source": [
377 | "og = OptimalGrowthModel()"
378 | ]
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "metadata": {},
383 | "source": [
384 | "Now we call `solve_model`, using the `%%time` magic to check how long it\n",
385 | "takes."
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {
392 | "hide-output": false
393 | },
394 | "outputs": [],
395 | "source": [
396 | "%%time\n",
397 | "v_solution = solve_model(og)"
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {},
403 | "source": [
404 | "You will notice that this is *much* faster than our [original implementation](https://python.quantecon.org/optgrowth.html#ogex1).\n",
405 | "\n",
406 | "Let’s plot the resulting policy:"
407 | ]
408 | },
409 | {
410 | "cell_type": "code",
411 | "execution_count": null,
412 | "metadata": {
413 | "hide-output": false
414 | },
415 | "outputs": [],
416 | "source": [
417 | "v_greedy = get_greedy(og, v_solution)\n",
418 | "\n",
419 | "fig, ax = plt.subplots()\n",
420 | "\n",
421 | "ax.plot(og.grid, v_greedy, lw=2,\n",
422 | " alpha=0.6, label='Approximate value function')\n",
423 | "\n",
424 | "ax.legend(loc='lower right')\n",
425 | "plt.show()"
426 | ]
427 | },
428 | {
429 | "cell_type": "markdown",
430 | "metadata": {},
431 | "source": [
432 | "Everything seems in order, so our code acceleration has been successful!"
433 | ]
434 | },
435 | {
436 | "cell_type": "markdown",
437 | "metadata": {},
438 | "source": [
439 | "## Exercises"
440 | ]
441 | },
442 | {
443 | "cell_type": "markdown",
444 | "metadata": {},
445 | "source": [
446 | "### Exercise 1\n",
447 | "\n",
448 | "Once an optimal consumption policy $ \\sigma $ is given, income follows\n",
449 | "\n",
450 | "$$\n",
451 | "y_{t+1} = f(y_t - \\sigma(y_t)) \\xi_{t+1}\n",
452 | "$$\n",
453 | "\n",
454 | "The next figure shows a simulation of 100 elements of this sequence for three\n",
455 | "different discount factors (and hence three different policies).\n",
456 | "\n",
457 | "
\n",
458 | "\n",
459 | " \n",
460 | "In each sequence, the initial condition is $ y_0 = 0.1 $.\n",
461 | "\n",
462 | "The discount factors are `discount_factors = (0.8, 0.9, 0.98)`.\n",
463 | "\n",
464 | "We have also dialed down the shocks a bit with `s = 0.05`.\n",
465 | "\n",
466 | "Otherwise, the parameters and primitives are the same as the log-linear model discussed earlier in the lecture.\n",
467 | "\n",
468 | "Notice that more patient agents typically have higher wealth.\n",
469 | "\n",
470 | "Replicate the figure modulo randomness."
471 | ]
472 | },
473 | {
474 | "cell_type": "markdown",
475 | "metadata": {},
476 | "source": [
477 | "## Solutions"
478 | ]
479 | },
480 | {
481 | "cell_type": "markdown",
482 | "metadata": {},
483 | "source": [
484 | "### Exercise 1\n",
485 | "\n",
486 | "Here’s one solution"
487 | ]
488 | },
489 | {
490 | "cell_type": "code",
491 | "execution_count": null,
492 | "metadata": {
493 | "hide-output": false
494 | },
495 | "outputs": [],
496 | "source": [
497 | "def simulate_og(σ_func, og, y0=0.1, ts_length=100):\n",
498 | " '''\n",
499 | " Compute a time series given consumption policy σ.\n",
500 | " '''\n",
501 | " y = np.empty(ts_length)\n",
502 | " ξ = np.random.randn(ts_length-1)\n",
503 | " y[0] = y0\n",
504 | " for t in range(ts_length-1):\n",
505 | " y[t+1] = (y[t] - σ_func(y[t]))**og.α * np.exp(og.μ + og.s * ξ[t])\n",
506 | " return y"
507 | ]
508 | },
509 | {
510 | "cell_type": "code",
511 | "execution_count": null,
512 | "metadata": {
513 | "hide-output": false
514 | },
515 | "outputs": [],
516 | "source": [
517 | "fig, ax = plt.subplots()\n",
518 | "\n",
519 | "for β in (0.8, 0.9, 0.98):\n",
520 | "\n",
521 | " og = OptimalGrowthModel(β=β, s=0.05)\n",
522 | "\n",
523 | " v_solution = solve_model(og)\n",
524 | " v_greedy = get_greedy(og, v_solution)\n",
525 | "\n",
526 | " # Define an optimal policy function\n",
527 | " σ_func = lambda x: interp(og.grid, v_greedy, x)\n",
528 | " y = simulate_og(σ_func, og)\n",
529 | " ax.plot(y, lw=2, alpha=0.6, label=rf'$\\beta = {β}$')\n",
530 | "\n",
531 | "ax.legend(loc='lower right')\n",
532 | "plt.show()"
533 | ]
534 | }
535 | ],
536 | "metadata": {
537 | "date": 1584334750.4842002,
538 | "filename": "optgrowth_fast.rst",
539 | "kernelspec": {
540 | "display_name": "Python",
541 | "language": "python3",
542 | "name": "python3"
543 | },
544 | "title": "Optimal Growth II: Accelerating the Code with Numba"
545 | },
546 | "nbformat": 4,
547 | "nbformat_minor": 2
548 | }
--------------------------------------------------------------------------------
/permanent_income_dles.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Permanent Income Model using the DLE Class"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Permanent Income Model using the DLE Class](#Permanent-Income-Model-using-the-DLE-Class) \n",
33 | " - [The Permanent Income Model](#The-Permanent-Income-Model) "
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "This lecture is part of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
41 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
42 | "\n",
43 | "In addition to what’s included in Anaconda, this lecture uses the quantecon library."
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "hide-output": true
51 | },
52 | "outputs": [],
53 | "source": [
54 | "!pip install --upgrade quantecon"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "metadata": {},
60 | "source": [
61 | "This lecture adds a third solution method for the\n",
62 | "linear-quadratic-Gaussian permanent income model with\n",
63 | "$ \\beta R = 1 $, complementing the other two solution methods described in\n",
64 | "[Optimal Savings I: The Permanent Income Model](https://python.quantecon.org/perm_income.html) and\n",
65 | "[Optimal Savings II: LQ Techniques](https://python.quantecon.org/perm_income_cons.html) and this Jupyter\n",
66 | "notebook [http://nbviewer.jupyter.org/github/QuantEcon/QuantEcon.notebooks/blob/master/permanent_income.ipynb](http://nbviewer.jupyter.org/github/QuantEcon/QuantEcon.notebooks/blob/master/permanent_income.ipynb).\n",
67 | "\n",
68 | "The additional solution method uses the **DLE** class.\n",
69 | "\n",
70 | "In this way, we map the permanent\n",
71 | "income model into the framework of Hansen & Sargent (2013) “Recursive\n",
72 | "Models of Dynamic Linear Economies” [[HS13b]](https://python.quantecon.org/zreferences.html#hs2013).\n",
73 | "\n",
74 | "We’ll also require the following imports"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": null,
80 | "metadata": {
81 | "hide-output": false
82 | },
83 | "outputs": [],
84 | "source": [
85 | "import quantecon as qe\n",
86 | "import numpy as np\n",
87 | "import scipy.linalg as la\n",
88 | "import matplotlib.pyplot as plt\n",
89 | "%matplotlib inline\n",
90 | "from quantecon import DLE\n",
91 | "\n",
92 | "np.set_printoptions(suppress=True, precision=4)"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "## The Permanent Income Model\n",
100 | "\n",
101 | "The LQ permanent income model is an example of a **savings problem**.\n",
102 | "\n",
103 | "A consumer has preferences over consumption streams that are ordered by\n",
104 | "the utility functional\n",
105 | "\n",
106 | "\n",
107 | "\n",
108 | "$$\n",
109 | "E_0 \\sum_{t=0}^\\infty \\beta^t u(c_t) \\tag{1}\n",
110 | "$$\n",
111 | "\n",
112 | "where $ E_t $ is the mathematical expectation conditioned on the\n",
113 | "consumer’s time $ t $ information, $ c_t $ is time $ t $\n",
114 | "consumption, $ u(c) $ is a strictly concave one-period utility\n",
115 | "function, and $ \\beta \\in (0,1) $ is a discount factor.\n",
116 | "\n",
117 | "The LQ model gets its name partly from assuming that the utility\n",
118 | "function $ u $ is quadratic:\n",
119 | "\n",
120 | "$$\n",
121 | "u(c) = -.5(c - \\gamma)^2\n",
122 | "$$\n",
123 | "\n",
124 | "where $ \\gamma>0 $ is a bliss level of consumption.\n",
125 | "\n",
126 | "The consumer maximizes the utility functional [(1)](#equation-perm-utility) by choosing a\n",
127 | "consumption, borrowing plan $ \\{c_t, b_{t+1}\\}_{t=0}^\\infty $\n",
128 | "subject to the sequence of budget constraints\n",
129 | "\n",
130 | "\n",
131 | "\n",
132 | "$$\n",
133 | "c_t + b_t = R^{-1} b_{t+1} + y_t, t \\geq 0 \\tag{2}\n",
134 | "$$\n",
135 | "\n",
136 | "where $ y_t $ is an exogenous stationary endowment process,\n",
137 | "$ R $ is a constant gross risk-free interest rate, $ b_t $ is\n",
138 | "one-period risk-free debt maturing at $ t $, and $ b_0 $ is a\n",
139 | "given initial condition.\n",
140 | "\n",
141 | "We shall assume that $ R^{-1} = \\beta $.\n",
142 | "\n",
143 | "Equation [(2)](#equation-max-utility) is linear.\n",
144 | "\n",
145 | "We use another set of linear equations to model the endowment process.\n",
146 | "\n",
147 | "In particular, we assume that the endowment process has the state-space\n",
148 | "representation\n",
149 | "\n",
150 | "\n",
151 | "\n",
152 | "$$\n",
153 | "\\begin{aligned} z_{t+1} & = A_{22} z_t + C_2 w_{t+1} \\cr\n",
154 | " y_t & = U_y z_t \\cr \\end{aligned} \\tag{3}\n",
155 | "$$\n",
156 | "\n",
157 | "where $ w_{t+1} $ is an IID process with mean zero and identity\n",
158 | "contemporaneous covariance matrix, $ A_{22} $ is a stable matrix,\n",
159 | "its eigenvalues being strictly below unity in modulus, and $ U_y $\n",
160 | "is a selection vector that identifies $ y $ with a particular linear\n",
161 | "combination of the $ z_t $.\n",
162 | "\n",
163 | "We impose the following condition on the consumption, borrowing plan:\n",
164 | "\n",
165 | "\n",
166 | "\n",
167 | "$$\n",
168 | "E_0 \\sum_{t=0}^\\infty \\beta^t b_t^2 < +\\infty \\tag{4}\n",
169 | "$$\n",
170 | "\n",
171 | "This condition suffices to rule out Ponzi schemes.\n",
172 | "\n",
173 | "(We impose this condition to rule out a borrow-more-and-more plan that\n",
174 | "would allow the household to enjoy bliss consumption forever)\n",
175 | "\n",
176 | "The state vector confronting the household at $ t $ is\n",
177 | "\n",
178 | "$$\n",
179 | "x_t = \\begin{bmatrix} z_t \\\\ b_t \\end{bmatrix}\n",
180 | "$$\n",
181 | "\n",
182 | "where $ b_t $ is its one-period debt falling due at the beginning of\n",
183 | "period $ t $ and $ z_t $ contains all variables useful for\n",
184 | "forecasting its future endowment.\n",
185 | "\n",
186 | "We assume that $ \\{y_t\\} $ follows a second order univariate\n",
187 | "autoregressive process:\n",
188 | "\n",
189 | "$$\n",
190 | "y_{t+1} = \\alpha + \\rho_1 y_t + \\rho_2 y_{t-1} + \\sigma w_{t+1}\n",
191 | "$$"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "### Solution with the DLE Class\n",
199 | "\n",
200 | "One way of solving this model is to map the problem into the framework\n",
201 | "outlined in Section 4.8 of [[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) by setting up our technology,\n",
202 | "information and preference matrices as follows:\n",
203 | "\n",
204 | "**Technology:**\n",
205 | "$ \\phi_c= \\left[ {\\begin{array}{c} 1 \\\\ 0 \\end{array} } \\right] $\n",
206 | ",\n",
207 | "$ \\phi_g= \\left[ {\\begin{array}{c} 0 \\\\ 1 \\end{array} } \\right] $\n",
208 | ",\n",
209 | "$ \\phi_i= \\left[ {\\begin{array}{c} -1 \\\\ -0.00001 \\end{array} } \\right] $,\n",
210 | "$ \\Gamma= \\left[ {\\begin{array}{c} -1 \\\\ 0 \\end{array} } \\right] $,\n",
211 | "$ \\Delta_k = 0 $, $ \\Theta_k = R $.\n",
212 | "\n",
213 | "**Information:**\n",
214 | "$ A_{22} = \\left[ {\\begin{array}{ccc} 1 & 0 & 0 \\\\ \\alpha & \\rho_1 & \\rho_2 \\\\ 0 & 1 & 0 \\end{array} } \\right] $,\n",
215 | "$ C_{2} = \\left[ {\\begin{array}{c} 0 \\\\ \\sigma \\\\ 0 \\end{array} } \\right] $,\n",
216 | "$ U_b = \\left[ {\\begin{array}{ccc} \\gamma & 0 & 0 \\end{array} } \\right] $,\n",
217 | "$ U_d = \\left[ {\\begin{array}{ccc} 0 & 1 & 0 \\\\ 0 & 0 & 0 \\end{array} } \\right] $.\n",
218 | "\n",
219 | "**Preferences:** $ \\Lambda = 0 $, $ \\Pi = 1 $,\n",
220 | "$ \\Delta_h = 0 $, $ \\Theta_h = 0 $.\n",
221 | "\n",
222 | "We set parameters\n",
223 | "\n",
224 | "$ \\alpha = 10, \\beta = 0.95, \\rho_1 = 0.9, \\rho_2 = 0, \\sigma = 1 $\n",
225 | "\n",
226 | "(The value of $ \\gamma $ does not affect the optimal decision rule)\n",
227 | "\n",
228 | "The chosen matrices mean that the household’s technology is:\n",
229 | "\n",
230 | "$$\n",
231 | "c_t + k_{t-1} = i_t + y_t\n",
232 | "$$\n",
233 | "\n",
234 | "$$\n",
235 | "\\frac{k_t}{R} = i_t\n",
236 | "$$\n",
237 | "\n",
238 | "$$\n",
239 | "l_t^2 = (0.00001)^2i_t\n",
240 | "$$\n",
241 | "\n",
242 | "Combining the first two of these gives the budget constraint of the\n",
243 | "permanent income model, where $ k_t = b_{t+1} $.\n",
244 | "\n",
245 | "The third equation is a very small penalty on debt-accumulation to rule\n",
246 | "out Ponzi schemes.\n",
247 | "\n",
248 | "We set up this instance of the DLE class below:"
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": null,
254 | "metadata": {
255 | "hide-output": false
256 | },
257 | "outputs": [],
258 | "source": [
259 | "α, β, ρ_1, ρ_2, σ = 10, 0.95, 0.9, 0, 1\n",
260 | "\n",
261 | "γ = np.array([[-1], [0]])\n",
262 | "ϕ_c = np.array([[1], [0]])\n",
263 | "ϕ_g = np.array([[0], [1]])\n",
264 | "ϕ_1 = 1e-5\n",
265 | "ϕ_i = np.array([[-1], [-ϕ_1]])\n",
266 | "δ_k = np.array([[0]])\n",
267 | "θ_k = np.array([[1 / β]])\n",
268 | "β = np.array([[β]])\n",
269 | "l_λ = np.array([[0]])\n",
270 | "π_h = np.array([[1]])\n",
271 | "δ_h = np.array([[0]])\n",
272 | "θ_h = np.array([[0]])\n",
273 | "\n",
274 | "a22 = np.array([[1, 0, 0],\n",
275 | " [α, ρ_1, ρ_2],\n",
276 | " [0, 1, 0]])\n",
277 | "\n",
278 | "c2 = np.array([[0], [σ], [0]])\n",
279 | "ud = np.array([[0, 1, 0],\n",
280 | " [0, 0, 0]])\n",
281 | "ub = np.array([[100, 0, 0]])\n",
282 | "\n",
283 | "x0 = np.array([[0], [0], [1], [0], [0]])\n",
284 | "\n",
285 | "info1 = (a22, c2, ub, ud)\n",
286 | "tech1 = (ϕ_c, ϕ_g, ϕ_i, γ, δ_k, θ_k)\n",
287 | "pref1 = (β, l_λ, π_h, δ_h, θ_h)\n",
288 | "econ1 = DLE(info1, tech1, pref1)"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "To check the solution of this model with that from the **LQ** problem,\n",
296 | "we select the $ S_c $ matrix from the DLE class.\n",
297 | "\n",
298 | "The solution to the\n",
299 | "DLE economy has:\n",
300 | "\n",
301 | "$$\n",
302 | "c_t = S_c x_t\n",
303 | "$$"
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": null,
309 | "metadata": {
310 | "hide-output": false
311 | },
312 | "outputs": [],
313 | "source": [
314 | "econ1.Sc"
315 | ]
316 | },
317 | {
318 | "cell_type": "markdown",
319 | "metadata": {},
320 | "source": [
321 | "The state vector in the DLE class is:\n",
322 | "\n",
323 | "$$\n",
324 | "x_t = \\left[ {\\begin{array}{c}\n",
325 | " h_{t-1} \\\\ k_{t-1} \\\\ z_t\n",
326 | " \\end{array} }\n",
327 | " \\right]\n",
328 | "$$\n",
329 | "\n",
330 | "where $ k_{t-1} $ = $ b_{t} $ is set up to be $ b_t $ in the\n",
331 | "permanent income model.\n",
332 | "\n",
333 | "The state vector in the LQ problem is\n",
334 | "$ \\begin{bmatrix} z_t \\\\ b_t \\end{bmatrix} $.\n",
335 | "\n",
336 | "Consequently, the relevant elements of econ1.Sc are the same as in\n",
337 | "$ -F $ occur when we apply other approaches to the same model in the lecture\n",
338 | "[Optimal Savings II: LQ Techniques](https://python.quantecon.org/perm_income_cons.html) and this Jupyter\n",
339 | "notebook [http://nbviewer.jupyter.org/github/QuantEcon/QuantEcon.notebooks/blob/master/permanent_income.ipynb](http://nbviewer.jupyter.org/github/QuantEcon/QuantEcon.notebooks/blob/master/permanent_income.ipynb).\n",
340 | "\n",
341 | "The plot below quickly replicates the first two figures of\n",
342 | "that lecture and that notebook to confirm that the solutions are the same"
343 | ]
344 | },
345 | {
346 | "cell_type": "code",
347 | "execution_count": null,
348 | "metadata": {
349 | "hide-output": false
350 | },
351 | "outputs": [],
352 | "source": [
353 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 5))\n",
354 | "\n",
355 | "for i in range(25):\n",
356 | " econ1.compute_sequence(x0, ts_length=150)\n",
357 | " ax1.plot(econ1.c[0], c='g')\n",
358 | " ax1.plot(econ1.d[0], c='b')\n",
359 | "ax1.plot(econ1.c[0], label='Consumption', c='g')\n",
360 | "ax1.plot(econ1.d[0], label='Income', c='b')\n",
361 | "ax1.legend()\n",
362 | "\n",
363 | "for i in range(25):\n",
364 | " econ1.compute_sequence(x0, ts_length=150)\n",
365 | " ax2.plot(econ1.k[0], color='r')\n",
366 | "ax2.plot(econ1.k[0], label='Debt', c='r')\n",
367 | "ax2.legend()\n",
368 | "plt.show()"
369 | ]
370 | }
371 | ],
372 | "metadata": {
373 | "date": 1584334752.5977762,
374 | "filename": "permanent_income_dles.rst",
375 | "kernelspec": {
376 | "display_name": "Python",
377 | "language": "python3",
378 | "name": "python3"
379 | },
380 | "title": "Permanent Income Model using the DLE Class"
381 | },
382 | "nbformat": 4,
383 | "nbformat_minor": 2
384 | }
--------------------------------------------------------------------------------
/rosen_schooling_model.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Rosen Schooling Model"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Rosen Schooling Model](#Rosen-Schooling-Model) \n",
33 | " - [A One-Occupation Model](#A-One-Occupation-Model) \n",
34 | " - [Mapping into HS2013 Framework](#Mapping-into-HS2013-Framework) "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "This lecture is yet another part of a suite of lectures that use the quantecon DLE class to instantiate models within the\n",
42 | "[[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) class of models described in detail in [Recursive Models of Dynamic Linear Economies](https://python.quantecon.org/hs_recursive_models.html).\n",
43 | "\n",
44 | "In addition to what’s included in Anaconda, this lecture uses the quantecon library"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "hide-output": true
52 | },
53 | "outputs": [],
54 | "source": [
55 | "!pip install --upgrade quantecon"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "We’ll also need the following imports:"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {
69 | "hide-output": false
70 | },
71 | "outputs": [],
72 | "source": [
73 | "import numpy as np\n",
74 | "import matplotlib.pyplot as plt\n",
75 | "from quantecon import LQ\n",
76 | "from collections import namedtuple\n",
77 | "from quantecon import DLE\n",
78 | "from math import sqrt\n",
79 | "%matplotlib inline"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "## A One-Occupation Model\n",
87 | "\n",
88 | "Ryoo and Rosen’s (2004) [[RR04]](https://python.quantecon.org/zreferences.html#ryoo2004engineering) partial equilibrium model determines\n",
89 | "\n",
90 | "- a stock of “Engineers” $ N_t $ \n",
91 | "- a number of new entrants in engineering school, $ n_t $ \n",
92 | "- the wage rate of engineers, $ w_t $ \n",
93 | "\n",
94 | "\n",
95 | "It takes k periods of schooling to become an engineer.\n",
96 | "\n",
97 | "The model consists of the following equations:\n",
98 | "\n",
99 | "- a demand curve for engineers: \n",
100 | "\n",
101 | "\n",
102 | "$$\n",
103 | "w_t = - \\alpha_d N_t + \\epsilon_{dt}\n",
104 | "$$\n",
105 | "\n",
106 | "- a time-to-build structure of the education process: \n",
107 | "\n",
108 | "\n",
109 | "$$\n",
110 | "N_{t+k} = \\delta_N N_{t+k-1} + n_t\n",
111 | "$$\n",
112 | "\n",
113 | "- a definition of the discounted present value of each new engineering\n",
114 | " student: \n",
115 | "\n",
116 | "\n",
117 | "$$\n",
118 | "v_t = \\beta_k \\mathbb{E} \\sum_{j=0}^\\infty (\\beta \\delta_N)^j w_{t+k+j}\n",
119 | "$$\n",
120 | "\n",
121 | "- a supply curve of new students driven by present value $ v_t $: \n",
122 | "\n",
123 | "\n",
124 | "$$\n",
125 | "n_t = \\alpha_s v_t + \\epsilon_{st}\n",
126 | "$$"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "## Mapping into HS2013 Framework\n",
134 | "\n",
135 | "We represent this model in the [[HS13b]](https://python.quantecon.org/zreferences.html#hs2013) framework by\n",
136 | "\n",
137 | "- sweeping the time-to-build structure and the demand for engineers\n",
138 | " into the household technology, and \n",
139 | "- putting the supply of engineers into the technology for producing\n",
140 | " goods "
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "### Preferences\n",
148 | "\n",
149 | "$$\n",
150 | "\\Pi = 0, \\Lambda=\n",
151 | "\\begin{bmatrix}\n",
152 | " \\alpha_d & 0 & \\cdots & 0\n",
153 | " \\end{bmatrix}\n",
154 | ", \\Delta_h =\n",
155 | "\\begin{bmatrix}\n",
156 | " \\delta_N & 1 & 0 & \\cdots & 0 \\\\ 0 & 0 & 1 & \\cdots & 0 \\\\ \\vdots & \\vdots & \\vdots & \\ddots & \\vdots \\\\ 0 & \\cdots& \\cdots & 0 & 1 \\\\ 0 & 0 & 0 & \\cdots & 0\n",
157 | " \\end{bmatrix}\n",
158 | " , \\Theta_h =\n",
159 | "\\begin{bmatrix}\n",
160 | " 0 \\\\ 0 \\\\ \\vdots \\\\ 0 \\\\ 1\n",
161 | " \\end{bmatrix}\n",
162 | "$$\n",
163 | "\n",
164 | "where $ \\Lambda $ is a k+1 x 1 matrix, $ \\Delta_h $ is a k_1 x\n",
165 | "k+1 matrix, and $ \\Theta_h $ is a k+1 x 1 matrix.\n",
166 | "\n",
167 | "This specification sets $ N_t = h_{1t-1} $, $ n_t = c_t $,\n",
168 | "$ h_{\\tau+1,t-1} = n_{t-(k-\\tau)} $ for $ \\tau = 1,...,k $.\n",
169 | "\n",
170 | "Below we set things up so that the number of years of education, k, can\n",
171 | "be varied."
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "metadata": {},
177 | "source": [
178 | "### Technology\n",
179 | "\n",
180 | "To capture Ryoo and Rosen’s [[RR04]](https://python.quantecon.org/zreferences.html#ryoo2004engineering) supply curve, we use the physical\n",
181 | "technology:\n",
182 | "\n",
183 | "$$\n",
184 | "c_t = i_t + d_{1t}\n",
185 | "$$\n",
186 | "\n",
187 | "$$\n",
188 | "\\psi_1i_t = g_t\n",
189 | "$$\n",
190 | "\n",
191 | "where $ \\psi_1 $ is inversely proportional to $ \\alpha_s $."
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "### Information\n",
199 | "\n",
200 | "Because we want $ b_t = \\epsilon_{dt} $ and $ d_{1t} =\\epsilon_{st} $, we set\n",
201 | "\n",
202 | "$$\n",
203 | "A_{22}=\n",
204 | "\\begin{bmatrix}\n",
205 | " 1 & 0 & 0 \\\\ 0 & \\rho_s & 0 \\\\ 0 & 0 & \\rho_d\n",
206 | " \\end{bmatrix}\n",
207 | ", C_2 =\n",
208 | "\\begin{bmatrix}\n",
209 | " 0 & 0 \\\\ 1 & 0 \\\\ 0 & 1\n",
210 | " \\end{bmatrix}\n",
211 | ", U_b =\n",
212 | "\\begin{bmatrix}\n",
213 | " 30 & 0 & 1\n",
214 | " \\end{bmatrix}\n",
215 | ", U_d =\n",
216 | "\\begin{bmatrix}\n",
217 | " 10 & 1 & 0 \\\\ 0 & 0 & 0\n",
218 | " \\end{bmatrix}\n",
219 | "$$\n",
220 | "\n",
221 | "where $ \\rho_s $ and $ \\rho_d $ describe the persistence of the\n",
222 | "supply and demand shocks"
223 | ]
224 | },
225 | {
226 | "cell_type": "code",
227 | "execution_count": null,
228 | "metadata": {
229 | "hide-output": false
230 | },
231 | "outputs": [],
232 | "source": [
233 | "Information = namedtuple('Information', ['a22', 'c2','ub','ud'])\n",
234 | "Technology = namedtuple('Technology', ['ϕ_c', 'ϕ_g', 'ϕ_i', 'γ', 'δ_k', 'θ_k'])\n",
235 | "Preferences = namedtuple('Preferences', ['β', 'l_λ', 'π_h', 'δ_h', 'θ_h'])"
236 | ]
237 | },
238 | {
239 | "cell_type": "markdown",
240 | "metadata": {},
241 | "source": [
242 | "### Effects of Changes in Education Technology and Demand\n",
243 | "\n",
244 | "We now study how changing\n",
245 | "\n",
246 | "- the number of years of education required to become an engineer and \n",
247 | "- the slope of the demand curve \n",
248 | "\n",
249 | "\n",
250 | "affects responses to demand shocks.\n",
251 | "\n",
252 | "To begin, we set $ k = 4 $ and $ \\alpha_d = 0.1 $"
253 | ]
254 | },
255 | {
256 | "cell_type": "code",
257 | "execution_count": null,
258 | "metadata": {
259 | "hide-output": false
260 | },
261 | "outputs": [],
262 | "source": [
263 | "k = 4 # Number of periods of schooling required to become an engineer\n",
264 | "\n",
265 | "β = np.array([[1 / 1.05]])\n",
266 | "α_d = np.array([[0.1]])\n",
267 | "α_s = 1\n",
268 | "ε_1 = 1e-7\n",
269 | "λ_1 = np.ones((1, k)) * ε_1\n",
270 | "# Use of ε_1 is trick to aquire detectability, see HS2013 p. 228 footnote 4\n",
271 | "l_λ = np.hstack((α_d, λ_1))\n",
272 | "π_h = np.array([[0]])\n",
273 | "\n",
274 | "δ_n = np.array([[0.95]])\n",
275 | "d1 = np.vstack((δ_n, np.zeros((k - 1, 1))))\n",
276 | "d2 = np.hstack((d1, np.eye(k)))\n",
277 | "δ_h = np.vstack((d2, np.zeros((1, k + 1))))\n",
278 | "\n",
279 | "θ_h = np.vstack((np.zeros((k, 1)),\n",
280 | " np.ones((1, 1))))\n",
281 | "\n",
282 | "ψ_1 = 1 / α_s\n",
283 | "\n",
284 | "ϕ_c = np.array([[1], [0]])\n",
285 | "ϕ_g = np.array([[0], [-1]])\n",
286 | "ϕ_i = np.array([[-1], [ψ_1]])\n",
287 | "γ = np.array([[0], [0]])\n",
288 | "\n",
289 | "δ_k = np.array([[0]])\n",
290 | "θ_k = np.array([[0]])\n",
291 | "\n",
292 | "ρ_s = 0.8\n",
293 | "ρ_d = 0.8\n",
294 | "\n",
295 | "a22 = np.array([[1, 0, 0],\n",
296 | " [0, ρ_s, 0],\n",
297 | " [0, 0, ρ_d]])\n",
298 | "\n",
299 | "c2 = np.array([[0, 0], [10, 0], [0, 10]])\n",
300 | "ub = np.array([[30, 0, 1]])\n",
301 | "ud = np.array([[10, 1, 0], [0, 0, 0]])\n",
302 | "\n",
303 | "info1 = Information(a22, c2, ub, ud)\n",
304 | "tech1 = Technology(ϕ_c, ϕ_g, ϕ_i, γ, δ_k, θ_k)\n",
305 | "pref1 = Preferences(β, l_λ, π_h, δ_h, θ_h)\n",
306 | "\n",
307 | "econ1 = DLE(info1, tech1, pref1)"
308 | ]
309 | },
310 | {
311 | "cell_type": "markdown",
312 | "metadata": {},
313 | "source": [
314 | "We create three other instances by:\n",
315 | "\n",
316 | "1. Raising $ \\alpha_d $ to 2 \n",
317 | "1. Raising k to 7 \n",
318 | "1. Raising k to 10 "
319 | ]
320 | },
321 | {
322 | "cell_type": "code",
323 | "execution_count": null,
324 | "metadata": {
325 | "hide-output": false
326 | },
327 | "outputs": [],
328 | "source": [
329 | "α_d = np.array([[2]])\n",
330 | "l_λ = np.hstack((α_d, λ_1))\n",
331 | "pref2 = Preferences(β, l_λ, π_h, δ_h, θ_h)\n",
332 | "econ2 = DLE(info1, tech1, pref2)\n",
333 | "\n",
334 | "α_d = np.array([[0.1]])\n",
335 | "\n",
336 | "k = 7\n",
337 | "λ_1 = np.ones((1, k)) * ε_1\n",
338 | "l_λ = np.hstack((α_d, λ_1))\n",
339 | "d1 = np.vstack((δ_n, np.zeros((k - 1, 1))))\n",
340 | "d2 = np.hstack((d1, np.eye(k)))\n",
341 | "δ_h = np.vstack((d2, np.zeros((1, k+1))))\n",
342 | "θ_h = np.vstack((np.zeros((k, 1)),\n",
343 | " np.ones((1, 1))))\n",
344 | "\n",
345 | "Pref3 = Preferences(β, l_λ, π_h, δ_h, θ_h)\n",
346 | "econ3 = DLE(info1, tech1, Pref3)\n",
347 | "\n",
348 | "k = 10\n",
349 | "λ_1 = np.ones((1, k)) * ε_1\n",
350 | "l_λ = np.hstack((α_d, λ_1))\n",
351 | "d1 = np.vstack((δ_n, np.zeros((k - 1, 1))))\n",
352 | "d2 = np.hstack((d1, np.eye(k)))\n",
353 | "δ_h = np.vstack((d2, np.zeros((1, k + 1))))\n",
354 | "θ_h = np.vstack((np.zeros((k, 1)),\n",
355 | " np.ones((1, 1))))\n",
356 | "\n",
357 | "pref4 = Preferences(β, l_λ, π_h, δ_h, θ_h)\n",
358 | "econ4 = DLE(info1, tech1, pref4)\n",
359 | "\n",
360 | "shock_demand = np.array([[0], [1]])\n",
361 | "\n",
362 | "econ1.irf(ts_length=25, shock=shock_demand)\n",
363 | "econ2.irf(ts_length=25, shock=shock_demand)\n",
364 | "econ3.irf(ts_length=25, shock=shock_demand)\n",
365 | "econ4.irf(ts_length=25, shock=shock_demand)"
366 | ]
367 | },
368 | {
369 | "cell_type": "markdown",
370 | "metadata": {},
371 | "source": [
372 | "The first figure plots the impulse response of $ n_t $ (on the left)\n",
373 | "and $ N_t $ (on the right) to a positive demand shock, for\n",
374 | "$ \\alpha_d = 0.1 $ and $ \\alpha_d = 2 $.\n",
375 | "\n",
376 | "When $ \\alpha_d = 2 $, the number of new students $ n_t $ rises\n",
377 | "initially, but the response then turns negative.\n",
378 | "\n",
379 | "A positive demand shock raises wages, drawing new students into the\n",
380 | "profession.\n",
381 | "\n",
382 | "However, these new students raise $ N_t $.\n",
383 | "\n",
384 | "The higher is $ \\alpha_d $, the larger the effect of this rise in\n",
385 | "$ N_t $ on wages.\n",
386 | "\n",
387 | "This counteracts the demand shock’s positive effect on wages, reducing\n",
388 | "the number of new students in subsequent periods.\n",
389 | "\n",
390 | "Consequently, when $ \\alpha_d $ is lower, the effect of a demand\n",
391 | "shock on $ N_t $ is larger"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": null,
397 | "metadata": {
398 | "hide-output": false
399 | },
400 | "outputs": [],
401 | "source": [
402 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
403 | "ax1.plot(econ1.c_irf,label='$\\\\alpha_d = 0.1$')\n",
404 | "ax1.plot(econ2.c_irf,label='$\\\\alpha_d = 2$')\n",
405 | "ax1.legend()\n",
406 | "ax1.set_title('Response of $n_t$ to a demand shock')\n",
407 | "\n",
408 | "ax2.plot(econ1.h_irf[:, 0], label='$\\\\alpha_d = 0.1$')\n",
409 | "ax2.plot(econ2.h_irf[:, 0], label='$\\\\alpha_d = 24$')\n",
410 | "ax2.legend()\n",
411 | "ax2.set_title('Response of $N_t$ to a demand shock')\n",
412 | "plt.show()"
413 | ]
414 | },
415 | {
416 | "cell_type": "markdown",
417 | "metadata": {},
418 | "source": [
419 | "The next figure plots the impulse response of $ n_t $ (on the left)\n",
420 | "and $ N_t $ (on the right) to a positive demand shock, for\n",
421 | "$ k=4 $, $ k=7 $ and $ k=10 $ (with $ \\alpha_d = 0.1 $)"
422 | ]
423 | },
424 | {
425 | "cell_type": "code",
426 | "execution_count": null,
427 | "metadata": {
428 | "hide-output": false
429 | },
430 | "outputs": [],
431 | "source": [
432 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
433 | "ax1.plot(econ1.c_irf, label='$k=4$')\n",
434 | "ax1.plot(econ3.c_irf, label='$k=7$')\n",
435 | "ax1.plot(econ4.c_irf, label='$k=10$')\n",
436 | "ax1.legend()\n",
437 | "ax1.set_title('Response of $n_t$ to a demand shock')\n",
438 | "\n",
439 | "ax2.plot(econ1.h_irf[:,0], label='$k=4$')\n",
440 | "ax2.plot(econ3.h_irf[:,0], label='$k=7$')\n",
441 | "ax2.plot(econ4.h_irf[:,0], label='$k=10$')\n",
442 | "ax2.legend()\n",
443 | "ax2.set_title('Response of $N_t$ to a demand shock')\n",
444 | "plt.show()"
445 | ]
446 | },
447 | {
448 | "cell_type": "markdown",
449 | "metadata": {},
450 | "source": [
451 | "Both panels in the above figure show that raising k lowers the effect of\n",
452 | "a positive demand shock on entry into the engineering profession.\n",
453 | "\n",
454 | "Increasing the number of periods of schooling lowers\n",
455 | "the number of new students in response to a demand shock.\n",
456 | "\n",
457 | "This occurs because with longer required schooling, new students ultimately benefit less from the impact of that shock on wages."
458 | ]
459 | }
460 | ],
461 | "metadata": {
462 | "date": 1584334756.6926937,
463 | "filename": "rosen_schooling_model.rst",
464 | "kernelspec": {
465 | "display_name": "Python",
466 | "language": "python3",
467 | "name": "python3"
468 | },
469 | "title": "Rosen Schooling Model"
470 | },
471 | "nbformat": 4,
472 | "nbformat_minor": 2
473 | }
--------------------------------------------------------------------------------
/schelling.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# Schelling’s Segregation Model\n",
21 | "\n",
22 | "\n",
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [Schelling’s Segregation Model](#Schelling’s-Segregation-Model) \n",
33 | " - [Outline](#Outline) \n",
34 | " - [The Model](#The-Model) \n",
35 | " - [Results](#Results) \n",
36 | " - [Exercises](#Exercises) \n",
37 | " - [Solutions](#Solutions) "
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "## Outline\n",
45 | "\n",
46 | "In 1969, Thomas C. Schelling developed a simple but striking model of racial segregation [[Sch69]](https://python.quantecon.org/zreferences.html#schelling1969).\n",
47 | "\n",
48 | "His model studies the dynamics of racially mixed neighborhoods.\n",
49 | "\n",
50 | "Like much of Schelling’s work, the model shows how local interactions can lead to surprising aggregate structure.\n",
51 | "\n",
52 | "In particular, it shows that relatively mild preference for neighbors of similar race can lead in aggregate to the collapse of mixed neighborhoods, and high levels of segregation.\n",
53 | "\n",
54 | "In recognition of this and other research, Schelling was awarded the 2005 Nobel Prize in Economic Sciences (joint with Robert Aumann).\n",
55 | "\n",
56 | "In this lecture, we (in fact you) will build and run a version of Schelling’s model.\n",
57 | "\n",
58 | "Let’s start with some imports:"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "hide-output": false
66 | },
67 | "outputs": [],
68 | "source": [
69 | "from random import uniform, seed\n",
70 | "from math import sqrt\n",
71 | "import matplotlib.pyplot as plt\n",
72 | "%matplotlib inline"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## The Model\n",
80 | "\n",
81 | "We will cover a variation of Schelling’s model that is easy to program and captures the main idea."
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "### Set-Up\n",
89 | "\n",
90 | "Suppose we have two types of people: orange people and green people.\n",
91 | "\n",
92 | "For the purpose of this lecture, we will assume there are 250 of each type.\n",
93 | "\n",
94 | "These agents all live on a single unit square.\n",
95 | "\n",
96 | "The location of an agent is just a point $ (x, y) $, where $ 0 < x, y < 1 $."
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {},
102 | "source": [
103 | "### Preferences\n",
104 | "\n",
105 | "We will say that an agent is *happy* if half or more of her 10 nearest neighbors are of the same type.\n",
106 | "\n",
107 | "Here ‘nearest’ is in terms of [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance).\n",
108 | "\n",
109 | "An agent who is not happy is called *unhappy*.\n",
110 | "\n",
111 | "An important point here is that agents are not averse to living in mixed areas.\n",
112 | "\n",
113 | "They are perfectly happy if half their neighbors are of the other color."
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "### Behavior\n",
121 | "\n",
122 | "Initially, agents are mixed together (integrated).\n",
123 | "\n",
124 | "In particular, the initial location of each agent is an independent draw from a bivariate uniform distribution on $ S = (0, 1)^2 $.\n",
125 | "\n",
126 | "Now, cycling through the set of all agents, each agent is now given the chance to stay or move.\n",
127 | "\n",
128 | "We assume that each agent will stay put if they are happy and move if unhappy.\n",
129 | "\n",
130 | "The algorithm for moving is as follows\n",
131 | "\n",
132 | "1. Draw a random location in $ S $ \n",
133 | "1. If happy at new location, move there \n",
134 | "1. Else, go to step 1 \n",
135 | "\n",
136 | "\n",
137 | "In this way, we cycle continuously through the agents, moving as required.\n",
138 | "\n",
139 | "We continue to cycle until no one wishes to move."
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "## Results\n",
147 | "\n",
148 | "Let’s have a look at the results we got when we coded and ran this model.\n",
149 | "\n",
150 | "As discussed above, agents are initially mixed randomly together.\n",
151 | "\n",
152 | "
\n",
153 | "\n",
154 | " \n",
155 | "But after several cycles, they become segregated into distinct regions.\n",
156 | "\n",
157 | "
\n",
158 | "\n",
159 | " \n",
160 | "
\n",
161 | "\n",
162 | " \n",
163 | "
\n",
164 | "\n",
165 | " \n",
166 | "In this instance, the program terminated after 4 cycles through the set of\n",
167 | "agents, indicating that all agents had reached a state of happiness.\n",
168 | "\n",
169 | "What is striking about the pictures is how rapidly racial integration breaks down.\n",
170 | "\n",
171 | "This is despite the fact that people in the model don’t actually mind living mixed with the other type.\n",
172 | "\n",
173 | "Even with these preferences, the outcome is a high degree of segregation."
174 | ]
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "metadata": {},
179 | "source": [
180 | "## Exercises\n",
181 | "\n",
182 | "\n",
183 | ""
184 | ]
185 | },
186 | {
187 | "cell_type": "markdown",
188 | "metadata": {},
189 | "source": [
190 | "### Exercise 1\n",
191 | "\n",
192 | "Implement and run this simulation for yourself.\n",
193 | "\n",
194 | "Consider the following structure for your program.\n",
195 | "\n",
196 | "Agents can be modeled as [objects](https://python.quantecon.org/python_oop.html).\n",
197 | "\n",
198 | "Here’s an indication of how they might look"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {
204 | "hide-output": false
205 | },
206 | "source": [
207 | "```text\n",
208 | "* Data:\n",
209 | "\n",
210 | " * type (green or orange)\n",
211 | " * location\n",
212 | "\n",
213 | "* Methods:\n",
214 | "\n",
215 | " * determine whether happy or not given locations of other agents\n",
216 | "\n",
217 | " * If not happy, move\n",
218 | "\n",
219 | " * find a new location where happy\n",
220 | "```\n"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {},
226 | "source": [
227 | "And here’s some pseudocode for the main loop"
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {
233 | "hide-output": false
234 | },
235 | "source": [
236 | "```text\n",
237 | "while agents are still moving\n",
238 | " for agent in agents\n",
239 | " give agent the opportunity to move\n",
240 | "```\n"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "Use 250 agents of each type."
248 | ]
249 | },
250 | {
251 | "cell_type": "markdown",
252 | "metadata": {},
253 | "source": [
254 | "## Solutions"
255 | ]
256 | },
257 | {
258 | "cell_type": "markdown",
259 | "metadata": {},
260 | "source": [
261 | "### Exercise 1\n",
262 | "\n",
263 | "Here’s one solution that does the job we want.\n",
264 | "\n",
265 | "If you feel like a further exercise, you can probably speed up some of the computations and\n",
266 | "then increase the number of agents."
267 | ]
268 | },
269 | {
270 | "cell_type": "code",
271 | "execution_count": null,
272 | "metadata": {
273 | "hide-output": false
274 | },
275 | "outputs": [],
276 | "source": [
277 | "seed(10) # For reproducible random numbers\n",
278 | "\n",
279 | "class Agent:\n",
280 | "\n",
281 | " def __init__(self, type):\n",
282 | " self.type = type\n",
283 | " self.draw_location()\n",
284 | "\n",
285 | " def draw_location(self):\n",
286 | " self.location = uniform(0, 1), uniform(0, 1)\n",
287 | "\n",
288 | " def get_distance(self, other):\n",
289 | " \"Computes the euclidean distance between self and other agent.\"\n",
290 | " a = (self.location[0] - other.location[0])**2\n",
291 | " b = (self.location[1] - other.location[1])**2\n",
292 | " return sqrt(a + b)\n",
293 | "\n",
294 | " def happy(self, agents):\n",
295 | " \"True if sufficient number of nearest neighbors are of the same type.\"\n",
296 | " distances = []\n",
297 | " # distances is a list of pairs (d, agent), where d is distance from\n",
298 | " # agent to self\n",
299 | " for agent in agents:\n",
300 | " if self != agent:\n",
301 | " distance = self.get_distance(agent)\n",
302 | " distances.append((distance, agent))\n",
303 | " # == Sort from smallest to largest, according to distance == #\n",
304 | " distances.sort()\n",
305 | " # == Extract the neighboring agents == #\n",
306 | " neighbors = [agent for d, agent in distances[:num_neighbors]]\n",
307 | " # == Count how many neighbors have the same type as self == #\n",
308 | " num_same_type = sum(self.type == agent.type for agent in neighbors)\n",
309 | " return num_same_type >= require_same_type\n",
310 | "\n",
311 | " def update(self, agents):\n",
312 | " \"If not happy, then randomly choose new locations until happy.\"\n",
313 | " while not self.happy(agents):\n",
314 | " self.draw_location()\n",
315 | "\n",
316 | "\n",
317 | "def plot_distribution(agents, cycle_num):\n",
318 | " \"Plot the distribution of agents after cycle_num rounds of the loop.\"\n",
319 | " x_values_0, y_values_0 = [], []\n",
320 | " x_values_1, y_values_1 = [], []\n",
321 | " # == Obtain locations of each type == #\n",
322 | " for agent in agents:\n",
323 | " x, y = agent.location\n",
324 | " if agent.type == 0:\n",
325 | " x_values_0.append(x)\n",
326 | " y_values_0.append(y)\n",
327 | " else:\n",
328 | " x_values_1.append(x)\n",
329 | " y_values_1.append(y)\n",
330 | " fig, ax = plt.subplots(figsize=(8, 8))\n",
331 | " plot_args = {'markersize': 8, 'alpha': 0.6}\n",
332 | " ax.set_facecolor('azure')\n",
333 | " ax.plot(x_values_0, y_values_0, 'o', markerfacecolor='orange', **plot_args)\n",
334 | " ax.plot(x_values_1, y_values_1, 'o', markerfacecolor='green', **plot_args)\n",
335 | " ax.set_title(f'Cycle {cycle_num-1}')\n",
336 | " plt.show()\n",
337 | "\n",
338 | "# == Main == #\n",
339 | "\n",
340 | "num_of_type_0 = 250\n",
341 | "num_of_type_1 = 250\n",
342 | "num_neighbors = 10 # Number of agents regarded as neighbors\n",
343 | "require_same_type = 5 # Want at least this many neighbors to be same type\n",
344 | "\n",
345 | "# == Create a list of agents == #\n",
346 | "agents = [Agent(0) for i in range(num_of_type_0)]\n",
347 | "agents.extend(Agent(1) for i in range(num_of_type_1))\n",
348 | "\n",
349 | "\n",
350 | "count = 1\n",
351 | "# == Loop until none wishes to move == #\n",
352 | "while True:\n",
353 | " print('Entering loop ', count)\n",
354 | " plot_distribution(agents, count)\n",
355 | " count += 1\n",
356 | " no_one_moved = True\n",
357 | " for agent in agents:\n",
358 | " old_location = agent.location\n",
359 | " agent.update(agents)\n",
360 | " if agent.location != old_location:\n",
361 | " no_one_moved = False\n",
362 | " if no_one_moved:\n",
363 | " break\n",
364 | "\n",
365 | "print('Converged, terminating.')"
366 | ]
367 | }
368 | ],
369 | "metadata": {
370 | "date": 1584334757.4135983,
371 | "filename": "schelling.rst",
372 | "kernelspec": {
373 | "display_name": "Python",
374 | "language": "python3",
375 | "name": "python3"
376 | },
377 | "title": "Schelling’s Segregation Model"
378 | },
379 | "nbformat": 4,
380 | "nbformat_minor": 2
381 | }
--------------------------------------------------------------------------------
/tax_smoothing_3.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | "\n",
14 | "\n",
15 | "\n",
16 | ""
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# How to Pay for a War: Part 3"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Contents\n",
31 | "\n",
32 | "- [How to Pay for a War: Part 3](#How-to-Pay-for-a-War:-Part-3) \n",
33 | " - [Another Application of Markov Jump Linear Quadratic Dynamic Programming](#Another-Application-of-Markov-Jump-Linear-Quadratic-Dynamic-Programming) \n",
34 | " - [Roll-Over Risk](#Roll-Over-Risk) \n",
35 | " - [A Dead End](#A-Dead-End) \n",
36 | " - [Better Representation of Roll-Over Risk](#Better-Representation-of-Roll-Over-Risk) "
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "In addition to what’s in Anaconda, this lecture deploys the quantecon library:"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "hide-output": true
51 | },
52 | "outputs": [],
53 | "source": [
54 | "!pip install --upgrade quantecon"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "metadata": {},
60 | "source": [
61 | "## Another Application of Markov Jump Linear Quadratic Dynamic Programming\n",
62 | "\n",
63 | "This is another [sequel to an earlier lecture](https://python.quantecon.org/tax_smoothing_1.html).\n",
64 | "\n",
65 | "We again use a method introduced in lecture [Markov Jump LQ dynamic programming](https://python.quantecon.org/markov_jump_lq.html)\n",
66 | "to implement some ideas Barro (1999 [[Bar99]](https://python.quantecon.org/zreferences.html#barro1999determinants), 2003 [[BM03]](https://python.quantecon.org/zreferences.html#barro2003religion)) that\n",
67 | "extend his classic 1979 [[Bar79]](https://python.quantecon.org/zreferences.html#barro1979) model of tax smoothing.\n",
68 | "\n",
69 | "Barro’s 1979 [[Bar79]](https://python.quantecon.org/zreferences.html#barro1979) model is about a government that borrows and lends in order\n",
70 | "to help it minimize an intertemporal measure of distortions caused by\n",
71 | "taxes.\n",
72 | "\n",
73 | "Technically, Barro’s 1979 [[Bar79]](https://python.quantecon.org/zreferences.html#barro1979) model looks a lot like a consumption-smoothing model.\n",
74 | "\n",
75 | "Our generalizations of his 1979 model will also look\n",
76 | "like souped-up consumption-smoothing models.\n",
77 | "\n",
78 | "In this lecture, we describe a tax-smoothing problem of a\n",
79 | "government that faces **roll-over risk**.\n",
80 | "\n",
81 | "Let’s start with some standard imports:"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {
88 | "hide-output": false
89 | },
90 | "outputs": [],
91 | "source": [
92 | "import quantecon as qe\n",
93 | "import numpy as np\n",
94 | "import matplotlib.pyplot as plt\n",
95 | "%matplotlib inline"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "## Roll-Over Risk\n",
103 | "\n",
104 | "Let $ T_t $ denote tax collections, $ \\beta $ a discount factor,\n",
105 | "$ b_{t,t+1} $ time $ t+1 $ goods that the government promises to\n",
106 | "pay at $ t $, $ G_t $ government purchases, $ p^t_{t+1} $\n",
107 | "the number of time $ t $ goods received per time $ t+1 $ goods\n",
108 | "promised.\n",
109 | "\n",
110 | "The stochastic process of government expenditures is\n",
111 | "exogenous.\n",
112 | "\n",
113 | "The government’s problem is to choose a plan for borrowing\n",
114 | "and tax collections $ \\{b_{t+1}, T_t\\}_{t=0}^\\infty $ to minimize\n",
115 | "\n",
116 | "$$\n",
117 | "E_0 \\sum_{t=0}^\\infty \\beta^t T_t^2\n",
118 | "$$\n",
119 | "\n",
120 | "subject to the constraints\n",
121 | "\n",
122 | "$$\n",
123 | "T_t + p^t_{t+1} b_{t,t+1} = G_t + b_{t-1,t}\n",
124 | "$$\n",
125 | "\n",
126 | "$$\n",
127 | "G_t = U_{g,t} z_t\n",
128 | "$$\n",
129 | "\n",
130 | "$$\n",
131 | "z_{t+1} = A_{22,t} z_t + C_{2,t} w_{t+1}\n",
132 | "$$\n",
133 | "\n",
134 | "where $ w_{t+1} \\sim {\\cal N}(0,I) $. The variables\n",
135 | "$ T_t, b_{t, t+1} $ are *control* variables chosen at $ t $,\n",
136 | "while $ b_{t-1,t} $ is an endogenous state variable inherited from\n",
137 | "the past at time $ t $ and $ p^t_{t+1} $ is an exogenous state\n",
138 | "variable at time $ t $.\n",
139 | "\n",
140 | "This is the same set-up as used [in this\n",
141 | "lecture](https://python.quantecon.org/tax_smoothing_1.html).\n",
142 | "\n",
143 | "We will consider a situation in which the government faces “roll-over\n",
144 | "risk”.\n",
145 | "\n",
146 | "Specifically, we shut down the government’s ability to borrow in\n",
147 | "one of the Markov states."
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "## A Dead End\n",
155 | "\n",
156 | "A first thought for how to implement this might be to allow\n",
157 | "$ p^t_{t+1} $ to vary over time with:\n",
158 | "\n",
159 | "$$\n",
160 | "p^t_{t+1} = \\beta\n",
161 | "$$\n",
162 | "\n",
163 | "in Markov state 1 and\n",
164 | "\n",
165 | "$$\n",
166 | "p^t_{t+1} = 0\n",
167 | "$$\n",
168 | "\n",
169 | "in Markov state 2.\n",
170 | "\n",
171 | "Consequently, in the second Markov state, the\n",
172 | "government is unable to borrow, and the budget constraint becomes\n",
173 | "$ T_t = G_t + b_{t-1,t} $.\n",
174 | "\n",
175 | "However, if this is the only adjustment we make in our linear-quadratic\n",
176 | "model, the government will not set $ b_{t,t+1} = 0 $, which is the\n",
177 | "outcome we want to express *roll-over* risk in period $ t $.\n",
178 | "\n",
179 | "Instead, the government would have an incentive to set $ b_{t,t+1} $\n",
180 | "to a large negative number in state 2 – it would accumulate large\n",
181 | "amounts of *assets* to bring into period $ t+1 $ because that is\n",
182 | "cheap (Our Riccati equations will discover this for us!).\n",
183 | "\n",
184 | "Thus, we must represent “roll-over risk” some other way."
185 | ]
186 | },
187 | {
188 | "cell_type": "markdown",
189 | "metadata": {},
190 | "source": [
191 | "## Better Representation of Roll-Over Risk\n",
192 | "\n",
193 | "To force the government to set $ b_{t,t+1} = 0 $, we can instead\n",
194 | "extend the model to have four Markov states:\n",
195 | "\n",
196 | "1. Good today, good yesterday \n",
197 | "1. Good today, bad yesterday \n",
198 | "1. Bad today, good yesterday \n",
199 | "1. Bad today, bad yesterday \n",
200 | "\n",
201 | "\n",
202 | "where good is a state in which effectively the government can issue debt\n",
203 | "and bad is a state in which effectively the government can’t issue debt.\n",
204 | "\n",
205 | "We’ll explain what *effectively* means shortly.\n",
206 | "\n",
207 | "We now set\n",
208 | "\n",
209 | "$$\n",
210 | "p^t_{t+1} = \\beta\n",
211 | "$$\n",
212 | "\n",
213 | "in all states.\n",
214 | "\n",
215 | "In addition – and this is important because it defines what we mean by\n",
216 | "*effectively* – we put a large penalty on the $ b_{t-1,t} $\n",
217 | "element of the state vector in states 2 and 4.\n",
218 | "\n",
219 | "This will prevent the\n",
220 | "government from wishing to issue any debt in states 3 or 4 because it\n",
221 | "would experience a large penalty from doing so in the next period.\n",
222 | "\n",
223 | "The transition matrix for this formulation is:\n",
224 | "\n",
225 | "$$\n",
226 | "\\Pi = \\begin{bmatrix} 0.95 & 0 & 0.05 & 0 \\\\\n",
227 | " 0.95 & 0 & 0.05 & 0 \\\\\n",
228 | " 0 & 0.9 & 0 & 0.1 \\\\\n",
229 | " 0 & 0.9 & 0 & 0.1 \\\\\n",
230 | "\\end{bmatrix}\n",
231 | "$$\n",
232 | "\n",
233 | "This transition matrix ensures that the Markov state cannot move, for\n",
234 | "example, from state 3 to state 1.\n",
235 | "\n",
236 | "Because state 3 is “bad today”, the next period cannot have “good yesterday”."
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": null,
242 | "metadata": {
243 | "hide-output": false
244 | },
245 | "outputs": [],
246 | "source": [
247 | "# Model parameters\n",
248 | "β, Gbar, ρ, σ = 0.95, 5, 0.8, 1\n",
249 | "\n",
250 | "# Basic model matrices\n",
251 | "A22 = np.array([[1, 0], [Gbar, ρ], ])\n",
252 | "C2 = np.array([[0], [σ]])\n",
253 | "Ug = np.array([[0, 1]])\n",
254 | "\n",
255 | "# LQ framework matrices\n",
256 | "A_t = np.zeros((1, 3))\n",
257 | "A_b = np.hstack((np.zeros((2, 1)), A22))\n",
258 | "A = np.vstack((A_t, A_b))\n",
259 | "\n",
260 | "B = np.zeros((3, 1))\n",
261 | "B[0, 0] = 1\n",
262 | "\n",
263 | "C = np.vstack((np.zeros((1, 1)), C2))\n",
264 | "\n",
265 | "Sg = np.hstack((np.zeros((1, 1)), Ug))\n",
266 | "S1 = np.zeros((1, 3))\n",
267 | "S1[0, 0] = 1\n",
268 | "S = S1 + Sg\n",
269 | "\n",
270 | "R = S.T @ S\n",
271 | "\n",
272 | "# Large penalty on debt in R2 to prevent borrowing in a bad state\n",
273 | "R1 = np.copy(R)\n",
274 | "R2 = np.copy(R)\n",
275 | "R1[0, 0] = R[0, 0] + 1e-9\n",
276 | "R2[0, 0] = R[0, 0] + 1e12\n",
277 | "\n",
278 | "M = np.array([[-β]])\n",
279 | "Q = M.T @ M\n",
280 | "W = M.T @ S\n",
281 | "\n",
282 | "Π = np.array([[0.95, 0, 0.05, 0],\n",
283 | " [0.95, 0, 0.05, 0],\n",
284 | " [0, 0.9, 0, 0.1],\n",
285 | " [0, 0.9, 0, 0.1]])\n",
286 | "\n",
287 | "# Construct lists of matrices that correspond to each state\n",
288 | "As = [A, A, A, A]\n",
289 | "Bs = [B, B, B, B]\n",
290 | "Cs = [C, C, C, C]\n",
291 | "Rs = [R1, R2, R1, R2]\n",
292 | "Qs = [Q, Q, Q, Q]\n",
293 | "Ws = [W, W, W, W]\n",
294 | "\n",
295 | "lqm = qe.LQMarkov(Π, Qs, Rs, As, Bs, Cs=Cs, Ns=Ws, beta=β)\n",
296 | "lqm.stationary_values();"
297 | ]
298 | },
299 | {
300 | "cell_type": "markdown",
301 | "metadata": {},
302 | "source": [
303 | "This model is simulated below, using the same process for $ G_t $ as\n",
304 | "in [this lecture](https://python.quantecon.org/tax_smoothing_2.html).\n",
305 | "\n",
306 | "When $ p^t_{t+1} = \\beta $\n",
307 | "government debt fluctuates around zero.\n",
308 | "\n",
309 | "The spikes in the series for\n",
310 | "taxation show periods when the government is unable to access financial\n",
311 | "markets: positive spikes occur when debt is positive, and the government\n",
312 | "must raise taxes in the current period.\n",
313 | "\n",
314 | "Negative spikes occur when the government has positive asset holdings.\n",
315 | "\n",
316 | "An inability to use financial markets in the next period means that the\n",
317 | "government uses those assets to lower taxation today."
318 | ]
319 | },
320 | {
321 | "cell_type": "code",
322 | "execution_count": null,
323 | "metadata": {
324 | "hide-output": false
325 | },
326 | "outputs": [],
327 | "source": [
328 | "x0 = np.array([[0, 1, 25]])\n",
329 | "T = 300\n",
330 | "x, u, w, state = lqm.compute_sequence(x0, ts_length=T)\n",
331 | "\n",
332 | "# Calculate taxation each period from the budget constraint and the Markov state\n",
333 | "tax = np.zeros([T, 1])\n",
334 | "for i in range(T):\n",
335 | " tax[i, :] = S @ x[:, i] + M @ u[:, i]\n",
336 | "\n",
337 | "# Plot of debt issuance and taxation\n",
338 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 4))\n",
339 | "ax1.plot(x[0, :])\n",
340 | "ax1.set_title('One-period debt issuance')\n",
341 | "ax1.set_xlabel('Time')\n",
342 | "ax2.plot(tax)\n",
343 | "ax2.set_title('Taxation')\n",
344 | "ax2.set_xlabel('Time')\n",
345 | "plt.show()"
346 | ]
347 | },
348 | {
349 | "cell_type": "markdown",
350 | "metadata": {},
351 | "source": [
352 | "We can adjust the model so that, rather than having debt fluctuate\n",
353 | "around zero, the government is a debtor in every period we allow it to\n",
354 | "borrow.\n",
355 | "\n",
356 | "To accomplish this, we simply raise $ p^t_{t+1} $ to\n",
357 | "$ \\beta + 0.02 = 0.97 $."
358 | ]
359 | },
360 | {
361 | "cell_type": "code",
362 | "execution_count": null,
363 | "metadata": {
364 | "hide-output": false
365 | },
366 | "outputs": [],
367 | "source": [
368 | "M = np.array([[-β - 0.02]])\n",
369 | "\n",
370 | "Q = M.T @ M\n",
371 | "W = M.T @ S\n",
372 | "\n",
373 | "# Construct lists of matrices\n",
374 | "As = [A, A, A, A]\n",
375 | "Bs = [B, B, B, B]\n",
376 | "Cs = [C, C, C, C]\n",
377 | "Rs = [R1, R2, R1, R2]\n",
378 | "Qs = [Q, Q, Q, Q]\n",
379 | "Ws = [W, W, W, W]\n",
380 | "\n",
381 | "lqm2 = qe.LQMarkov(Π, Qs, Rs, As, Bs, Cs=Cs, Ns=Ws, beta=β)\n",
382 | "x, u, w, state = lqm2.compute_sequence(x0, ts_length=T)\n",
383 | "\n",
384 | "# Calculate taxation each period from the budget constraint and the\n",
385 | "# Markov state\n",
386 | "tax = np.zeros([T, 1])\n",
387 | "for i in range(T):\n",
388 | " tax[i, :] = S @ x[:, i] + M @ u[:, i]\n",
389 | "\n",
390 | "# Plot of debt issuance and taxation\n",
391 | "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 4))\n",
392 | "ax1.plot(x[0, :])\n",
393 | "ax1.set_title('One-period debt issuance')\n",
394 | "ax1.set_xlabel('Time')\n",
395 | "ax2.plot(tax)\n",
396 | "ax2.set_title('Taxation')\n",
397 | "ax2.set_xlabel('Time')\n",
398 | "plt.show()"
399 | ]
400 | },
401 | {
402 | "cell_type": "markdown",
403 | "metadata": {},
404 | "source": [
405 | "With a lower interest rate, the government has an incentive to\n",
406 | "increase debt over time.\n",
407 | "\n",
408 | "However, with “roll-over risk”, debt is\n",
409 | "recurrently reset to zero and taxes spike up.\n",
410 | "\n",
411 | "Consequently, the\n",
412 | "government is wary of letting debt get too high, due to the high costs of\n",
413 | "a “sudden stop”."
414 | ]
415 | }
416 | ],
417 | "metadata": {
418 | "date": 1584334758.924878,
419 | "filename": "tax_smoothing_3.rst",
420 | "kernelspec": {
421 | "display_name": "Python",
422 | "language": "python3",
423 | "name": "python3"
424 | },
425 | "title": "How to Pay for a War: Part 3"
426 | },
427 | "nbformat": 4,
428 | "nbformat_minor": 2
429 | }
--------------------------------------------------------------------------------
/troubleshooting.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "\n",
9 | ""
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "# Troubleshooting"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "## Contents\n",
28 | "\n",
29 | "- [Troubleshooting](#Troubleshooting) \n",
30 | " - [Fixing Your Local Environment](#Fixing-Your-Local-Environment) \n",
31 | " - [Reporting an Issue](#Reporting-an-Issue) "
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "This page is for readers experiencing errors when running the code from the lectures."
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Fixing Your Local Environment\n",
46 | "\n",
47 | "The basic assumption of the lectures is that code in a lecture should execute whenever\n",
48 | "\n",
49 | "1. it is executed in a Jupyter notebook and \n",
50 | "1. the notebook is running on a machine with the latest version of Anaconda Python. \n",
51 | "\n",
52 | "\n",
53 | "You have installed Anaconda, haven’t you, following the instructions in [this lecture](https://python.quantecon.org/getting_started.html)?\n",
54 | "\n",
55 | "Assuming that you have, the most common source of problems for our readers is that their Anaconda distribution is not up to date.\n",
56 | "\n",
57 | "[Here’s a useful article](https://www.anaconda.com/keeping-anaconda-date/)\n",
58 | "on how to update Anaconda.\n",
59 | "\n",
60 | "Another option is to simply remove Anaconda and reinstall.\n",
61 | "\n",
62 | "You also need to keep the external code libraries, such as [QuantEcon.py](https://quantecon.org/quantecon-py) up to date.\n",
63 | "\n",
64 | "For this task you can either\n",
65 | "\n",
66 | "- use pip install –upgrade quantecon on the command line, or \n",
67 | "- execute !pip install –upgrade quantecon within a Jupyter notebook. \n",
68 | "\n",
69 | "\n",
70 | "If your local environment is still not working you can do two things.\n",
71 | "\n",
72 | "First, you can use a remote machine instead, by clicking on the Launch Notebook icon available for each lecture\n",
73 | "\n",
74 | "
\n",
75 | "\n",
76 | "Second, you can report an issue, so we can try to fix your local set up.\n",
77 | "\n",
78 | "We like getting feedback on the lectures so please don’t hesitate to get in\n",
79 | "touch."
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "## Reporting an Issue\n",
87 | "\n",
88 | "One way to give feedback is to raise an issue through our [issue tracker](https://github.com/QuantEcon/lecture-source-py/issues).\n",
89 | "\n",
90 | "Please be as specific as possible. Tell us where the problem is and as much\n",
91 | "detail about your local set up as you can provide.\n",
92 | "\n",
93 | "Another feedback option is to use our [discourse forum](https://discourse.quantecon.org/).\n",
94 | "\n",
95 | "Finally, you can provide direct feedback to [contact@quantecon.org](mailto:contact@quantecon.org)"
96 | ]
97 | }
98 | ],
99 | "metadata": {
100 | "date": 1584334758.9779892,
101 | "filename": "troubleshooting.rst",
102 | "kernelspec": {
103 | "display_name": "Python",
104 | "language": "python3",
105 | "name": "python3"
106 | },
107 | "title": "Troubleshooting"
108 | },
109 | "nbformat": 4,
110 | "nbformat_minor": 2
111 | }
--------------------------------------------------------------------------------