# The Basic Solow Model and COVID-19

Imports and set magics:


```python
import numpy as np
from scipy import optimize
import sympy as sm
from IPython.display import display
import matplotlib.pyplot as plt
import ipywidgets as widgets
plt.style.use("seaborn")
# autoreload modules when code is run
%load_ext autoreload
%autoreload 2
```

    The autoreload extension is already loaded. To reload it, use:
      %reload_ext autoreload


# The Basic Solow Model


\begin{equation}
Y_t = AK_t^{\alpha}L_t^{1-\alpha} \tag{1}
\end{equation}
\begin{equation}
S_t = sY_t \tag{2}
\end{equation}
\begin{equation}
K_{t+1} - K_t = S_t -\delta K_t \tag{3}
\end{equation}
\begin{equation}
L_{t+1} = (1+n)L_t \tag{4}
\end{equation}
\begin{equation}
y_t = \frac{Y_t}{L_t} = Ak_t^{\alpha} \tag{5}
\end{equation}
\begin{equation}
k_t = \frac{K_t}{L_t} \tag{6}
\end{equation}




## Description of the Solow model

Equation 1: The economy’s output takes the shape of a Cobb-Douglas production function, taking inputs of capital and labour to produce outcome. Alpha is the share of capital in the economy.

Equation 2: The total savings is determined solely by the savings rate in the economy

Equation 3: Capital in the next period is determined by the total savings subtracting the intra-period depreciation of capital

Equation 4: The labour force in the next period is the current labour force plus the intra-period growth of the labour force

Equation 5: Definition of production per worker

Equation 6:  Definition of capital per worker



## Furthermore the model contains other implicit assumptions

1: The model depicts a closed economy with full competition with homogenous households/firms that maximize utility and profit, respectively

2: Labour and capital are perfect substitutes, and the economy produces one composite good Y. This good is produced with constant returns to scale.

3: Technological growth is constant

4: The population grows at a constant value n, and there is always full employment

5: Depreciation of capital is constant

6: All consumers save a proportion s of their income, and spend the rest on consumption in the current period.




```python
Y = sm.symbols("Y_t")          #GDP in the economy
y = sm.symbols("y_t")          #GDP per worker
K = sm.symbols("K_t")          #Capital in the economy
K_next = sm.symbols("K_{t+1}") #Capital in the economy next period
k = sm.symbols("k_t")          #Capital per worker
k_next = sm.symbols("k_{t+1}") #Capital per worker next period
s = sm.symbols("s")            #Rate of savings
n = sm.symbols("n")            #Population growth rate
g = sm.symbols("g")            #Growth in technology
A = sm.symbols("A")            #Total factor productivity
L = sm.symbols("L_t")          #Labour supply
L_next = sm.symbols("L_{t+1}") #Labour supply next period
alpha = sm.symbols("alpha")    #Share of capital out of output
delta = sm.symbols("delta")    #Depreciation rate on capital
kstar = sm.symbols("k^*")      #Steady state for capital
ystar = sm.symbols("y^*")      #Steady state for GDP per worker



```


```python
r = sm.symbols("r_t")          #Real rental rate
w = sm.symbols("w_t")          #Real wage
```

\begin{equation}
r_t = \alpha A \left(\frac{K_t}{L_t}\right)^{\alpha-1} \tag{7}
\end{equation}
\begin{equation}
w_t = (1-\alpha) A \left(\frac{K_t}{L_t}\right)^{\alpha} \tag{8}
\end{equation}

Equation 7-8: The two factors are paid their marginal productivities, rent and wage respectively.
The model has no rigidities, both in wages and prices.

We assert that the real rental rate and real wages are given as (7) and (8), using the Sympy package to find the derivatives of output with respecto capital and labour.


```python
foc_wrt_K = sm.Eq(sm.simplify(sm.diff(A * K**(alpha) * L**(1-alpha), K)),r)
foc_wrt_K
```




