Using Python CompEcon English
Using Python CompEcon English
Using Python CompEcon English
Randall Romero-Aguilar1
rromero@secmca.org
The use of programming languages has become increasingly necessary in many of the
tasks that we economist do, either because the theoretic models we develop lack analytic
solutions, or because the new econometric estimator we wish to use is not yet available in
a program with a graphical user interface (GUI, where we could just click with a mouse),
or just because it is not efficient to analyze huge datasets with spreadsheets.
Those who wish to exploit the advantages of programming to do these tasks must
first decide which of many programming languages to learn. For instance, to a greater or
lesser extend the languages R, Python, Julia, Fortran, Gauss, and MATLAB are all used
by economists. MATLAB has been especially popular in this field, and there are many
tools that have been developed to be run in this program, among them DYNARE and
IRIS (to solve and estimate DSGE models), CompEcon (for computational economics),
and Econometrics (for spacial econometrics).
Despite the fact that Python is not yet as popular as MATLAB among economists,
its popularity has certainly skyrocketed in recent years. For example, the following books
use Python to do typical economists tasks:
1
tasks (thanks to packages such as Numpy and Scipy), data management (pandas), visu-
alization (Matplotlib) and econometric modeling (Statsmodels).
Another advantage of using Python is that, unlike proprietary programs, Python and
many of these complementary packages are completely free. The best way to get Python
is through Anaconda, a free distribution that includes more than 300 very useful pack-
ages in science, mathematics, engineering, and data analysis. Besides Python, Anaconda
includes tools such as IPython (to run Python interactively), Jupyter (an editor that
allows combining text, code and results in a single file, excellent for documenting your
work), Spyder (a GUI for code editing, similar to that of MATLAB) and Conda (allows
to install and update packages).
If you want to start working with Python, you should consider two issues. First,
there are currently two versions of Python that are not entirely compatible with each
other, the 2 (whose last update is 2.7) and the 3 (currently updated to 3.6). Personally, I
recommend working with version 3.6 because it has significant improvements over version
2.7, and most of the packages needed to work in typical economists tasks have already
been ported to 3.6.
Second, although Spyder facilitates code editing, more advanced users may prefer
PyCharm, an excellent Python editor whose “Community” version can be used for free.
This editor makes it much easier to edit programs, because of features such as auto-
complete (especially useful when we have not yet memorized Python functions), syntax
highlighting (shows keywords in different color, to make it easier to understand the code’s
logic), and debugger (to partially run a program when it is necessary to find a bug).
The purpose of this note is to illustrate some of the common tasks that economists
can do using Python. First, we use numerical techniques to solve two Cournot compe-
tition models presented by Miranda and Fackler (2002) using the ”CompEcon-python”
package 2 , which is freely available at Github3 . Second, it illustrates how to automate
the collection of Internet data and its presentation in tables and graphs. Third, some
examples of econometric models estimated with Python are shown.
For each of the problems, I provide Python code to solve it, along with brief explana-
tions of how this code works. However, this note is not intended to teach programming
in Python because, as mentioned above, there are already many high quality teaching
resources for this purpose, including the site of Google developers, the site learnpython,
2
This package was developed by the author and is based precisely on the CompEcon toolbox for
MATLAB from Miranda and Fackler (2002).
3
Readers interested in the topic of computational economics will find more of these examples in
Romero-Aguilar (2016).
2
and several online courses at edx. Likewise, in the first two examples, the numerical
methods implemented in Python are presented concisely, but readers interested in this
topic are advised to consult the textbooks of Miranda and Fackler (2002), Judd (1998),
and Press, Teukolsky, and Brian P. Flannery (2007).
3
Example 1: A 2-firms Cournot model
Assume the market is controlled by two firms that compete with each other. For this
duopoly, the inverse of the demand function is given by
P (q) = q −α
C1 = 12 β1 q12
C2 = 21 β2 q22
In a Cournot equilibrium, each firm maximizes its profits taking as given the other
firm’s output. Thus, it must follow that
∂π1 (q1 , q2 )
= P (q1 + q2 ) + P ′ (q1 + q2 ) q1 − C1′ (q1 ) = 0
∂q1
∂π2 (q1 , q2 )
= P (q1 + q2 ) + P ′ (q1 + q2 ) q2 − C2′ (q2 ) = 0
∂q2
Therefore, equilibrium output levels for this market are given by the solution to this
nonlinear equation system
[ ] [ ]
(q1 + q2 )−α − αq1 (q1 + q2 )−α−1 − β1 q1 0
f (q1 , q2 ) = −α −α−1 = (1)
(q1 + q2 ) − αq2 (q1 + q2 ) − β2 q 2 0
Newton’s method
To find the root of the function defined in (1) we will use Newton’s method. In general,
this method is applied to the function f : ℜn → ℜn to find some4 value x∗ such that
f (x∗ ) = 0. To that end, we start with a value x0 ∈ ℜn and make the recursion
4
Solving the model with Python
First, we begin a Python session and import compecon
import numpy as np
import matplotlib.pyplot as plt
alpha = 0.625
beta = np.array([0.6, 0.8])
The unknowns in our problem are the firms’ output levels, q1 and q2 . We define the
market function to tell us total output and resulting price, given the levels of q1 y q2 .
Notice that both quantities are passed to this function in the q vector
def market(q):
quantity = q.sum()
price = quantity ** (-alpha)
return price, quantity
Then, we define the cournot function, returning a two-element tuple: the objective
function and its Jacobian matrix, both evaluated in a pair of quantities contained by
the q vector. To make the code easier, notice that the (1) function can be written more
succinctly as [ ] [ ]
P + (P ′ − c1 ) q1 0
f (q1 , q2 ) = ′ =
P + (P − c2 ) q2 0
and its Jacobian matrix is
[ ]
2P ′ + P ′′ q1 − c1 P ′ + P ′′ q1
J (q1 , q2 ) =
P ′ − P ′′ q2 2P ′ + P ′′ q2 − c2
If we define total output as Q = q1 + q2 , notice also that
P P′
P ′ = −α y que P ′′ = −(α + 1)
Q Q
def cournot(q):
P, Q = market(q)
P1 = -alpha * P/Q
5
P2 = (-alpha - 1) * P1 / Q
fval = P + (P1 - beta) * q
fjac = np.diag(2*P1 + P2*q - beta) + np.fliplr(np.diag(P1 + P2*q))
return fval, fjac
Next, we compute the equilibrium using Newton’s
[ ]method (equation (2)) to find the
′
root of the cournot function. We set q0 = 0.2 0.2 as our initial value and iterate
until the norm of the change between two successive values of the recursion is less than
10−10 .
q = np.array([0.2, 0.2])
for it in range(40):
f, J = cournot(q)
step = -np.linalg.solve(J, f)
q += step
if np.linalg.norm(step) < 1.e-10: break
We see that the code has found the equilibrium to this market.
The compecon package provides the NLP (non-linear problem) class, useful to solve
last problem without the need of coding Newton’s algorithm. To use it, we create an
instance of NLP from the cournot function, and simply call the newton method, using q0
as initial value.
q0 = np.array([0.2, 0.2])
cournot_problem = NLP(cournot)
q = cournot_problem.newton(q0)
6
After completing this code block, Python prints the following to screen:
Company 1 produces 0.8396 units, while company 2 produces 0.6888 units. Total
production is 1.5284 and price is 0.7671
Figure 1 illustrates the problem we just solved, where the axes represent the output
levels of each firm. The quasi-vertical white line represents the profit-maximizing output
level for firm 1, taking the output of firm 2 as given. Similarly, the quasi-horizontal
line represents the profit maximizing output level for firm 2, given firm 1 output. The
solution to the problem corresponds to the intersection[ of these
]′ two lines. See also the
path to convergence (blue line) from the initial q0 = 0.2 0.2 point to the solution.
n = 100
q1 = np.linspace(0.1, 1.5, n)
q2 = np.linspace(0.1, 1.5, n)
z = np.array([cournot(q)[0] for q in gridmake(q1, q2).T]).T
7
plt.contour(Q1, Q2, Z0, **contour_options)
plt.contour(Q1, Q2, Z1, **contour_options)
plt.plot(*cournot_problem.x_sequence, **steps_options)
&