# 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}

- (Optional) Inada (1963) conditions:

\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