$\displaystyle A K_{t}^{\alpha - 1} L_{t}^{1 - \alpha} \alpha = r_{t}$




```python
foc_wrt_L = sm.Eq(sm.simplify(sm.diff(A * K**(alpha) * L**(1-alpha), L)),w)
foc_wrt_L
```




$\displaystyle - A K_{t}^{\alpha} L_{t}^{- \alpha} \left(\alpha - 1\right) = w_{t}$



With our model written out and verified we now look at one of the core components of the basic Solow model, capital accumulation

# Capital Accumulation and Steady State Values


By inserting equation (1) in (2) and then inserting that in equation 3, finally we divide by equation (4) to end up at the transition equation.



```python
Transition_equation = sm.simplify(sm.Eq((((1/(1+n))*(A*s*k**(alpha)+(1-delta)*k))), k_next))
Transition_equation
```




$\displaystyle k_{t+1} = \frac{A k_{t}^{\alpha} s - k_{t} \left(\delta - 1\right)}{n + 1}$



To find the steady state of capital, we use that $$\begin{equation}
k_{t+1}=k_t=k^*
\end{equation}$$
 in steady state.
 We turn to the Sympy's solver function



```python
steady_state_capital = sm.solve(((A*s*kstar**(alpha)-(delta-1)*kstar)/(1+n)-kstar), kstar) 
sm.Eq(steady_state_capital[0], kstar)

```




$\displaystyle \left(\frac{\delta + n}{A s}\right)^{\frac{1}{\alpha - 1}} = k^{*}$




```python
sm.Eq(steady_state_capital[0], kstar)

```




$\displaystyle \left(\frac{\delta + n}{A s}\right)^{\frac{1}{\alpha - 1}} = k^{*}$



substituting this result in equation (5), we get the following steady state output


```python
steady_state_output = sm.simplify(A*steady_state_capital[0]**alpha)
sm.Eq(ystar, steady_state_output)

```




$\displaystyle y^{*} = A \left(\left(\frac{\delta + n}{A s}\right)^{\frac{1}{\alpha - 1}}\right)^{\alpha}$




```python
steady_state_capital_func = sm.lambdify((delta,n,A,s,alpha),steady_state_capital[0])

def _steady_state_capital_func(delta,n,A,s,alpha):
    """ Defines the parametrical relationships of the steady state capital as it is given in the Solow Model
    
    Args:
    
        delta (float): Depreciation rate on capital
        n     (float): Population growth rate
        A     (float): Total factor productivity
        s     (float): Rate of savings
        alpha (float): Share of capital out of output

    Returns:
    
       steady_state_capital_func: Steady State Capital Per Worky
    
    """   

    return steady_state_capital_func(delta,n,A,s,alpha)

```

To assert that our new function works we plot the function for different savings rates. Both analytically and theoretically we should see that capital is increasing in the savings rate, all else equal


```python
# Investigating the relationship between the savings rate and output
delta= 0.05
n= 0.02
A= 1
savings_vec = np.array([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9])
alpha = 0.33
steady_state_capital_func(delta,n,A,savings_vec,alpha)
plt.figure(figsize=(10,10))
plt.xlabel("Savings rate")
plt.ylabel("Output")
plt.plot(savings_vec,steady_state_capital_func(delta,n,A,savings_vec,alpha));

```


