Solow-Swan growth model

Let us start the lecture by taking a look at the differences in GDP per capita across countries. Throughout this lecture we will mostly use the data from the 9th version of the Penn World Table database.

In [1]:
# Make graphs appear within notebook
%matplotlib inline

# Import numerical computations library
import numpy as np

# Import dataframe management library
import pandas as pd

# Import statistics library
import statsmodels.api as sm

# Import statistics library, allows R-like regression syntax
import statsmodels.formula.api as smf

# Import plotting library
import matplotlib.pyplot as plt
In [2]:
# Restore old behavior of rounding default axis ranges
import matplotlib as mpl

mpl.rcParams['axes.autolimit_mode'] = 'round_numbers'
mpl.rcParams['axes.xmargin'] = 0
mpl.rcParams['axes.ymargin'] = 0
In [3]:
# Read dataset
pwt = pd.read_stata('PWT/pwt90.dta')

# Display last 5 observations
pwt.tail()
Out[3]:
countrycode country currency_unit year rgdpe rgdpo pop emp avh hc ... csh_g csh_x csh_m csh_r pl_c pl_i pl_g pl_x pl_m pl_k
11825 ZWE Zimbabwe US Dollar 2010 20652.718750 21053.855469 13.973897 6.298438 NaN 2.372605 ... 0.127251 0.214657 -0.454497 0.014462 0.447170 0.543100 0.411316 0.701797 0.606324 1.015145
11826 ZWE Zimbabwe US Dollar 2011 20720.435547 21592.298828 14.255592 6.518841 NaN 2.415823 ... 0.189860 0.219809 -0.625170 0.004390 0.531029 0.606065 0.440252 0.739989 0.637035 0.470333
11827 ZWE Zimbabwe US Dollar 2012 23708.654297 24360.527344 14.565482 6.248271 NaN 2.459828 ... 0.178643 0.225631 -0.479897 -0.076998 0.474047 1.363167 0.458315 0.712036 0.634858 0.608320
11828 ZWE Zimbabwe US Dollar 2013 27011.988281 28157.886719 14.898092 6.287056 NaN 2.504635 ... 0.162252 0.174443 -0.436145 -0.000005 0.498061 0.575870 0.465031 0.717884 0.630712 0.414526
11829 ZWE Zimbabwe US Dollar 2014 28495.554688 29149.708984 15.245855 6.499974 NaN 2.550258 ... 0.253410 0.147346 -0.349806 -0.020068 0.528013 0.550110 0.464699 0.716963 0.628869 0.386039

5 rows × 47 columns

In [4]:
# Modify the dataset so that it is easier to work with

# Store country names and codes for later use
countries = pwt['country']
countries = countries.drop_duplicates()

countrycodes = pwt['countrycode']
countrycodes = countrycodes.drop_duplicates()

# Set MultiIndex
pwt.set_index(['country', 'year'], inplace=True)
pwt.tail()
Out[4]:
countrycode currency_unit rgdpe rgdpo pop emp avh hc ccon cda ... csh_g csh_x csh_m csh_r pl_c pl_i pl_g pl_x pl_m pl_k
country year
Zimbabwe 2010 ZWE US Dollar 20652.718750 21053.855469 13.973897 6.298438 NaN 2.372605 21862.835938 26023.046875 ... 0.127251 0.214657 -0.454497 0.014462 0.447170 0.543100 0.411316 0.701797 0.606324 1.015145
2011 ZWE US Dollar 20720.435547 21592.298828 14.255592 6.518841 NaN 2.415823 26202.080078 30250.195312 ... 0.189860 0.219809 -0.625170 0.004390 0.531029 0.606065 0.440252 0.739989 0.637035 0.470333
2012 ZWE US Dollar 23708.654297 24360.527344 14.565482 6.248271 NaN 2.459828 30321.824219 32171.179688 ... 0.178643 0.225631 -0.479897 -0.076998 0.474047 1.363167 0.458315 0.712036 0.634858 0.608320
2013 ZWE US Dollar 27011.988281 28157.886719 14.898092 6.287056 NaN 2.504635 32283.355469 35336.441406 ... 0.162252 0.174443 -0.436145 -0.000005 0.498061 0.575870 0.465031 0.717884 0.630712 0.414526
2014 ZWE US Dollar 28495.554688 29149.708984 15.245855 6.499974 NaN 2.550258 32038.916016 35454.808594 ... 0.253410 0.147346 -0.349806 -0.020068 0.528013 0.550110 0.464699 0.716963 0.628869 0.386039

5 rows × 45 columns

In [5]:
# Extract data for GDP per capita in 2014
gdp_pc_2014 = (pwt.xs(2014, level='year')['rgdpe']/
               pwt.xs(2014, level='year')['pop'])

# Plot histogram
plt.hist(gdp_pc_2014)

plt.title('Histogram of GDP per capita in 2014')
plt.xlabel('GDP per capita (2011 \$)')
plt.ylabel('Number of countries')

plt.show()
In [6]:
# List countries with very high GDP per capita
gdp_pc_2014[gdp_pc_2014 > 50000]
Out[6]:
country
United Arab Emirates     64397.512519
Bermuda                  57530.840406
Brunei Darussalam        68498.552364
Switzerland              58468.915194
Cayman Islands           51465.018690
China, Hong Kong SAR     51807.835108
Kuwait                   63885.571835
Luxembourg               95175.724085
China, Macao SAR        126980.019951
Norway                   64274.358388
Qatar                   144340.365620
Singapore                72582.994255
United States            52292.281832
dtype: float64
In [7]:
# Data is highly skewed -- maybe better display in logarithms of base 10

log10_bins_2014 = np.logspace(np.log10(np.min(gdp_pc_2014)),
                              np.log10(np.max(gdp_pc_2014)),
                              num=1+10, base=10)

plt.hist(gdp_pc_2014, bins=log10_bins_2014, histtype='bar', rwidth=0.8)

plt.xscale('log')

plt.xlim(500, 200000)

plt.xticks([500, 1000, 2000, 5000, 10000, 20000, 50000, 100000], 
           [500, 1000, 2000, 5000, 10000, 20000, 50000, 100000])

plt.title('Histogram of GDP per capita in 2014')
plt.xlabel('GDP per capita (2011 \$)')
plt.ylabel('Number of countries')

plt.show()
In [8]:
# Plot the population-weighted distribution of GDP per capita in given years

plt.subplots(figsize = (7, 4))

for i, year in enumerate([1960, 1985, 2014]):
    sl = pwt.xs(year, level='year').dropna(subset=['rgdpe','pop'])
    pop_tot = np.sum(sl['pop'])

    weighted = sm.nonparametric.KDEUnivariate(np.log(sl['rgdpe']/sl['pop']))
    weighted.fit(bw=0.3, fft=False, weights=sl['pop'])
    plt.plot(np.exp(weighted.support), 
             weighted.density/np.sum(weighted.density), 
             lw=2, label='{0}'.format(year))

plt.xscale('log')

plt.xticks([200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000], 
           [200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000])
    
plt.legend(frameon=False)

plt.xlim(2e2, 2e5)

plt.title('GDP per capita population-weighed density')
plt.xlabel('GDP per capita (2011 \$)')
plt.ylabel('Population density')

plt.show()
In [9]:
# Plot the histogram of average growth rates

x_70 = pwt.xs(1970, level='year')['rgdpe']/pwt.xs(1970, level='year')['pop']

x_14 = pwt.xs(2014, level='year')['rgdpe']/pwt.xs(2014, level='year')['pop']

g = 100*((x_14/x_70)**(1/(2014-1970))-1)

plt.hist(g.dropna(), np.arange(1.5, 2.5, 0.5), histtype='bar', rwidth=0.8, fc='darkgrey', label='Developed countries')
plt.hist(g.dropna(), np.arange(-10, 2, 0.5), histtype='bar', rwidth=0.8, fc='C3', label='Lagging behind')
plt.hist(g.dropna(), np.arange(2, 10, 0.5), histtype='bar', rwidth=0.8, fc='C2', label='Catching up')

