Ramsey-Cass-Koopmans (RCK) model

The RCK model is an extension of the Solow-Swan model, pioneered by Ramsey (1928) and extended by Cass (1965) and Koopmans (1965). Known also as the Neoclassical Growth Model, it is a "workhorse" of modern macroeconomics and forms the basis of the majority of modern works in economic growth and business cycles literature.

While in the OLG model there were an infinite number of agents (since in every new period a new generation entered the economy) and they had a finite time horizon, in the Ramsey model there is a finite number of agents with an infinite time horizon.

This can be justified by the following argument. In the (basic) OLG model parents are "selfish" and leave no assets to their children. However in the real world we see that at least some individuals leave sizeable bequests and support their children financially throughout their lives. This implies that parents care for their children's "utility".

In the RCK model it is assumed that parents care about their children as much as they care about themselves. Therefore, each household is in fact a "dynasty" of individuals with an infinite planning horizon, and the welfare function of a household is constructed as follows:

\begin{align} U = \sum_{t=0}^{\infty}\beta^{t}u\left(c_{t}\right) \end{align}

where $\beta$ is a discount factor and $u\left(\cdot\right)$ is an instantaneous utility function (felicity function).

Usually the instantaneous utility function is represented by a Constant Relative Risk Aversion (CRRA) function:

\begin{align} u\left(c_{t}\right) = \frac{c_{t}^{1-\sigma}-1}{1-\sigma} \end{align}

where $\sigma>0$ regulates the degree of risk aversion.

We will first consider a RCK model with simplifying assumptions that yield an analytical solution, and then consider a general case.

Firms' problem

The problem of the firms will be the same for both simplified and general cases. The firms want to hire optimal quantities of labor and capital to maximize their profits:

\begin{align} \max\quad\Pi_{t}=K_{t}^{\alpha}\left(A_{t}L_{t}\right)^{1-\alpha}-w_{t}L_{t}-r_{t}^{k}K_{t} \end{align}

First order conditions (FOCs):

\begin{align} \frac{\partial\Pi_{t}}{\partial L_{t}} & =\left(1-\alpha\right)K_{t}^{\alpha}A_{t}^{1-\alpha}L_{t}^{-\alpha}-w_{t}=0\\ \frac{\partial\Pi_{t}}{\partial K_{t}} & =\alpha K_{t}^{\alpha-1}\left(A_{t}L_{t}\right)^{1-\alpha}-r_{t}^{k}=0 \end{align}

Simplify the above expressions:

\begin{align} w_{t} & =\left(1-\alpha\right)A_{t}\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha}\\ r_{t}^{k} & =\alpha\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha-1} \end{align}

The above equations determine both the wage $w$ and the capital rental rate $r^{k}$ as functions of capital (per effective labor). The real interest rate is equal to the capital rental rate, less the capital depreciation rate:

\begin{align} r_{t} & =r_{t}^{k}-\delta \end{align}

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

# Import numerical computations library
import numpy as np

# Import plotting library
import matplotlib.pyplot as plt

# Import minimization function
from scipy.optimize import minimize

# Import functions from AppliedMacroPlots.py
from AppliedMacroPlots import *

Simplified model

Households' problem

Let us now make the simplifying assumptions. There is no population and technology growth, and without loss of generality we can normalize $A=1$, so that capital per effective labor and capital per worker are equivalent. We will also assume total depreciation of capital ($\delta=1$) and that the instantaneous utility function is logarithmic.

The representative "dynasty" solves the following problem:

\begin{align} \max\quad & U=\sum_{t=0}^{\infty}\beta^{t}\log c_{t}\\ \text{subject to}\quad & c_{t}+a_{t+1}=w_{t}+\left(1+r_{t}\right)a_{t} \end{align}

Write down the Lagrangian:

\begin{align} \mathcal{L}=\sum_{t=0}^{\infty}\beta^{t}\log c_{t}+\sum_{t=0}^{\infty}\lambda_{t}\left[w_{t}+\left(1+r_{t}\right)a_{t}-c_{t}-a_{t+1}\right] \end{align}

Note that we have an infinity of time periods and Lagrange multipliers. Rewrite the Lagrangian so that it is easier to take derivatives:

\begin{align} \mathcal{L} & =\ldots+\beta^{t}\log c_{t}+\ldots\\ & \quad+\ldots+\lambda_{t}\left[w_{t}+\left(1+r_{t}\right)a_{t}-c_{t}-a_{t+1}\right]\\ & \quad+\lambda_{t+1}\left[w_{t+1}+\left(1+r_{t+1}\right)a_{t+1}-c_{t+1}-a_{t+2}\right]+\ldots \end{align}

