In [1]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
%matplotlib inline

Homework 2 (DUE: Thursday February 16)

Instructions: Complete the instructions in this notebook. You may work together with other students in the class and you may take full advantage of any internet resources available. You must provide thorough comments in your code so that it's clear that you understand what your code is doing and so that your code is readable.

Submit the assignment by saving your notebook as an html file (File -> Download as -> HTML) and uploading it to the appropriate Dropbox folder on EEE.

Question 1

For each of the following first-difference processes, compute the values of $y$ from $t=0$ through $t = 20$. For each, assume that $y_0 = 0$, $w_1 = 1$, and $w_2 = w_3 = \cdots w_T = 0$.

  • $y_t = 0.99y_{t-1} + w_t$
  • $y_t = y_{t-1} + w_t$
  • $y_t = 1.01y_{t-1} + w_t$

Plot the the simulated values for each process on the same axes and be sure to include a legend.


In [2]:
# Question 1

T = 20
w = np.zeros(T)
w[0] = 1

def firstDiff(mu,rho,w,y0,T):
    
    y = np.zeros(T+1)
    y[0] = y0
    for t in range(T):
        y[t+1] = (1-rho)*mu + rho*y[t] + w[t]
    
    return y

y1 = firstDiff(mu=0,rho=0.99,w=w,y0=0,T=T)
y2 = firstDiff(mu=0,rho=1,w=w,y0=0,T=T)
y3 = firstDiff(mu=0,rho=1.01,w=w,y0=0,T=T)


plt.plot(y1,lw=3,alpha = 0.65,label = '$\\rho = 0.99$')
plt.plot(y2,lw=3,alpha = 0.65,label = '$\\rho = 1$')
plt.plot(y3,lw=3,alpha = 0.65,label = '$\\rho = 1.01$')
    
    
plt.legend(loc='lower right')
plt.grid()
plt.title('Three first difference processes')


Out[2]:
<matplotlib.text.Text at 0x119a10400>

Question 2

For each of the following first-difference processes, compute the values of $y$ from $t=0$ through $t = 12$. For each, assume that $y_0 = 0$.

  • $y_t = 1 + 0.5y_{t-1}$
  • $y_t = 0.5y_{t-1}$
  • $y_t = -1 + 0.5y_{t-1}$

Plot the the simulated values for each process on the same axes and be sure to include a legend. Set the $y$-axis limits to $[-3,3]$.


In [3]:
# Question 2

T = 12
w = np.zeros(T)


y1 = firstDiff(mu=1/(1-0.5),rho=0.5,w=w,y0=0,T=T)
y2 = firstDiff(mu=0,rho=0.5,w=w,y0=0,T=T)
y3 = firstDiff(mu=-1/(1-0.5),rho=0.5,w=w,y0=0,T=T)


plt.plot(y1,lw=3,alpha = 0.65,label = '$\\rho = 0.99$')
plt.plot(y2,lw=3,alpha = 0.65,label = '$\\rho = 1$')
plt.plot(y3,lw=3,alpha = 0.65,label = '$\\rho = 1.01$')
    
    
plt.legend(ncol=3)
plt.grid()
plt.ylim([-3,3])
plt.title('Three first difference processes')


Out[3]:
<matplotlib.text.Text at 0x119d751d0>

Question 3

Download a file called Econ129_US_Production_A_Data.csv from the link "Production data for the US" under the "Data" section on the course website. The file contains annual production data for the US economy including ouput, consumption, investment, and labor hours, among others. The capital stock of the US is only given for 1948. Import the data into a Pandas DataFrame and do the following:

  1. Suppose that the depreciation rate for the US is $\delta = 0.0375$. Use the capital accumulation equation $K_{t+1} = I_t + (1-\delta)K_t$ to fill in the missing values for the capital column. Construct a plot of the computed capital stock.
  2. Add columns to your DataFrame equal to capital per worker and output per worker by dividing the capital and output columns by the labor column. Print the first five rows of the DataFrame.
  3. Print the average annual growth rates of capital per worker and output per worker for the US.