plt.xlim(-4, 8)

plt.title('Histogram of GDP per capita growth rates')
plt.xlabel('Annual GDP per capita growth rate, 1970-2014 (%)')
plt.ylabel('Number of countries')

plt.legend(frameon=False)

plt.show()

What want to explain the following set of facts:

  • There is high dispersion in GDP per capita across countries
  • The developed countries keep growing
  • Some (but not all) developing countries (notably China and India) are catching up to the developed countries
In [10]:
# Recall that in the course we have assumed that production depends on capital and workers

gdp_pw_2014 = (pwt.xs(2014, level='year')['rgdpna']/
               pwt.xs(2014, level='year')['emp'])

k_pw_2014 = (pwt.xs(2014, level='year')['rkna']/
             pwt.xs(2014, level='year')['emp'])

pop_2014 = pwt.xs(2014, level='year')['pop']

plt.scatter(k_pw_2014, gdp_pw_2014, s=pop_2014, alpha=0.5)

plt.xscale('log')
plt.yscale('log')

plt.xlim(1e3, 1e6)
plt.ylim(1e3, 3e5)

# Add a simple trend line
fit = np.polyfit(np.log(k_pw_2014.dropna()), np.log(gdp_pw_2014).dropna(), deg=1)
plt.plot(k_pw_2014.dropna(), np.exp(fit[1]) * k_pw_2014.dropna()**fit[0], color='C3', lw=2)

plt.title('Capital per worker vs GDP per worker in 2014')
plt.xlabel('Capital stock per worker (2011 \$)')
plt.ylabel('GDP per worker (2011 \$)')

plt.show()

The model

Authors: Robert Solow (1956) and Trevor Swan (1956)

Assumptions and simplifications:

  • One sector economy: produces a single good that can be either consumed or invested
  • Complete information, no externalities
  • Markets for the final good and factors of production are perfectly competitive
  • Closed economy and no government
  • Two types of representative agents: firms and households
  • Firms optimize, while households do not
  • Households own capital and labor and rent them to the firms
  • Households save a fixed fraction of their income
  • Output is produced according to a neoclassical production fuction

A consequence of the (Closed economy and no government) assumption is that private savings are equal to private investment. This is an accounting identity and says nothing about any causal relationships between savings and investment.

Start from the national accounting identity and assume no government ($G=0$) and no international trade ($NX=0$):

\begin{align} Y=C+I+\underbrace{G}_{0}+\underbrace{NX}_{0}\quad\longrightarrow\quad Y=C+I \end{align}

Then consider the disposition of households' disposable income $Y^{d}$ between consumption and savings. If there is no government, taxes $T=0$ and disposable income is equal to the economy's output: \begin{align} Y^{d}=C+S\quad\text{and}\quad Y^{d}=Y-\underbrace{T}_{0}\quad\longrightarrow\quad Y=C+S \end{align}

Together those two accounting exercises yield the result that savings are equal to investment: \begin{align} Y=C+I\quad\text{and}\quad Y=C+S\quad\longrightarrow\quad S=I \end{align}

Three core equations

  • Capital accumulation (accounting identity)
\begin{align} K_{t+1} = I_{t} + \left( 1-\delta \right) K_{t} \end{align}
  • Investment / saving decisions: households save a constant fraction $s$ of their income (behavioral assumption)
\begin{align} I_{t} = S_{t} = s \cdot Y_{t} \end{align}
  • Output is produced using capital $K$ and labor $L$, using technology $A$, and the production function $F$ is neoclassical (functional restriction)
\begin{align} Y_{t} = F \left( K_{t}, L_{t}, A_{t} \right) \end{align}

Fundamental equation of the Solow-Swan model

By combining the three core equations of the model, we get the following relationship:

\begin{align} K_{t+1} = s F \left( K_{t}, L_{t}, A_{t} \right) + \left( 1-\delta \right) K_{t} \end{align}

Next we will use the properties of the neoclassical production function to simplify the above equation.

Neoclassical production function

A production function describes how capital $K$ and labor $L$, using technology $A$, is transformed into output $Y$:

\begin{align} Y = F \left( K, L, A \right) \end{align}

A neoclassical production function $F$ has the following properties:

  • Continuous and at least twice differentiable

  • Constant returns to scale in $K$ and $L$. Multiplying both capital and labor inputs by a certain proportion $z$ translates to multiplying produced output by that same proportion $z$:

\begin{align} F\left(z \cdot K, \cdot z \cdot L, A \right) = z \cdot F \left( K, L, A \right) = z \cdot Y \quad \text{for all } z > 0 \end{align}
  • Positive but diminishing marginal products of $K$ and $L$:
\begin{align} \frac{\partial F \left( K, L, A \right)}{\partial K} \equiv F_{K} \left( K, L, A \right) > 0 \quad &\text{and} \quad \frac{\partial^{2} F \left( K, L, A \right)}{\partial K^{2}} \equiv F_{KK} \left( K, L, A \right) < 0 \\ \frac{\partial F \left( K, L, A \right)}{\partial L} \equiv F_{L} \left( K, L, A \right) > 0 \quad &\text{and} \quad \frac{\partial^{2} F \left( K, L, A \right)}{\partial L^{2}} \equiv F_{LL} \left( K, L, A \right) < 0 \end{align} \begin{align} \lim_{K \to 0} F_{K} \left( K, L, A \right) = \infty \quad &\text{and} \quad \lim_{K \to \infty} F_{K} \left( K, L, A \right) = 0 \quad \text{for all } L > 0 \\ \lim_{L \to 0} F_{L} \left( K, L, A \right) = \infty \quad &\text{and} \quad \lim_{L \to \infty} F_{L} \left( K, L, A \right) = 0 \quad \text{for all } K > 0 \end{align}
  • (Optional) Necessity of both inputs:
\begin{align} F \left( 0, L, A \right) = F \left( K, 0, A \right) = 0 \end{align}

Solow-Swan model with population growth

First let us consider the following case. Population $N$ (and thus labor force $L$) grows at a constant (possibly negative) rate $n$, while technology is constant at a level $\bar{A}$:

\begin{align} \frac{L_{t+1}}{L_{t}} = \frac{N_{t+1}}{N_{t}} = 1+n \end{align}

It is very convenient to define output per worker $y$ and capital per worker $k$:

\begin{align} y_{t} \equiv \frac{Y_{t}}{L_{t}} \quad \text{and} \quad k_{t} \equiv \frac{K_{t}}{L_{t}} \end{align}

Use the constant returns to scale property of the neoclassical production function:

\begin{align} y_{t} = \frac{Y_{t}}{L_{t}} = \frac{1}{L_{t}} \cdot F \left( K_{t}, L_{t}, \bar{A} \right) = F \left( \frac{1}{L_{t}} \cdot K_{t}, \frac{1}{L_{t}} \cdot L_{t}, \bar{A} \right) = F \left( k_{t}, 1, \bar{A} \right) \equiv f \left( k_{t} \right) \end{align}

where $f$ is called the production function in the intensive (per worker) form.

Recall the fundamental equation of the model:

\begin{align} K_{t+1} = s F \left( K_{t}, L_{t}, A_{t} \right) + \left( 1-\delta \right) K_{t} \end{align}

We can now express it in terms of variables per worker:

\begin{align} K_{t+1} &= s F \left( K_{t}, L_{t}, \bar{A} \right) + \left( 1-\delta \right) K_{t} \qquad | \quad : L_{t} \\ \frac{K_{t+1}}{L_{t}} &= s \frac{F \left( K_{t}, L_{t}, \bar{A} \right)}{L_{t}} + \left( 1-\delta \right) \frac{K_{t}}{L_{t}} \\ \frac{L_{t+1}}{L_{t}} \cdot \frac{K_{t+1}}{L_{t+1}} &= s f \left( k_{t} \right) + \left( 1-\delta \right) k_{t} \\ \left( 1+n \right) k_{t+1} &= s f \left( k_{t} \right) + \left( 1-\delta \right) k_{t} \end{align}

Finally, we get an equation that determines next period's level of capital stock per worker as a function of current period's level of capital per worker and model parameters:

