43. Market Equilibrium with Heterogeneity#
43.1. Overview#
In the previous lecture, we studied competitive equilibria in an economy with many goods.
While the results of the study were informative, we used a strong simplifying assumption: all of the agents in the economy are identical.
In the real world, households, firms and other economic agents differ from one another along many dimensions.
In this lecture, we introduce heterogeneity across consumers by allowing their preferences and endowments to differ.
We will examine competitive equilibrium in this setting.
We will also show how a “representative consumer” can be constructed.
Here are some imports:
import numpy as np
from scipy.linalg import inv
43.2. An simple example#
Let’s study a simple example of pure exchange economy without production.
There are two consumers who differ in their endowment vectors \(e_i\) and their bliss-point vectors \(b_i\) for \(i=1,2\).
The total endowment is \(e_1 + e_2\).
A competitive equilibrium requires that
Assume the demand curves
Competitive equilibrium then requires that
which, after a line or two of linear algebra, implies that
We can normalize prices by setting \(\mu_1 + \mu_2 =1\) and then solving
for \(\mu_i, i = 1,2\).
Show that, up to normalization by a positive scalar, the same competitive equilibrium price vector that you computed in the preceding two-consumer economy would prevail in a single-consumer economy in which a single representative consumer has utility function
and endowment vector \(e\), where
and
43.3. Pure exchange economy#
Let’s further explore a pure exchange economy with \(n\) goods and \(m\) people.
43.3.1. Competitive equilibrium#
We’ll compute a competitive equilibrium.
To compute a competitive equilibrium of a pure exchange economy, we use the fact that
Relative prices in a competitive equilibrium are the same as those in a special single person or representative consumer economy with preference \(\Pi\) and \(b=\sum_i b_i\), and endowment \(e = \sum_i e_{i}\).
We can use the following steps to compute a competitive equilibrium:
First we solve the single representative consumer economy by normalizing \(\mu = 1\). Then, we renormalize the price vector by using the first consumption good as a numeraire.
Next we use the competitive equilibrium prices to compute each consumer’s marginal utility of wealth:
Finally we compute a competitive equilibrium allocation by using the demand curves:
43.3.2. Designing some Python code#
Below we shall construct a Python class with the following attributes:
Preferences in the form of
an \(n \times n\) positive definite matrix \(\Pi\)
an \(n \times 1\) vector of bliss points \(b\)
Endowments in the form of
an \(n \times 1\) vector \(e\)
a scalar “wealth” \(W\) with default value \(0\)
The class will include a test to make sure that \(b \gg \Pi e \) and raise an exception if it is violated (at some threshold level we’d have to specify).
A Person in the form of a pair that consists of
Preferences and Endowments
A Pure Exchange Economy will consist of
a collection of \(m\) persons
\(m=1\) for our single-agent economy
\(m=2\) for our illustrations of a pure exchange economy
an equilibrium price vector \(p\) (normalized somehow)
an equilibrium allocation \(c_1, c_2, \ldots, c_m\) – a collection of \(m\) vectors of dimension \(n \times 1\)
Now let’s proceed to code.
class ExchangeEconomy:
def __init__(self,
Π,
bs,
es,
Ws=None,
thres=1.5):
"""
Set up the environment for an exchange economy
Args:
Π (np.array): shared matrix of substitution
bs (list): all consumers' bliss points
es (list): all consumers' endowments
Ws (list): all consumers' wealth
thres (float): a threshold set to test b >> Pi e violated
"""
n, m = Π.shape[0], len(bs)
# check non-satiation
for b, e in zip(bs, es):
if np.min(b / np.max(Π @ e)) <= thres:
raise Exception('set bliss points further away')
if Ws == None:
Ws = np.zeros(m)
else:
if sum(Ws) != 0:
raise Exception('invalid wealth distribution')
self.Π, self.bs, self.es, self.Ws, self.n, self.m = Π, bs, es, Ws, n, m
def competitive_equilibrium(self):
"""
Compute the competitive equilibrium prices and allocation
"""
Π, bs, es, Ws = self.Π, self.bs, self.es, self.Ws
n, m = self.n, self.m
slope_dc = inv(Π.T @ Π)
Π_inv = inv(Π)
# aggregate
b = sum(bs)
e = sum(es)
# compute price vector with mu=1 and renormalize
p = Π.T @ b - Π.T @ Π @ e
p = p / p[0]
# compute marginal utility of wealth
μ_s = []
c_s = []
A = p.T @ slope_dc @ p
for i in range(m):
μ_i = (-Ws[i] + p.T @ (Π_inv @ bs[i] - es[i])) / A
c_i = Π_inv @ bs[i] - μ_i * slope_dc @ p
μ_s.append(μ_i)
c_s.append(c_i)
for c_i in c_s:
if any(c_i < 0):
print('allocation: ', c_s)
raise Exception('negative allocation: equilibrium does not exist')
return p, c_s, μ_s
43.4. Implementation#
Next we use the class ExchangeEconomy
defined above to study
a two-person economy without production,
a dynamic economy, and
an economy with risk and arrow securities.
43.4.1. Two-person economy without production#
Here we study how competitive equilibrium \(p, c_1, c_2\) respond to different \(b_i\) and \(e_i\), \(i \in \{1, 2\}\).
Π = np.array([[1, 0],
[0, 1]])
bs = [np.array([5, 5]), # first consumer's bliss points
np.array([5, 5])] # second consumer's bliss points
es = [np.array([0, 2]), # first consumer's endowment
np.array([2, 0])] # second consumer's endowment
EE = ExchangeEconomy(Π, bs, es)
p, c_s, μ_s = EE.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 1.]
Competitive equilibrium allocation: [array([1., 1.]), array([1., 1.])]
What happens if the first consumer likes the first good more and the second consumer likes the second good more?
EE.bs = [np.array([6, 5]), # first consumer's bliss points
np.array([5, 6])] # second consumer's bliss points
p, c_s, μ_s = EE.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 1.]
Competitive equilibrium allocation: [array([1.5, 0.5]), array([0.5, 1.5])]
Let the first consumer be poorer.
EE.es = [np.array([0.5, 0.5]), # first consumer's endowment
np.array([1, 1])] # second consumer's endowment
p, c_s, μ_s = EE.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 1.]
Competitive equilibrium allocation: [array([1., 0.]), array([0.5, 1.5])]
Now let’s construct an autarky (i.e., no-trade) equilibrium.
EE.bs = [np.array([4, 6]), # first consumer's bliss points
np.array([6, 4])] # second consumer's bliss points
EE.es = [np.array([0, 2]), # first consumer's endowment
np.array([2, 0])] # second consumer's endowment
p, c_s, μ_s = EE.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 1.]
Competitive equilibrium allocation: [array([0., 2.]), array([2., 0.])]
Now let’s redistribute endowments before trade.
bs = [np.array([5, 5]), # first consumer's bliss points
np.array([5, 5])] # second consumer's bliss points
es = [np.array([1, 1]), # first consumer's endowment
np.array([1, 1])] # second consumer's endowment
Ws = [0.5, -0.5]
EE_new = ExchangeEconomy(Π, bs, es, Ws)
p, c_s, μ_s = EE_new.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 1.]
Competitive equilibrium allocation: [array([1.25, 1.25]), array([0.75, 0.75])]
43.4.2. A dynamic economy#
Now let’s use the tricks described above to study a dynamic economy, one with two periods.
beta = 0.95
Π = np.array([[1, 0],
[0, np.sqrt(beta)]])
bs = [np.array([5, np.sqrt(beta) * 5])]
es = [np.array([1, 1])]
EE_DE = ExchangeEconomy(Π, bs, es)
p, c_s, μ_s = EE_DE.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 0.95]
Competitive equilibrium allocation: [array([1., 1.])]
43.4.3. Risk economy with arrow securities#
We use the tricks described above to interpret \(c_1, c_2\) as “Arrow securities” that are state-contingent claims to consumption goods.
prob = 0.7
Π = np.array([[np.sqrt(prob), 0],
[0, np.sqrt(1 - prob)]])
bs = [np.array([np.sqrt(prob) * 5, np.sqrt(1 - prob) * 5]),
np.array([np.sqrt(prob) * 5, np.sqrt(1 - prob) * 5])]
es = [np.array([1, 0]),
np.array([0, 1])]
EE_AS = ExchangeEconomy(Π, bs, es)
p, c_s, μ_s = EE_AS.competitive_equilibrium()
print('Competitive equilibrium price vector:', p)
print('Competitive equilibrium allocation:', c_s)
Competitive equilibrium price vector: [1. 0.42857143]
Competitive equilibrium allocation: [array([0.7, 0.7]), array([0.3, 0.3])]
43.5. Deducing a representative consumer#
In the class of multiple consumer economies that we are studying here, it turns out that there exists a single representative consumer whose preferences and endowments can be deduced from lists of preferences and endowments for separate individual consumers.
Consider a multiple consumer economy with initial distribution of wealth \(W_i\) satisfying \(\sum_i W_{i}=0\)
We allow an initial redistribution of wealth.
We have the following objects
The demand curve:
The marginal utility of wealth:
Market clearing:
Denote aggregate consumption \(\sum_i c_{i}=c\) and \(\sum_i \mu_i = \mu\).
Market clearing requires
which, after a few steps, leads to
where
Now consider the representative consumer economy specified above.
Denote the marginal utility of wealth of the representative consumer by \(\tilde{\mu}\).
The demand function is
Substituting this into the budget constraint gives
In an equilibrium \(c=e\), so
Thus, we have verified that, up to the choice of a numeraire in which to express absolute prices, the price vector in our representative consumer economy is the same as that in an underlying economy with multiple consumers.