Recall that the average annnual growth rate of a quantity $y$ from date $0$ to date $T$ is: \begin{align} g & = \left(\frac{y_T}{y_0}\right)^{\frac{1}{T}}-1 \end{align}


In [4]:
# Question 3.1

df = pd.read_csv('Econ129_US_Production_A_Data.csv',index_col=0)

delta = 0.0375
T = len(df.index)

capital = df['Capital [Bil. of 2009 Dollars]'].values
investment = df['Investment [Bil. of 2009 Dollars]'].values

for t in range(T-1):
    capital[t+1] = investment[t] + (1-delta)*capital[t]
    
df['Capital [Bil. of 2009 Dollars]'] = capital


df['Capital [Bil. of 2009 Dollars]'].plot(lw=3,alpha=0.65,grid=True)
plt.title('US capital stock')
plt.ylabel('[Bil. of 2009 Dollars]')


Out[4]:
<matplotlib.text.Text at 0x119cc0358>

In [5]:
# Question 3.2
df['Output per worker'] = df['Output [Bil. of 2009 Dollars]']/df['Labor [Mil. of Hours]']
df['Capital per worker'] = df['Capital [Bil. of 2009 Dollars]']/df['Labor [Mil. of Hours]']

print(df.head())


      Output [Bil. of 2009 Dollars]  Consumption [Bil. of 2009 Dollars]  \
Year                                                                      
1948                         2019.8                              1286.3   
1949                         2008.7                              1314.3   
1950                         2184.1                              1398.3   
1951                         2360.0                              1416.8   
1952                         2455.9                              1466.1   

      Investment [Bil. of 2009 Dollars]  \
Year                                      
1948                              369.7   
1949                              287.9   
1950                              411.1   
1951                              426.7   
1952                              382.7   

      Government Purchases [Bil. of 2009 Dollars]  \
Year                                                
1948                                        323.4   
1949                                        368.2   
1950                                        368.9   
1951                                        499.5   
1952                                        599.8   

      Exports [Bil. of 2009 Dollars]  Imports [Bil. of 2009 Dollars]  \
Year                                                                   
1948                            40.4                            40.4   
1949                            38.3                            38.3   
1950                             5.1                             5.1   
1951                            17.0                            17.0   
1952                             8.0                             8.0   

      Net Exports [Bil. of 2009 Dollars]  Capital [Bil. of 2009 Dollars]  \
Year                                                                       
1948                                40.4                     5049.600000   
1949                                38.3                     5229.940000   
1950                                 5.1                     5321.717250   
1951                                17.0                     5533.252853   
1952                                 8.0                     5752.455871   

      Labor [Mil. of Hours]  Output per worker  Capital per worker  
Year                                                                
1948                  99119           0.020378            0.050945  
1949                  95610           0.021009            0.054701  
1950                 100064           0.021827            0.053183  
1951                 108525           0.021746            0.050986  
1952                 110757           0.022174            0.051938  

In [6]:
# Question 3.3

T = len(df.index-1)

gy = (df['Output per worker'].iloc[-1]/df['Output per worker'].iloc[0])**(1/T)-1
gk = (df['Capital per worker'].iloc[-1]/df['Capital per worker'].iloc[0])**(1/T)-1


print('Average growth rate of output per worker: ',round(gy,5))
print('Average growth rate of capital per worker:',round(gk,5))


Average growth rate of output per worker:  0.01772
Average growth rate of capital per worker: 0.01928

Question 4: The Solow model with exogenous population and TFP growth

Suppose that the aggregate production function is given by:

\begin{align} Y_t & = A_tK_t^{\alpha} L_t^{1-\alpha}, \tag{1} \end{align}

where $Y_t$ denotes output, $K_t$ denotes the capital stock, $L_t$ denotes the labor supply, and $A_t$ denotes total factor productivity $TFP$. $\alpha$ is a constant.

The supply of labor grows at an exogenously determined rate $n$ and so it's value is determined recursively by a first-order difference equation:

\begin{align} L_{t+1} & = (1+n) L_t. \tag{2} \end{align}