\begin{align} k_{t+1} = \frac{ s f \left( k_{t} \right) + \left( 1-\delta \right) k_{t} }{1+n} \end{align}

Let us draw an example plot below, assuming that the production function is of the following Cobb-Douglas form:

\begin{align} F \left( K, L \right) = \bar{A} K^{\alpha} L^{1-\alpha} \quad \longrightarrow \quad f \left( k \right) = \bar{A} k^{\alpha} \end{align}
In [11]:
# Parameter values (some of them are exaggerated to make the plot easier to read)
A = 1
α = 1/3
δ = 0.75
n = 0.05
s = 0.8

# Production function in intensive form
def f(k):
    return k**α

# Function for k_{t+1}
def k_next(k):
    return ( s*A*f(k) + (1-δ)*k ) / (1+n)

# Plot range
k_star = ((s*A)/(δ+n))**(1/(1-α))
kk = np.linspace(0, 2*k_star, 1e3)

# Make "square" plot
plt.subplots(figsize = (5, 5))

# Plot k_{t+1} function as well as k_{t+1}=k_{t} line
plt.plot(kk, k_next(kk), lw=2)
plt.plot(kk, kk)

plt.hlines(k_star, 0, k_star, linestyle='dashed', lw=0.5)
plt.vlines(k_star, 0, k_star, linestyle='dashed', lw=0.5)

plt.title('Next period vs current period level of capital per worker')
plt.xlabel('$k_{t}$')
plt.ylabel('$k_{t+1}$')

plt.show()

print('')
print('Steady state level of capital per worker =', k_star)
Steady state level of capital per worker = 1.0

From the plot we can easily see that there is a level of $k$ for which the next period and current period level of capital are the same. We will call this level a steady state level of capital per worker, and we will denote it with $k^{*}$. The properties of the neoclassical production function guarantee that there is only one, positive level of $k^{*}$.

Let us find the expression for the steady state level of capital per worker under the Cobb-Douglas production function, by setting $k_{t+1} = k_{t} = k^{*}$:

\begin{align} \left( 1+n \right) k^{*} &= s \bar{A} \left( k^{*} \right)^{\alpha} + \left( 1-\delta \right) k^{*} \\ \left( \delta+n \right) k^{*} &= s \bar{A} \left( k^{*} \right)^{\alpha} \\ \left( k^{*} \right)^{1-\alpha} &= \frac{s \bar{A}}{\delta+n} \\ k^{*} &= \left( \frac{s \bar{A}}{\delta+n} \right)^{1/(1-\alpha)} \end{align}

We can also obtain the steady state level of output per worker:

\begin{align} y^{*} = f \left( k^{*} \right) = \bar{A} \left( k^{*} \right)^{\alpha} = \bar{A} \left( \frac{s \bar{A}}{\delta+n} \right)^{\alpha/(1-\alpha)} \end{align}

It is also useful to take a look at the dynamics of capital per worker, to see how a steady state can be reached:

\begin{align} k_{t+1} &= \frac{ s f \left( k_{t} \right) + \left( 1-\delta \right) k_{t} }{1+n} \qquad | \quad - k_{t} \\ k_{t+1} - k_{t} &= \frac{ s f \left( k_{t} \right) - \left( \delta + n \right) k_{t} }{1+n} \\ \Delta k_{t+1} &= \frac{ s f \left( k_{t} \right) - \left( \delta + n \right) k_{t} }{1+n} \qquad | \quad : k_{t} \\ \frac{\Delta k_{t+1}}{k_{t}} &= \frac{ s f \left( k_{t} \right) / k_{t} - \left( \delta + n \right) }{1+n} \end{align}

The above formula gives the expression for the rate of growth of capital per worker. Let us plot the result below (again assuming Cobb-Douglas production function).

In [12]:
# Plot Δk_{t+1}/k_{t} function
def Δk_k(k):
    return ( s*A*f(k)/k - (δ+n) ) / (1+n)

plt.plot(kk[1:], Δk_k(kk[1:]), lw=2)
plt.hlines(0, 0, 2*k_star, lw=0.5)
plt.vlines(k_star, -2, 0, linestyle='dashed', lw=0.5)

plt.ylim(-2, 10)

plt.title('Rate of growth of capital per worker')
plt.xlabel('$k_{t}$')
plt.ylabel('$\Delta k_{t+1} / k_{t}$')

plt.show()

# Plot k over time, assuming that k_0 < k_ss
T = 1+20
k_t = np.zeros(T)
k_0 = 0.1 * k_star
k_t[0] = k_0

for t in range(T-1):
    k_t[t+1] = k_next(k_t[t])
    
plt.plot(k_t, lw=2)

plt.hlines(k_star, 0, T-1, linestyle='dashed', lw=0.5)

plt.ylim(0, 1.2)

plt.title('Capital per worker over time')
plt.xlabel('Period')
plt.ylabel('Capital per worker')

plt.show()

Model predictions

Recall the expression for the steady state level of output per worker (assuming Cobb-Douglas production function):

\begin{align} y^{*} = f \left( k^{*} \right) = \bar{A} \left( k^{*} \right)^{\alpha} = \bar{A} \left( \frac{s \bar{A}}{\delta+n} \right)^{\alpha/(1-\alpha)} \end{align}

As can be easily seen above, the model predicts that:

  • countries with high saving / investment rate $s$ and technology level $\bar{A}$ will have higher levels of steady state capital and output per worker
  • countries with high depreciation rate $\delta$ and population growth rate $n$ will have lower levels of steady state capital and output per worker

Let us now take a look at the data to see whether the model's predictions are verified.

In [13]:
# Construct average values for investment and population growth rates
s = np.zeros(len(countries))
n = np.zeros(len(countries))
y = np.zeros(len(countries))
N = np.zeros(len(countries))

for i, country in enumerate(countries):
    s[i] = 100*np.mean(pwt.loc[country]['csh_i'])
    n[i] = 100*np.mean(pwt.loc[country]['pop'].pct_change())
    y[i] = pwt.loc[country, 2014]['rgdpo']/pwt.loc[country, 2014]['emp']
    N[i] = pwt.loc[country, 2014]['pop']

d = {'y': y, 's': s, 'n': n, 'N': N}
dta = pd.DataFrame(data=d, index=countries)
dta.head()
Out[13]:
N n s y
country
Aruba 0.103441 1.296789 42.210510 77942.781250
Angola 24.227524 3.108949 33.841056 25559.947266
Anguilla 0.014460 1.881208 58.721423 NaN
Albania 2.889676 0.683705 16.737467 36037.253906
United Arab Emirates 9.086139 8.773528 36.438182 107243.687500
In [14]:
# Investment rate vs GDP per worker
plt.scatter(s, y, s=N, alpha=0.5)

plt.yscale('log')

plt.yticks([1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000],
           [1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000])

plt.xlim(0, 50)
plt.ylim(1e3, 2e5)

plt.title('Investment rate vs GDP per worker')
plt.xlabel('Average investment share of GDP, 1950-2014 (%)')
plt.ylabel('GDP per worker in 2014 (2011 \$)')

plt.show()
In [15]:
# Population growth rate vs GDP per worker
plt.scatter(n, y, s=N, alpha=0.5)

plt.yscale('log')

plt.yticks([1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000],
           [1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000])

plt.xlim(-2, 5)
plt.ylim(1e3, 2e5)

plt.title('Population growth rate vs GDP per worker')
plt.xlabel('Average population growth rate, 1950-2014 (%)')
plt.ylabel('GDP per worker in 2014 (2011 \$)')

plt.show()

So it seems that the model correctly predicts the sign of the relationships.

However, at this stage the model cannot explain the continued increase in GDP per capita in the developed countries, as in the steady state, by definition, the rate of growth of capital per worker, as well as output per worker, is exactly 0.

This actually has profound consequences for growth theory: capital accumulation cannot be the mechanism responsible for long-run growth! Therefore, to explain the continued growth in GDP per capita of developed countries (see below), we need to expand our analysis and allow for improvements in technology.