In each period $t$ we can choose period $t$ consumption $c_{t}$ and end-of-period $t$ assets $a_{t+1}$.

First order conditions (FOCs):

\begin{align} \frac{\partial\mathcal{L}}{\partial c_{t}} & =\beta^{t}\frac{1}{c_{t}}+\lambda_{t}\left[-1\right]=0\\ \frac{\partial\mathcal{L}}{\partial a_{t+1}} & =\lambda_{t}\left[-1\right]+\lambda_{t+1}\left[\left(1+r_{t+1}\right)\right]=0 \end{align}

Simplify and rewrite:

\begin{align} \lambda_{t} & =\beta^{t}\frac{1}{c_{t}}\\ \lambda_{t} & =\left(1+r_{t+1}\right)\lambda_{t+1} \end{align}

Join conditions:

\begin{align} \beta^{t}\frac{1}{c_{t}} & =\left(1+r_{t+1}\right)\beta^{t+1}\frac{1}{c_{t+1}}\\ \frac{1}{c_{t}} & =\left(1+r_{t+1}\right)\beta\frac{1}{c_{t+1}}\\ c_{t+1} & =\beta\left(1+r_{t+1}\right)c_{t} \end{align}

We have obtained the standard Euler equation.

The optimal behavior of the households can then be restated as:

\begin{align} c_{t+1} & =\beta\left(1+r_{t+1}\right)c_{t}\\ c_{t}+a_{t+1} & =w_{t}+\left(1+r_{t}\right)a_{t} \end{align}

And after some algebra the optimal consumpion in period $t$ can be expressed as:

\begin{align} c_{t}=\frac{1}{1-\beta}\left[\left(1+r_{t}\right)a_{t}+\sum_{i=0}^{\infty}\frac{w_{t+i}}{1+\bar{r}_{t+i}}\right] \end{align}

where:

\begin{align} 1+\bar{r}_{t+i}=\begin{cases} 1 & \text{for }i=0\\ \left(1+r_{t+1}\right)\cdot\ldots\cdot\left(1+r_{t+i}\right) & \text{for }i=1,2,\ldots \end{cases} \end{align}

As you can see, the optimal behavior of households requires them to formulate accurate forecasts of prices $w$ and $r$.

General Equilibrium

The above solution of the households' problem is still relatively general, as we haven't made full use of our simplifying assumptions yet. Consider now the general equilibrium, where all markets clear.

Since there is no government and no international trade, domestic capital is the only asset which can be in positive net supply:

\begin{align} a_{t} = k_{t} \quad \text{for all } t \end{align}

And the budget constraint of the households can be rewritten as:

\begin{align} c_{t}+a_{t+1} & =w_{t}+\left(1+r_{t}\right)a_{t} \\ c_{t}+k_{t+1}&=w_{t}+\left(1+r_{t}\right)k_{t} \end{align}

We can also use the expressions for prices (recall that $A=1$ and $\delta=1$):

\begin{align} w_{t} & =\left(1-\alpha\right)A_{t}\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha}=\left(1-\alpha\right)k_{t}^{\alpha}\\ r_{t}^{k} & =\alpha\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha-1}=\alpha k_{t}^{\alpha-1}\\ r_{t} & =r_{t}^{k}-\delta=\alpha k_{t}^{\alpha-1}-1 \end{align}

And plug them into the budget constraint:

\begin{align} c_{t}+k_{t+1} & =\left(1-\alpha\right)k_{t}^{\alpha}+\left(1+\alpha k_{t}^{\alpha-1}-1\right)k_{t}\\ c_{t}+k_{t+1} & =\left(1-\alpha\right)k_{t}^{\alpha}+\alpha k_{t}^{\alpha}\\ c_{t}+k_{t+1} & =k_{t}^{\alpha} \end{align}

Solution

Finally, let us guess-and-verify that this economy behaves as a Solow-Swan economy, and the households save a constant fraction $s$ of their income:

\begin{align} k_{t+1} & =sy_{t}=s\cdot k_{t}^{\alpha}\\ c_{t} & =\left(1-s\right)y_{t}=\left(1-s\right)\cdot k_{t}^{\alpha} \end{align}

Use the Euler equation:

\begin{align} c_{t+1} & =\beta\left(1+r_{t+1}\right)c_{t}\\ c_{t+1} & =\beta\alpha k_{t+1}^{\alpha-1}c_{t}\\ \left(1-s\right)\cdot k_{t+1}^{\alpha} & =\beta\alpha k_{t+1}^{\alpha-1}\left(1-s\right)\cdot k_{t}^{\alpha}\\ k_{t+1} & =\beta\alpha\cdot k_{t}^{\alpha} \end{align}

Indeed, the saving rate is a constant:

\begin{align} s=\alpha\beta \end{align}