```python
def solow_graph_1(k,delta,n,A,s,alpha):
    """  Defines the parametrical relationships of steady state output as it is given in the Solow Model
    
    Args:
    
        k     (float): Capital per worker
        delta (float): Depreciation rate on capital
        n     (float): Population growth rate
        A     (float): Total factor productivity
        s     (float): Rate of savings
        alpha (float): Share of capital out of output

    Returns:
    
      deltavec    : Plots total depreciation over time including population growths - to ensure a 45 degree line

      svec        : plots total output at different savings rates

    """

    # savings path
    svec = []

    # depreciation path
    deltavec = []

    for t in range(1,k):
        depreciation = (delta+n)*t
        deltavec.append(depreciation)
   
    for t in range(1,k):
        savings = s*A*t**alpha
        svec.append(savings)

    plt.figure(figsize=(10,10))
    plt.plot(deltavec[:k], label = '$(n+\delta)k_t$', color = 'black')
    plt.plot(svec[:k], color = 'green')
    plt.xlim(0,k)
    plt.ylim(0,deltavec[-1])
    plt.xlabel('$k_t$')
    plt.ylabel("Savings/Depreciation")
    plt.grid(True)
    plt.legend(['$(n+\delta)k_t$', '$sAk_t^{\u03B1}$'])
    return plt.show()
```


```python
solow_graph_1(200,0.02,0.01,1,savings_vec,0.33)
```

As we know from equation 2, savings are increasing in the savings rate s

Underneath, we have added a widget that lets you control the parameters