In [16]:
# Plot of GDP per capita of selected developed countries

(pwt.loc['United States']['rgdpe']/pwt.loc['United States']['pop']).plot(lw=2, label='United States')
(pwt.loc['United Kingdom']['rgdpe']/pwt.loc['United Kingdom']['pop']).plot(lw=2, label='United Kingdom')
(pwt.loc['France']['rgdpe']/pwt.loc['France']['pop']).plot(lw=2, label='France')
(pwt.loc['Switzerland']['rgdpe']/pwt.loc['Switzerland']['pop']).plot(lw=2, label='Switzerland')
(pwt.loc['Germany']['rgdpe']/pwt.loc['Germany']['pop']).plot(lw=2, label='Germany')

plt.xlim(1950, 2014)

plt.yscale('log')
plt.ylim(5000, 10000)

plt.yticks([5000, 10000, 20000, 50000, 100000],
           [5000, 10000, 20000, 50000, 100000])

plt.legend(frameon=False)

plt.title('GDP per capita in developed countries')
plt.xlabel('Year')
plt.ylabel('GDP per capita (2011 \$)')

plt.show()

Balanced growth path

Consider the fundamental equation of a one-sector closed economy:

\begin{align} K_{t+1} = I_{t} + \left( 1-\delta \right) K_{t} \end{align}

And rewrite it in difference form:

\begin{align} \Delta K_{t+1} \equiv K_{t+1} - K_{t} = I_{t} - \delta K_{t} = Y_{t}-C_{t}-\delta K_{t} \end{align}

It turns out that this equation generates a lot of interesting results.

Definition: balanced growth path (BGP)

A balanced growth path is a path $\left\{ Y_{t},K_{t},C_{t}\right\} _{t=0}^{\infty}$ along which the quantities $Y_{t}$, $K_{t}$ and $C_{t}$ are positive and grow at constant (possibly 0) rates, which we denote $g_{Y}$, $g_{K}$ and $g_{C}$, respectively.

Proposition: equivalence of balanced growth and constancy of key ratios

Let $\left\{ Y_{t},K_{t},C_{t}\right\} _{t=0}^{\infty}$ be a path along which $Y_{t}$, $K_{t}$, $C_{t}$ and $I_{t}=Y_{t}-C_{t}$ are positive for all $t\geq0$. Then, given the capital accumulation equation, the following holds:

(1) If there is balanced growth, then $g_{Y}=g_{K}=g_{C}=g_{I}$ and the ratios $K/Y$, $C/Y$ and $I/Y$ are constant.

(2) If $K/Y$ and $C/Y$ are constant, then $Y$, $K$, $C$ and $I$ all grow at the same constant rate, i.e. there is not only balanced growth, but balanced growth where $g_{Y}=g_{K}=g_{C}=g_{I}$.

Proof of (1)

Consider an economy on a balanced growth path. Then, by definition, $g_{Y}$, $g_{K}$ and $g_{C}$ are constant. If we use the capital accumulation equation, we get the result that $g_{I}=g_{K}$:

\begin{align} \Delta K_{t+1} & =I_{t}-\delta K_{t}\quad|\quad:K_{t}\\ g_{K}\equiv\frac{\Delta K_{t+1}}{K_{t}} & =\frac{I_{t}}{K_{t}}-\delta\\ \frac{I_{t}}{K_{t}} & =g_{K}+\delta \end{align}

Since the right hand side of the above equation is constant, then the $I/K$ ratio is constant and that means that the rates of growth of $I$ and $K$ have to be identical.

Focus now on the national accounting relationship:

\begin{align} Y_{t} = C_{t} + I_{t} \quad \longrightarrow \quad \Delta Y_{t+1} = \Delta C_{t+1} + \Delta I_{t+1} \end{align}\begin{align} g_{Y} & \equiv \frac{\Delta Y_{t+1}}{Y_{t}} = \frac{\Delta C_{t+1}}{Y_{t}} + \frac{\Delta I_{t+1}}{Y_{t}} = \frac{\Delta C_{t+1}}{C_{t}} \cdot \frac{C_{t}}{Y_{t}} + \frac{\Delta I_{t+1}}{I_{t}} \cdot \frac{I_{t}}{Y_{t}} \\ g_{Y} & =g_{C}\frac{C_{t}}{Y_{t}} + g_{I}\frac{Y_{t}-C_{t}}{Y_{t}} = \frac{C_{t}}{Y_{t}}\left(g_{C}-g_{I}\right)+g_{I}\\ g_{Y} & =\frac{C_{t}}{Y_{t}}\left(g_{C}-g_{K}\right)+g_{K} \end{align}

where in the last line the equality between growth rates of $I$ and $K$ was used.

We have now two possibilities: either $g_{C}=g_{K}$ (and in consequence $g_{Y}=g_{K}$) or $g_{C} \neq g_{K}$.

Let us assume that $g_{C} \neq g_{K}$. Then we can rewrite the above expression as:

\begin{align} \frac{C_{t}}{Y_{t}}=\frac{g_{Y}-g_{K}}{g_{C}-g_{K}} \end{align}

The right hand side contains only growth rates, which are constant by the definition of the BGP. That means that the $C/Y$ ratio is constant as well, and $g_{C}=g_{Y}$. But this implies that the right hand side is equal to 1 and $C_{t}=Y_{t}$, which contradicts our assumption that $I_{t}=Y_{t}-C_{t}$ is positive.

That means that the assumption $g_{C} \neq g_{K}$ was wrong and $g_{C}=g_{K}$. This also implies that $g_{Y}=g_{K}=g_{I}=g_{C}$.

Proof of (2)

Suppose that $K/Y$ and $C/Y$ are constant. Then $g_{Y}=g_{K}=g_{C}$ and as a consequence ($I/Y=1-C/Y$) $g_{Y}=g_{I}=g_{K}$. Now we need to show that the growth rates are also constant. To that end we use the capital accumulation equation:

\begin{align} \Delta K_{t+1} & =I_{t}-\delta K_{t}\quad|\quad:K_{t}\\ g_{K} & =\frac{I_{t}}{K_{t}}-\delta \end{align}

Since $g_{I}=g_{K}$ then $I/K$ is constant and in consequence $g_{K}$ and all other key growth rates are constant.

Note that (1) means that any economy on a balanced growth path has to generate constant key ratios. (2) ensures that if we observe constant ratios, the economy is on a balanced growth path.

Let us now check whether the United States economy is on its balanced growth path.

In [17]:
# Capital to GDP ratio in the United States
(pwt.loc['United States']['rkna']/pwt.loc['United States']['rgdpna']).plot(lw=2)

plt.xlim(1950, 2014)
plt.ylim(2, 4.5)

plt.title('Capital to GDP ratio in the United States')
plt.xlabel('Year')
plt.ylabel('$K/Y$ ratio')

plt.show()

# Investment to GDP ratio in the United States
pwt.loc['United States']['csh_i'].plot(lw=2)

plt.xlim(1950, 2014)
plt.ylim(0, 0.5)

plt.title('Investment to GDP ratio in the United States')
plt.xlabel('Year')
plt.ylabel('$I/Y$ ratio')

plt.show()

# Consumption to GDP ratio in the United States
pwt.loc['United States']['csh_c'].plot(lw=2)

plt.xlim(1950, 2014)
plt.ylim(0.5, 1)

plt.title('Consumption to GDP ratio in the United States')
plt.xlabel('Year')
plt.ylabel('$I/Y$ ratio')

plt.show()

In the United States, both the $K/Y$ and $I/Y$ ratios were stable since 1950, but the $C/Y$ ratio exhibits since the 1980s an increasing trend, probably linked with an increasing trade deficit.

In [18]:
# Net exports to GDP ratio in the United States
(pwt.loc['United States']['csh_x']+pwt.loc['United States']['csh_m']+pwt.loc['United States']['csh_r']).plot(lw=2)
plt.hlines(0, 1950, 2014, lw=0.5)

plt.xlim(1950, 2014)

plt.title('Net exports to GDP ratio in the United States')
plt.xlabel('Year')
plt.ylabel('$(X-M)/Y$ ratio')