Note that $\partial s / \partial \beta > 0$ and that $s \leq \alpha = s_{GR}$, with equality when $\beta=1$ (households care just as much about the future and the present). This implies that the RCK economy is never dynamically inefficient.

Under our assumptions, we can obtain an analytical, closed form solution (no need to forecast prices!) of the RCK model:

\begin{align} c_{t} & =\left(1-\alpha\beta\right)\cdot k_{t}^{\alpha}\\ k_{t+1} & =\alpha\beta\cdot k_{t}^{\alpha} \end{align}

Finally, let us find the steady state of the model:

\begin{align} k^{*} & =\alpha\beta\left(k^{*}\right)^{\alpha}\\ \left(k^{*}\right)^{1-\alpha} & =\alpha\beta\\ k^{*} & =\left(\alpha\beta\right)^{1/\left(1-\alpha\right)}\\ c^{*} & =\left(1-\alpha\beta\right)\cdot \left(\alpha\beta\right)^{\alpha/\left(1-\alpha\right)} \end{align}

The first plot below illustrates the process of convergence to the steady state over time. Note that since $\delta=1$, the convergence is very fast.

The second plot is a new type of plot, called a phase diagram, and will illustrate the convergence to the steady state in the $(k, c)$ space.

In [2]:
# Parameters
α = 0.33
β = 0.96
δ = 1

# Steady state
k_star = (α*β)**(1/(1-α))
c_star = (1-α*β) * k_star**α

# Number of periods
T = 10+1

k_t = np.zeros(T)
c_t = np.zeros(T)

# Initial level of capital per worker
k_0 = k_star/20

# Solving the model forward
k_t[0] = k_0
c_t[0] = (1-α*β) * k_0**α

for t in range(T-1):
    k_t[t+1] = α*β * k_t[t]**α
    c_t[t+1] = (1-α*β) * k_t[t+1]**α

# Store results for future use
k_simple, c_simple = k_t, c_t
In [3]:
# Convergence plot
plt.plot(k_t, lw=2, label='$k$')
plt.plot(c_t, lw=2, label='$c$')

plt.hlines(k_star, 0, T-1, color='C0', lw=1, linestyle='--')
plt.hlines(c_star, 0, T-1, color='C1', lw=1, linestyle='--')

plt.title('Convergence to steady state over time')
plt.xlabel('Period')
plt.legend(loc='lower right')

plt.show()
In [4]:
# Phase diagram

kk = np.linspace(0, 1.5*k_star, 1000)
cc = np.linspace(0, 1.5*c_star, 1000)

plt.plot(kk, kk**α - δ*kk, lw=2, label='$k_{t+1}=k_{t}$')
plt.plot(kk**0 * k_star, cc, lw=2, label='$c_{t+1}=c_{t}$')
plt.plot(k_star, c_star, 'ro', label='Steady state')
plt.plot(k_t, c_t, 'k-', label='Saddle path')

plt.title('Phase diagram of the RCK model')
plt.xlabel('Capital per worker $k$')
plt.ylabel('Consumption per worker $c$')
plt.legend(loc='lower right')

plt.show()

The phase diagram shows a number of conditions.

The first one, $k_{t+1}=k_{t}$, describes a set of combinations of $k$ and $c$ for which capital per worker does not change over time. We can find them via the budget/resource constraint:

\begin{align} c_{t}+k_{t+1} & =k_{t}^{\alpha}\\ c_{t} &= k_{t}^{\alpha} - k_{t+1} \end{align}

If $k_{t+1}=k_{t}=k$:

\begin{align} c = k^{\alpha} - k \end{align}

The second condition, $c_{t+1}=c_{t}$, describes a set of combinations of $k$ and $c$ for which consumption per worker does not change over time. We can find them via the Euler equation:

\begin{align} c_{t+1} & =\beta\left(1+r_{t+1}\right)c_{t}\\ 1 &= \beta\left(1+r_{t+1}\right)\\ r_{t+1} &= \frac{1}{\beta} - 1\\ \alpha k_{t+1}^{\alpha-1}-1 &= \frac{1}{\beta} - 1 \\ k_{t+1}^{\alpha-1} &= \frac{1}{\alpha\beta}\\ k_{t+1} &= \left(\alpha\beta\right)^{1/\left(1-\alpha\right)} = k^{*}\\ \end{align}

That means that when the capital per worker is at its steady state level, $c_{t+1}=c_{t}$ for all $c$.

Obviously, the intersection of $k_{t+1}=k_{t}$ and $c_{t+1}=c_{t}$ is by definition the steady state of the model.

Finally, the "saddle path" is our model's solution. Importantly, there is only one path that leads from any possible level of capital per worker $k$ to the steady state. This guarantees that the model has a unique solution.

