Skip to article frontmatterSkip to article content
Contents
and

23. Dynamics in One Dimension

23.1Overview

In economics many variables depend on their past values

For example, it seems reasonable to believe that inflation last year with affects inflation this year.

(Perhaps high inflation last year will lead people to demand higher wages to compensate, which will feed into higher prices this year.)

Letting πt\pi_t be inflation this year and πt1\pi_{t-1} be inflation last year, we can write this relationship in a general form as

πt=f(πt1)\pi_t = f(\pi_{t-1})

where ff is some function describing the relationship between the variables.

This equation is an example of one-dimensional discrete time dynamic system.

In this lecture we cover the foundations of one-dimensional discrete time dynamics.

(While most quantitative models have two or more state variables, the one-dimensional setting is a good place to learn foundations and understand key concepts.)

Let’s start with some standard imports:

import matplotlib.pyplot as plt
import numpy as np

23.2Some definitions

This section sets out the objects of interest and the kinds of properties we study.

23.2.1Composition of functions

For this lecture you should know the following.

If

  • gg is a function from AA to BB and
  • ff is a function from BB to CC,

then the composition fgf \circ g of ff and gg is defined by

(fg)(x)=f(g(x))(f \circ g)(x) = f(g(x))

For example, if

  • A=B=C=RA=B=C=\mathbb R, the set of real numbers,
  • g(x)=x2g(x)=x^2 and f(x)=xf(x)=\sqrt{x}, then (fg)(x)=x2=x(f \circ g)(x) = \sqrt{x^2} = |x|.

If ff is a function from AA to itself, then f2f^2 is the composition of ff with itself.

For example, if A=(0,)A = (0, \infty), the set of positive numbers, and f(x)=xf(x) = \sqrt{x}, then

f2(x)=x=x1/4f^2(x) = \sqrt{\sqrt{x}} = x^{1/4}

Similarly, if nn is a positive integer, then fnf^n is nn compositions of ff with itself.

In the example above, fn(x)=x1/(2n)f^n(x) = x^{1/(2^n)}.

23.2.2Dynamic systems

A (discrete time) dynamic system is a set SS and a function gg that sends set SS back into to itself.

Examples of dynamic systems include

  • S=(0,1)S = (0, 1) and g(x)=xg(x) = \sqrt{x}
  • S=(0,1)S = (0, 1) and g(x)=x2g(x) = x^2
  • S=ZS = \mathbb Z (the integers) and g(x)=2xg(x) = 2 x

On the other hand, if S=(1,1)S = (-1, 1) and g(x)=x+1g(x) = x+1, then SS and gg do not form a dynamic system, since g(1)=2g(1) = 2.

  • gg does not always send points in SS back into SS.

We care about dynamic systems because we can use them to study dynamics!

Given a dynamic system consisting of set SS and function gg, we can create a sequence {xt}\{x_t\} of points in SS by setting

xt+1=g(xt) with x0 given. x_{t+1} = g(x_t) \quad \text{ with } x_0 \text{ given}.

This means that we choose some number x0x_0 in SS and then take

x0,x1=g(x0),x2=g(x1)=g(g(x0)),etc. x_0, \quad x_1 = g(x_0), \quad x_2 = g(x_1) = g(g(x_0)), \quad \text{etc.}

This sequence {xt}\{x_t\} is called the trajectory of x0x_0 under gg.

In this setting, SS is called the state space and xtx_t is called the state variable.

Recalling that gng^n is the nn compositions of gg with itself, we can write the trajectory more simply as

xt=gt(x0) for t=0,1,2,x_t = g^t(x_0) \quad \text{ for } t = 0, 1, 2, \ldots

In all of what follows, we are going to assume that SS is a subset of R\mathbb R, the real numbers.

Equation (4) is sometimes called a first order difference equation

  • first order means dependence on only one lag (i.e., earlier states such as xt1x_{t-1} do not enter into (4)).

23.2.3Example: a linear model