Likewise, TFP grows at an exogenously determined rate $g$:

\begin{align} A_{t+1} & = (1+g) A_t. \tag{3} \end{align}

The rest of the economy is characterized by the same equations as before:

\begin{align} C_t & = (1-s)Y_t \tag{4}\\ Y_t & = C_t + I_t \tag{5}\\ K_{t+1} & = I_t + ( 1- \delta)K_t. \tag{6}\\ \end{align}

Equation (4) is the consumption function where $s$ denotes the exogenously given saving rate. Equation (5) is the aggregate market clearing condition. Finally, Equation (6) is the capital evolution equation specifying that capital in year $t+1$ is the sum of newly created capital $I_t$ and the capital stock from year $t$ that has not depreciated $(1-\delta)K_t$.

Combine Equations (1) and (4) through (6) to eliminate $C_t$, $I_t$, and $Y_t$ and obtain a recurrence relation specifying $K_{t+1}$ as a funtion of $K_t$, $A_t$, and $L_t$: \begin{align} K_{t+1} & = sA_tK_t^{\alpha}L_t^{1-\alpha} + ( 1- \delta)K_t \tag{7} \end{align}

Given an initial values for capital and labor, Equations (2), (3), and (7) can be iterated on to compute the values of the capital stock and labor supply at some future date $T$. Furthermore, the values of consumption, output, and investment at date $T$ can also be computed using Equations (1), (4), (5), and (6).

Simulation

Simulate the Solow growth model with exogenous labor growth for $t=0\ldots 100$. For the simulation, assume the following values of the parameters:

\begin{align} A & = 10\\ \alpha & = 0.35\\ s & = 0.15\\ \delta & = 0.1\\ g & = 0.015 \\ n & = 0.01 \end{align}

Furthermore, suppose that the initial values of capital and labor are:

\begin{align} K_0 & = 2\\ A_0 & = 1\\ L_0 & = 1 \end{align}

In [7]:
# Initialize parameters for the simulation (A, s, T, delta, alpha, g, n, K0, A0, L0)
K0 = 2
A0 = 1
L0 = 1
T= 100
A= 10
alpha = 0.35
delta = 0.1
s = 0.15
g = 0.015
n = 0.01


# Initialize a variable called tfp as a (T+1)x1 array of zeros and set first value to A0
tfp = np.zeros(T+1)
tfp[0] = A0

# Compute all subsequent tfp values by iterating over t from 0 through T
for t in np.arange(T):
    tfp[t+1] = (1+g)*tfp[t]
    
# Plot the simulated tfp series
plt.plot(tfp,lw=3)
plt.grid()
plt.title('TFP')


Out[7]:
<matplotlib.text.Text at 0x11a16cf98>

In [8]:
# Initialize a variable called labor as a (T+1)x1 array of zeros and set first value to L0
labor = np.zeros(T+1)
labor[0] = L0

# Compute all subsequent labor values by iterating over t from 0 through T
for t in np.arange(T):
    labor[t+1] = (1+n)*labor[t]
    
# Plot the simulated labor series
plt.plot(labor,lw=3)
plt.grid()
plt.title('Labor')


Out[8]:
<matplotlib.text.Text at 0x11a3c8240>

In [9]:
# Initialize a variable called capital as a (T+1)x1 array of zeros and set first value to K0
capital = np.zeros(T+1)
capital[0] = K0

# Compute all subsequent capital values by iterating over t from 0 through T
for t in np.arange(T):
    capital[t+1] = s*tfp[t]*capital[t]**alpha*labor[t]**(1-alpha) + (1-delta)*capital[t]
    
# Plot the simulated capital series
plt.plot(capital,lw=3)
plt.grid()
plt.title('Capital')


Out[9]:
<matplotlib.text.Text at 0x11a50b7f0>

In [10]:
# Store the simulated capital, labor, and tfp data in a pandas DataFrame called data
data = pd.DataFrame({'capital':capital,'labor':labor,'TFP':tfp})