plt.show()

Technological progress

There are at least three possibilities in how technological progress might manifest itself in our production function. Let $\tilde{F}$ denote the "true" production function and $\tilde{A}$ the "true" form of technological progress:

  • Hicks-neutral: technology acts as a multiplicative constant: $\tilde{F}\left(K_{t},L_{t},\tilde{A}_{t}\right)=A_{t}\cdot F\left(K_{t},L_{t}\right)$

  • Solow-neutral: technology increases productivity of capital: $\tilde{F}\left(K_{t},L_{t},\tilde{A}_{t}\right)=F\left(A_{t}\cdot K_{t},L_{t}\right)$

  • Harrod-neutral: technology increases productivity of labor: $\tilde{F}\left(K_{t},L_{t},\tilde{A}_{t}\right)=F\left(K_{t},A_{t}\cdot L_{t}\right)$

Obviously the technological progress might manifest itself as a combination of the above possibilities: $\tilde{F}\left(K_{t},L_{t},\tilde{A}_{t}\right)=A_{F,t}\cdot F\left(A_{K,t}\cdot K_{t},A_{L,t}\cdot L_{t}\right)$

Despite all of the above forms seem ex ante plausible, balanced growth requires that the "true" production function has a representation of the Harrod-neutral form. Note that it does not mean that literally all technological progress directly increases labor productivity, just that the "true" production function can be rewritten in the required functional form.

Theorem: Uzawa's (1961) balanced growth path theorem

Let $\left\{ Y_{t},K_{t},C_{t}\right\} _{t=0}^{\infty}$, where $0

Then a necessary condition for this path to be a balanced growth path is that along the path it holds that:

\begin{align} Y_{t}=\tilde{F}\left(K_{t},L_{t},\tilde{A}_{t}\right)=F\left(K_{t},A_{t}\cdot L_{t}\right) \end{align}

where $A_{t}=\exp\left(g \cdot t\right)$ with $g \equiv g_{Y}-n$.

Proof

Suppose the path $\left\{ Y_{t},K_{t},C_{t}\right\} _{t=0}^{\infty}$ is a balanced growth path. Then $g_{Y}$ and $g_{K}$ are equal and constant. As a consequence, we can write $Y_{t}=Y_{0}\cdot\exp\left(g_{Y}\cdot t\right)$ and $K_{t}=K_{0}\cdot\exp\left(g_{K}\cdot t\right)$. We then have:

\begin{align} Y_{t}\cdot e^{-g_{Y}t}=Y_{0}=\tilde{F}\left(K_{0},L_{0},\tilde{A}_{0}\right)=\tilde{F}\left(K_{t}\cdot e^{-g_{K}t},L_{t}\cdot e^{-nt},\tilde{A}_{0}\right) \end{align}

Because $g_{Y}=g_{K}$ and the function $\tilde{F}$ satifies constant returns to scale, we can rewrite the above equation as:

\begin{align} Y_{t}=\tilde{F}\left(K_{t}\cdot e^{-g_{K}t}\cdot e^{g_{Y}t},L_{t}\cdot e^{-nt}\cdot e^{g_{Y}t},\tilde{A}_{0}\right)=\tilde{F}\left(K_{t},L_{t}\cdot e^{\left(g_{Y}-n\right)t},\tilde{A}_{0}\right) \end{align}

Note that in the above formulation $\tilde{A}$ is reduced to a constant $\tilde{A}_{0}$. Therefore, there exists a function $F\left(K,L\right)$ such that:

\begin{align} Y_{t}=F\left(K_{t},L_{t}\cdot e^{\left(g_{Y}-n\right)t}\right) \end{align}

which we can rewrite as

\begin{align} Y_{t}=F\left(K_{t},A_{t}\cdot L_{t}\right) \end{align}

where $A_{t}=\exp\left[\left(g_{Y}-n\right) t\right]$ and $g=g_{Y}-n$ is the rate of "rewritten" technology growth.

Solow-Swan model with technological improvements

Accordingly, we will now assume that the production function has the following form:

\begin{align} Y_{t} = F \left( K_{t}, A_{t} L_{t} \right) \end{align}

And that technology $A$ improves at a constant rate $g$:

\begin{align} \frac{A_{t+1}}{A_{t}} = 1+g \end{align}

Define output per effective labor $\hat{y}$ and capital per effective labor $\hat{k}$:

\begin{align} \hat{y}_{t} \equiv \frac{Y_{t}}{A_{t} L_{t}} \quad \text{and} \quad \hat{k}_{t} \equiv \frac{K_{t}}{A_{t} L_{t}} \end{align}

Again use the constant returns to scale property of the neoclassical production function:

\begin{align} \hat{y}_{t} = \frac{Y_{t}}{A_{t} L_{t}} = \frac{1}{A_{t} L_{t}} \cdot F \left( K_{t}, A_{t} L_{t} \right) = F \left( \frac{1}{A_{t} L_{t}} \cdot K_{t}, \frac{1}{A_{t} L_{t}} \cdot A_{t} L_{t} \right) = F \left( \hat{k}_{t}, 1 \right) \equiv f \left( \hat{k}_{t} \right) \end{align}

where now $f$ denotes the production function per effective labor.

Recall the fundamental equation of the model:

\begin{align} K_{t+1} = s F \left( K_{t}, A_{t} L_{t} \right) + \left( 1-\delta \right) K_{t} \end{align}

Express it in terms of variables per effective labor:

\begin{align} K_{t+1} &= s F \left( K_{t}, A_{t} L_{t} \right) + \left( 1-\delta \right) K_{t} \qquad | \quad : A_{t} L_{t} \\ \frac{K_{t+1}}{A_{t} L_{t}} &= s \frac{F \left( K_{t}, A_{t} L_{t} \right)}{A_{t} L_{t}} + \left( 1-\delta \right) \frac{K_{t}}{A_{t} L_{t}} \\ \frac{L_{t+1}}{L_{t}} \cdot \frac{A_{t+1}}{A_{t}} \cdot \frac{K_{t+1}}{A_{t+1} L_{t+1}} &= s f \left( \hat{k}_{t} \right) + \left( 1-\delta \right) \hat{k}_{t} \\ \left( 1+n \right) \left( 1+g \right) \hat{k}_{t+1} &= s f \left( \hat{k}_{t} \right) + \left( 1-\delta \right) \hat{k}_{t} \end{align}

As before, we can find the steady state level of capital per effective labor, assuming a Cobb-Douglas production function:

\begin{align} F \left( K, AL \right) = K^{\alpha} \left( AL \right)^{1-\alpha} \quad \longrightarrow \quad f \left( \hat{k} \right) = \hat{k}^{\alpha} \end{align}\begin{align} \left( 1+n+g+ng \right) \hat{k}_{t+1} &= s f \left( \hat{k}_{t} \right) + \left( 1-\delta \right) \hat{k}_{t} \\ \left( 1+n+g+ng \right) \hat{k}^{*} &= s \left( \hat{k}^{*} \right)^{\alpha} + \left( 1-\delta \right) \hat{ss}_{t} \\ \left( \delta+n+g+ng \right) \hat{k}^{*} &= s \left( \hat{k}^{*} \right)^{\alpha} \\ \left( \hat{k}^{*} \right)^{1-\alpha} &= \frac{s}{\delta+n+g+ng} \\ \hat{k}^{*} &= \left( \frac{s}{\delta+n+g+ng} \right)^{1/(1-\alpha)} \\ \hat{k}^{*} &\approx \left( \frac{s}{\delta+n+g} \right)^{1/(1-\alpha)} \end{align}

Where the approximation above utilizes the fact that the product of $n$ and $g$ is very small.

GDP per worker along the Balanced Growth Path

In the case of positive rate of technologial improvements, even if capital per effective labor converges to the steady state, output per worker continues to grow (at a rate $g$):