One simple example of a dynamic system is when S=RS=\mathbb R and g(x)=ax+bg(x)=ax + b, where a,ba, b are constants (sometimes called ``parameters’').

This leads to the linear difference equation

xt+1=axt+b with x0 given.x_{t+1} = a x_t + b \quad \text{ with } x_0 \text{ given}.

The trajectory of x0x_0 is

x0,ax0+b,a2x0+ab+b,etc.x_0, \quad a x_0 + b, \quad a^2 x_0 + a b + b, \quad \text{etc.}

Continuing in this way, and using our knowledge of geometric series, we find that, for any t=0,1,2,t = 0, 1, 2, \ldots,

xt=atx0+b1at1a x_t = a^t x_0 + b \frac{1 - a^t}{1 - a}

We have an exact expression for xtx_t for all non-negative integer tt and hence a full understanding of the dynamics.

Notice in particular that a<1|a| < 1, then, by (9), we have

xtb1a as tx_t \to \frac{b}{1 - a} \text{ as } t \to \infty

regardless of x0x_0.

This is an example of what is called global stability, a topic we return to below.

23.2.4Example: a nonlinear model

In the linear example above, we obtained an exact analytical expression for xtx_t in terms of arbitrary non-negative integer tt and x0x_0.

This made analysis of dynamics very easy.

When models are nonlinear, however, the situation can be quite different.

For example, in a later lecture The Solow-Swan Growth Model, we will study the Solow-Swan growth model, which has dynamics

kt+1=sAktα+(1δ)ktk_{t+1} = s A k_t^{\alpha} + (1 - \delta) k_t

Here k=K/Lk=K/L is the per capita capital stock, ss is the saving rate, AA is the total factor productivity, α is the capital share, and δ is the depreciation rate.

All these parameter are positive and 0<α,δ<10 < \alpha, \delta < 1.

If you try to iterate like we did in (8), you will find that the algebra gets messy quickly.

Analyzing the dynamics of this model requires a different method (see below).

23.3Stability

Consider a dynamic system consisting of set SRS \subset \mathbb R and gg mapping SS to SS.

23.3.1Steady states

A steady state of this system is a point xx^* in SS such that x=g(x)x^* = g(x^*).

In other words, xx^* is a fixed point of the function gg in SS.

For example, for the linear model xt+1=axt+bx_{t+1} = a x_t + b, you can use the definition to check that

  • x:=b/(1a)x^* := b/(1-a) is a steady state whenever a1a \not= 1,
  • if a=1a = 1 and b=0b=0, then every xRx \in \mathbb R is a steady state,
  • if a=1a = 1 and b0b \not= 0, then the linear model has no steady state in R\mathbb R.

23.3.2Global stability

A steady state xx^* of the dynamic system is called globally stable if, for all x0Sx_0 \in S,

xt=gt(x0)x as tx_t = g^t(x_0) \to x^* \text{ as } t \to \infty

For example, in the linear model xt+1=axt+bx_{t+1} = a x_t + b with a1a \not= 1, the steady state xx^*

  • is globally stable if a<1|a| < 1 and
  • fails to be globally stable otherwise.

This follows directly from (9).

23.3.3Local stability

A steady state xx^* of the dynamic system is called locally stable if there exists an ϵ>0\epsilon > 0 such that

x0x<ϵ        xt=gt(x0)x as t| x_0 - x^* | < \epsilon \; \implies \; x_t = g^t(x_0) \to x^* \text{ as } t \to \infty

Obviously every globally stable steady state is also locally stable.

Here is an example where the converse is not true.

23.4Graphical analysis

As we saw above, analyzing the dynamics for nonlinear models is nontrivial.

There is no single way to tackle all nonlinear models.

However, there is one technique for one-dimensional models that provides a great deal of intuition.

This is a graphical approach based on 45-degree diagrams.

Let’s look at an example: the Solow-Swan model with dynamics given in (11).

We begin with some plotting code that you can ignore at first reading.

The function of the code is to produce 45-degree diagrams and time series plots.

Source
def subplots():
    "Custom subplots with axes throught the origin"
    fig, ax = plt.subplots()

    # Set the axes through the origin
    for spine in ['left', 'bottom']:
        ax.spines[spine].set_position('zero')
        ax.spines[spine].set_color('green')
    for spine in ['right', 'top']:
        ax.spines[spine].set_color('none')

    return fig, ax


def plot45(g, xmin, xmax, x0, num_arrows=6, var='x'):

    xgrid = np.linspace(xmin, xmax, 200)

    fig, ax = subplots()
    ax.set_xlim(xmin, xmax)
    ax.set_ylim(xmin, xmax)
    ax.set_xlabel(r'${}_t$'.format(var), fontsize=14)
    ax.set_ylabel(r'${}_{}$'.format(var, str('{t+1}')), fontsize=14)

    hw = (xmax - xmin) * 0.01
    hl = 2 * hw
    arrow_args = dict(fc="k", ec="k", head_width=hw,
            length_includes_head=True, lw=1,
            alpha=0.6, head_length=hl)

    ax.plot(xgrid, g(xgrid), 'b-', lw=2, alpha=0.6, label='g')
    ax.plot(xgrid, xgrid, 'k-', lw=1, alpha=0.7, label='45')

    x = x0
    xticks = [xmin]
    xtick_labels = [xmin]

    for i in range(num_arrows):
        if i == 0:
            ax.arrow(x, 0.0, 0.0, g(x), **arrow_args) # x, y, dx, dy
        else:
            ax.arrow(x, x, 0.0, g(x) - x, **arrow_args)
            ax.plot((x, x), (0, x), 'k', ls='dotted')

        ax.arrow(x, g(x), g(x) - x, 0, **arrow_args)
        xticks.append(x)
        xtick_labels.append(r'${}_{}$'.format(var, str(i)))

        x = g(x)
        xticks.append(x)
        xtick_labels.append(r'${}_{}$'.format(var, str(i+1)))
        ax.plot((x, x), (0, x), 'k', ls='dotted')

    xticks.append(xmax)
    xtick_labels.append(xmax)
    ax.set_xticks(xticks)
    ax.set_yticks(xticks)
    ax.set_xticklabels(xtick_labels)
    ax.set_yticklabels(xtick_labels)

    bbox = (0., 1.04, 1., .104)
    legend_args = {'bbox_to_anchor': bbox, 'loc': 'upper right'}

    ax.legend(ncol=2, frameon=False, **legend_args, fontsize=14)
    plt.show()

def ts_plot(g, xmin, xmax, x0, ts_length=6, var='x'):
    fig, ax = subplots()
    ax.set_ylim(xmin, xmax)
    ax.set_xlabel(r'$t$', fontsize=14)
    ax.set_ylabel(r'${}_t$'.format(var), fontsize=14)
    x = np.empty(ts_length)
    x[0] = x0
    for t in range(ts_length-1):
        x[t+1] = g(x[t])
    ax.plot(range(ts_length),
            x,
            'bo-',
            alpha=0.6,
            lw=2,
            label=r'${}_t$'.format(var))
    ax.legend(loc='best', fontsize=14)
    ax.set_xticks(range(ts_length))
    plt.show()

Let’s create a 45-degree diagram for the Solow-Swan model with a fixed set of parameters. Here’s the update function corresponding to the model.

def g(k, A = 2, s = 0.3, alpha = 0.3, delta = 0.4):
    return A * s * k**alpha + (1 - delta) * k

Here is the 45-degree plot.

xmin, xmax = 0, 4  # Suitable plotting region.

plot45(g, xmin, xmax, 0, num_arrows=0)
<Figure size 640x480 with 1 Axes>

The plot shows the function gg and the 45-degree line.

Think of ktk_t as a value on the horizontal axis.

To calculate kt+1k_{t+1}, we can use the graph of gg to see its value on the vertical axis.

Clearly,

  • If gg lies above the 45-degree line at this point, then we have kt+1>ktk_{t+1} > k_t.
  • If gg lies below the 45-degree line at this point, then we have kt+1<ktk_{t+1} < k_t.
  • If gg hits the 45-degree line at this point, then we have kt+1=ktk_{t+1} = k_t, so ktk_t is a steady state.

For the Solow-Swan model, there are two steady states when S=R+=[0,)S = \mathbb R_+ = [0, \infty).

  • the origin k=0k=0
  • the unique positive number such that k=szkα+(1δ)kk = s z k^{\alpha} + (1 - \delta) k.

By using some algebra, we can show that in the second case, the steady state is

k=(szδ)1/(1α)k^* = \left( \frac{sz}{\delta} \right)^{1/(1-\alpha)}

23.4.1Trajectories

By the preceding discussion, in regions where gg lies above the 45-degree line, we know that the trajectory is increasing.

The next figure traces out a trajectory in such a region so we can see this more clearly.

The initial condition is k0=0.25k_0 = 0.25.

k0 = 0.25

plot45(g, xmin, xmax, k0, num_arrows=5, var='k')
<Figure size 640x480 with 1 Axes>

We can plot the time series of per capita capital corresponding to the figure above as follows:

ts_plot(g, xmin, xmax, k0, var='k')
<Figure size 640x480 with 1 Axes>

Here’s a somewhat longer view:

ts_plot(g, xmin, xmax, k0, ts_length=20, var='k')
<Figure size 640x480 with 1 Axes>

When per capita capital stock is higher than the unique positive steady state, we see that it declines:

k0 = 2.95

plot45(g, xmin, xmax, k0, num_arrows=5, var='k')
<Figure size 640x480 with 1 Axes>

Here is the time series:

ts_plot(g, xmin, xmax, k0, var='k')
<Figure size 640x480 with 1 Axes>

23.4.2Complex dynamics

The Solow-Swan model is nonlinear but still generates very regular dynamics.

One model that generates irregular dynamics is the quadratic map

g(x)=4x(1x),x[0,1]g(x) = 4 x (1 - x), \qquad x \in [0, 1]

Let’s have a look at the 45-degree diagram.

xmin, xmax = 0, 1
g = lambda x: 4 * x * (1 - x)

x0 = 0.3
plot45(g, xmin, xmax, x0, num_arrows=0)
<Figure size 640x480 with 1 Axes>

Now let’s look at a typical trajectory.

plot45(g, xmin, xmax, x0, num_arrows=6)
<Figure size 640x480 with 1 Axes>

Notice how irregular it is.

Here is the corresponding time series plot.

ts_plot(g, xmin, xmax, x0, ts_length=6)
<Figure size 640x480 with 1 Axes>

The irregularity is even clearer over a longer time horizon:

ts_plot(g, xmin, xmax, x0, ts_length=20)
<Figure size 640x480 with 1 Axes>

23.5Exercises

Solution to Exercise 1

We will start with the case a=0.5a=0.5.

Let’s set up the model and plotting region:

a, b = 0.5, 1
xmin, xmax = -1, 3
g = lambda x: a * x + b

Now let’s plot a trajectory:

x0 = -0.5
plot45(g, xmin, xmax, x0, num_arrows=5)
<Figure size 640x480 with 1 Axes>

Here is the corresponding time series, which converges towards the steady state.

ts_plot(g, xmin, xmax, x0, ts_length=10)
<Figure size 640x480 with 1 Axes>

Now let’s try a=0.5a=-0.5 and see what differences we observe.

Let’s set up the model and plotting region:

a, b = -0.5, 1
xmin, xmax = -1, 3
g = lambda x: a * x + b

Now let’s plot a trajectory:

x0 = -0.5
plot45(g, xmin, xmax, x0, num_arrows=5)
<Figure size 640x480 with 1 Axes>

Here is the corresponding time series, which converges towards the steady state.

ts_plot(g, xmin, xmax, x0, ts_length=10)
<Figure size 640x480 with 1 Axes>

Once again, we have convergence to the steady state but the nature of convergence differs.

In particular, the time series jumps from above the steady state to below it and back again.

In the current context, the series is said to exhibit damped oscillations.

CC-BY-SA-4.0

Creative Commons License – This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International.