Neoclassical Growth Model

We now turn to analyzing the full RCK/NGM model. Population grows at rate $n$, while technology improves at rate $g$. The firms' problem is the same as before. What is a bit different is the households' problem.

Households' problem

The representative "dynasty" solves the following problem:

\begin{align} \max\quad & U=\sum_{t=0}^{\infty}\beta^{t}\cdot\frac{c_{t}^{1-\sigma}-1}{1-\sigma}\\ \text{subject to}\quad & c_{t}+\left(1+n\right)a_{t+1}=w_{t}+\left(1+r_{t}\right)a_{t} \end{align}

Lagrangian:

\begin{align} \mathcal{L}=\sum_{t=0}^{\infty}\beta^{t}\cdot\frac{c_{t}^{1-\sigma}-1}{1-\sigma}+\sum_{t=0}^{\infty}\lambda_{t}\left[w_{t}+\left(1+r_{t}\right)a_{t}-c_{t}-\left(1+n\right)a_{t+1}\right] \end{align}

Expand the Lagrangian:

\begin{align} \mathcal{L} & =\ldots+\beta^{t}\cdot\frac{c_{t}^{1-\sigma}-1}{1-\sigma}+\ldots\\ & \quad+\ldots+\lambda_{t}\left[w_{t}+\left(1+r_{t}\right)a_{t}-c_{t}-\left(1+n\right)a_{t+1}\right]\\ & \quad+\lambda_{t+1}\left[w_{t+1}+\left(1+r_{t+1}\right)a_{t+1}-c_{t+1}-\left(1+n\right)a_{t+2}\right]+\ldots \end{align}

First order conditions (FOCs):

\begin{align} \frac{\partial\mathcal{L}}{\partial c_{t}} & =\beta^{t}c_{t}^{-\sigma}+\lambda_{t}\left[-1\right]=0\\ \frac{\partial\mathcal{L}}{\partial a_{t+1}} & =\lambda_{t}\left[-\left(1+n\right)\right]+\lambda_{t+1}\left[\left(1+r_{t+1}\right)\right]=0 \end{align}

Simplify and rewrite:

\begin{align} \lambda_{t} & =\beta^{t}c_{t}^{-\sigma}\\ \left(1+n\right)\lambda_{t} & =\left(1+r_{t+1}\right)\lambda_{t+1} \end{align}

Join conditions:

\begin{align} \left(1+n\right)\beta^{t}c_{t}^{-\sigma} & =\left(1+r_{t+1}\right)\beta^{t+1}c_{t+1}^{-\sigma}\\ c_{t}^{-\sigma} & =\frac{1+r_{t+1}}{1+n}\beta c_{t+1}^{-\sigma}\\ \left(\frac{c_{t+1}}{c_{t}}\right)^{\sigma} & =\beta\frac{1+r_{t+1}}{1+n}\\ \frac{c_{t+1}}{c_{t}} & =\left(\beta\frac{1+r_{t+1}}{1+n}\right)^{1/\sigma}\\ c_{t+1} & =\left(\beta\frac{1+r_{t+1}}{1+n}\right)^{1/\sigma}c_{t} \end{align}

We have obtained the Euler equation. Note that if $n=0$ and $\sigma=1$, we go back to our usual form of Euler equation.

General Equilibrium

Again, since there is no government and no international trade, domestic capital is the only asset which can be in positive net supply:

\begin{align} a_{t} = k_{t} \quad \text{for all } t \end{align}

And the budget constraint of the households can be rewritten as:

\begin{align} c_{t}+\left(1+n\right)a_{t+1} & =w_{t}+\left(1+r_{t}\right)a_{t} \\ c_{t}+\left(1+n\right)k_{t+1}&=w_{t}+\left(1+r_{t}\right)k_{t} \end{align}

We can also use the expressions for prices (but this time technology improves over time, so we make use of per effective labor variables):

\begin{align} w_{t} & =\left(1-\alpha\right)A_{t}\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha}=\left(1-\alpha\right)A_{t}\hat{k}_{t}^{\alpha}\\ r_{t}^{k} & =\alpha\left(\frac{K_{t}}{A_{t}L_{t}}\right)^{\alpha-1}=\alpha \hat{k}_{t}^{\alpha-1}\\ r_{t} & =r_{t}^{k}-\delta=\alpha \hat{k}_{t}^{\alpha-1}-\delta \end{align}

And plug them into the budget constraint:

\begin{align} c_{t}+\left(1+n\right)k_{t+1} & =\left(1-\alpha\right)A_{t}\hat{k}_{t}^{\alpha}+\left(1+\alpha\hat{k}_{t}^{\alpha-1}-\delta\right)k_{t}\quad|\quad:A_{t}\\ \hat{c}_{t}+\left(1+n\right)\frac{k_{t+1}}{A_{t}} & =\left(1-\alpha\right)\hat{k}_{t}^{\alpha}+\left(1+\alpha\hat{k}_{t}^{\alpha-1}-\delta\right)\hat{k}_{t}\\ \hat{c}_{t}+\left(1+n\right)\frac{A_{t+1}}{A_{t}}\frac{k_{t+1}}{A_{t+1}} & =\left(1-\alpha\right)\hat{k}_{t}^{\alpha}+\alpha\hat{k}_{t}^{\alpha}+\left(1-\delta\right)\hat{k}_{t}\\ \left(1+n\right)\left(1+g\right)\hat{k}_{t+1} & =\hat{k}_{t}^{\alpha}-\hat{c}_{t}+\left(1-\delta\right)\hat{k}_{t}\\ \hat{k}_{t+1} & =\frac{\hat{k}_{t}^{\alpha}-\hat{c}_{t}+\left(1-\delta\right)\hat{k}_{t}}{\left(1+n\right)\left(1+g\right)} \end{align}

The $\hat{k}_{t}^{\alpha}-\hat{c}_{t}$ part represents gross investment, and is the analogue of $s\cdot\hat{k}_{t}^{\alpha}$ in the Solow-Swan and OLG models.

Plug in the interest rate into the Euler equation and rewrite it in per effective labor terms:

\begin{align} c_{t+1} & =\left(\beta\frac{1+r_{t+1}}{1+n}\right)^{1/\sigma}c_{t}\quad|\quad:A_{t}\\ \frac{c_{t+1}}{A_{t}} & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\frac{c_{t}}{A_{t}}\\ \frac{A_{t+1}}{A_{t}}\frac{c_{t+1}}{A_{t+1}} & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\hat{c}_{t}\\ \left(1+g\right)\hat{c}_{t+1} & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\hat{c}_{t}\\ \hat{c}_{t+1} & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\frac{\hat{c}_{t}}{\left(1+g\right)} \end{align}

Steady state

If $\hat{c}_{t+1}=\hat{c}_{t}$, then:

\begin{align} \left(1+g\right) & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\\ \left(1+g\right)^{\sigma} & =\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\\ \frac{\left(1+g\right)^{\sigma}\left(1+n\right)}{\beta} & =1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta\\ \alpha\hat{k}_{t+1}^{\alpha-1} & =\frac{\left(1+g\right)^{\sigma}\left(1+n\right)}{\beta}-\left(1-\delta\right)\\ \hat{k}_{t+1}^{\alpha-1} & =\frac{\left(1+g\right)^{\sigma}\left(1+n\right)-\beta\left(1-\delta\right)}{\alpha\beta}\\ \hat{k}^{*} & =\left[\frac{\alpha\beta}{\left(1+g\right)^{\sigma}\left(1+n\right)-\beta\left(1-\delta\right)}\right]^{1/\left(1-\alpha\right)} \end{align}

Note that if $\beta=1$ and $\sigma=1$, then we can express $\hat{k}^{*}$ as:

\begin{align} \hat{k}^{*}=\left[\frac{\alpha}{\left(1+g\right)\left(1+n\right)-\left(1-\delta\right)}\right]^{1/\left(1-\alpha\right)}=\left[\frac{\alpha}{\delta+n+g+ng}\right]^{1/\left(1-\alpha\right)} \end{align}

which is equivalent to the Solow-Swan model solution, given that the saving rate is at its golden rule level.

If $\hat{k}_{t+1}=\hat{k}_{t}=\hat{k}$, then:

\begin{align} \left(1+n\right)\left(1+g\right)\hat{k}_{t+1} & =\hat{k}_{t}^{\alpha}-\hat{c}_{t}+\left(1-\delta\right)\hat{k}_{t}\\ \left(1+n\right)\left(1+g\right)\hat{k} & =\hat{k}^{\alpha}-\hat{c}+\left(1-\delta\right)\hat{k} \end{align}

\begin{align} \hat{c} & =\hat{k}^{\alpha}+\left(1-\delta\right)\hat{k}-\left(1+n\right)\left(1+g\right)\hat{k}\\ \hat{c} & =\hat{k}^{\alpha}-\left(\delta+n+g+ng\right)\hat{k} \end{align}

And the steady state level of consumption per effective labor is given by:

\begin{align} \hat{c}^{*} & =\left(\hat{k}^{*}\right)^{\alpha}-\left(\delta+n+g+ng\right)\hat{k}^{*}\\ \end{align}

Transition (saddle) path

Along the transition to the steady state, the model variables have to obey the following conditions:

\begin{align} \hat{k}_{t+1} & =\frac{\hat{k}_{t}^{\alpha}-\hat{c}_{t}+\left(1-\delta\right)\hat{k}_{t}}{\left(1+n\right)\left(1+g\right)}\\ \hat{c}_{t+1} & =\left(\beta\frac{1+\alpha\hat{k}_{t+1}^{\alpha-1}-\delta}{1+n}\right)^{1/\sigma}\frac{\hat{c}_{t}}{\left(1+g\right)} \end{align}

Solving the RCK model is equivalent to finding, for some initial level of capital per effective labor $\hat{k}_{0}$, such $\hat{c}_{0}$ that the above forward equations bring $\hat{k}$ and $\hat{c}$ to the steady state.

We will solve the model by the shooting algorithm. We will try different values of $\hat{c}_{0}$ and see whether they are too high or too low.

In [5]:
# Define needed functions

def ProductionFunction(k, params):
    α = params['α']
    return k**α

def InterestRate(k, params):
    α = params['α']
    δ = params['δ']
    return α*k**(α-1) - δ
    
def SteadyState(params):
    α = params['α']
    δ = params['δ']
    n = params['n']
    g = params['g']
    β = params['β']
    σ = params['σ']
    
    r_star = (1+n) * (1+g)**σ / β - 1
    k_star = (α/(r_star+δ))**(1/(1-α))
    c_star = ProductionFunction(k_star, params) - (δ+n+g+n*g)*k_star
    
    return k_star, c_star

def ResourceConstraint(k, c, params):
    α = params['α']
    δ = params['δ']
    n = params['n']
    g = params['g']
    
    return (ProductionFunction(k, params) + (1-δ)*k - c)/((1+n)*(1+g))

def EulerEquation(k, c, params):
    n = params['n']
    g = params['g']
    β = params['β']
    σ = params['σ']
    
    k_next = ResourceConstraint(k, c, params)
    
    if k_next > 0:
        r = InterestRate(k_next, params)
        c_next = (β*(1+r)/(1+n))**(1/σ) * c / (1+g)
        return c_next
    else:
        return 0

def Constant_k(k, params):
    δ = params['δ']
    n = params['n']
    g = params['g']
    
    return ProductionFunction(k, params) - (δ+n+g+n*g)*k
In [6]:
# Parameters
params = {'α':0.33, 'δ':0.1, 'n':0.01, 'g':0.02, 'σ':2, 'β':0.96}

# Steady state
print(SteadyState(params))
k_star, c_star = SteadyState(params)
(2.1998170781123654, 1.0107259548758)
In [7]:
# Forward equations and convergence criterion

def Path(c_0, k_0, params, T=100):
    
    T += 1
    
    k_t = np.zeros(T)
    c_t = np.zeros(T)
    
    k_t[0] = k_0
    c_t[0] = c_0
    
    for t in range(T-1):
        k_t[t+1] = ResourceConstraint(k_t[t], c_t[t], params)
        if k_t[t+1] > 0:
            c_t[t+1] = EulerEquation(k_t[t], c_t[t], params)
        else:
            k_t[t+1] = 0
            c_t[t+1] = 0
            
    return k_t, c_t

def Path_crit(c_0, k_0, params, T=100):
    
    k_t, c_t = Path(c_0, k_0, params, T)
    k_star, c_star = SteadyState(params)
    
    ss_diff = np.sqrt((k_t-k_star)**2 + (c_t-c_star)**2)
    
    return np.min(ss_diff) + ss_diff[-1]

Below we will make attempts to target the steady state, but in the first case the initial guess will be too low and in the second too high.

In [8]:
k_0 = k_star / 20
c_0 = 0.34

k_t, c_t = Path(c_0, k_0, params)

plt.plot(k_t, c_t, 'ko-')
plt.plot(k_star, c_star, 'ro')
plt.show()
In [9]:
k_0 = k_star / 20
c_0 = 0.35

k_t, c_t = Path(c_0, k_0, params)

plt.plot(k_t, c_t, 'ko-')
plt.plot(k_star, c_star, 'ro')
plt.show()
In [10]:
# Confirm that convergence criterion attains minimum in the chosen range

cc_0 = np.linspace(0.34, 0.345)

for c_0 in cc_0:
    plt.plot(c_0, Path_crit(c_0, k_0, params), 'bo')
    
plt.show()
In [11]:
# Find the function minimum, starting from an initial guess
result = minimize(Path_crit, 0.34, args=(k_0, params, 100), method='Nelder-Mead')
print(result)

c_0 = result.x
 final_simplex: (array([[0.34203463],
       [0.34203463]]), array([0.0003119 , 0.00039346]))
           fun: 0.00031189826075628333
       message: 'Optimization terminated successfully.'
          nfev: 100
           nit: 50
        status: 0
       success: True
             x: array([0.34203463])