\begin{align} y_{t} = \frac{Y_{t}}{L_{t}} = A_{t} \cdot \frac{Y_{t}}{A_{t} L_{t}} = A_{t} \cdot \hat{y}_{t} = A_{t} \cdot f \left( \hat{k}_{t} \right) \end{align}\begin{align} \frac{\Delta y_{t+1}}{y_{t}} = \frac{A_{t+1} \cdot f \left( \hat{k}_{t+1} \right) - A_{t} \cdot f \left( \hat{k}_{t} \right)} {A_{t} \cdot f \left( \hat{k}_{t} \right)} = \frac{A_{t+1}}{A_{t}} \cdot \frac{f \left( \hat{k}_{t+1} \right)}{f \left( \hat{k}_{t} \right)} - 1 \end{align}

So along the balanced growth path when $\hat{k}_{t+1} = \hat{k}_{t} = \hat{k}^{*}$:

\begin{align} g_{y}^{*} = \frac{\Delta y_{t+1}^{*}}{y_{t}^{*}} = \frac{A_{t+1}}{A_{t}} \cdot \frac{f \left( \hat{k}^{*} \right)}{f \left( \hat{k}^{*} \right)} - 1 = \left( 1 + g \right) \cdot 1 - 1 = g \end{align}

And the value of output per worker along the balanced growth path is equal to:

\begin{align} y_{t}^{*} = A_{t} \cdot \left( \frac{s}{\delta+n+g} \right)^{\alpha/(1-\alpha)} \end{align}

If we take the logarithms of the above equation, we get:

\begin{align} \log y_{t}^{*} &= \log \left( A_{0} \cdot \left( 1+g \right)^{t} \right) + \frac{\alpha}{1-\alpha} \log s - \frac{\alpha}{1-\alpha} \log \left( \delta+n+g \right) \\ \log y_{t}^{*} &= \log A_{0} + t \cdot \log \left( 1+g \right) + \frac{\alpha}{1-\alpha} \log s - \frac{\alpha}{1-\alpha} \log \left( \delta+n+g \right) \end{align}

The above equation can be rewritten as an empirical model for a regression:

\begin{align} \log y_{t} &= a_{0} + a_{1} \log s + a_{2} \log \left( \delta+n+g \right) + \epsilon \end{align}

where $a_{0}$ is a constant and $\epsilon$ is a country-specific shock to initial technology and the distance from the balanced growth path.

Additionally, one can run a restricted regression:

\begin{align} \log y_{t} &= a_{0} + a_{1} \left[ \log s - \log \left( \delta+n+g \right) \right] + \epsilon \end{align}

where:

\begin{align} a_{1} = -a_{2} = \frac{\alpha}{1-\alpha} \end{align}

This is the first empirical exercise in Mankiw, Romer and Weil (1992), which we will replicate below.

In [19]:
# Read in Mankiw, Romer and Weil (1992) data
mrw = pd.read_stata('MRW/MRW1992.dta')
mrw_countries = mrw['country']
mrw.head()
Out[19]:
country N I O Y60 Y85 Y_growth pop_growth invest school
0 Algeria 1 1 0 2485.0 4371.0 4.8 2.6 24.100000 4.5
1 Angola 1 0 0 1588.0 1171.0 0.8 2.1 5.800000 1.8
2 Benin 1 0 0 1116.0 1071.0 2.2 2.4 10.800000 1.8
3 Botswana 1 1 0 959.0 3671.0 8.6 3.2 28.299999 2.9
4 Burkina Faso 1 0 0 529.0 857.0 2.9 0.9 12.700000 0.4
In [20]:
# Prepare variables for regression
mrw['y_85'] = np.log(mrw['Y85'])
mrw['s'] = np.log(mrw['invest']/100)
mrw['δ_n_g'] = np.log(0.05+mrw['pop_growth']/100)
mrw['restricted'] = mrw['s'] - mrw['δ_n_g']
In [21]:
# Run regression on the non-oil countries sample
mrw_N = mrw[mrw['N']==1]
print('\t Non-oil countries')
mrw_results = smf.ols('y_85 ~ s + δ_n_g', data=mrw_N).fit()
print(mrw_results.summary())
	 Non-oil countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   y_85   R-squared:                       0.601
Model:                            OLS   Adj. R-squared:                  0.592
Method:                 Least Squares   F-statistic:                     71.51
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           1.13e-19
Time:                        20:50:31   Log-Likelihood:                -101.04
No. Observations:                  98   AIC:                             208.1
Df Residuals:                      95   BIC:                             215.8
Df Model:                           2                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      5.4299      1.584      3.428      0.001       2.285       8.574
s              1.4240      0.143      9.951      0.000       1.140       1.708
δ_n_g         -1.9898      0.563     -3.532      0.001      -3.108      -0.871
==============================================================================
Omnibus:                        2.881   Durbin-Watson:                   1.453
Prob(Omnibus):                  0.237   Jarque-Bera (JB):                2.631
Skew:                          -0.401   Prob(JB):                        0.268
Kurtosis:                       2.976   Cond. No.                         81.7
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
In [22]:
# Run restricted regression on the non-oil countries sample
print('\t Restricted regression')
print('\t Non-oil countries')
mrw_results_restricted = smf.ols('y_85 ~ restricted', data=mrw_N).fit()
print(mrw_results_restricted.summary())
print('')
print('Implied α =', mrw_results_restricted.params[1]/(1+mrw_results_restricted.params[1]))
	 Restricted regression
	 Non-oil countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   y_85   R-squared:                       0.597
Model:                            OLS   Adj. R-squared:                  0.593
Method:                 Least Squares   F-statistic:                     142.4
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           1.13e-20
Time:                        20:50:31   Log-Likelihood:                -101.46
No. Observations:                  98   AIC:                             206.9
Df Residuals:                      96   BIC:                             212.1
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      6.8724      0.121     56.995      0.000       6.633       7.112
restricted     1.4880      0.125     11.934      0.000       1.241       1.735
==============================================================================
Omnibus:                        4.010   Durbin-Watson:                   1.421
Prob(Omnibus):                  0.135   Jarque-Bera (JB):                3.720
Skew:                          -0.477   Prob(JB):                        0.156
Kurtosis:                       3.015   Cond. No.                         3.15
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Implied α = 0.598069768055

So it seems that our empirical model is quite successful, as it is able to explain aroun 60% of total variation in GDP per worker across countries with the observables suggested by the theory.

There is however a problem: implied level of $\alpha$ is well above $0.5$, whereas economists usually think that $\alpha \in [0.3, 0.4]$.

Let us turn back to theory and see whether we can construct a way to recover $\alpha$ from other data.

Firms' profit maximization problem

Firms choose employment $L$ and rent such levels of capital $K$ which maximizes their profits:

\begin{align} \max_{K, L} \quad & \Pi = Y - w L - r^{k} K \\ \text{subject to} \quad & Y = K^{\alpha} \left( AL \right)^{1-\alpha} \end{align}

where $w$ is real wage and $r^{k}$ is the rental rate of capital. Rewrite the problem:

\begin{align} \max_{K, L} \quad & \Pi = K^{\alpha} \left( AL \right)^{1-\alpha} - w L - r^{k} K \end{align}

Derive the first order conditions:

\begin{align} \frac{\partial \Pi}{\partial K} &= \alpha K^{\alpha-1} \left( AL \right)^{1-\alpha} - r^{k} = 0 \quad \quad \,\,\, \longrightarrow \quad r^{k} = \alpha \frac{Y}{K} \\ \frac{\partial \Pi}{\partial L} &= \left( 1-\alpha \right) K^{\alpha} A^{1-\alpha} L^{-\alpha} - w = 0 \quad \longrightarrow \quad w = \left( 1-\alpha \right) \frac{Y}{L} \end{align}

Now take a look at the share of labor income in GDP:

\begin{align} \frac{wL}{Y} = \frac{\left( 1-\alpha \right) \dfrac{Y}{L} \cdot L}{Y} = 1-\alpha \end{align}

We can see that we can recover the value of $\alpha$ via the following formula:

\begin{align} \alpha = 1 - \frac{wL}{Y} \end{align}
In [23]:
(1-pwt.loc['United States']['labsh']).plot(lw=2)

