Shone, R. (2002). Economic Dynamics: Phase Diagrams and their Economic Application, 2nd ed. Cambridge University Press. Chapters 1–7. DOI: 10.1017/CBO9781139165020
Shone, R. (2001). An Introduction to Economic Dynamics. Cambridge University Press. Chapter 1 (linear recursion, nonlinear fixed points — the spreadsheet-based treatment). DOI: 10.1017/CBO9781139164733
Azariadis, C. (1993). Intertemporal Macroeconomics. Blackwell.
Chiang, A. C. (1992). Elements of Dynamic Optimization. McGraw-Hill.
Soetaert, K., Petzoldt, T. & Setzer, R. W. (2010). Solving differential equations in R. Journal of Statistical Software, 33(9). DOI: 10.18637/jss.v033.i09
Part I: Introduction to Economic Dynamics
Foundations — what dynamics is and why it matters
What Is Economic Dynamics?
A dynamic model describes how economic variables change over time, in contrast to a static model where relationships hold at a single point in time.
Both fixed points repel; trajectories converge instead to the stable period-2 cycle\(\{0, 2\}\), since \(f(0) = 2\) and \(f(2) = 0\) with \(|f'(0)\,f'(2)| = 0 < 1\) (Shone 2001, §1.8).
Stability: the deviation \((x_0 - x^*)\) decays to zero if and only if \(b < 0\). If \(b = 0\) the system reduces to \(\dot{x} = a\), giving linear growth \(x(t) = x_0 + at\).
Key insight: As compounding frequency \(m \to \infty\), discrete and continuous compound interest formulas coincide. This is the bridge between Parts II and III.
Separable ODE:
\[\dot{x} = \alpha x \!\left(1 - \frac{x}{K}\right)\]
Economic applications: population growth models, diffusion of new technology, market saturation — any bounded growth process.
Technology/information diffusion (S-curve)
Let \(N\) = total population, \(x(t)\) = adopters:
\[\dot{x} = \beta x(N - x)\]
This is the logistic equation with \(K = N\), \(\alpha = \beta N\).
Solution:\(x(t) = \dfrac{N}{1 + e^{-\beta N(t - t_0)}}\) where \(t_0\) is the inflection point.
Bass model (1969)
Bass model (1969): extends this to \(\dot{x} = (p + q x/N)(N - x)\), where \(p\) = innovation coefficient, \(q\) = imitation coefficient. Used to forecast adoption of new products (TVs, mobile phones, EV cars).
Step 3 — write general solution according to the sign of \(\Delta\):
\(\Delta\)
Roots
General solution \(x(t)\)
Behaviour
\(> 0\)
real distinct \(r_1 \neq r_2\)
\(A e^{r_1 t} + B e^{r_2 t}\)
monotone
\(= 0\)
repeated \(r_1 = r_2 = r\)
\((A + Bt)e^{rt}\)
monotone with \(t\)-weight
\(< 0\)
complex \(\alpha \pm \beta i\)
\(e^{\alpha t}(A\cos\beta t + B\sin\beta t)\)
oscillatory
Step 4 — apply initial conditions to pin down \(A\) and \(B\) (shown in each case tab).
Why the exponential trial?
Why assume \(e^{rt}\)? Because it is the only function whose derivatives are proportional to itself, so all three terms \(\ddot{x}, \dot{x}, x\) share the same exponential — the equation reduces to an algebraic problem.
When \(\Delta = 0\) the two basis functions \(e^{r_1 t}\) and \(e^{r_2 t}\) coincide, so we need a second independent solution. It can be shown by reduction of order that \(t e^{rt}\) is the missing solution.
The \(t\) prefactor means the function first rises then falls if \(B > 0\) (the \(Bt\) term dominates briefly before the exponential wins). This hump-shaped path is characteristic of the repeated-root case.
The conditions are necessary and sufficient — check them without computing the roots.
\(a\)
\(b\)
Verdict
\(> 0\)
\(> 0\)
stable — all roots have negative real part
\(> 0\)
\(< 0\)
unstable — one root positive
\(< 0\)
any
unstable — roots sum to \(-a > 0\)
\(= 0\)
\(> 0\)
centre — pure oscillation, \(\text{Re}(r) = 0\)
Economic interpretation: for a second-order economic model (e.g. multiplier-accelerator, inventory cycle), stability requires both a positive damping coefficient (\(a > 0\), friction in adjustment) and a positive restoring force (\(b > 0\), tendency to return to equilibrium).
Euler is first-order accurate — error \(\mathcal{O}(h^2)\) per step, \(\mathcal{O}(h)\) globally. Use deSolve::ode() (RK4/5) or scipy.integrate.solve_ivp() in practice. Euler matters for intuition and for proving stability results, not for accurate computation.
Geometric picture: the true solution is a curve; Euler replaces it with a sequence of straight-line segments, each following the slope \(f(t_n, x_n)\) computed at the start of the interval. Because the slope is frozen for the whole step, the approximation drifts away from the curve — more so when \(f\) changes quickly or \(h\) is large.
Local truncation error (error introduced in one step, assuming the previous point was exact):
Each ten-fold reduction in \(h\) reduces the error by roughly ten-fold — confirming \(\mathcal{O}(h)\) global convergence.
Stability of the discretisation itself
Stability of the discretisation itself: applying Euler to \(\dot{x} = \lambda x\) gives \(x_{n+1} = (1 + h\lambda)x_n\). This recursion is stable only if \(|1 + h\lambda| < 1\). For \(\lambda < 0\) this requires \(h < 2/|\lambda|\) — too large a step can make Euler diverge even when the true ODE is stable.
Code
# Hand-written Euler integrator: dx/dt = f(t, x)euler_step <-function(f, x, t, h) x + h *f(t, x)euler_solve <-function(f, x0, t0, tmax, h) { n_steps <-floor((tmax - t0) / h) t_vec <- t0 + (0:n_steps) * h x_vec <-numeric(n_steps +1); x_vec[1] <- x0for (n inseq_len(n_steps)) { x_vec[n +1] <-euler_step(f, x_vec[n], t_vec[n], h) }data.frame(t = t_vec, x = x_vec)}f_decay <-function(t, x) -2* x # ẋ = -2xexact <-function(t) exp(-2* t)# Compare several step sizes against the exact solutionstep_sizes <-c(0.5, 0.1, 0.01)euler_runs <-lapply(step_sizes, function(h) {euler_solve(f_decay, x0 =1, t0 =0, tmax =3, h = h) %>%mutate(h =factor(h))})t_fine <-seq(0, 3, by =0.01)df_exact <-data.frame(t = t_fine, x =exact(t_fine))bind_rows(euler_runs) %>%ggplot() +aes(x = t, y = x, color = h) +geom_line(data = df_exact, aes(x = t, y = x),inherit.aes =FALSE, color ="black", linewidth =1, linetype ="dashed") +geom_line(linewidth =1) +geom_point(size =1) +scale_color_manual(values =c(col_accent, col_warn, col_ok), name ="step h") +labs(x ="t", y ="x(t)",title ="Euler method vs. exact solution: ẋ = -2x (dashed = exact)") + theme_lecture
General form with a forcing term \(g(t)\) on the right-hand side:
\[a\ddot{y} + b\dot{y} + cy = g(t)\]
Write \(L(y) = a\ddot{y} + b\dot{y} + cy\), so the equation is \(L(y) = g(t)\).
Key idea — superposition: if \(y_c\) solves the homogeneous equation \(L(y_c)=0\) (the “complementary solution”, found exactly as in the previous slide) and \(y_p\) solves \(L(y_p) = g(t)\) (a “particular solution”), then their sum also solves the full equation:
Differentiate the whole equation enough times to turn \(g(t)\) into \(0\), giving a higher-order homogeneous equation \(L_h(y_h) = 0\); solve for \(y_h\)
Subtract\(y_q = y_h - y_c\) — this isolates the new terms introduced by \(g(t)\)
Substitute \(y_q\) back into \(L(y_q) = g(t)\) and match coefficients of like powers of \(t\) to pin down the unknown constants, giving \(y_p\)
Shortcut in practice
Shortcut in practice: for polynomial, exponential, or sinusoidal \(g(t)\), guess \(y_p\) has the same functional form as \(g(t)\) (a polynomial of matching degree, etc.) and solve directly for its coefficients — steps 2–3 are a formal justification for why that guess works.
Step 2 — raise the order. Differentiate the whole equation once more to eliminate the constant forcing term \(t\): \(y^{(3)} + y^{(2)} = 0\) has auxiliary equation \(r^3 + r^2 = 0\), roots \(0,0,0,-1\) (double root \(r=0\) needs \(t,\,t^2\) terms):
\[y_h = c_1 + c_2 e^{-t} + c_3 t + c_4 t^2\]
Step 3 — isolate the new terms.\(y_q = y_h - y_c = c_3 t + c_4 t^2\)
Step 4 — match coefficients. Substitute \(y_q = c_3 t + c_4 t^2\) into \(\ddot{y}+\dot{y}=t\):
\(c_1, c_2\) are then fixed by \(y(0)\) and \(\dot y(0)\), exactly as in the homogeneous case.
Economic reading
Economic reading: the particular solution \(y_p = -t + \tfrac12 t^2\) is the trend the system is forced to follow because of the constant push \(g(t)=t\); the complementary solution \(y_c = c_1 + c_2e^{-t}\) is the transient that dies out (\(e^{-t}\to 0\)), leaving the trend to dominate as \(t\to\infty\).
Code
# ÿ + ẏ = t with y(0) = 1, ẏ(0) = 0# Convert to first-order system: z1 = y, z2 = ẏrhs_nonhom <-function(t, z, parms) {list(c(z[2], t - z[2])) # ż2 = g(t) - z2 = t - ẏ}sol_nonhom <-ode(y =c(y =1, v =0), times =seq(0, 6, by =0.05),func = rhs_nonhom, parms =NULL) %>%as.data.frame()# Closed form: y(t) = c1 + c2*exp(-t) - t + 0.5*t^2# Apply y(0)=1, ẏ(0)=0 ⇒ c1 + c2 = 1, -c2 - 1 = 0 ⇒ c2 = -1, c1 = 2exact_nonhom <-function(t) 2-exp(-t) - t +0.5* t^2sol_nonhom %>%ggplot() +aes(x = time) +geom_line(aes(y = y), color = col_main, linewidth =1.6) +geom_line(data =data.frame(t = sol_nonhom$time, ex =exact_nonhom(sol_nonhom$time)),aes(x = t, y = ex), color = col_accent, linewidth =1, linetype ="dashed") +labs(x ="t", y ="y(t)",title =expression(ddot(y) +dot(y) == t ~" — numeric (blue) vs. closed form (dashed)")) + theme_lecture
Code
import sympy as spimport numpy as npimport matplotlib.pyplot as pltt = sp.Symbol("t")y = sp.Function("y")# ÿ + ẏ = t, y(0)=1, ẏ(0)=0ode_eq = sp.Eq(y(t).diff(t, 2) + y(t).diff(t), t)sol = sp.dsolve(ode_eq, y(t), ics={y(0): 1, y(t).diff(t).subs(t, 0): 0})print("Particular solution with y(0)=1, ẏ(0)=0:")
Problem: most economically-interesting ODEs \(\dot{x} = f(x)\) are nonlinear and have no closed-form solution. But we can still determine local stability near a fixed point.
Step 1 — find fixed points by solving \(f(x^*) = 0\) (there may be several).
Liapunov’s Theorem: if \(\dot{x}=f(x)\) has linear approximation \(f(x) \approx f'(x^*)(x-x^*)\) and \(x^*\) is (globally) stable for this linear approximation, then \(x^*\) is asymptotically stable for the original nonlinear equation — but only locally, near \(x^*\). The converse is false: a nonlinear system can be stable while its linearisation is not (see the cautionary example).
Solow growth model in continuous time:
\[\dot{k} = f(k) = sak^{\alpha} - (n+\delta)k\]
where \(k\) = capital per worker, \(s\) = savings rate, \(a\) = TFP, \(\alpha \in (0,1)\), \(n\) = population growth, \(\delta\) = depreciation.
Fixed points: factor out \(k\): \(k\bigl[sak^{\alpha-1}-(n+\delta)\bigr]=0\)
Linearise at \(k_1^*=0\):\(f'(k) = \alpha sa\,k^{\alpha-1} - (n+\delta) \to \infty\) as \(k\to 0\) (since \(\alpha - 1 < 0\)) — the linear approximation breaks down at the origin.
Conditional convergence, derived analytically: the speed of convergence \((n+\delta)(1-\alpha)\) falls out directly from linearising the Solow ODE — no simulation needed. Economies with higher depreciation/population growth or lower capital share converge faster to \(k_2^*\).
The unique fixed point \(x^*\) is globally stable: for \(x<x^*\), \((x-x^*)^3<0\) so \(\dot x = a(x-x^*)^3 > 0\) (moves right, toward \(x^*\)); for \(x>x^*\), \((x-x^*)^3>0\) so \(\dot x<0\) (moves left, toward \(x^*\)). Trajectories converge to \(x^*\) from both sides.
The linear approximation is \(\dot x = 0\) — a system that does not move at all, which is not stable in the usual asymptotic sense (any \(x_0 \neq x^*\) just stays at \(x_0\) forever under the linearised dynamics).
Lesson
Lesson: when \(f'(x^*)=0\), the first-order Taylor approximation is uninformative — higher-order terms (here the cubic) govern the true dynamics. Liapunov’s theorem is a one-way implication: linear stability \(\Rightarrow\) nonlinear stability, but not the reverse. Always check \(f'(x^*) \neq 0\) before trusting the linearisation.
Code
s_p <-0.25; a_p <-1; alpha_p <-0.35; n_p <-0.02; delta_p <-0.04f_solow <-function(k) s_p * a_p * k^alpha_p - (n_p + delta_p) * kk2_star <- (s_p * a_p / (n_p + delta_p))^(1/ (1- alpha_p))slope_at_k2 <--(n_p + delta_p) * (1- alpha_p) # analytical f'(k2*)k_grid <-seq(0.01, k2_star *2, length.out =200)# True nonlinear ODE vs. its linear approximation around k2*f_true <-f_solow(k_grid)f_linear <- slope_at_k2 * (k_grid - k2_star)df_lin <-data.frame(k = k_grid, nonlinear = f_true, linear = f_linear)df_lin %>%ggplot() +aes(x = k) +geom_line(aes(y = nonlinear), color = col_main, linewidth =1.6) +geom_line(aes(y = linear), color = col_accent, linewidth =1.2, linetype ="dashed") +geom_hline(yintercept =0, color ="grey40") +geom_vline(xintercept = k2_star, linetype ="dotted", color = col_ok) +annotate("text", x = k2_star *1.05, y =max(f_true) *0.3,label =paste0("k2* = ", round(k2_star, 2)), color = col_ok, size =5, hjust =0) +labs(x ="k", y =expression(dot(k) ==f(k)),title ="Solow: nonlinear f(k) (blue) vs. linear approx. at k2* (dashed)") + theme_lecture
Code
import numpy as npimport matplotlib.pyplot as plts, a, alpha, n, delta =0.25, 1.0, 0.35, 0.02, 0.04def f_solow(k):return s * a * k**alpha - (n + delta) * kk2_star = (s * a / (n + delta)) ** (1/ (1- alpha))slope_k2 =-(n + delta) * (1- alpha) # analytical f'(k2*)k_grid = np.linspace(0.01, k2_star *2, 300)f_true = f_solow(k_grid)f_linear = slope_k2 * (k_grid - k2_star)fig, ax = plt.subplots(figsize=(10, 5))ax.plot(k_grid, f_true, color="#185FA5", linewidth=2.2, label="nonlinear f(k)")ax.plot(k_grid, f_linear, color="#D85A30", linewidth=1.4, linestyle="--", label="linear approx. at k2*")ax.axhline(0, color="grey", linewidth=0.9)ax.axvline(k2_star, color="#1D9E75", linestyle=":", linewidth=1.2)ax.text(k2_star *1.05, max(f_true) *0.3, f"k2* = {k2_star:.2f}", color="#1D9E75", fontsize=12)ax.set_xlabel("k", fontsize=13)ax.set_ylabel(r"$\dot{k} = f(k)$", fontsize=13)ax.set_title("Solow: nonlinear f(k) vs. linear approximation at k2*", fontsize=13)ax.legend(fontsize=11)plt.tight_layout()plt.show()
\[f'(x^*) > 0 \;\Rightarrow\; \text{arrows point away from } x^* \;\Rightarrow\; \textbf{unstable (repeller)}\]
Why it is useful
Why it is useful: you get a complete qualitative picture — stability, direction of motion, basins of attraction — without solving a single integral. This is especially powerful when \(f(x)\) has no closed-form solution.
Key read-offs from the phase portrait: - The \(x\)-intercept gives \(x^*\) immediately - The sign of the slope of \(f\) at the crossing tells you stability - The distance of the curve from zero tells you how fast \(x\) moves
Time path without solving
Time path without solving: starting from \(x_0 = 0.1\) (left of \(x^*\)), arrows point right all the way to \(x^* = 2\). The closer \(x\) is to \(x^*\), the flatter \(f(x)\), so the slower the approach — the system decelerates as it converges. This matches the exponential \(x(t) = 2 + (0.1 - 2)e^{-2t}\).
Code
xv <-seq(-0.5, 4.5, by =0.05)f_val <-4-2* xv # f(x) = 4 - 2x# Direction arrows on the x-axisarrow_x <-c(0.4, 1.0, 1.6, 2.4, 3.0, 3.6)arrow_dx <-ifelse(4-2* arrow_x >0, 0.35, -0.35)ggplot() +aes(x = xv, y = f_val) +geom_line(data =data.frame(xv, f_val),color = col_main, linewidth =1.6) +geom_hline(yintercept =0, color ="grey40", linewidth =0.8) +geom_vline(xintercept =2, linetype ="dashed", color = col_accent, linewidth =1) +geom_segment(data =data.frame(x = arrow_x, xend = arrow_x + arrow_dx, y =-0.25, yend =-0.25),aes(x = x, xend = xend, y = y, yend = yend),arrow =arrow(type ="closed", length =unit(0.18, "cm")),color = col_ok, linewidth =1.2 ) +geom_point(aes(x =2, y =0), color = col_accent, size =4) +annotate("text", x =2.15, y =4.5,label ="x* = 2 (stable)", color = col_accent, size =5, hjust =0) +annotate("text", x =0.3, y =2.8,label ="f(x) > 0\nx increases", color = col_ok, size =4, hjust =0) +annotate("text", x =2.8, y =-1.5,label ="f(x) < 0\nx decreases", color = col_accent, size =4, hjust =0) +labs(x ="x", y =expression(dot(x) ==f(x)),title ="Phase portrait: ẋ = 4 − 2x (one stable equilibrium)") + theme_lecture
Basin of attraction: all \(x_0 > 0\) converge to \(K = 100\); \(x_0 < 0\) is infeasible here.
Multiple stable equilibria → path dependence
Multiple stable equilibria → path dependence. A cubic \(f(x)\) with three zeros (e.g. two stable, one unstable) means the long-run outcome depends entirely on the initial condition \(x_0\). History matters — there is no unique globally-stable equilibrium. This is the formal basis for hysteresis in unemployment and poverty traps in development economics.
Generalisation: for any smooth \(f\): - zeros alternate between stable and unstable (under generic conditions) - stable equilibria are separated by unstable ones (the unstable ones act as thresholds) - the unstable equilibrium defines the boundary between basins of attraction
Code
r_l <-0.5; K_l <-100xv_m <-seq(-10, 130, by =0.5)fv_m <- r_l * xv_m * (1- xv_m / K_l)# Arrow positions and directionsax_m <-c(-8, -4, 20, 50, 80, 110, 120)adx_m <-ifelse(r_l * ax_m * (1- ax_m / K_l) >0, 6, -6)# Labels for equilibrium stabilityeq_pts <-data.frame(x =c(0, 100),label =c("x*=0\n(unstable)", "x*=100\n(stable)"),col =c(col_accent, col_ok))ggplot() +geom_line(data =data.frame(x = xv_m, y = fv_m),aes(x = x, y = y), color = col_main, linewidth =1.6) +geom_hline(yintercept =0, color ="grey40", linewidth =0.8) +geom_segment(data =data.frame(x = ax_m, xend = ax_m + adx_m, y =-1.8, yend =-1.8),aes(x = x, xend = xend, y = y, yend = yend),arrow =arrow(type ="closed", length =unit(0.18, "cm")),color = col_ok, linewidth =1.2 ) +geom_point(data = eq_pts, aes(x = x, y =0, color = col), size =5) +scale_color_identity() +geom_vline(xintercept =0, linetype ="dashed", color = col_accent, linewidth =0.9) +geom_vline(xintercept =100, linetype ="dashed", color = col_ok, linewidth =0.9) +annotate("text", x =3, y =11, label ="x*=0\n(unstable)", color = col_accent, size =4.5) +annotate("text", x =103, y =11, label ="x*=100\n(stable)", color = col_ok, size =4.5) +labs(x ="x", y =expression(dot(x) ==f(x)),title ="Phase portrait: logistic growth ẋ = 0.5x(1 − x/100)") + theme_lecture
\[q^d_t = a - b p_t \quad \text{(demand, current price)}\]\[q^s_t = c + d p_{t-1} \quad \text{(supply, lagged price)}\]
Market clearing \(q^d_t = q^s_t\):
\[p_t = \frac{a-c}{b+d} - \frac{d}{b} p_{t-1}\]
Fixed point:\(p^* = (a-c)/(b+d)\)
Stability:\(|{-d/b}| < 1\), i.e., \(d < b\)
Producers base supply on last period’s price; demand responds to current price.
\(|d/b|\)
Behaviour
\(< 1\)
converging cobweb
\(= 1\)
perpetual oscillation
\(> 1\)
diverging cobweb
Empirical relevance
Empirical relevance: Agricultural markets (pig cycles, cattle cycles) exhibit cobweb dynamics. The slope ratio \(d/b\) compares supply elasticity to demand elasticity. When supply is more elastic than demand, the market diverges.
Oscillations possible for \(\beta > (1-\alpha)^2/(4\alpha)\).
Samuelson (1939)
Samuelson (1939): The multiplier-accelerator model explains business cycles endogenously — no external shocks needed. The interplay between consumption smoothing (\(\alpha\)) and investment acceleration (\(\beta\)) produces cyclical fluctuations.
Global convergence: \(k_t \to k^*\) from any \(k_0 > 0\).
Conditional convergence
Conditional convergence: The Solow model predicts countries converge to their own \(k^*\), which depends on \(s\), \(\delta\), and the production technology \(\alpha\). Countries with higher savings rates have higher steady-state capital per worker.
Nullclines (isoclines): - \(\dot{x} = 0\): locus where \(x\) is stationary - \(\dot{y} = 0\): locus where \(y\) is stationary - Intersection: fixed point \((x^*, y^*)\)
Direction of motion: determine sign of \(\dot{x}\), \(\dot{y}\) in each region; arrows define the vector field.
Linear system:
\[\begin{bmatrix} \dot{x} \\ \dot{y} \end{bmatrix} = \mathbf{A} \begin{bmatrix} x \\ y \end{bmatrix} + \mathbf{b}\]
Limit cycle: closed orbit in phase space to which all nearby trajectories converge.
Economic application: endogenous business cycles — persistent oscillations without external shocks.
Energy injection and dissipation: - Near \(|x| < 1\): damping term \(\mu(1-x^2) > 0\)injects energy - For \(|x| > 1\): \(\mu(1-x^2) < 0\)dissipates energy - Net result: stable oscillation of fixed amplitude \(\approx 2\)
For any \(\mu > 0\) and any initial condition (except origin): - Interior trajectories spiral outward to the limit cycle - Exterior trajectories spiral inward to the limit cycle
Hopf bifurcation (Part VII)
Hopf bifurcation (Part VII): At \(\mu = 0\) the origin is a centre. As \(\mu\) increases through 0, the equilibrium becomes unstable and a limit cycle is born — this is the supercritical Hopf bifurcation.
If \(\mathbf{A}\) has distinct eigenvalues \(r, s\) with eigenvectors \(\mathbf{v}^r, \mathbf{v}^s\), form \(\mathbf{V} = [\mathbf{v}^r \; \mathbf{v}^s]\):
\[\mathbf{D} = \mathbf{V}^{-1}\mathbf{A}\mathbf{V} = \begin{bmatrix} r & 0 \\ 0 & s \end{bmatrix}\]
Contrast with continuous systems: continuous stability requires \(\text{Re}(\lambda) < 0\) (left half-plane); discrete stability requires \(|\lambda| < 1\) (inside unit circle). The unit circle is the discrete analogue of the imaginary axis.
Negative \(s\) → oscillations (sign alternation) while converging.
Eigenvectors:
For \(r = 0.7262\): \(\mathbf{v}^r = \begin{bmatrix}0.5793\\1\end{bmatrix}\)
For \(s = -0.8262\): \(\mathbf{v}^s = \begin{bmatrix}5.7537\\1\end{bmatrix}\)
Alternating Overshooting
The negative eigenvalue \(s = -0.826\) produces alternating overshooting — the system oscillates while converging. This resembles “cobweb” dynamics in 2D.
Fish harvesting:\(x(t)\) = fish stock; \(u(t)\) = harvest rate; \(V\) = profit. Too much → stock collapse; too little → foregone profit. Find: optimal harvest path\(\{u^*(t)\}\).
Mine problem
Mine problem: finite resource \(x_0\) tons of iron ore; \(u_t\) = extraction rate; \(V(u_t)\) = revenue. Optimal plan exhausts the resource exactly at \(T\) (Hotelling rule: price rises at rate of interest).
Ramsey-Cass-Koopmans
Ramsey-Cass-Koopmans: choose consumption \(c(t)\) to maximise discounted utility \(\int_0^\infty e^{-\rho t} u(c) \, dt\) subject to capital accumulation \(\dot{k} = f(k) - c - \delta k\).
Costate interpretation:\(\lambda(t)\) is the shadow price — the marginal increase in objective \(J\) from a unit increase in the state \(x(t)\). Transversality \(\lambda(T) = 0\) means additional state at the terminal time has zero value.
Current value Hamiltonian:\(H_c = V + \rho\lambda_{t+1}f\)
Hotelling rule
Hotelling rule: For an exhaustible resource (mine), the optimal price rises at the rate of interest: \(\dot{p}/p = \delta\). Discounting accelerates extraction — future revenue is worth less today, so it pays to extract more now.
Nullclines: - \(\dot{x} = 0\): \(\lambda\) as function of \(x\) when \(x\) stationary - \(\dot{\lambda} = 0\): analogously
Intersection = steady state \((x^{ss}, \lambda^{ss})\).
Optimal control problems typically yield a saddle point in the \((x, \lambda)\) phase plane: - One stable manifold: the saddle path - One unstable manifold
The transversality condition\(\lambda(\infty) = 0\) selects the unique trajectory on the saddle path.
Jump variable logic
Jump variable logic: Given \(x(0) = x^0\) (predetermined), there is a unique\(\lambda(0)\) consistent with optimality. The costate \(\lambda(0)\) “jumps” to the saddle path at \(t = 0\) and the economy follows it to the steady state. This is the basis of rational expectations / perfect-foresight equilibria.
Interpretation: consumption grows when the net return to capital \(r(k) > \rho\) (impatience rate). At steady state \(r(k^*) = \rho\) — the modified golden rule.
Saddle path: The \((k, c)\) phase plane has a saddle equilibrium. The unique optimal trajectory is the saddle path — the economy jumps to it at \(t=0\) given \(k_0\), then follows it to \((k^*, c^*)\).
A bifurcation occurs when a small smooth change in a parameter causes a sudden qualitative change in system behaviour.
Types relevant to economics: - Pitchfork: one fixed point splits into two stable ones - Transcritical: fixed points exchange stability - Hopf: equilibrium loses stability; limit cycle born (see Part IV) - Period-doubling: period-\(n\) cycle → period-\(2n\) — route to chaos
\[x_t = \lambda x_{t-1}(1-x_{t-1})\]
\(\lambda\)
Attractor
\(1 < \lambda \leq 3\)
fixed point \(x^* = 1-1/\lambda\)
\(\lambda \approx 3\)
1st bifurcation → period-2
\(\lambda \approx 3.449\)
2nd → period-4
\(\lambda \approx 3.544\)
3rd → period-8
\(\lambda \approx 3.569\)
onset of chaos
\(\lambda > 3.57\)
chaos (with periodic windows)
Periodic windows
Periodic windows: even within the chaotic regime \(\lambda > 3.57\), there are islands of periodicity (e.g., \(\lambda \approx 3.83\) gives period-3). Sarkovskii’s theorem guarantees that period-3 implies all other periods exist.
Feigenbaum (1978): the constant \(\delta_F \approx 4.669\) was discovered numerically — it is the same for any unimodal map with a quadratic maximum. A remarkable universal constant of nonlinear dynamics.
As parameter \(\mu\) crosses critical value \(\mu_c\): - \(\mu < \mu_c\): stable spiral (all trajectories → equilibrium) - \(\mu = \mu_c\): purely imaginary eigenvalues \(\pm\beta i\) — centre - \(\mu > \mu_c\): equilibrium unstable; limit cycle born continuously
The equilibrium loses stability and a closed orbit emerges — this is the supercritical Hopf bifurcation.
\[\dot{x} = y, \quad \dot{y} = \mu(1-x^2)y - x\]
At \(\mu = 0\): centre (neutral stability, no dissipation)
For \(\mu > 0\): limit cycle of amplitude \(\approx 2\) emerges
As \(\mu \to \infty\): relaxation oscillations — slow drift punctuated by fast jumps (slow-fast dynamics)
Goodwin (1967) growth cycle
Goodwin (1967) growth cycle: GDP \(y\) and employment share \(v\) follow a predator-prey system \(\dot{y} = (1-v)y\), \(\dot{v} = (\rho - \alpha)v\). Trajectories are closed orbits — persistent cycles even in a purely deterministic economy.
Originally atmospheric convection (Lorenz, 1963). Demonstrates: deterministic systems can be fundamentally unpredictable.
Implications for economics: - Fundamental limits on forecasting exchange rates, financial prices, business cycles - Positive Lyapunov exponent → forecasting horizon \(\approx 1/\lambda_1\) - Related phenomena: sunspot equilibria, exchange rate chaos
Phase space structure:
Two “wings” — trajectories circle one wing for a while, then switch unpredictably. The number of loops per wing is irregular and never exactly repeats.
Chaos ≠ randomness
Chaos ≠ randomness. The Lorenz system is deterministic — given exact initial conditions, the trajectory is uniquely determined. But arbitrarily small measurement error grows exponentially, making long-run prediction impossible in practice.
where \(\lambda_1 > 0\) is the maximal Lyapunov exponent.
Prediction horizon: errors grow until they are \(O(1)\) — the “doubling time” is \(\tau \approx \ln(2)/\lambda_1\).
Forecasting limit
Forecasting limit: For the logistic map at \(\lambda = 3.9\), Lyapunov exponent \(\approx 0.5\), so errors double every \(\ln(2)/0.5 \approx 1.4\) periods. Long-run prediction is impossible even with near-perfect initial data.
If economic dynamics are chaotic: - Short-run forecasts remain feasible (within \(1/\lambda_1\) periods) - Long-run forecasts are fundamentally unreliable — not just statistically uncertain, but physically impossible given finite measurement precision - Observed volatility in financial markets may be deterministic chaos, not random noise
Policy implication
Policy implication: Chaotic systems do not respond predictably to policy interventions. Stabilisation policy that works well in the short run may produce perverse long-run effects.
Tests for chaos in economic time series:
Method
What it measures
BDS test
i.i.d. against nonlinear dependence
Correlation dimension
fractal dimension of attractor
Lyapunov exponent
divergence rate of nearby trajectories
Recurrence plots
structure of the phase portrait
Empirical findings: Some evidence of nonlinearity in exchange rates, commodity prices, business cycles — but distinguishing chaos from stochastic processes remains difficult.
Li, T.-Y. & Yorke, J. A. (1975). Period three implies chaos. American Mathematical Monthly, 82(10), 985–992. DOI: 10.2307/2318254
Brock, W. A. & Sayers, C. L. (1988). Is the business cycle characterised by deterministic chaos? Journal of Monetary Economics, 22(1), 71–90. DOI: 10.1016/0304-3932(88)90170-5
Exercises — Dynamic Modelling
(Part II — Shone §2.2) For \(\dot{x} = -0.5x + 10\): find \(x^*\), determine stability, solve for \(x(t)\) with \(x(0) = 5\), plot over \([0, 10]\).
(Part III — Shone §3.3) Cobweb with \(q^d = 12 - 3p\), \(q^s = -3 + 2p_{t-1}\): (a) find equilibrium; (b) determine stability; (c) simulate 20 periods from \(p_0 = 1\).
(Part III — Shone §3.12) Solow with \(s=0.25\), \(\delta=0.06\), \(\alpha=0.35\): (a) find \(k^*\); (b) simulate from \(k_0 = 2\) and verify convergence.
(Part IV — Shone §4.10) Van der Pol with \(\mu = 0.5\) and \(\mu = 2\): simulate from \((0.1, 0)\) and \((3, 0)\); compare limit cycles in the phase plane.
(Part V — Shone §5.3) For \(x_{t+1} = 0.8x_t - 0.3y_t\), \(y_{t+1} = 0.2x_t + 0.7y_t\): (a) find eigenvalues; (b) check stability; (c) simulate from \((5, 3)\).
(Part VI — Shone §6.2) For \(\max \int_0^2 (x - u^2/2) dt\), \(\dot{x} = u\), \(x(0) = 1\), \(x(2)\) free: derive the Hamiltonian, FOCs, and solve for \(x^*(t)\), \(u^*(t)\), \(\lambda^*(t)\).
Exercises — Stability & Chaos
(Part VII — Shone §7.3) Logistic map with \(x_0 = 0.4\) for \(\lambda = 2.8\), \(3.2\), \(3.5\), \(3.9\): (a) simulate 100 periods; (b) classify the attractor; (c) reproduce the bifurcation diagram.
(Part VII — Shone §7.4) Using \(\lambda_1 \approx 3.000\), \(\lambda_2 \approx 3.449\), \(\lambda_3 \approx 3.544\), \(\lambda_4 \approx 3.5644\): estimate \(\delta_F\) at each step and compare with the true value \(4.6692\).
(Part V — Shone §5.8) Internal/external balance model: (a) find equilibrium \((g^*, S^*)\); (b) compute eigenvalues and check \(|\lambda_i| < 1\); (c) simulate from four initial conditions and plot phase plane trajectories.
(Part VII — Shone §7.7) Lorenz sensitivity: (a) simulate two trajectories from \((1,1,1)\) and \((1.001,1,1)\); (b) plot \(x(t)\) for both; (c) identify when trajectories diverge noticeably.
Goodwin, R. M. (1967). A growth cycle. In C. H. Feinstein (Ed.), Socialism, Capitalism and Economic Growth: Essays Presented to Maurice Dobb. Cambridge University Press.
Li, T.-Y. & Yorke, J. A. (1975). Period three implies chaos. American Mathematical Monthly, 82(10), 985–992. DOI: 10.2307/2318254
Brock, W. A. & Sayers, C. L. (1988). Is the business cycle characterised by deterministic chaos? Journal of Monetary Economics, 22(1), 71–90. DOI: 10.1016/0304-3932(88)90170-5
Chiang, A. C. (1992). Elements of Dynamic Optimization. McGraw-Hill.
Conrad, J. M. & Clark, C. W. (1987). Natural Resource Economics: Notes and Problems. Cambridge University Press. DOI: 10.1017/CBO9781139173575
Sandefur, J. T. (1990). Discrete Dynamical Systems. Oxford.
Soetaert, K., Petzoldt, T. & Setzer, R. W. (2010). Solving differential equations in R. Journal of Statistical Software, 33(9). DOI: 10.18637/jss.v033.i09
Thank You
Athanassios Stavrakoudis Applied Informatics and Computational Economics Lab Department of Economics University of Ioannina, Greece