In [12]:
# Phase diagram
k_t, c_t = Path(c_0, k_0, params, 50)

kk = np.linspace(0, 1.5*k_star, 1000)
cc = np.linspace(0, 1.5*c_star, 1000)

plt.plot(kk, Constant_k(kk, params), lw=2, label='$\hat{k}_{t+1}=\hat{k}_{t}$')
plt.plot(kk**0 * k_star, cc, lw=2, label='$\hat{c}_{t+1}=\hat{c}_{t}$')
plt.plot(k_star, c_star, 'ro', label='Steady state')
plt.plot(k_t, c_t, 'k-', label='Saddle path')

plt.title('Phase diagram of the RCK model')
plt.xlabel('Capital per effective labor $\hat{k}$')
plt.ylabel('Consumption per effective labor $\hat{c}$')
plt.legend(loc='lower right')

plt.show()

Let us now verify that our code runs correctly, by solving again the simplified model, for which we have an analytic solution.

In [13]:
# Parameters
params_simple = {'α':0.33, 'δ':1, 'n':0, 'g':0, 'σ':1, 'β':0.96}

# Steady state
print(SteadyState(params_simple))
k_star_simple, c_star_simple = SteadyState(params_simple)
(0.17984701877776357, 0.3878519041318438)
In [14]:
# Find the function minimum, starting from an initial guess
result_simple = minimize(Path_crit, 0.1, 
                         args=(k_star_simple / 20, params_simple, 100), 
                         method='Nelder-Mead')
print(result_simple)

c_0_simple = result_simple.x
 final_simplex: (array([[0.14431984],
       [0.14431984]]), array([0.42762086, 0.42769224]))
           fun: 0.4276208631306686
       message: 'Optimization terminated successfully.'
          nfev: 69
           nit: 34
        status: 0
       success: True
             x: array([0.14431984])
In [15]:
# Generate transition path
k_check, c_check = Path(c_0_simple, k_star_simple / 20, params_simple, 10)

kk = np.linspace(0, 1.5*k_star_simple, 1000)
cc = np.linspace(0, 1.5*c_star_simple, 1000)

plt.plot(kk, Constant_k(kk, params_simple), lw=2, label='$k_{t+1}=k_{t}$')
plt.plot(kk**0 * k_star_simple, cc, lw=2, label='$c_{t+1}=c_{t}$')
plt.plot(k_star_simple, c_star_simple, 'ro', label='Steady state')
plt.plot(k_check, c_check, 'k-', lw=4, label='Saddle path')
plt.plot(k_simple, c_simple, 'y-', lw=2, label='Analytic solution')

plt.title('Phase diagram of the RCK model')
plt.xlabel('Capital per worker $k$')
plt.ylabel('Consumption per worker $c$')
plt.legend(loc='lower right')

plt.show()

plt.plot(k_simple, (c_simple-c_check)**2, lw=2)
plt.title('Squared errors')
plt.show()

It seems that our numerical procedure can recover the analytical solution (although there might be some coding error at the last period, which I have to fix :) ).

Let us now take a look at the behavior of capital, consumption and saving rate over time in our full model.

In [16]:
s_t = 1 - c_t/ProductionFunction(k_t, params)
s_star = 1-c_star/ProductionFunction(k_star, params)

plt.plot(k_t, lw=2)
plt.hlines(k_star, 0, 50, lw=1, linestyle='--')
plt.title('Capital per effective labor $\hat{k}$')
plt.xlabel('Period')
plt.show()

plt.plot(c_t, lw=2)
plt.hlines(c_star, 0, 50, lw=1, linestyle='--')
plt.title('Consumption per effective labor $\hat{c}$')
plt.xlabel('Period')
plt.show()

plt.plot(s_t, lw=2)
plt.hlines(s_star, 0, 50, lw=1, linestyle='--')
plt.title('Saving rate $s$')
plt.xlabel('Period')
plt.ylim(0.2, 0.3)
plt.show()

Usually the RCK model generates decreasing saving rate along the transition path. The condition for when the saving rate is decreasing is summarized by:

\begin{align} s^{*} < 1/\sigma \end{align}

while the BGP saving rate is a function of model parameters. The saving rates of countries rarely exceed 40%, and empirical estimates for $\sigma$ usually place it around 2 (although with high uncertainty).

Below I present a set of parameters for which the saving rate is increasing over time.

In [17]:
# Parameters
params_dec = {'α':0.33, 'δ':0.1, 'n':0.01, 'g':0.02, 'σ':5, 'β':0.96}

# Steady state
print(SteadyState(params_dec))
k_star_dec, c_star_dec = SteadyState(params_dec)