plt.xlim(1950, 2014)
plt.ylim(0.2, 0.5)

plt.title(r'Value of $\alpha$ in United States (obtained from labor share)')
plt.xlabel('Year')
plt.ylabel(r'$\alpha$')

plt.show()

Therefore, MRW consider the following modification of the Solow-Swan model:

  • Production function:
\begin{align} Y = K^{\alpha} H^{\beta} \left( AL \right)^{1-\alpha-\beta} \end{align}

where $H$ denotes the stock of human capital.

  • Balanced growth path level of GDP per worker:
\begin{align} \log y_{t}^{*} = \log A_{0} + t \cdot \log \left( 1+g \right) - \frac{\alpha+\beta}{1-\alpha-\beta} \log \left( \delta+n+g \right) + \frac{\alpha}{1-\alpha-\beta} \log s_{k} + \frac{\beta}{1-\alpha-\beta} \log s_{h} \end{align}

where $s_{k}$ and $s_{h}$ denote saving/investment rates in physical and human capital

In [24]:
# Add in log of s_h
mrw['s_h'] = np.log(mrw['school'])

# Run regression on the non-oil countries sample
print('\t Non-oil countries')
mrw_h_results = smf.ols('y_85 ~ s + δ_n_g + s_h', data=mrw[mrw['N']==1]).fit()
print(mrw_h_results.summary())
	 Non-oil countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   y_85   R-squared:                       0.786
Model:                            OLS   Adj. R-squared:                  0.779
Method:                 Least Squares   F-statistic:                     114.8
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           2.54e-31
Time:                        20:50:31   Log-Likelihood:                -70.576
No. Observations:                  98   AIC:                             149.2
Df Residuals:                      94   BIC:                             159.5
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      3.8305      1.180      3.245      0.002       1.487       6.174
s              0.6967      0.133      5.245      0.000       0.433       0.960
δ_n_g         -1.7452      0.416     -4.196      0.000      -2.571      -0.919
s_h            0.6545      0.073      9.001      0.000       0.510       0.799
==============================================================================
Omnibus:                        2.001   Durbin-Watson:                   2.124
Prob(Omnibus):                  0.368   Jarque-Bera (JB):                2.008
Skew:                          -0.330   Prob(JB):                        0.366
Kurtosis:                       2.764   Cond. No.                         89.0
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
In [25]:
# Add in restrictions
mrw['restricted_h'] = mrw['s_h'] - mrw['δ_n_g']
mrw_N = mrw[mrw['N']==1]

# Run restricted regression on the non-oil countries sample
print('\t Restricted regression')
print('\t Non-oil countries')
mrw_h_results_restricted = smf.ols('y_85 ~ restricted + restricted_h', data=mrw_N).fit()
print(mrw_h_results_restricted.summary())

α_β = ((mrw_h_results_restricted.params[1]+mrw_h_results_restricted.params[2])/
       (1+mrw_h_results_restricted.params[1]+mrw_h_results_restricted.params[2]))

print('')
print('Implied α =', mrw_h_results_restricted.params[1] * (1-α_β))
print('Implied β =', mrw_h_results_restricted.params[2] * (1-α_β))
	 Restricted regression
	 Non-oil countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   y_85   R-squared:                       0.784
Model:                            OLS   Adj. R-squared:                  0.779
Method:                 Least Squares   F-statistic:                     172.3
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           2.47e-32
Time:                        20:50:32   Log-Likelihood:                -70.963
No. Observations:                  98   AIC:                             147.9
Df Residuals:                      95   BIC:                             155.7
Df Model:                           2                                         
Covariance Type:            nonrobust                                         
================================================================================
                   coef    std err          t      P>|t|      [0.025      0.975]
--------------------------------------------------------------------------------
Intercept        4.8271      0.243     19.894      0.000       4.345       5.309
restricted       0.7383      0.124      5.972      0.000       0.493       0.984
restricted_h     0.6571      0.073      9.057      0.000       0.513       0.801
==============================================================================
Omnibus:                        2.571   Durbin-Watson:                   2.047
Prob(Omnibus):                  0.277   Jarque-Bera (JB):                2.582
Skew:                          -0.365   Prob(JB):                        0.275
Kurtosis:                       2.682   Cond. No.                         21.8
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Implied α = 0.308214148352
Implied β = 0.274312682162

And as you can see, the modification places the value of $\alpha$ back in the range of plausible values.

Moreover, the model can now explain around 78% of total variation of GDP per capita across countries.

Convergence

The model can also be used to evaluate the speed of convergence across countries. While deriving the formula is quite tedious, the end result is quite straightforward:

\begin{align} \frac{\Delta y_{t+1}}{y_{t}} \approx \underbrace{ \left( \delta+n+g \right) \left( 1-\alpha-\beta \right) }_{\lambda} \cdot [\log y_{t}^{*} - \log y_{t}] \end{align}

The above formula implies that the growth rate of GDP per worker in a country is a positive function of its distance to its balanced growth path level. The value of $\lambda$ dictates how fast a country converges. For example, if $\lambda=0.02$ then a country closes half of the distance between the initial and BGP level of GDP in around 35 years.

The equation can be rewritten into a form that is easy to run a regression on:

\begin{align} \log y_{t} - \log y_{0} = \left( 1-e^{-\lambda t} \right) \left[ \frac{\alpha}{1-\alpha-\beta} \log s_{k} + \frac{\beta}{1-\alpha-\beta} \log s_{h} - \frac{\alpha+\beta}{1-\alpha-\beta} \log \left( \delta+n+g \right) - \log y_{0} \right] \end{align}

where $\log y_{0}$ denotes an initial level of GDP per worker.

In [26]:
# Add in log of initial GDP per worker
mrw['y_60'] = np.log(mrw['Y60'])

# Add in log-difference of levels of GDP per worker
mrw['y_85_60'] = mrw['y_85'] - mrw['y_60']

mrw_N = mrw[mrw['N']==1]

# Run regressions
print('\t Non-oil countries')
mrw_results_N = smf.ols('y_85_60 ~ y_60 + s + δ_n_g + s_h', data=mrw_N).fit()
print(mrw_results_N.summary())
print('')
print('Implied λ =', np.log(1+mrw_results_N.params[1])/(-25))

print('')
print('\t Intermediate countries')
mrw_results_I = smf.ols('y_85_60 ~ y_60 + s + δ_n_g + s_h', data=mrw[mrw['I']==1]).fit()
print(mrw_results_I.summary())
print('')
print('Implied λ =', np.log(1+mrw_results_I.params[1])/(-25))


print('')
print('\t OECD countries')
mrw_results_O = smf.ols('y_85_60 ~ y_60 + s + δ_n_g + s_h', data=mrw[mrw['O']==1]).fit()
print(mrw_results_O.summary())
print('')
print('Implied λ =', np.log(1+mrw_results_O.params[1])/(-25))
	 Non-oil countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                y_85_60   R-squared:                       0.485
Model:                            OLS   Adj. R-squared:                  0.463
Method:                 Least Squares   F-statistic:                     21.94
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           8.99e-13
Time:                        20:50:32   Log-Likelihood:                -26.952
No. Observations:                  98   AIC:                             63.90
Df Residuals:                      93   BIC:                             76.83
Df Model:                           4                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      1.9572      0.777      2.517      0.014       0.413       3.501
y_60          -0.2884      0.062     -4.683      0.000      -0.411      -0.166
s              0.5237      0.087      6.029      0.000       0.351       0.696
δ_n_g         -0.5057      0.289     -1.752      0.083      -1.079       0.067
s_h            0.2311      0.059      3.887      0.000       0.113       0.349
==============================================================================
Omnibus:                        2.061   Durbin-Watson:                   2.135
Prob(Omnibus):                  0.357   Jarque-Bera (JB):                1.518
Skew:                          -0.153   Prob(JB):                        0.468
Kurtosis:                       3.528   Cond. No.                         209.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Implied λ = 0.0136080957016

	 Intermediate countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                y_85_60   R-squared:                       0.465
