Skip to content

Commit 856dda8

Browse files
authored
REF and TEST: rank_size in inequality.py (#551)
1 parent ca8fb06 commit 856dda8

File tree

3 files changed

+70
-29
lines changed

3 files changed

+70
-29
lines changed

quantecon/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from .graph_tools import DiGraph, random_tournament_graph
2828
from .gridtools import cartesian, mlinspace, simplex_grid, simplex_index
2929
from .inequality import lorenz_curve, gini_coefficient, shorrocks_index, \
30-
rank_size_plot
30+
rank_size
3131
from .kalman import Kalman
3232
from .lae import LAE
3333
from .arma import ARMA

quantecon/inequality.py

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@
1010
@njit
1111
def lorenz_curve(y):
1212
"""
13-
Calculates the Lorenz Curve, a graphical representation of the distribution of income
14-
or wealth.
13+
Calculates the Lorenz Curve, a graphical representation of
14+
the distribution of income or wealth.
1515
16-
It returns the cumulative share of people (x-axis) and the cumulative share of income earned
16+
It returns the cumulative share of people (x-axis) and
17+
the cumulative share of income earned.
1718
1819
Parameters
1920
----------
2021
y : array_like(float or int, ndim=1)
21-
Array of income/wealth for each individual. Unordered or ordered is fine.
22+
Array of income/wealth for each individual.
23+
Unordered or ordered is fine.
2224
2325
Returns
2426
-------
@@ -60,7 +62,8 @@ def gini_coefficient(y):
6062
Parameters
6163
-----------
6264
y : array_like(float)
63-
Array of income/wealth for each individual. Ordered or unordered is fine
65+
Array of income/wealth for each individual.
66+
Ordered or unordered is fine
6467
6568
Returns
6669
-------
@@ -96,15 +99,15 @@ def shorrocks_index(A):
9699
The Shorrocks mobility index calculated as
97100
98101
.. math::
99-
102+
100103
s(A) = \frac{m - \sum_j a_{jj} }{m - 1} \in (0, 1)
101104
102105
An index equal to 0 indicates complete immobility.
103106
104107
References
105108
-----------
106-
.. [1] Wealth distribution and social mobility in the US: A quantitative approach
107-
(Benhabib, Bisin, Luo, 2017).
109+
.. [1] Wealth distribution and social mobility in the US:
110+
A quantitative approach (Benhabib, Bisin, Luo, 2017).
108111
https://www.econ.nyu.edu/user/bisina/RevisionAugust.pdf
109112
"""
110113

@@ -119,38 +122,32 @@ def shorrocks_index(A):
119122
return (m - diag_sum) / (m - 1)
120123

121124

122-
def rank_size_plot(data, ax, label=None, c=1.0):
125+
def rank_size(data, c=1.0):
123126
"""
124127
Generate rank-size data corresponding to distribution data.
125128
126129
Examples
127130
--------
128-
129-
> import numpy as np
130-
> import matplotlib.pyplot as plt
131-
> y = np.exp(np.random.randn(1000)) # simulate data
132-
> fig, ax = plt.subplots()
133-
> rank_size_plot(y, ax)
134-
> plt.show()
131+
>>> y = np.exp(np.random.randn(1000)) # simulate data
132+
>>> rank_data, size_data = rank_size(y, c=0.85)
135133
136134
Parameters
137135
----------
138-
139136
data : array_like
140137
the set of observations
141138
c : int or float
142139
restrict plot to top (c x 100)% of the distribution
143-
ax : axis object
144-
for plotting on, has method ax.loglog
140+
141+
Returns
142+
-------
143+
rank_data : array_like(float, ndim=1)
144+
Location in the population when sorted from smallest to largest
145+
size_data : array_like(float, ndim=1)
146+
Size data for top (c x 100)% of the observations
145147
"""
146148
w = - np.sort(- data) # Reverse sort
147149
w = w[:int(len(w) * c)] # extract top (c * 100)%
148150
rank_data = np.arange(len(w)) + 1
149151
size_data = w
150-
ax.loglog(rank_data, size_data, 'o', markersize=3.0, alpha=0.5, label=label)
151-
if label:
152-
ax.legend()
153-
ax.set_xlabel("log rank")
154-
ax.set_ylabel("log size")
155-
152+
return rank_data, size_data
156153

quantecon/tests/test_inequality.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
"""
66

77
import numpy as np
8-
from numpy.testing import assert_allclose
9-
from quantecon import lorenz_curve, gini_coefficient, shorrocks_index
8+
from numpy.testing import assert_allclose, assert_raises
9+
from scipy.stats import linregress
10+
from quantecon import lorenz_curve, gini_coefficient, \
11+
shorrocks_index, rank_size
1012

1113

1214
def test_lorenz_curve():
@@ -37,7 +39,7 @@ def test_lorenz_curve():
3739

3840
def test_gini_coeff():
3941
"""
40-
Tests how the funciton `gini_coefficient` calculates the Gini coefficient
42+
Tests how the function `gini_coefficient` calculates the Gini coefficient
4143
with the Pareto and the Weibull distribution.
4244
4345
Analytically, we know that Pareto with parameter `a` has
@@ -88,3 +90,45 @@ def test_shorrocks_index():
8890
index = shorrocks_index(P)
8991
assert_allclose(expected, index, rtol=1e-2)
9092

93+
94+
def test_rank_size():
95+
"""
96+
Tests `rank_size` function, which generates rank-size data for
97+
a Pareto distribution.
98+
99+
The rank-size plot for a sample drawn from a Pareto distribution
100+
should be a straight line.
101+
102+
The length of the `rank_data` array should be within (c x 100)%
103+
of the size of the distribution.
104+
"""
105+
106+
sample_size = 1000
107+
c = 0.74
108+
109+
# Tests Pareto; r_squared ~ 1
110+
pareto_draw = np.exp(np.random.exponential(scale=1.0, size=sample_size))
111+
rank_data, size_data = rank_size(pareto_draw, c=c)
112+
113+
assert len(rank_data) == len(size_data)
114+
assert_allclose(c*sample_size, len(rank_data), rtol=1e-3)
115+
116+
_, _, r_value, _, _ = linregress(np.log(rank_data), np.log(size_data))
117+
r_sqval = r_value**2
118+
119+
assert_allclose(r_sqval, 1, rtol=1e-4)
120+
121+
# Tests Exponential; r_squared < 1
122+
np.random.seed(13)
123+
z = np.random.randn(sample_size)
124+
125+
exp_draw = np.exp(z)
126+
rank_data_exp, size_data_exp = rank_size(exp_draw, c=c)
127+
128+
_, _, r_value_exp, _, _ = linregress(np.log(rank_data_exp),
129+
np.log(size_data_exp))
130+
r_sqval_exp = r_value_exp**2
131+
132+
assert_raises(AssertionError, assert_allclose, r_sqval_exp, 1, rtol=1e-4)
133+
134+

0 commit comments

Comments
 (0)