# Find the function minimum, starting from an initial guess
result_dec = minimize(Path_crit, 0, 
                      args=(k_star_dec / 20, params_dec, 100), 
                      method='Nelder-Mead')
print('\n', result_dec)

# Generate transition path
c_0_dec = result_dec.x
k_dec, c_dec = Path(c_0_dec, k_star_dec / 20, params_dec, 100)

# Check if steady state was reached

kk = np.linspace(0, 1.5*k_star_dec, 1000)
cc = np.linspace(0, 1.5*c_star_dec, 1000)

plt.plot(kk, Constant_k(kk, params_dec), lw=2, label='$\hat{k}_{t+1}=\hat{k}_{t}$')
plt.plot(kk**0 * k_star_dec, cc, lw=2, label='$\hat{c}_{t+1}=\hat{c}_{t}$')
plt.plot(k_star_dec, c_star_dec, 'ro', label='Steady state')
plt.plot(k_dec, c_dec, 'k-', label='Saddle path')

plt.title('Phase diagram of the RCK model')
plt.xlabel('Capital per effective labor $\hat{k}$')
plt.ylabel('Consumption per effective labor $\hat{c}$')
plt.legend(loc='lower right')

plt.show()

# Saving rate
s_dec = 1 - c_dec/ProductionFunction(k_dec, params_dec)
s_star_dec = 1-c_star_dec/ProductionFunction(k_star_dec, params_dec)

plt.plot(s_dec[:51], lw=2)
plt.hlines(s_star_dec, 0, 50, lw=1, linestyle='--')
plt.title('Saving rate $s$')
plt.xlabel('Period')
plt.show()
(1.4144859318431158, 0.937071262069986)

  final_simplex: (array([[0.3656976],
       [0.3656976]]), array([0.00026281, 0.00030694]))
           fun: 0.0002628131940320468
       message: 'Optimization terminated successfully.'
          nfev: 143
           nit: 71
        status: 0
       success: True
             x: array([0.3656976])

This last exercise also gives us insight on the shape of the transition path as a function of $\sigma$.

As can be seen below, transition path for higher $\sigma$ consumers runs close to the $\hat{k}_{t+1}=\hat{k}_{t}$ condition.

Also, higher $\sigma$ consumers end up with lower consumption per effective worker in the steady state, provided that $g>0$.

In [18]:
# Parameters
params_low = {'α':0.33, 'δ':0.1, 'n':0.01, 'g':0.02, 'σ':0.2, 'β':0.96}

# Steady state
print(SteadyState(params_low))
k_star_low, c_star_low = SteadyState(params_low)

# Find the function minimum, starting from an initial guess
result_low = minimize(Path_crit, 0, 
                      args=(k_star_dec / 20, params_low, 50), 
                      method='Nelder-Mead')
print('\n', result_low)

# Generate transition path
c_0_low = result_low.x
k_low, c_low = Path(c_0_low, k_star_dec / 20, params_low, 50)
(3.051988845882611, 1.0477792009922147)

  final_simplex: (array([[0.02842781],
       [0.02842781]]), array([0.00061262, 0.00070923]))
           fun: 0.0006126176462043319
       message: 'Optimization terminated successfully.'
          nfev: 116
           nit: 58
        status: 0
       success: True
             x: array([0.02842781])
In [19]:
kk = np.linspace(0, 1.5*k_star_low, 1000)
cc = np.linspace(0, 1.5*c_star_low, 1000)

plt.plot(kk, Constant_k(kk, params_low), lw=2)

plt.plot(kk**0 * k_star_low, cc, 'r--', lw=2)
plt.plot(k_star_low, c_star_low, 'ro', label='Steady state ($\sigma_{L}$)')
plt.plot(k_low, c_low, 'r-', label='Saddle path ($\sigma_{L}$)')

plt.plot(kk**0 * k_star_dec, cc, 'b--', lw=2)
plt.plot(k_star_dec, c_star_dec, 'bo', label='Steady state ($\sigma_{L}$)')
plt.plot(k_dec, c_dec, 'b-', label='Saddle path ($\sigma_{L}$)')

plt.title('Phase diagram of the RCK model')
plt.xlabel('Capital per effective labor $\hat{k}$')
plt.ylabel('Consumption per effective labor $\hat{c}$')
plt.legend(loc='lower right')

# plt.xlim(0, 4)

plt.show()
In [20]:
# Compare consumption paths

plt.plot(c_t, 'r')
plt.plot(c_dec[:51], 'b')
plt.show()

In this context, risk aversion can be related to the standard deviation of consumption paths: consumers with high $\sigma$ start with higher and end up with lower consumption that consumers with low $\sigma$.