Model:                            OLS   Adj. R-squared:                  0.435
Method:                 Least Squares   F-statistic:                     15.23
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           5.26e-09
Time:                        20:50:32   Log-Likelihood:                -14.635
No. Observations:                  75   AIC:                             39.27
Df Residuals:                      70   BIC:                             50.86
Df Model:                           4                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      2.4635      0.801      3.075      0.003       0.866       4.061
y_60          -0.3660      0.067     -5.427      0.000      -0.500      -0.231
s              0.5376      0.102      5.255      0.000       0.334       0.742
δ_n_g         -0.5450      0.288     -1.890      0.063      -1.120       0.030
s_h            0.2705      0.080      3.365      0.001       0.110       0.431
==============================================================================
Omnibus:                        6.278   Durbin-Watson:                   2.452
Prob(Omnibus):                  0.043   Jarque-Bera (JB):                9.147
Skew:                          -0.208   Prob(JB):                       0.0103
Kurtosis:                       4.659   Cond. No.                         207.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Implied λ = 0.0182278393042

	 OECD countries
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                y_85_60   R-squared:                       0.718
Model:                            OLS   Adj. R-squared:                  0.651
Method:                 Least Squares   F-statistic:                     10.80
Date:                Tue, 27 Mar 2018   Prob (F-statistic):           0.000152
Time:                        20:50:32   Log-Likelihood:                 13.798
No. Observations:                  22   AIC:                            -17.60
Df Residuals:                      17   BIC:                            -12.14
Df Model:                           4                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      1.7068      1.168      1.461      0.162      -0.758       4.172
y_60          -0.3977      0.070     -5.668      0.000      -0.546      -0.250
s              0.3318      0.173      1.914      0.073      -0.034       0.698
δ_n_g         -0.8634      0.338     -2.557      0.020      -1.576      -0.151
s_h            0.2277      0.145      1.570      0.135      -0.078       0.534
==============================================================================
Omnibus:                        1.879   Durbin-Watson:                   1.695
Prob(Omnibus):                  0.391   Jarque-Bera (JB):                1.098
Skew:                           0.547   Prob(JB):                        0.578
Kurtosis:                       3.009   Cond. No.                         368.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Implied λ = 0.0202793415318

For the developed countries, the theoretical model would predict that $\lambda \approx 0.02$ since $\delta+n+g \approx 0.06$ and $1-\alpha-\beta \approx 0.33$. This is exactly the value implied by the regression for the OECD countries.

In the plots below we can see that while there is no unconditional convergence, as poorer countries do not consistently grow faster than richer countries, once we control for observables impacting the steady states of the economies, convergence is evident.

In [27]:
# Convergence plots

par = mrw_results_N.params

# plt.scatter(mrw_N['y_60'], 100*((mrw_N['Y85']/mrw_N['Y60'])**(1/25)-1))
plt.scatter(mrw_N['y_60'], 100*mrw_N['y_85_60']/25)

plt.title('Unconditional')
plt.xlabel('Log output per working age adult: 1960')
plt.ylabel('Growth rate: 1960-85')

plt.show()

###
plt.scatter(mrw_N['y_60'], 
            100/25*(mrw_N['y_85_60']
                    -par[2]*(mrw_N['s']-mrw_N['s'].mean())
                    -par[3]*(mrw_N['δ_n_g']-mrw_N['δ_n_g'].mean())))

plt.title('Conditional on saving and population growth')
plt.xlabel('Log output per working age adult: 1960')
plt.ylabel('Growth rate: 1960-85')

plt.show()

###
plt.scatter(mrw_N['y_60'], 
            100/25*(mrw_N['y_85_60']
                    -par[2]*(mrw_N['s']-mrw_N['s'].mean())
                    -par[3]*(mrw_N['δ_n_g']-mrw_N['δ_n_g'].mean())
                    -par[4]*(mrw_N['s_h']-mrw_N['s_h'].mean())))

plt.title('Conditional on saving, population growth and human capital')
plt.xlabel('Log output per working age adult: 1960')
plt.ylabel('Growth rate: 1960-85')

plt.show()

Homework: replication of MRW results using PWT 9.0

In [28]:
# Construct replication dataset

# First detect countries from MRW that are absent in PWT
not_found = []

for i, country in enumerate(mrw_countries[mrw['N']==1]):
    try:
        temp = np.log(np.mean(pwt.loc[country]['csh_i']))
    except:
        not_found.append(country)

print(not_found)
['CentralAfr. Rep.', 'Congo, Peop. Rep.', 'Ivory Cost', 'Somalia', 'S. Africa', 'Sudan', 'Tanzania', 'Zaire', 'Burma', 'Hong Kong', 'Korea, Rep. of', 'Syrian Arab Rep.', 'Germany, Fed. Rep.', 'Dominican Rep.', 'Trinidad & Tobago', 'Bolivia', 'Venezuela', 'Papua New Guinea']
In [29]:
# Construct a list of PWT-compatible country names (but still some countries are not covered by PWT 9.0)
not_found_PWT = ['Central African Republic', 'Congo', "Côte d'Ivoire", 
                 'South Africa', 'Sudan (Former)', 'U.R. of Tanzania: Mainland', 
                 'D.R. of the Congo', 'Myanmar', 'China, Hong Kong SAR', 
                 'Republic of Korea', 'Syrian Arab Republic', 'Germany', 
                 'Dominican Republic', 'Trinidad and Tobago', 
                 'Bolivia (Plurinational State of)', 'Venezuela (Bolivarian Republic of)']
In [30]:
mrw_pwt_countries = [n for n in mrw_countries[mrw['N']==1].tolist() if n not in not_found]
mrw_pwt_countries = mrw_pwt_countries + not_found_PWT
In [31]:
# Construct replication dataset
s = np.zeros(len(mrw_pwt_countries))
n = np.zeros(len(mrw_pwt_countries))
h = np.zeros(len(mrw_pwt_countries))
y_80 = np.zeros(len(mrw_pwt_countries))
y_14 = np.zeros(len(mrw_pwt_countries))

for i, country in enumerate(mrw_pwt_countries):
    s[i] = np.log(np.mean(pwt.loc[country]['csh_i'][20:]))
    n[i] = np.log(0.05+np.mean(pwt.loc[country]['emp'][20:].pct_change()))
    h[i] = np.mean(pwt.loc[country]['hc'][20:])
    y_80[i] = np.log(pwt.loc[country, 1980]['rgdpo']/pwt.loc[country, 1980]['emp'])
    y_14[i] = np.log(pwt.loc[country, 2014]['rgdpo']/pwt.loc[country, 2014]['emp'])

d = {'y_14': y_14, 'y_80': y_80, 's': s, 'δ_n_g': n, 's_h': np.log(np.log(h)*10)}
mrw_rep = pd.DataFrame(data=d, index=mrw_pwt_countries)
mrw_rep['y_14_80'] = mrw_rep['y_14'] - mrw_rep['y_80']
mrw_rep.head()
Out[31]:
s s_h y_14 y_80 δ_n_g y_14_80
Algeria -0.986690 1.567856 10.735659 11.010285 -2.415365 -0.274627
Angola -1.083495 0.584940 10.148782 9.192177 -2.544458 0.956605
Benin -2.060066 0.970865 8.559134 8.546510 -2.495051 0.012624
Botswana -1.132083 1.956610 10.473295 9.091190 -2.330065 1.382105
Burkina Faso -1.573916 -0.480044 8.365299 7.819805 -2.624513 0.545494

Task 1: run an unrestricted estimation on the replication dataset of the human capital augmented Solow model, with y_14 as the dependent variable and s, δ_n_g and s_h as independent variables. Comment on the coefficient signs and explanatory power of the model.

Task 2: run a restricted estimation on the replication dataset of the human capital augmented Solow model, with y_14 as the dependent variable, and appropriate restrictions as independent variables. Comment on the implied values of $\alpha$ and $\beta$.

Task 3: run a convergence estimation on the replication dataset of the human capital augmented Solow model, with y_14_80 as the dependent variable and y_80, s, δ_n_g and s_h as independent variables. Produce a conditional convergence plot.

In [32]:
# Your codes