```python
widgets.interact(solow_graph_1, 
                k_0     = widgets.fixed(0), 
                alpha = widgets.FloatSlider(description = '\u03B1' , min = 0 ,    max = 0.9 , step = 0.01 , value = 0.33),
                delta = widgets.FloatSlider(description = '\u03B4' , min = 0 ,    max = 0.1 , step = 0.01 , value = 0.01),
                s     = widgets.FloatSlider(description = 's' ,        min = 0.01, max = 0.9 , step = 0.01 , value = 0.4),
                n     = widgets.FloatSlider(description ='n',        min = -0.1 , max = 0.1 , step = 0.005, value = 0.01),
                A     = widgets.fixed(1),
                k     = widgets.IntSlider(description='k' ,          min = 1,     max = 1001, step = 10,    value = 100));
```


    interactive(children=(IntSlider(value=100, description='k', max=1001, min=1, step=10), FloatSlider(value=0.01,…


Finally we can plot the transition in terms of output. We show this by plotting capital, total depreciation and output. As total depreciation and growth in capital converge, we see that output growth also converges to 0


```python
def solow_equation(k, delta, n, A, s, alpha):
    """  defines the outcomes of the Solow model as specified by the model equations
    
    Args:
    
        k     (float): Capital per worker
        delta (float): Depreciation rate on capital
        n     (float): Population growth rate
        A     (float): Total factor productivity
        s     (float): Rate of savings
        alpha (float): Share of capital out of output

    Returns:
    
      savings            : equation for savings
      depreciation       : depreciation at time t  
      k_extended         : equation for capital, savings and depreciation

    """


    savings = s *A* k ** alpha
    depreciation = (delta+n) * k
    k_extended =  k + savings - depreciation 
    return k_extended, savings, depreciation
```


```python
def solow_graph_2(k_0,delta,n,A,s,alpha,t):
    """  graphs the solow equation above
    
    Args:
    
        k_0   (integer)  : initial capial
        delta (float)    : Depreciation rate on capital
        n     (float)    : Population growth rate
        A     (float)    : Total factor productivity
        s     (float)    : Rate of savings
        alpha (float)    : Share of capital out of output
        t     (integer)  : periods

    Returns:
    
      savings            : equation for savings at time t
      depreciation       : depreciation at time t 
      k_extended         : equation for capital, savings and depreciation

    """


    # capital path
    kvec = [k_0]
    # savings path
    svec = []
    # depreciation path
    deltavec = []

        
    for t_ in range(1, t):

        k_extended, savings, depreciation = solow_equation(kvec[t_-1], delta,n,A, s, alpha)
        kvec.append(k_extended)
        svec.append(savings)
        deltavec.append(depreciation)
    

    plt.figure(figsize=(10,10))
    plt.plot(kvec[:t], label='$Ak_t^{\u03B1}$', color = 'blue')
    plt.plot(deltavec[:t], label = '$(n+\delta)k_t$', color = 'black')
    plt.plot(svec[:t], label = '$sAk_t^{\u03B1}$', color = 'red')
    plt.xlim(0,t)
    plt.ylim(0, )
    plt.xlabel('$t$')
    plt.grid(True)
    plt.legend()
    return plt.plot()

```


```python
solow_graph_2(1,0.05,0.02,1,0.4,0.33,100);

```

And with widgets for testing out effects of different parameters.


```python
widgets.interact(
        solow_graph_2,
        k_0=widgets.FloatSlider(
            description="k_0", min=0, max=10, step=0.05, value=2
        ),
        alpha=widgets.FloatSlider(
            description="alpha", min=0.01, max=0.99, step=0.01, value=0.3
        ),
        delta=widgets.FloatSlider(
            description="delta", min=0.01, max=0.50, step=0.01, value=0.05
        ),
        s=widgets.FloatSlider(
            description="s", min=0.01, max=0.99, step=0.01, value=0.33
        ),
        n= widgets.FloatSlider(description ='n', min = -0.1 , max = 0.1 , step = 0.005, value = 0.01),
        A     = widgets.fixed(1),
        t     = widgets.IntSlider(description='t' , min = 1, max = 150, step = 10,  value = 100),
      
    );
```


    interactive(children=(FloatSlider(value=2.0, description='k_0', max=10.0, step=0.05), FloatSlider(value=0.05, …


# The COVID-19 Extended Solow Model
Given the current global crisis, we wanted to extended the basic Solow model to fit the current climate. Such a model could look like this


```python
Y = sm.symbols("Y_t")          # GDP in the economy
y = sm.symbols("y_t")          # GDP per worker
K = sm.symbols("K_t")          # Capital in the economy
K_next = sm.symbols("K_{t+1}") # Capital in the economy next period
k = sm.symbols("k_t")          # Capital per worker
k_next = sm.symbols("k_{t+1}") # Capital per worker
s = sm.symbols("s")            # Rate of savings
n = sm.symbols("n")            # Population growth
g = sm.symbols("g")            # Growth in technology
A = sm.symbols("A")            # Total factor productivity
L = sm.symbols("L_t")          # Labour
L_next = sm.symbols("L_{t+1}") # Labour next period
alpha = sm.symbols("alpha")    # Return on capital
delta = sm.symbols("delta")    # Depreciation rate on capital
kstar = sm.symbols("k^*")      # Steady state for capital
ystar = sm.symbols("y^*")      # Steady state for GDP per worker
C = sm.symbols("C_t")            # Initial destruction of coronavirus lockdown
c = sm.symbols("c")            # definition C/L
D = sm.symbols("D_t")            # destruction of infection caused by the infection pressure
eta = sm.symbols("eta")        # Infection pressure rate
r = sm.symbols("r_t")          # Real rental rate
w = sm.symbols("w_t")          # Real wage
v = sm.symbols("v_t")          # Vaccine dummy
```

\begin{equation}
Y_t = AK_t^{\alpha}L_t^{1-\alpha} * D_t - C_t \tag{1}
\end{equation}
\begin{equation}
S_t = sY_t \tag{2}
\end{equation}
\begin{equation}
K_{t+1} - K_t = S_t -\delta K_t \tag{3}
\end{equation}
\begin{equation}
L_{t+1} = (1+n)L_t \tag{4}
\end{equation}
\begin{equation}
y_t = \frac{Y_t}{L_t} = Ak_t^{\alpha} \tag{5}
\end{equation}
\begin{equation}
k_t = \frac{K_t}{L_t} \tag{6}
\end{equation}
\begin{equation}
D_t = \frac{1}{1+\eta-v_t*\eta} \tag{7}
\end{equation}
\begin{equation}
r_t = \alpha A \left(\frac{K_t}{L_t}\right)^{\alpha-1} D_t \tag{8}
\end{equation}
\begin{equation}
w_t = (1-\alpha) A \left(\frac{K_t}{L_t}\right)^{\alpha-1} D_t \tag{9}
\end{equation}

At $t < T$   (before the corona lockdown) we have that: $ C=0, $  $ \eta = 0 $

At $t = T$  (the corona crisis occurs) we have that: $ 0<C<1, $  $ \eta > 0 $

At $t > T$  (reopening) we have that: $ 0<C<1, $  $ \eta > 0 $

Furthermore, v can only take the shapes of 0 and 1. Note that when $v_t = 1$ it will imply that $D_t = 1$ which means that the destruction caused by the infection is neutralized 

The initial impact of the infection is due to the comprehensive lockdown in period $t = T$. In $t > T$ the infection pressure impacts the output due to social distancing and other safety measures.


As with the basic model, we verify the derivatives of the production function


```python
foc_wrt_K_2 = sm.Eq(sm.simplify(sm.diff(A * K**(alpha) * L**(1-alpha) * D -C, K)),r)
foc_wrt_K_2
```




$\displaystyle A D_{t} K_{t}^{\alpha - 1} L_{t}^{1 - \alpha} \alpha = r_{t}$




```python
foc_wrt_L_2 = sm.Eq(sm.simplify(sm.diff(A * K**(alpha) * L**(1-alpha) * D -C, L)),w)
foc_wrt_L_2
```




$\displaystyle - A D_{t} K_{t}^{\alpha} L_{t}^{- \alpha} \left(\alpha - 1\right) = w_{t}$




```python
Transition_equation_2 = sm.simplify(sm.Eq((((1/(1+n))*((A*D*k**(alpha)- c)*s+(1-delta)*k))), k_next))
Transition_equation_2
```




$\displaystyle k_{t+1} = \frac{- k_{t} \left(\delta - 1\right) + s \left(A D_{t} k_{t}^{\alpha} - c\right)}{n + 1}$




```python
infection_vec = np.array([0.001,0.005,0.001]) # array of diffent infection pressure levels

```


```python
def solow_equation_2(k, delta, n, A, s, alpha, c, eta,d):
    """  defines the outcomes of the extended Solow model as specified by the model equations
    
    Args:
    
        k     (float): Capital per worker
        delta (float): Depreciation rate on capital
        n     (float): Population growth rate
        A     (float): Total factor productivity
        s     (float): Rate of savings
        alpha (float): Share of capital out of output
        c     (float): Initial destruction of the coronavirus lockdown
        eta   (float): Infection pressure rate
        d     (float): destruction caused by the infection pressure rate

    Returns:
    
      savings            : equation for total production per capita

      depreciation       : equation of total depreciation over time including population growths 
      k_extended         : equation for capital, savings and total depreciation

    """
    savings = s *A* k ** alpha
    depreciation = (delta+n) * k
    k_extended =  1/(1+eta)*(k + savings - depreciation) - d*c*(1/(1+eta))*(k + savings - depreciation)
    return k_extended, savings, depreciation

```


```python
def solow_graph_3(k_0,delta,n,A,s,alpha,t, c,eta,v,d):
    """  graphs the solow equation above
    
    Args:
    
        k_0   (integer)  : initial capial
        delta (float)    : Depreciation rate on capital
        n     (float)    : Population growth rate
        A     (float)    : Total factor productivity
        s     (float)    : Rate of savings
        alpha (float)    : Share of capital out of output
        t     (integer)  : Share of capital out of output
        c     (float)    : Initial destruction of the coronavirus lockdown
        eta   (float)    : Infection pressure rate
        d     (float)    : destruction caused by the infection pressure rate
        v     (float)    : decided at what time the vaccine enters

    Returns:
        savings          : equation for total production per capita
        depreciation     : equation of total depreciation over time including population growths 
        k_extended       : equation for capital, savings and total depreciation

    """

    # capital path
    kvec = [k_0]
    # savings path
    svec = []
    # depreciation path
    deltavec = []

        
    for t_ in range(1, t):
         if (50 < t_*1 < v):
            k_extended, savings, depreciation = solow_equation_2(kvec[t_-1], delta,n,A, s, alpha,c,eta,0)

            kvec.append(k_extended)
            svec.append(savings)
            deltavec.append(depreciation)

         elif (t_*1 == 50):
            k_extended, savings, depreciation = solow_equation_2(kvec[t_-1], delta,n,A, s, alpha,c,eta,d)

            kvec.append(k_extended)
            svec.append(savings)
            deltavec.append(depreciation)     
         else: 
            k_extended, savings, depreciation = solow_equation_2(kvec[t_-1], delta,n,A, s, alpha,c,0,0)

            kvec.append(k_extended)
            svec.append(savings)
            deltavec.append(depreciation)

    plt.figure(figsize=(10,10))
    plt.plot(kvec[:t], label='$Ak_t^{\u03B1}$', color = 'blue')
    plt.plot(deltavec[:t], label = '$(n+\delta)k_t$', color = 'black')
    plt.plot(svec[:t], label = '$sAk_t^{\u03B1}$', color = 'red')
    plt.xlim(0,t)
    plt.ylim(0, )
    plt.xlabel('$t$')
    plt.grid(True)
    plt.legend()
    return plt.plot()
```


```python
solow_graph_3(1,0.05,0.02,1,0.4,0.33,300,0,0.01,200,1)
```


```python
widgets.interact(
        solow_graph_3,
        k_0   =widgets.fixed(1),
        alpha =widgets.fixed(0.33),
        delta =widgets.fixed(0.05),
        s     =widgets.fixed(0.4),
        n     = widgets.fixed(0.01),
        A     = widgets.fixed(1),
        d     = widgets.fixed(1),
        t     = widgets.fixed(400),
        c     = widgets.FloatSlider(description="c", min=0.0, max=1, step=0.05, value=0.2),
        eta   = widgets.FloatSlider(description="eta", min=0.000, max=0.1, step=0.001, value=0.01),
        v     = widgets.IntSlider(description="v", min=51, max=300, step=1, value=200),
    );
```


    interactive(children=(FloatSlider(value=0.2, description='c', max=1.0, step=0.05), FloatSlider(value=0.01, des…


We see that as the shock from the initial lockdown increases, output per capita decreases, disrupts the convergence to steady steady which is reached marginally slower. The infection pressure lowers the steady state level of output. Even though savings are higher than depreciations in the period where the infection pressure is present, output cannot increase as the infection pressure dilutes the positive effect from savings surpassing depreciation. Finally we see that whenever a vaccine is introduced, we see that output converges towards its structural steady state of output.

The implications of our model is that output cannot return to the structural steady state without a vaccine or a complete elimination of the infection pressure. Our model suggests that a vaccine is the quickest way back to the structural steady state of output whenever an infection pressure is present. 



# Conclusion

We started this project by setting up the basic Solow model, solving for key properties of the model and graphing the results such as the impact of changes in the savings rate on aggregated wealth. After this we extended the basic Solow model with both long og short term  damage function resembling the impact of the coronavirus, so the model can be used to understand the economic consequences of the current virus epidemic.


b0779553276953f50b551f36ed4249309d9bbcdc
ipynb
Jupyter Notebook
modelproject/modelproject.ipynb
NumEconCopenhagen/projects-2020-1001numpyarrays
ef97deb595415062f0e56089e413444d34f020f4
MIT
modelproject/modelproject.ipynb
NumEconCopenhagen/projects-2020-1001numpyarrays
ef97deb595415062f0e56089e413444d34f020f4
MIT
2020-04-14T19:28:49.000Z
2020-05-15T14:56:01.000Z
modelproject/modelproject.ipynb
NumEconCopenhagen/projects-2020-1001numpyarrays
ef97deb595415062f0e56089e413444d34f020f4
MIT
2020-09-01T23:55:44.000Z
2020-09-01T23:55:44.000Z
Qwen/Qwen-72B
1. YES
2. YES