# Print the first 5 frows of the DataFrame
print(data.head())


        TFP   capital     labor
0  1.000000  2.000000  1.000000
1  1.015000  1.991184  1.010000
2  1.030225  1.987075  1.020100
3  1.045678  1.987442  1.030301
4  1.061364  1.992083  1.040604

In [11]:
# Create columns in the DataFrame to store computed values of the other endogenous variables: Y, C, and I
data['output'] = data['TFP']*data['capital']**alpha*data['labor']**(1-alpha)
data['consumption'] = (1-s)*data['output']
data['investment'] = data['output'] - data['consumption']

# Print the first five rows of the DataFrame
print(data.head())


        TFP   capital     labor    output  consumption  investment
0  1.000000  2.000000  1.000000  1.274561     1.083377    0.191184
1  1.015000  1.991184  1.010000  1.300062     1.105052    0.195009
2  1.030225  1.987075  1.020100  1.327165     1.128090    0.199075
3  1.045678  1.987442  1.030301  1.355901     1.152516    0.203385
4  1.061364  1.992083  1.040604  1.386300     1.178355    0.207945

In [12]:
# Create columns in the DataFrame to store capital per worker, output per worker, consumption per worker, and investment per worker
data['capital_pw'] = data['capital']/data['labor']
data['output_pw'] = data['output']/data['labor']
data['consumption_pw'] = data['consumption']/data['labor']
data['investment_pw'] = data['investment']/data['labor']

# Print the first five rows of the DataFrame
print(data.head())


        TFP   capital     labor    output  consumption  investment  \
0  1.000000  2.000000  1.000000  1.274561     1.083377    0.191184   
1  1.015000  1.991184  1.010000  1.300062     1.105052    0.195009   
2  1.030225  1.987075  1.020100  1.327165     1.128090    0.199075   
3  1.045678  1.987442  1.030301  1.355901     1.152516    0.203385   
4  1.061364  1.992083  1.040604  1.386300     1.178355    0.207945   

   capital_pw  output_pw  consumption_pw  investment_pw  
0    2.000000   1.274561        1.083377       0.191184  
1    1.971469   1.287190        1.094111       0.193078  
2    1.947922   1.301014        1.105862       0.195152  
3    1.928992   1.316024        1.118620       0.197404  
4    1.914353   1.332207        1.132376       0.199831  

In [13]:
# Create a 2x2 grid of plots of capital, output, consumption, and investment
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(2,2,1)
ax.plot(data['capital'],lw=3)
ax.grid()
ax.set_title('Capital')

ax = fig.add_subplot(2,2,2)
ax.plot(data['output'],lw=3)
ax.grid()
ax.set_title('Output')

ax = fig.add_subplot(2,2,3)
ax.plot(data['consumption'],lw=3)
ax.grid()
ax.set_title('Consumption')

ax = fig.add_subplot(2,2,4)
ax.plot(data['investment'],lw=3)
ax.grid()
ax.set_title('Investment')


Out[13]:
<matplotlib.text.Text at 0x11a77c780>

In [14]:
# Create a 2x2 grid of plots of capital per worker, output per worker, consumption per worker, and investment per worker
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(2,2,1)
ax.plot(data['capital_pw'],lw=3)
ax.grid()
ax.set_title('Capital per worker')

ax = fig.add_subplot(2,2,2)
ax.plot(data['output_pw'],lw=3)
ax.grid()
ax.set_title('Output per worker')

ax = fig.add_subplot(2,2,3)
ax.plot(data['consumption_pw'],lw=3)
ax.grid()
ax.set_title('Consumption per worker')

ax = fig.add_subplot(2,2,4)
ax.plot(data['investment_pw'],lw=3)
ax.grid()
ax.set_title('Investment per worker')


Out[14]:
<matplotlib.text.Text at 0x11b0425f8>

Question 5

Recall the Solow growth model with exogenous growth in labor and TFP:

\begin{align} Y_t & = A_tK_t^{\alpha} L_t^{1-\alpha}, \tag{1}\\ C_t & = (1-s)Y_t \tag{2}\\ Y_t & = C_t + I_t \tag{3}\\ K_{t+1} & = I_t + ( 1- \delta)K_t \tag{4}\\ L_{t+1} & = (1+n) L_t \tag{5} \\ A_{t+1} & = (1+g) A_t. \tag{6} \end{align}

Suppose that two countries called Westeros and Essos are identical except that TFP in Westeros grows faster than in Essos. Specifically:

\begin{align} g_{Westeros} & = 0.03\\ g_{Essos} & = 0.01 \end{align}

Otherwise, the parameters for each economy are the same including the initial values of capital, labor, and TFP:

\begin{align} \alpha & = 0.35\\ s & = 0.15\\ \delta & = 0.1\\ n & = 0.01\\ K_0 & = 20\\ A_0 & = 10\\ L_0 & = 1 \end{align}

Do the following:

  1. Find the date (value for $t$) at which output per worker in Westeros becomes at least twice as large as output per worker in Essos. Print the value for t and the values of ouput per worker for each country.

  2. On a single set of axes, plot simulated values of output per worker for each country for t = $1, 2, \ldots 100$.

Hint: Copy into this notebook the function that simulates the Solow model with exogenous labor growth from the end of the Notebook from Class 9. Modify the function to fit this problem.


In [15]:
# Question 5.1

def solow_sim(alpha,delta,s,g,n,A0,K0,L0,T):
    '''Returns DataFrame with simulated values for a Solow model with labor growth and TFP growth'''
    
    # Initialize a variable called tfp as a (T+1)x1 array of zeros and set first value to k0
    tfp = np.zeros(T+1)
    tfp[0] = A0
    
    # Initialize a variable called capital as a (T+1)x1 array of zeros and set first value to k0
    capital = np.zeros(T+1)
    capital[0] = K0
    
    # Initialize a variable called labor as a (T+1)x1 array of zeros and set first value to l0
    labor = np.zeros(T+1)
    labor[0] = L0


    # Compute all capital and labor values by iterating over t from 0 through T
    for t in np.arange(T):
        labor[t+1] = (1+n)*labor[t]
        tfp[t+1] = (1+g)*tfp[t]
        capital[t+1] = s*tfp[t]*capital[t]**alpha*labor[t]**(1-alpha) + (1-delta)*capital[t]
    
    # Store the simulated capital df in a pandas DataFrame called data
    df = pd.DataFrame({'capital':capital,'labor':labor,'tfp':tfp})
    
    # Create columns in the DataFrame to store computed values of the other endogenous variables
    df['output'] = df['tfp']*df['capital']**alpha*df['labor']**(1-alpha)
    df['consumption'] = (1-s)*df['output']
    df['investment'] = df['output'] - df['consumption']
    
    # Create columns in the DataFrame to store capital per worker, output per worker, consumption per worker, and investment per worker
    df['capital_pw'] = df['capital']/df['labor']
    df['output_pw'] = df['output']/df['labor']
    df['consumption_pw'] = df['consumption']/df['labor']
    df['investment_pw'] = df['investment']/df['labor']
    
    return df


westeros = solow_sim(alpha=0.35,delta=0.1,s=0.15,g=0.03,n=0.01,A0=10,K0=20,L0=1,T=100)
essos =    solow_sim(alpha=0.35,delta=0.1,s=0.15,g=0.01,n=0.01,A0=10,K0=20,L0=1,T=100)

for t in range(200):
    if westeros['output_pw'].iloc[t]>=2*essos['output_pw'].iloc[t]:
        print(t)
        break
        
print(westeros[westeros['output_pw']>=2*essos['output_pw']].index[0])


27
27

In [16]:
# Question 5.2
westeros['output_pw'].plot(lw=3,alpha = 0.65,label='Westeros')
essos['output_pw'].plot(lw=3,alpha = 0.65,label='Essos')
plt.grid()
plt.title('Output per worker in Westeros and Essos')
plt.legend(loc='upper left')


Out[16]:
<matplotlib.legend.Legend at 0x11a2e8668>