From cc7358ea96272b35495c9b1a7e6e04f3d996b32f Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 27 Feb 2024 10:38:47 +1100 Subject: [PATCH 01/13] update cagan ree --- lectures/cagan_ree.md | 157 +++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 85 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 4273c69c..93a09da5 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.5 + jupytext_version: 1.16.1 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -18,13 +18,10 @@ kernelspec: We'll use linear algebra first to explain and then do some experiments with a "monetarist theory of price levels". +Economists call it a "monetary" or "monetarist" theory of price levels because effects on price levels occur via a central banks's decisions to print money supply. - - -Economist call it a "monetary" or "monetarist" theory of price levels because effects on price levels occur via a central banks's decisions to print money supply. - - * a goverment's fiscal policies determine whether it **expenditures** exceed its **tax collections** - * if its expenditures exceeds it tax collections, the government can instruct the central bank to cover the difference by **printing money** + * a goverment's fiscal policies determine whether its *expenditures* exceed its *tax collections* + * if its expenditures exceed its tax collections, the government can instruct the central bank to cover the difference by *printing money* * that leads to effects on the price level as price level path adjusts to equate the supply of money to the demand for money Such a theory of price levels was described by Thomas Sargent and Neil Wallace in chapter 5 of @@ -42,11 +39,11 @@ Elemental forces at work in the fiscal theory of the price level help to underst According to this theory, when the government persistently spends more than it collects in taxes and prints money to finance the shortfall (the "shortfall" is called the "government deficit"), it puts upward pressure on the price level and generates persistent inflation. -The ''monetarist'' or ''fiscal theory of price levels" asserts that +The "monetarist" or "fiscal theory of price levels" asserts that -* to **start** a persistent inflation the government beings persistently to run a money-financed government deficit +* to *start* a persistent inflation the government beings persistently to run a money-financed government deficit -* to **stop** a persistent inflation the government stops persistently running a money-financed government deficit +* to *stop* a persistent inflation the government stops persistently running a money-financed government deficit The model in this lecture is a "rational expectations" (or "perfect foresight") version of a model that Philip Cagan {cite}`Cagan` used to study the monetary dynamics of hyperinflations. @@ -60,7 +57,7 @@ While Cagan didn't use that "rational expectations" version of the model, Thoma Some of our quantitative experiments with the rational expectations version of the model are designed to illustrate how the fiscal theory explains the abrupt end of those big inflations. -In those experiments, we'll encounter an instance of a ''velocity dividend'' that has sometimes accompanied successful inflation stabilization programs. +In those experiments, we'll encounter an instance of a "velocity dividend" that has sometimes accompanied successful inflation stabilization programs. To facilitate using linear matrix algebra as our main mathematical tool, we'll use a finite horizon version of the model. @@ -90,7 +87,7 @@ To represent the model formally, let * $T$ the horizon -- i.e., the last period for which the model will determine $p_t$ * $\pi_{T+1}^*$ the terminal rate of inflation between times $T$ and $T+1$. -The demand for real balances $\exp\left(\frac{m_t^d}{p_t}\right)$ is governed by the following version of the Cagan demand function +The demand for real balances $\exp\left(m_t^d - p_t\right)$ is governed by the following version of the Cagan demand function $$ m_t^d - p_t = -\alpha \pi_t^* \: , \: \alpha > 0 ; \quad t = 0, 1, \ldots, T . @@ -113,7 +110,7 @@ while equating demand for money to supply lets us set $m_t^d = m_t$ for all $t \ The preceding equations then imply $$ -m_t - p_t = -\alpha(p_{t+1} - p_t) \: , \: \alpha > 0 +m_t - p_t = -\alpha(p_{t+1} - p_t) $$ (eq:cagan) To fill in details about what it means for private agents @@ -132,7 +129,7 @@ $$ where $ 0< \frac{\alpha}{1+\alpha} <1 $. -Setting $\delta =\frac{\alpha}{1+\alpha}$ let's us represent the preceding equation as +Setting $\delta =\frac{\alpha}{1+\alpha}$, let's us represent the preceding equation as $$ \pi_t = \delta \pi_{t+1} + (1-\delta) \mu_t , \quad t =0, 1, \ldots, T @@ -246,41 +243,33 @@ First, we store parameters in a `namedtuple`: ```{code-cell} ipython3 # Create the rational expectation version of Cagan model in finite time CaganREE = namedtuple("CaganREE", - ["m0", "T", "μ_seq", "α", "δ", "π_end"]) + ["m0", "μ_seq", "α", "δ", "π_end"]) -def create_cagan_model(m0, α, T, μ_seq): +def create_cagan_model(m0=1, # Initial money supply + α=5, # Sensitivity parameter + μ_seq=None # Rate of growth + ): δ = α/(1 + α) π_end = μ_seq[-1] # compute terminal expected inflation - return CaganREE(m0, T, μ_seq, α, δ, π_end) -``` - -Here we use the following parameter values: - -```{code-cell} ipython3 -# parameters -T = 80 -T1 = 60 -α = 5 -m0 = 1 - -μ0 = 0.5 -μ_star = 0 + return CaganREE(m0, μ_seq, α, δ, π_end) ``` Now we can solve the model to compute $\pi_t$, $m_t$ and $p_t$ for $t =1, \ldots, T+1$ using the matrix equation above ```{code-cell} ipython3 -def solve(model): - model_params = model.m0, model.T, model.π_end, model.μ_seq, model.α, model.δ - m0, T, π_end, μ_seq, α, δ = model_params +def solve(model, T): + m0, π_end, μ_seq, α, δ = (model.m0, model.π_end, + model.μ_seq, model.α, model.δ) + + # Create matrix representation above A1 = np.eye(T+1, T+1) - δ * np.eye(T+1, T+1, k=1) A2 = np.eye(T+1, T+1) - np.eye(T+1, T+1, k=-1) b1 = (1-δ) * μ_seq + np.concatenate([np.zeros(T), [δ * π_end]]) b2 = μ_seq + np.concatenate([[m0], np.zeros(T)]) - π_seq = np.linalg.inv(A1) @ b1 - m_seq = np.linalg.inv(A2) @ b2 + π_seq = np.linalg.solve(A1, b1) + m_seq = np.linalg.solve(A2, b2) π_seq = np.append(π_seq, π_end) m_seq = np.append(m0, m_seq) @@ -325,46 +314,41 @@ $$ \end{cases} $$ -We'll start by executing a version of our "experiment 1" in which the government implements a **foreseen** sudden permanent reduction in the rate of money creation at time $T_1$. +We'll start by executing a version of our "experiment 1" in which the government implements a *foreseen* sudden permanent reduction in the rate of money creation at time $T_1$. -The following code performs the experiment and plots outcomes. ++++ + +Let's experiment with the following parameters ```{code-cell} ipython3 -def solve_and_plot(m0, α, T, μ_seq): - model_params = create_cagan_model(m0=m0, α=α, T=T, μ_seq=μ_seq) - π_seq, m_seq, p_seq = solve(model_params) - T_seq = range(T + 2) - - fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) - - ax[0].plot(T_seq[:-1], μ_seq) - ax[0].set_ylabel(r'$\mu$') +T1 = 60 +μ0 = 0.5 +μ_star = 0 +T = 80 - ax[1].plot(T_seq, π_seq) - ax[1].set_ylabel(r'$\pi$') +μ_seq_1 = np.append(μ0*np.ones(T1+1), μ_star*np.ones(T-T1)) - ax[2].plot(T_seq, m_seq - p_seq) - ax[2].set_ylabel(r'$m - p$') +cm = create_cagan_model(μ_seq=μ_seq_1) - ax[3].plot(T_seq, m_seq) - ax[3].set_ylabel(r'$m$') +# solve the model +π_seq_1, m_seq_1, p_seq_1 = solve(cm, T) +``` - ax[4].plot(T_seq, p_seq) - ax[4].set_ylabel(r'$p$') - - for i in range(5): - ax[i].set_xlabel(r'$t$') - +Now we use the following function to plot the result + +```{code-cell} ipython3 +def plot_sequences(sequences, labels): + fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12], dpi=200) + for ax, seq, label in zip(axs, sequences, labels): + ax.plot(range(len(seq)), seq, label=label) + ax.set_ylabel(label) + ax.set_xlabel('$t$') + ax.legend() plt.tight_layout() plt.show() - - return π_seq, m_seq, p_seq - -μ_seq_1 = np.append(μ0*np.ones(T1+1), μ_star*np.ones(T-T1)) -# solve and plot -π_seq_1, m_seq_1, p_seq_1 = solve_and_plot(m0=m0, α=α, - T=T, μ_seq=μ_seq_1) +sequences = [μ_seq_1, π_seq_1, m_seq_1 - p_seq_1, m_seq_1, p_seq_1] +plot_sequences(sequences, [r'$\mu$', r'$\pi$', r'$m - p$', r'$m$', r'$p$']) ``` +++ {"user_expressions": []} @@ -406,7 +390,7 @@ was completely unanticipated. At time $T_1$ when the "surprise" money growth rate change occurs, to satisfy equation {eq}`eq:pformula2`, the log of real balances jumps -**upward** as $\pi_t$ jumps **downward**. +*upward* as $\pi_t$ jumps *downward*. But in order for $m_t - p_t$ to jump, which variable jumps, $m_{T_1}$ or $p_{T_1}$? @@ -428,7 +412,7 @@ $$ m_{T_1}^2 - m_{T_1}^1 = \alpha (\pi^1 - \pi^2) $$ (eq:eqnmoneyjump) -By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from **falling** at the moment that the unanticipated stabilization arrives. +By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from *falling* at the moment that the unanticipated stabilization arrives. In various research papers about stabilizations of high inflations, the jump in the money supply described by equation {eq}`eq:eqnmoneyjump` has been called "the velocity dividend" that a government reaps from implementing a regime change that sustains a permanently lower inflation rate. @@ -503,16 +487,15 @@ The following code does the calculations and plots outcomes. # path 1 μ_seq_2_path1 = μ0 * np.ones(T+1) -mc1 = create_cagan_model(m0=m0, α=α, - T=T, μ_seq=μ_seq_2_path1) -π_seq_2_path1, m_seq_2_path1, p_seq_2_path1 = solve(mc1) +cm1 = create_cagan_model(μ_seq=μ_seq_2_path1) +π_seq_2_path1, m_seq_2_path1, p_seq_2_path1 = solve(cm1, T) # continuation path μ_seq_2_cont = μ_star * np.ones(T-T1) -mc2 = create_cagan_model(m0=m_seq_2_path1[T1+1], - α=α, T=T-1-T1, μ_seq=μ_seq_2_cont) -π_seq_2_cont, m_seq_2_cont1, p_seq_2_cont1 = solve(mc2) +cm2 = create_cagan_model(m0=m_seq_2_path1[T1+1], + μ_seq=μ_seq_2_cont) +π_seq_2_cont, m_seq_2_cont1, p_seq_2_cont1 = solve(cm2, T-1-T1) # regime 1 - simply glue π_seq, μ_seq @@ -526,11 +509,10 @@ p_seq_2_regime1 = np.concatenate([p_seq_2_path1[:T1+1], p_seq_2_cont1]) # regime 2 - reset m_T1 -m_T1 = (m_seq_2_path1[T1] + μ0) + α*(μ0 - μ_star) +m_T1 = (m_seq_2_path1[T1] + μ0) + cm2.α*(μ0 - μ_star) -mc = create_cagan_model(m0=m_T1, α=α, - T=T-1-T1, μ_seq=μ_seq_2_cont) -π_seq_2_cont2, m_seq_2_cont2, p_seq_2_cont2 = solve(mc) +cm3 = create_cagan_model(m0=m_T1, μ_seq=μ_seq_2_cont) +π_seq_2_cont2, m_seq_2_cont2, p_seq_2_cont2 = solve(cm3, T-1-T1) m_seq_2_regime2 = np.concatenate([m_seq_2_path1[:T1+1], m_seq_2_cont2]) @@ -541,7 +523,7 @@ T_seq = range(T+2) # plot both regimes fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) - + ax[0].plot(T_seq[:-1], μ_seq_2) ax[0].set_ylabel(r'$\mu$') @@ -640,7 +622,6 @@ plt.tight_layout() plt.show() ``` - It is instructive to compare the preceding graphs with graphs of log price levels and inflation rates for data from four big inflations described in {doc}`this lecture `. @@ -665,24 +646,30 @@ $$ \mu_t = \phi^t \mu_0 + (1 - \phi^t) \mu^* . $$ -Next we perform an experiment in which there is a perfectly foreseen **gradual** decrease in the rate of growth of the money supply. +Next we perform an experiment in which there is a perfectly foreseen *gradual* decrease in the rate of growth of the money supply. The following code does the calculations and plots the results. ```{code-cell} ipython3 # parameters ϕ = 0.9 -μ_seq = np.array([ϕ**t * μ0 + (1-ϕ**t)*μ_star for t in range(T)]) -μ_seq = np.append(μ_seq, μ_star) +μ_seq_stab = np.array([ϕ**t * μ0 + (1-ϕ**t)*μ_star for t in range(T)]) +μ_seq_stab = np.append(μ_seq_stab, μ_star) +cm4 = create_cagan_model(μ_seq=μ_seq_stab) -# solve and plot -π_seq, m_seq, p_seq = solve_and_plot(m0=m0, α=α, T=T, μ_seq=μ_seq) +π_seq_4, m_seq_4, p_seq_4 = solve(cm4, T) + +sequences = [μ_seq_stab, π_seq_4, + m_seq_4 - p_seq_4, m_seq_4, p_seq_4] +plot_sequences(sequences, [r'$\mu$', r'$\pi$', + r'$m - p$', r'$m$', r'$p$']) ``` + ## Sequel Another lecture {doc}`monetarist theory of price levels with adaptive expectations ` describes an "adaptive expectations" version of Cagan's model. The dynamics become more complicated and so does the algebra. -Nowadays, the "rational expectations" version of the model is more popular among central bankers and economists advising them. \ No newline at end of file +Nowadays, the "rational expectations" version of the model is more popular among central bankers and economists advising them. From 99619ebb25b9f6ea11fa51f1c0ee2ed104fc0516 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 27 Feb 2024 10:41:38 +1100 Subject: [PATCH 02/13] remove extra annotations in the code --- lectures/cagan_ree.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 93a09da5..976b13b3 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -316,8 +316,6 @@ $$ We'll start by executing a version of our "experiment 1" in which the government implements a *foreseen* sudden permanent reduction in the rate of money creation at time $T_1$. -+++ - Let's experiment with the following parameters ```{code-cell} ipython3 @@ -351,8 +349,6 @@ sequences = [μ_seq_1, π_seq_1, m_seq_1 - p_seq_1, m_seq_1, p_seq_1] plot_sequences(sequences, [r'$\mu$', r'$\pi$', r'$m - p$', r'$m$', r'$p$']) ``` -+++ {"user_expressions": []} - The plot of the money growth rate $\mu_t$ in the top level panel portrays a sudden reduction from $.5$ to $0$ at time $T_1 = 60$. From f98e01d59d85a6bed86396c6149c411e51da4629 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 27 Feb 2024 23:56:06 +1100 Subject: [PATCH 03/13] remove double spaces --- lectures/cagan_ree.md | 160 +++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 976b13b3..18b4723c 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -11,27 +11,27 @@ kernelspec: name: python3 --- -# A Monetarist Theory of Price Levels +# A Monetarist Theory of Price Levels ## Overview -We'll use linear algebra first to explain and then do some experiments with a "monetarist theory of price levels". +We'll use linear algebra first to explain and then do some experiments with a "monetarist theory of price levels". -Economists call it a "monetary" or "monetarist" theory of price levels because effects on price levels occur via a central banks's decisions to print money supply. +Economists call it a "monetary" or "monetarist" theory of price levels because effects on price levels occur via a central banks's decisions to print money supply. * a goverment's fiscal policies determine whether its *expenditures* exceed its *tax collections* - * if its expenditures exceed its tax collections, the government can instruct the central bank to cover the difference by *printing money* + * if its expenditures exceed its tax collections, the government can instruct the central bank to cover the difference by *printing money* * that leads to effects on the price level as price level path adjusts to equate the supply of money to the demand for money -Such a theory of price levels was described by Thomas Sargent and Neil Wallace in chapter 5 of -{cite}`sargent2013rational`, which reprints a 1981 Federal Reserve Bank of Minneapolis article entitled "Unpleasant Monetarist Arithmetic". +Such a theory of price levels was described by Thomas Sargent and Neil Wallace in chapter 5 of +{cite}`sargent2013rational`, which reprints a 1981 Federal Reserve Bank of Minneapolis article entitled "Unpleasant Monetarist Arithmetic". -Sometimes this theory is also called a "fiscal theory of price levels" to emphasize the importance of fisal deficits in shaping changes in the money supply. +Sometimes this theory is also called a "fiscal theory of price levels" to emphasize the importance of fisal deficits in shaping changes in the money supply. -The theory has been extended, criticized, and applied by John Cochrane {cite}`cochrane2023fiscal`. +The theory has been extended, criticized, and applied by John Cochrane {cite}`cochrane2023fiscal`. -In another lecture {doc}`price level histories `, we described some European hyperinflations that occurred in the wake of World War I. +In another lecture {doc}`price level histories `, we described some European hyperinflations that occurred in the wake of World War I. Elemental forces at work in the fiscal theory of the price level help to understand those episodes. @@ -39,29 +39,29 @@ Elemental forces at work in the fiscal theory of the price level help to underst According to this theory, when the government persistently spends more than it collects in taxes and prints money to finance the shortfall (the "shortfall" is called the "government deficit"), it puts upward pressure on the price level and generates persistent inflation. -The "monetarist" or "fiscal theory of price levels" asserts that +The "monetarist" or "fiscal theory of price levels" asserts that * to *start* a persistent inflation the government beings persistently to run a money-financed government deficit -* to *stop* a persistent inflation the government stops persistently running a money-financed government deficit +* to *stop* a persistent inflation the government stops persistently running a money-financed government deficit -The model in this lecture is a "rational expectations" (or "perfect foresight") version of a model that Philip Cagan {cite}`Cagan` used to study the monetary dynamics of hyperinflations. +The model in this lecture is a "rational expectations" (or "perfect foresight") version of a model that Philip Cagan {cite}`Cagan` used to study the monetary dynamics of hyperinflations. -While Cagan didn't use that "rational expectations" version of the model, Thomas Sargent {cite}`sargent1982ends` did when he studied the Ends of Four Big Inflations in Europe after World War I. +While Cagan didn't use that "rational expectations" version of the model, Thomas Sargent {cite}`sargent1982ends` did when he studied the Ends of Four Big Inflations in Europe after World War I. -* this lecture {doc}`fiscal theory of the price level with adaptive expectations ` describes a version of the model that does not impose "rational expectations" but instead uses - what Cagan and his teacher Milton Friedman called "adaptive expectations" +* this lecture {doc}`fiscal theory of the price level with adaptive expectations ` describes a version of the model that does not impose "rational expectations" but instead uses + what Cagan and his teacher Milton Friedman called "adaptive expectations" * a reader of both lectures will notice that the algebra is less complicated in the present rational expectations version of the model - * the difference in algebra complications can be traced to the following source: the adaptive expectations version of the model has more endogenous variables and more free parameters + * the difference in algebra complications can be traced to the following source: the adaptive expectations version of the model has more endogenous variables and more free parameters -Some of our quantitative experiments with the rational expectations version of the model are designed to illustrate how the fiscal theory explains the abrupt end of those big inflations. +Some of our quantitative experiments with the rational expectations version of the model are designed to illustrate how the fiscal theory explains the abrupt end of those big inflations. In those experiments, we'll encounter an instance of a "velocity dividend" that has sometimes accompanied successful inflation stabilization programs. -To facilitate using linear matrix algebra as our main mathematical tool, we'll use a finite horizon version of the model. +To facilitate using linear matrix algebra as our main mathematical tool, we'll use a finite horizon version of the model. -As in the {doc}`present values ` and {doc}`consumption smoothing` lectures, our mathematical tools are matrix multiplication and matrix inversion. +As in the {doc}`present values ` and {doc}`consumption smoothing` lectures, our mathematical tools are matrix multiplication and matrix inversion. ## Structure of the model @@ -71,32 +71,32 @@ The model consists of * a function that expresses the demand for real balances of government printed money as an inverse function of the public's expected rate of inflation -* an exogenous sequence of rates of growth of the money supply. The money supply grows because the government prints it to pay for goods and services +* an exogenous sequence of rates of growth of the money supply. The money supply grows because the government prints it to pay for goods and services * an equilibrium condition that equates the demand for money to the supply -* a "perfect foresight" assumption that the public's expected rate of inflation equals the actual rate of inflation. +* a "perfect foresight" assumption that the public's expected rate of inflation equals the actual rate of inflation. To represent the model formally, let -* $ m_t $ be the log of the supply of nominal money balances; -* $\mu_t = m_{t+1} - m_t $ be the net rate of growth of nominal balances; +* $ m_t $ be the log of the supply of nominal money balances; +* $\mu_t = m_{t+1} - m_t $ be the net rate of growth of nominal balances; * $p_t $ be the log of the price level; -* $\pi_t = p_{t+1} - p_t $ be the net rate of inflation between $t$ and $ t+1$; -* $\pi_t^*$ be the public's expected rate of inflation between $t$ and $t+1$; +* $\pi_t = p_{t+1} - p_t $ be the net rate of inflation between $t$ and $ t+1$; +* $\pi_t^*$ be the public's expected rate of inflation between $t$ and $t+1$; * $T$ the horizon -- i.e., the last period for which the model will determine $p_t$ * $\pi_{T+1}^*$ the terminal rate of inflation between times $T$ and $T+1$. -The demand for real balances $\exp\left(m_t^d - p_t\right)$ is governed by the following version of the Cagan demand function - -$$ +The demand for real balances $\exp\left(m_t^d - p_t\right)$ is governed by the following version of the Cagan demand function + +$$ m_t^d - p_t = -\alpha \pi_t^* \: , \: \alpha > 0 ; \quad t = 0, 1, \ldots, T . $$ (eq:caganmd) -This equation asserts that the demand for real balances +This equation asserts that the demand for real balances is inversely related to the public's expected rate of inflation. -People somehow acquire **perfect foresight** by their having solved a forecasting +People somehow acquire **perfect foresight** by their having solved a forecasting problem. This lets us set @@ -114,14 +114,14 @@ m_t - p_t = -\alpha(p_{t+1} - p_t) $$ (eq:cagan) To fill in details about what it means for private agents -to have perfect foresight, we subtract equation {eq}`eq:cagan` at time $ t $ from the same equation at $ t+1$ to get +to have perfect foresight, we subtract equation {eq}`eq:cagan` at time $ t $ from the same equation at $ t+1$ to get $$ -\mu_t - \pi_t = -\alpha \pi_{t+1} + \alpha \pi_t , +\mu_t - \pi_t = -\alpha \pi_{t+1} + \alpha \pi_t , $$ which we rewrite as a forward-looking first-order linear difference -equation in $\pi_s$ with $\mu_s$ as a "forcing variable": +equation in $\pi_s$ with $\mu_s$ as a "forcing variable": $$ \pi_t = \frac{\alpha}{1+\alpha} \pi_{t+1} + \frac{1}{1+\alpha} \mu_t , \quad t= 0, 1, \ldots , T @@ -146,7 +146,7 @@ $$ 0 & 0 & 0 & 0 & \cdots & 0 & 1 \end{bmatrix} \begin{bmatrix} \pi_0 \cr \pi_1 \cr \pi_2 \cr \vdots \cr \pi_{T-1} \cr \pi_T \end{bmatrix} -= (1 - \delta) \begin{bmatrix} += (1 - \delta) \begin{bmatrix} \mu_0 \cr \mu_1 \cr \mu_2 \cr \vdots \cr \mu_{T-1} \cr \mu_T \end{bmatrix} + \begin{bmatrix} @@ -164,7 +164,7 @@ $$ It turns out that $$ -\pi_t = (1-\delta) \sum_{s=t}^T \delta^{s-t} \mu_s + \delta^{T+1-t} \pi_{T+1}^* +\pi_t = (1-\delta) \sum_{s=t}^T \delta^{s-t} \mu_s + \delta^{T+1-t} \pi_{T+1}^* $$ (eq:fisctheory1) We can represent the equations @@ -179,23 +179,23 @@ $$ \begin{bmatrix} 1 & 0 & 0 & \cdots & 0 & 0 \cr -1 & 1 & 0 & \cdots & 0 & 0 \cr -0 & -1 & 1 & \cdots & 0 & 0 \cr -\vdots & \vdots & \vdots & \vdots & 0 & 0 \cr -0 & 0 & 0 & \cdots & 1 & 0 \cr -0 & 0 & 0 & \cdots & -1 & 1 +0 & -1 & 1 & \cdots & 0 & 0 \cr +\vdots & \vdots & \vdots & \vdots & 0 & 0 \cr +0 & 0 & 0 & \cdots & 1 & 0 \cr +0 & 0 & 0 & \cdots & -1 & 1 \end{bmatrix} -\begin{bmatrix} +\begin{bmatrix} m_1 \cr m_2 \cr m_3 \cr \vdots \cr m_T \cr m_{T+1} \end{bmatrix} -= \begin{bmatrix} += \begin{bmatrix} \mu_0 \cr \mu_1 \cr \mu_2 \cr \vdots \cr \mu_{T-1} \cr \mu_T \end{bmatrix} -+ \begin{bmatrix} ++ \begin{bmatrix} m_0 \cr 0 \cr 0 \cr \vdots \cr 0 \cr 0 \end{bmatrix} $$ (eq:eq101) -Multiplying both sides of equation {eq}`eq:eq101` with the inverse of the matrix on the left will give +Multiplying both sides of equation {eq}`eq:eq101` with the inverse of the matrix on the left will give $$ m_t = m_0 + \sum_{s=0}^{t-1} \mu_s, \quad t =1, \ldots, T+1 @@ -283,7 +283,7 @@ def solve(model, T): In the experiments below, we'll use formula {eq}`eq:piterm` as our terminal condition for expected inflation. -In devising these experiments, we'll make assumptions about $\{\mu_t\}$ that are consistent with formula +In devising these experiments, we'll make assumptions about $\{\mu_t\}$ that are consistent with formula {eq}`eq:piterm`. We describe several such experiments. @@ -314,7 +314,7 @@ $$ \end{cases} $$ -We'll start by executing a version of our "experiment 1" in which the government implements a *foreseen* sudden permanent reduction in the rate of money creation at time $T_1$. +We'll start by executing a version of our "experiment 1" in which the government implements a *foreseen* sudden permanent reduction in the rate of money creation at time $T_1$. Let's experiment with the following parameters @@ -349,8 +349,8 @@ sequences = [μ_seq_1, π_seq_1, m_seq_1 - p_seq_1, m_seq_1, p_seq_1] plot_sequences(sequences, [r'$\mu$', r'$\pi$', r'$m - p$', r'$m$', r'$p$']) ``` -The plot of the money growth rate $\mu_t$ in the top level panel portrays -a sudden reduction from $.5$ to $0$ at time $T_1 = 60$. +The plot of the money growth rate $\mu_t$ in the top level panel portrays +a sudden reduction from $.5$ to $0$ at time $T_1 = 60$. This brings about a gradual reduction of the inflation rate $\pi_t$ that precedes the money supply growth rate reduction at time $T_1$. @@ -358,9 +358,9 @@ money supply growth rate reduction at time $T_1$. Notice how the inflation rate declines smoothly (i.e., continuously) to $0$ at $T_1$ -- unlike the money growth rate, it does not suddenly "jump" downward at $T_1$. -This is because the reduction in $\mu$ at $T_1$ has been foreseen from the start. +This is because the reduction in $\mu$ at $T_1$ has been foreseen from the start. -While the log money supply portrayed in the bottom panel has a kink at $T_1$, the log price level does not -- it is "smooth" -- once again a consequence of the fact that the +While the log money supply portrayed in the bottom panel has a kink at $T_1$, the log price level does not -- it is "smooth" -- once again a consequence of the fact that the reduction in $\mu$ has been foreseen. To set the stage for our next experiment, we want to study the determinants of the price level a little more. @@ -378,27 +378,27 @@ $$ (eq:pformula2) or, by using equation {eq}`eq:fisctheory1`, $$ -p_t = m_t + \alpha \left[ (1-\delta) \sum_{s=t}^T \delta^{s-t} \mu_s + \delta^{T+1-t} \pi_{T+1}^* \right] +p_t = m_t + \alpha \left[ (1-\delta) \sum_{s=t}^T \delta^{s-t} \mu_s + \delta^{T+1-t} \pi_{T+1}^* \right] $$ (eq:pfiscaltheory2) In our next experiment, we'll study a "surprise" permanent change in the money growth that beforehand -was completely unanticipated. +was completely unanticipated. -At time $T_1$ when the "surprise" money growth rate change occurs, to satisfy +At time $T_1$ when the "surprise" money growth rate change occurs, to satisfy equation {eq}`eq:pformula2`, the log of real balances jumps -*upward* as $\pi_t$ jumps *downward*. +*upward* as $\pi_t$ jumps *downward*. But in order for $m_t - p_t$ to jump, which variable jumps, $m_{T_1}$ or $p_{T_1}$? We'll study that interesting question next. -### What jumps? +### What jumps? What jumps at $T_1$? -Is it $p_{T_1}$ or $m_{T_1}$? +Is it $p_{T_1}$ or $m_{T_1}$? -If we insist that the money supply $m_{T_1}$ is locked at its value $m_{T_1}^1$ inherited from the past, then formula {eq}`eq:pformula2` implies that the price level jumps downward at time $T_1$, to coincide with the downward jump in +If we insist that the money supply $m_{T_1}$ is locked at its value $m_{T_1}^1$ inherited from the past, then formula {eq}`eq:pformula2` implies that the price level jumps downward at time $T_1$, to coincide with the downward jump in $\pi_{T_1}$ An alternative assumption about the money supply level is that as part of the "inflation stabilization", @@ -408,14 +408,14 @@ $$ m_{T_1}^2 - m_{T_1}^1 = \alpha (\pi^1 - \pi^2) $$ (eq:eqnmoneyjump) -By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from *falling* at the moment that the unanticipated stabilization arrives. +By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from *falling* at the moment that the unanticipated stabilization arrives. In various research papers about stabilizations of high inflations, the jump in the money supply described by equation {eq}`eq:eqnmoneyjump` has been called "the velocity dividend" that a government reaps from implementing a regime change that sustains a permanently lower inflation rate. #### Technical details about whether $p$ or $m$ jumps at $T_1$ -We have noted that with a constant expected forward sequence $\mu_s = \bar \mu$ for $s\geq t$, $\pi_{t} =\bar{\mu}$. +We have noted that with a constant expected forward sequence $\mu_s = \bar \mu$ for $s\geq t$, $\pi_{t} =\bar{\mu}$. A consequence is that at $T_1$, either $m$ or $p$ must "jump" at $T_1$. @@ -431,9 +431,9 @@ $$ Simply glue the sequences $t\leq T_1$ and $t > T_1$. -#### $m_{T_{1}}$ jumps. +#### $m_{T_{1}}$ jumps. -We reset $m_{T_{1}}$ so that $p_{T_{1}}=\left(m_{T_{1}-1}+\mu_{0}\right)+\alpha\mu_{0}$, with $\pi_{T_{1}}=\mu^{*}$. +We reset $m_{T_{1}}$ so that $p_{T_{1}}=\left(m_{T_{1}-1}+\mu_{0}\right)+\alpha\mu_{0}$, with $\pi_{T_{1}}=\mu^{*}$. Then, @@ -449,27 +449,27 @@ We are now technically equipped to discuss our next experiment. This experiment deviates a little bit from a pure version of our "perfect foresight" assumption by assuming that a sudden permanent reduction in $\mu_t$ like that -analyzed in experiment 1 is completely unanticipated. +analyzed in experiment 1 is completely unanticipated. -Such a completely unanticipated shock is popularly known as an "MIT shock". +Such a completely unanticipated shock is popularly known as an "MIT shock". -The mental experiment involves switching at time $T_1$ from an initial "continuation path" for $\{\mu_t, \pi_t\} $ to another path that involves a permanently lower inflation rate. +The mental experiment involves switching at time $T_1$ from an initial "continuation path" for $\{\mu_t, \pi_t\} $ to another path that involves a permanently lower inflation rate. **Initial Path:** $\mu_t = \mu_0$ for all $t \geq 0$. So this path is for $\{\mu_t\}_{t=0}^\infty$; the associated path for $\pi_t$ has $\pi_t = \mu_0$. -**Revised Continuation Path** Where $ \mu_0 > \mu^*$, we construct a continuation path $\{\mu_s\}_{s=T_1}^\infty$ -by setting $\mu_s = \mu^*$ for all $s \geq T_1$. The perfect foresight continuation path for -$\pi$ is $\pi_s = \mu^*$ +**Revised Continuation Path** Where $ \mu_0 > \mu^*$, we construct a continuation path $\{\mu_s\}_{s=T_1}^\infty$ +by setting $\mu_s = \mu^*$ for all $s \geq T_1$. The perfect foresight continuation path for +$\pi$ is $\pi_s = \mu^*$ -To capture a "completely unanticipated permanent shock to the $\{\mu\}$ process at time $T_1$, we simply glue the $\mu_t, \pi_t$ +To capture a "completely unanticipated permanent shock to the $\{\mu\}$ process at time $T_1$, we simply glue the $\mu_t, \pi_t$ that emerges under path 2 for $t \geq T_1$ to the $\mu_t, \pi_t$ path that had emerged under path 1 for $ t=0, \ldots, T_1 -1$. We can do the MIT shock calculations mostly by hand. -Thus, for path 1, $\pi_t = \mu_0 $ for all $t \in [0, T_1-1]$, while for path 2, -$\mu_s = \mu^*$ for all $s \geq T_1$. +Thus, for path 1, $\pi_t = \mu_0 $ for all $t \in [0, T_1-1]$, while for path 2, +$\mu_s = \mu^*$ for all $s \geq T_1$. We now move on to experiment 2, our "MIT shock", completely unforeseen sudden stabilization. @@ -551,13 +551,13 @@ plt.tight_layout() plt.show() ``` -We invite you to compare these graphs with corresponding ones for the foreseen stabilization analyzed in experiment 1 above. +We invite you to compare these graphs with corresponding ones for the foreseen stabilization analyzed in experiment 1 above. Note how the inflation graph in the top middle panel is now identical to the money growth graph in the top left panel, and how now the log of real balances portrayed in the top right panel jumps upward at time $T_1$. The bottom panels plot $m$ and $p$ under two possible ways that $m_{T_1}$ might adjust -as required by the upward jump in $m - p$ at $T_1$. +as required by the upward jump in $m - p$ at $T_1$. * the orange line lets $m_{T_1}$ jump upward in order to make sure that the log price level $p_{T_1}$ does not fall. @@ -565,7 +565,7 @@ as required by the upward jump in $m - p$ at $T_1$. Here is a way to interpret what the government is doing when the orange line policy is in place. -The government prints money to finance expenditure with the "velocity dividend" that it reaps from the increased demand for real balances brought about by the permanent decrease in the rate of growth of the money supply. +The government prints money to finance expenditure with the "velocity dividend" that it reaps from the increased demand for real balances brought about by the permanent decrease in the rate of growth of the money supply. The next code generates a multi-panel graph that includes outcomes of both experiments 1 and 2. @@ -618,16 +618,16 @@ plt.tight_layout() plt.show() ``` -It is instructive to compare the preceding graphs with graphs of log price levels and inflation rates for data from four big inflations described in +It is instructive to compare the preceding graphs with graphs of log price levels and inflation rates for data from four big inflations described in {doc}`this lecture `. -In particular, in the above graphs, notice how a gradual fall in inflation precedes the "sudden stop" when it has been anticipated long beforehand, but how -inflation instead falls abruptly when the permanent drop in money supply growth is unanticipated. +In particular, in the above graphs, notice how a gradual fall in inflation precedes the "sudden stop" when it has been anticipated long beforehand, but how +inflation instead falls abruptly when the permanent drop in money supply growth is unanticipated. It seems to the author team at quantecon that the drops in inflation near the ends of the four hyperinflations described in {doc}`this lecture ` -more closely resemble outcomes from the experiment 2 "unforeseen stabilization". +more closely resemble outcomes from the experiment 2 "unforeseen stabilization". -(It is fair to say that the preceding informal pattern recognition exercise should be supplemented with a more formal structural statistical analysis.) +(It is fair to say that the preceding informal pattern recognition exercise should be supplemented with a more formal structural statistical analysis.) #### Experiment 3 @@ -636,7 +636,7 @@ more closely resemble outcomes from the experiment 2 "unforeseen stabilization". Instead of a foreseen sudden stabilization of the type studied with experiment 1, it is also interesting to study the consequences of a foreseen gradual stabilization. -Thus, suppose that $\phi \in (0,1)$, that $\mu_0 > \mu^*$, and that for $t = 0, \ldots, T-1$ +Thus, suppose that $\phi \in (0,1)$, that $\mu_0 > \mu^*$, and that for $t = 0, \ldots, T-1$ $$ \mu_t = \phi^t \mu_0 + (1 - \phi^t) \mu^* . @@ -644,7 +644,7 @@ $$ Next we perform an experiment in which there is a perfectly foreseen *gradual* decrease in the rate of growth of the money supply. -The following code does the calculations and plots the results. +The following code does the calculations and plots the results. ```{code-cell} ipython3 # parameters @@ -664,7 +664,7 @@ plot_sequences(sequences, [r'$\mu$', r'$\pi$', ## Sequel -Another lecture {doc}`monetarist theory of price levels with adaptive expectations ` describes an "adaptive expectations" version of Cagan's model. +Another lecture {doc}`monetarist theory of price levels with adaptive expectations ` describes an "adaptive expectations" version of Cagan's model. The dynamics become more complicated and so does the algebra. From c2afe22d3abaefd7bb225116a3af157a367a1070 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 27 Feb 2024 23:56:19 +1100 Subject: [PATCH 04/13] remove figsize --- lectures/cagan_ree.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 18b4723c..bed51838 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -336,7 +336,7 @@ Now we use the following function to plot the result ```{code-cell} ipython3 def plot_sequences(sequences, labels): - fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12], dpi=200) + fig, axs = plt.subplots(len(sequences), 1, dpi=200) for ax, seq, label in zip(axs, sequences, labels): ax.plot(range(len(seq)), seq, label=label) ax.set_ylabel(label) @@ -518,7 +518,7 @@ p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], T_seq = range(T+2) # plot both regimes -fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) +fig, ax = plt.subplots(5, 1, dpi=200) ax[0].plot(T_seq[:-1], μ_seq_2) ax[0].set_ylabel(r'$\mu$') @@ -574,7 +574,7 @@ unanticipated, as in experiment 2. ```{code-cell} ipython3 # compare foreseen vs unforeseen shock -fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) +fig, ax = plt.subplots(5, dpi=200) ax[0].plot(T_seq[:-1], μ_seq_2) ax[0].set_ylabel(r'$\mu$') From ff690f52eb3a182b38d5a92b7c5b46573c56bdb2 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 28 Feb 2024 11:38:01 +1100 Subject: [PATCH 05/13] Revert "remove figsize" This reverts commit c2afe22d3abaefd7bb225116a3af157a367a1070. --- lectures/cagan_ree.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index bed51838..18b4723c 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -336,7 +336,7 @@ Now we use the following function to plot the result ```{code-cell} ipython3 def plot_sequences(sequences, labels): - fig, axs = plt.subplots(len(sequences), 1, dpi=200) + fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12], dpi=200) for ax, seq, label in zip(axs, sequences, labels): ax.plot(range(len(seq)), seq, label=label) ax.set_ylabel(label) @@ -518,7 +518,7 @@ p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], T_seq = range(T+2) # plot both regimes -fig, ax = plt.subplots(5, 1, dpi=200) +fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) ax[0].plot(T_seq[:-1], μ_seq_2) ax[0].set_ylabel(r'$\mu$') @@ -574,7 +574,7 @@ unanticipated, as in experiment 2. ```{code-cell} ipython3 # compare foreseen vs unforeseen shock -fig, ax = plt.subplots(5, dpi=200) +fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) ax[0].plot(T_seq[:-1], μ_seq_2) ax[0].set_ylabel(r'$\mu$') From 47286bd3f8875321b17f3b6a4eeea4bd22be0a24 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 29 Feb 2024 10:14:31 +1100 Subject: [PATCH 06/13] improve code comments based on feedback --- lectures/cagan_ree.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 18b4723c..bfcfd95e 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -243,12 +243,14 @@ First, we store parameters in a `namedtuple`: ```{code-cell} ipython3 # Create the rational expectation version of Cagan model in finite time CaganREE = namedtuple("CaganREE", - ["m0", "μ_seq", "α", "δ", "π_end"]) - -def create_cagan_model(m0=1, # Initial money supply - α=5, # Sensitivity parameter - μ_seq=None # Rate of growth - ): + ["m0", # initial money supply + "μ_seq", # sequence of rate of growth + "α", # sensitivity parameter + "δ", # α/(1 + α) + "π_end" # terminal expected inflation + ]) + +def create_cagan_model(m0=1, α=5, μ_seq=None): δ = α/(1 + α) π_end = μ_seq[-1] # compute terminal expected inflation return CaganREE(m0, μ_seq, α, δ, π_end) From 84e0a2f89641cbb967ec60eca9625278a6c77cda Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Sat, 23 Mar 2024 21:22:39 +1100 Subject: [PATCH 07/13] update feedback for the second section --- lectures/cagan_ree.md | 126 +++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 69 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index bfcfd95e..7f20a7e3 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -296,7 +296,7 @@ $$ \mu_t = \mu^* , \quad t \geq T_1 $$ -so that, in terms of our notation and formula for $\theta_{T+1}^*$ above, $\tilde \gamma = 1$. +so that, in terms of our notation and formula for $\pi_{T+1}^*$ above, $\tilde \gamma = 1$. #### Experiment 1: Foreseen sudden stabilization @@ -464,7 +464,7 @@ path for $\pi_t$ has $\pi_t = \mu_0$. by setting $\mu_s = \mu^*$ for all $s \geq T_1$. The perfect foresight continuation path for $\pi$ is $\pi_s = \mu^*$ -To capture a "completely unanticipated permanent shock to the $\{\mu\}$ process at time $T_1$, we simply glue the $\mu_t, \pi_t$ +To capture a "completely unanticipated permanent shock to the $\{\mu_t\}$ process at time $T_1$, we simply glue the $\mu_t, \pi_t$ that emerges under path 2 for $t \geq T_1$ to the $\mu_t, \pi_t$ path that had emerged under path 1 for $ t=0, \ldots, T_1 -1$. @@ -482,6 +482,7 @@ are identical to those for experiment 1, the foreseen sudden stabilization. The following code does the calculations and plots outcomes. ```{code-cell} ipython3 +:tags: [hide-cell] # path 1 μ_seq_2_path1 = μ0 * np.ones(T+1) @@ -522,32 +523,31 @@ T_seq = range(T+2) # plot both regimes fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) -ax[0].plot(T_seq[:-1], μ_seq_2) -ax[0].set_ylabel(r'$\mu$') - -ax[1].plot(T_seq, π_seq_2) -ax[1].set_ylabel(r'$\pi$') - -ax[2].plot(T_seq, m_seq_2_regime1 - p_seq_2_regime1) -ax[2].set_ylabel(r'$m - p$') - -ax[3].plot(T_seq, m_seq_2_regime1, - label='Smooth $m_{T_1}$') -ax[3].plot(T_seq, m_seq_2_regime2, - label='Jumpy $m_{T_1}$') -ax[3].set_ylabel(r'$m$') - -ax[4].plot(T_seq, p_seq_2_regime1, - label='Smooth $m_{T_1}$') -ax[4].plot(T_seq, p_seq_2_regime2, - label='Jumpy $m_{T_1}$') -ax[4].set_ylabel(r'$p$') - -for i in range(5): - ax[i].set_xlabel(r'$t$') - -for i in [3, 4]: - ax[i].legend() +# Data configuration for each subplot +plot_configs = [ + {'data': [(T_seq[:-1], μ_seq_2)], 'ylabel': r'$\mu$'}, + {'data': [(T_seq, π_seq_2)], 'ylabel': r'$\pi$'}, + {'data': [(T_seq, m_seq_2_regime1 - p_seq_2_regime1)], + 'ylabel': r'$m - p$'}, + {'data': [(T_seq, m_seq_2_regime1, 'Smooth $m_{T_1}$'), + (T_seq, m_seq_2_regime2, 'Jumpy $m_{T_1}$')], + 'ylabel': r'$m$'}, + {'data': [(T_seq, p_seq_2_regime1, 'Smooth $p_{T_1}$'), + (T_seq, p_seq_2_regime2, 'Jumpy $p_{T_1}$')], + 'ylabel': r'$p$'} +] + +# Loop through each subplot configuration +for axi, config in zip(ax, plot_configs): + for data in config['data']: + if len(data) == 3: # Plot with label for legend + axi.plot(data[0], data[1], label=data[2]) + else: # Plot without label + axi.plot(data[0], data[1]) + axi.set_ylabel(config['ylabel']) + axi.set_xlabel(r'$t$') + if 'label' in config: # If there's a label, add a legend + axi.legend() plt.tight_layout() plt.show() @@ -555,11 +555,11 @@ plt.show() We invite you to compare these graphs with corresponding ones for the foreseen stabilization analyzed in experiment 1 above. -Note how the inflation graph in the top middle panel is now identical to the -money growth graph in the top left panel, and how now the log of real balances portrayed in the top right panel jumps upward at time $T_1$. +Note how the inflation graph in the second panel is now identical to the +money growth graph in the top panel, and how now the log of real balances portrayed in the third panel jumps upward at time $T_1$. -The bottom panels plot $m$ and $p$ under two possible ways that $m_{T_1}$ might adjust -as required by the upward jump in $m - p$ at $T_1$. +The bottom two panels plot $m$ and $p$ under two possible ways that $m_{T_1}$ might adjust +as required by the upward jump in $m - p$ at $T_1$. * the orange line lets $m_{T_1}$ jump upward in order to make sure that the log price level $p_{T_1}$ does not fall. @@ -578,43 +578,31 @@ unanticipated, as in experiment 2. # compare foreseen vs unforeseen shock fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) -ax[0].plot(T_seq[:-1], μ_seq_2) -ax[0].set_ylabel(r'$\mu$') - -ax[1].plot(T_seq, π_seq_2, - label='Unforeseen') -ax[1].plot(T_seq, π_seq_1, - label='Foreseen', color='tab:green') -ax[1].set_ylabel(r'$\pi$') - -ax[2].plot(T_seq, - m_seq_2_regime1 - p_seq_2_regime1, - label='Unforeseen') -ax[2].plot(T_seq, m_seq_1 - p_seq_1, - label='Foreseen', color='tab:green') -ax[2].set_ylabel(r'$m - p$') - -ax[3].plot(T_seq, m_seq_2_regime1, - label=r'Unforeseen (Smooth $m_{T_1}$)') -ax[3].plot(T_seq, m_seq_2_regime2, - label=r'Unforeseen ($m_{T_1}$ jumps)') -ax[3].plot(T_seq, m_seq_1, - label='Foreseen shock') -ax[3].set_ylabel(r'$m$') - -ax[4].plot(T_seq, p_seq_2_regime1, - label=r'Unforeseen (Smooth $m_{T_1}$)') -ax[4].plot(T_seq, p_seq_2_regime2, - label=r'Unforeseen ($m_{T_1}$ jumps)') -ax[4].plot(T_seq, p_seq_1, - label='Foreseen') -ax[4].set_ylabel(r'$p$') - -for i in range(5): - ax[i].set_xlabel(r'$t$') - -for i in range(1, 5): - ax[i].legend() +plot_data = [ + (T_seq[:-1], [μ_seq_2], r'$\mu$', ['']), + (T_seq, [π_seq_2, π_seq_1], r'$\pi$', ['Unforeseen', 'Foreseen']), + (T_seq, [m_seq_2_regime1 - p_seq_2_regime1, m_seq_1 - p_seq_1], + r'$m - p$', ['Unforeseen', 'Foreseen']), + (T_seq, [m_seq_2_regime1, m_seq_2_regime2, m_seq_1], r'$m$', + ['Unforeseen (Smooth $m_{T_1}$)', + 'Unforeseen ($m_{T_1}$ jumps)', + 'Foreseen shock']), + (T_seq, [p_seq_2_regime1, p_seq_2_regime2, p_seq_1], r'$p$', + ['Unforseen (Smooth $m_{T_1}$)', + 'Unforseen ($m_{T_1}$ jumps)', + 'Foreseen shock']) +] + +for i, (times, sequences, ylabel, labels) in enumerate(plot_data): + for seq, label in zip(sequences, labels): + ax[i].plot(times, seq, label=label) + ax[i].set_ylabel(ylabel) + if labels[0]: + ax[i].legend() + +# Set the x-axis label for all subplots +for axis in ax: + axis.set_xlabel(r'$t$') plt.tight_layout() plt.show() From 6a49bd44dbc62083a5f47863257b9bcc7a29df26 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Sun, 24 Mar 2024 03:12:35 +1100 Subject: [PATCH 08/13] update labels and descriptions --- lectures/cagan_ree.md | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 7f20a7e3..d39846e7 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -20,8 +20,8 @@ We'll use linear algebra first to explain and then do some experiments with a "m Economists call it a "monetary" or "monetarist" theory of price levels because effects on price levels occur via a central banks's decisions to print money supply. - * a goverment's fiscal policies determine whether its *expenditures* exceed its *tax collections* - * if its expenditures exceed its tax collections, the government can instruct the central bank to cover the difference by *printing money* + * a goverment's fiscal policies determine whether its _expenditures_ exceed its _tax collections_ + * if its expenditures exceed its tax collections, the government can instruct the central bank to cover the difference by _printing money_ * that leads to effects on the price level as price level path adjusts to equate the supply of money to the demand for money Such a theory of price levels was described by Thomas Sargent and Neil Wallace in chapter 5 of @@ -41,9 +41,9 @@ persistent inflation. The "monetarist" or "fiscal theory of price levels" asserts that -* to *start* a persistent inflation the government beings persistently to run a money-financed government deficit +* to _start_ a persistent inflation the government beings persistently to run a money-financed government deficit -* to *stop* a persistent inflation the government stops persistently running a money-financed government deficit +* to _stop_ a persistent inflation the government stops persistently running a money-financed government deficit The model in this lecture is a "rational expectations" (or "perfect foresight") version of a model that Philip Cagan {cite}`Cagan` used to study the monetary dynamics of hyperinflations. @@ -316,7 +316,7 @@ $$ \end{cases} $$ -We'll start by executing a version of our "experiment 1" in which the government implements a *foreseen* sudden permanent reduction in the rate of money creation at time $T_1$. +We'll start by executing a version of our "experiment 1" in which the government implements a _foreseen_ sudden permanent reduction in the rate of money creation at time $T_1$. Let's experiment with the following parameters @@ -388,7 +388,7 @@ was completely unanticipated. At time $T_1$ when the "surprise" money growth rate change occurs, to satisfy equation {eq}`eq:pformula2`, the log of real balances jumps -*upward* as $\pi_t$ jumps *downward*. +_upward_ as $\pi_t$ jumps _downward_. But in order for $m_t - p_t$ to jump, which variable jumps, $m_{T_1}$ or $p_{T_1}$? @@ -407,10 +407,14 @@ An alternative assumption about the money supply level is that as part of the "i the government resets $m_{T_1}$ according to $$ -m_{T_1}^2 - m_{T_1}^1 = \alpha (\pi^1 - \pi^2) +m_{T_1}^2 - m_{T_1}^1 = \alpha (\pi_{T_1}^1 - \pi_{T_1}^2), $$ (eq:eqnmoneyjump) -By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from *falling* at the moment that the unanticipated stabilization arrives. +which describes how the government could reset the money supply at $T_1$ in response to the jump in expected inflation associated with the monetary stabilization. + +Doing this would let the price level be continuous at $T_1$. + +By letting money jump according to equation {eq}`eq:eqnmoneyjump` the monetary authority prevents the price level from _falling_ at the moment that the unanticipated stabilization arrives. In various research papers about stabilizations of high inflations, the jump in the money supply described by equation {eq}`eq:eqnmoneyjump` has been called "the velocity dividend" that a government reaps from implementing a regime change that sustains a permanently lower inflation rate. @@ -482,7 +486,6 @@ are identical to those for experiment 1, the foreseen sudden stabilization. The following code does the calculations and plots outcomes. ```{code-cell} ipython3 -:tags: [hide-cell] # path 1 μ_seq_2_path1 = μ0 * np.ones(T+1) @@ -517,13 +520,16 @@ m_seq_2_regime2 = np.concatenate([m_seq_2_path1[:T1+1], m_seq_2_cont2]) p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], p_seq_2_cont2]) +``` +```{code-cell} ipython3 +:tags: [hide-input] T_seq = range(T+2) # plot both regimes fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) -# Data configuration for each subplot +# Configuration for each subplot plot_configs = [ {'data': [(T_seq[:-1], μ_seq_2)], 'ylabel': r'$\mu$'}, {'data': [(T_seq, π_seq_2)], 'ylabel': r'$\pi$'}, @@ -575,6 +581,7 @@ That allows us to assess how important it is to understand whether the sudden pe unanticipated, as in experiment 2. ```{code-cell} ipython3 +:tags: [hide-input] # compare foreseen vs unforeseen shock fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) @@ -600,7 +607,6 @@ for i, (times, sequences, ylabel, labels) in enumerate(plot_data): if labels[0]: ax[i].legend() -# Set the x-axis label for all subplots for axis in ax: axis.set_xlabel(r'$t$') @@ -632,7 +638,7 @@ $$ \mu_t = \phi^t \mu_0 + (1 - \phi^t) \mu^* . $$ -Next we perform an experiment in which there is a perfectly foreseen *gradual* decrease in the rate of growth of the money supply. +Next we perform an experiment in which there is a perfectly foreseen _gradual_ decrease in the rate of growth of the money supply. The following code does the calculations and plots the results. From 92c51467de0a6cd001beaeae2c79c695fc1b6115 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 25 Mar 2024 20:17:30 +1100 Subject: [PATCH 09/13] update request on `the` --- lectures/cagan_ree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index d39846e7..2d4a1b8a 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -410,7 +410,7 @@ $$ m_{T_1}^2 - m_{T_1}^1 = \alpha (\pi_{T_1}^1 - \pi_{T_1}^2), $$ (eq:eqnmoneyjump) -which describes how the government could reset the money supply at $T_1$ in response to the jump in expected inflation associated with the monetary stabilization. +which describes how the government could reset the money supply at $T_1$ in response to the jump in expected inflation associated with monetary stabilization. Doing this would let the price level be continuous at $T_1$. From d7fd2d74d05d1c308ab4148eafbc7e8ae98b3c8d Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 25 Mar 2024 20:38:36 +1100 Subject: [PATCH 10/13] update graph function and set global dpi --- lectures/cagan_ree.md | 79 ++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 2d4a1b8a..7c2cb745 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -236,6 +236,7 @@ As usual, we'll start by importing some Python modules. import numpy as np from collections import namedtuple import matplotlib.pyplot as plt +plt.rcParams['figure.dpi'] = 200 ``` First, we store parameters in a `namedtuple`: @@ -338,7 +339,7 @@ Now we use the following function to plot the result ```{code-cell} ipython3 def plot_sequences(sequences, labels): - fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12], dpi=200) + fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12]) for ax, seq, label in zip(axs, sequences, labels): ax.plot(range(len(seq)), seq, label=label) ax.set_ylabel(label) @@ -524,10 +525,11 @@ p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], ```{code-cell} ipython3 :tags: [hide-input] + T_seq = range(T+2) # plot both regimes -fig, ax = plt.subplots(5, 1, figsize=[5, 12], dpi=200) +fig, ax = plt.subplots(5, 1, figsize=[5, 12]) # Configuration for each subplot plot_configs = [ @@ -543,20 +545,22 @@ plot_configs = [ 'ylabel': r'$p$'} ] -# Loop through each subplot configuration -for axi, config in zip(ax, plot_configs): - for data in config['data']: - if len(data) == 3: # Plot with label for legend - axi.plot(data[0], data[1], label=data[2]) - else: # Plot without label - axi.plot(data[0], data[1]) - axi.set_ylabel(config['ylabel']) - axi.set_xlabel(r'$t$') - if 'label' in config: # If there's a label, add a legend - axi.legend() - -plt.tight_layout() -plt.show() +def generate_plots(plot_configs, ax): + + # Loop through each subplot configuration + for axi, config in zip(ax, plot_configs): + for data in config['data']: + if len(data) == 3: # Plot with label for legend + axi.plot(data[0], data[1], label=data[2]) + axi.legend() + else: # Plot without label + axi.plot(data[0], data[1]) + axi.set_ylabel(config['ylabel']) + axi.set_xlabel(r'$t$') + plt.tight_layout() + plt.show() + +generate_plots(plot_configs, ax) ``` We invite you to compare these graphs with corresponding ones for the foreseen stabilization analyzed in experiment 1 above. @@ -582,36 +586,25 @@ unanticipated, as in experiment 2. ```{code-cell} ipython3 :tags: [hide-input] -# compare foreseen vs unforeseen shock -fig, ax = plt.subplots(5, figsize=[5, 12], dpi=200) - -plot_data = [ - (T_seq[:-1], [μ_seq_2], r'$\mu$', ['']), - (T_seq, [π_seq_2, π_seq_1], r'$\pi$', ['Unforeseen', 'Foreseen']), - (T_seq, [m_seq_2_regime1 - p_seq_2_regime1, m_seq_1 - p_seq_1], - r'$m - p$', ['Unforeseen', 'Foreseen']), - (T_seq, [m_seq_2_regime1, m_seq_2_regime2, m_seq_1], r'$m$', - ['Unforeseen (Smooth $m_{T_1}$)', - 'Unforeseen ($m_{T_1}$ jumps)', - 'Foreseen shock']), - (T_seq, [p_seq_2_regime1, p_seq_2_regime2, p_seq_1], r'$p$', - ['Unforseen (Smooth $m_{T_1}$)', - 'Unforseen ($m_{T_1}$ jumps)', - 'Foreseen shock']) -] -for i, (times, sequences, ylabel, labels) in enumerate(plot_data): - for seq, label in zip(sequences, labels): - ax[i].plot(times, seq, label=label) - ax[i].set_ylabel(ylabel) - if labels[0]: - ax[i].legend() +# compare foreseen vs unforeseen shock +fig, ax = plt.subplots(5, figsize=[5, 12]) -for axis in ax: - axis.set_xlabel(r'$t$') +plot_configs = [ + {'data': [(T_seq[:-1], μ_seq_2)], 'ylabel': r'$\mu$'}, + {'data': [(T_seq, π_seq_2, 'Unforeseen'), + (T_seq, π_seq_1, 'Foreseen')], 'ylabel': r'$p$'}, + {'data': [(T_seq, m_seq_2_regime1 - p_seq_2_regime1, 'Unforeseen'), + (T_seq, m_seq_1 - p_seq_1, 'Foreseen')], 'ylabel': r'$m - p$'}, + {'data': [(T_seq, m_seq_2_regime1, 'Unforeseen (Smooth $m_{T_1}$)'), + (T_seq, m_seq_2_regime2, 'Unforeseen ($m_{T_1}$ jumps)'), + (T_seq, m_seq_1, 'Foreseen')], 'ylabel': r'$m$'}, + {'data': [(T_seq, p_seq_2_regime1, 'Unforeseen (Smooth $m_{T_1}$)'), + (T_seq, p_seq_2_regime2, 'Unforeseen ($m_{T_1}$ jumps)'), + (T_seq, p_seq_1, 'Foreseen')], 'ylabel': r'$p$'} +] -plt.tight_layout() -plt.show() +generate_plots(plot_configs, ax) ``` It is instructive to compare the preceding graphs with graphs of log price levels and inflation rates for data from four big inflations described in From b5b58bddaae972afcdaac7f30dba8263cc2976c8 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 25 Mar 2024 20:47:12 +1100 Subject: [PATCH 11/13] distinguish the names of the two plotting functions --- lectures/cagan_ree.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 7c2cb745..3c12a6ec 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -545,8 +545,7 @@ plot_configs = [ 'ylabel': r'$p$'} ] -def generate_plots(plot_configs, ax): - +def experiment_plot(plot_configs, ax): # Loop through each subplot configuration for axi, config in zip(ax, plot_configs): for data in config['data']: @@ -560,7 +559,7 @@ def generate_plots(plot_configs, ax): plt.tight_layout() plt.show() -generate_plots(plot_configs, ax) +experiment_plot(plot_configs, ax) ``` We invite you to compare these graphs with corresponding ones for the foreseen stabilization analyzed in experiment 1 above. @@ -604,7 +603,7 @@ plot_configs = [ (T_seq, p_seq_1, 'Foreseen')], 'ylabel': r'$p$'} ] -generate_plots(plot_configs, ax) +experiment_plot(plot_configs, ax) ``` It is instructive to compare the preceding graphs with graphs of log price levels and inflation rates for data from four big inflations described in From 0f98e5f9826b830bde824618d7179616e816f72d Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 25 Mar 2024 21:08:45 +1100 Subject: [PATCH 12/13] switch to tuple whenever possible --- lectures/cagan_ree.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index 3c12a6ec..a082995d 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -339,7 +339,7 @@ Now we use the following function to plot the result ```{code-cell} ipython3 def plot_sequences(sequences, labels): - fig, axs = plt.subplots(len(sequences), 1, figsize=[5, 12]) + fig, axs = plt.subplots(len(sequences), 1, figsize=(5, 12)) for ax, seq, label in zip(axs, sequences, labels): ax.plot(range(len(seq)), seq, label=label) ax.set_ylabel(label) @@ -348,8 +348,8 @@ def plot_sequences(sequences, labels): plt.tight_layout() plt.show() -sequences = [μ_seq_1, π_seq_1, m_seq_1 - p_seq_1, m_seq_1, p_seq_1] -plot_sequences(sequences, [r'$\mu$', r'$\pi$', r'$m - p$', r'$m$', r'$p$']) +sequences = (μ_seq_1, π_seq_1, m_seq_1 - p_seq_1, m_seq_1, p_seq_1) +plot_sequences(sequences, (r'$\mu$', r'$\pi$', r'$m - p$', r'$m$', r'$p$')) ``` The plot of the money growth rate $\mu_t$ in the top level panel portrays @@ -502,14 +502,14 @@ cm2 = create_cagan_model(m0=m_seq_2_path1[T1+1], # regime 1 - simply glue π_seq, μ_seq -μ_seq_2 = np.concatenate([μ_seq_2_path1[:T1+1], - μ_seq_2_cont]) -π_seq_2 = np.concatenate([π_seq_2_path1[:T1+1], - π_seq_2_cont]) -m_seq_2_regime1 = np.concatenate([m_seq_2_path1[:T1+1], - m_seq_2_cont1]) -p_seq_2_regime1 = np.concatenate([p_seq_2_path1[:T1+1], - p_seq_2_cont1]) +μ_seq_2 = np.concatenate((μ_seq_2_path1[:T1+1], + μ_seq_2_cont)) +π_seq_2 = np.concatenate((π_seq_2_path1[:T1+1], + π_seq_2_cont)) +m_seq_2_regime1 = np.concatenate((m_seq_2_path1[:T1+1], + m_seq_2_cont1)) +p_seq_2_regime1 = np.concatenate((p_seq_2_path1[:T1+1], + p_seq_2_cont1)) # regime 2 - reset m_T1 m_T1 = (m_seq_2_path1[T1] + μ0) + cm2.α*(μ0 - μ_star) @@ -517,10 +517,10 @@ m_T1 = (m_seq_2_path1[T1] + μ0) + cm2.α*(μ0 - μ_star) cm3 = create_cagan_model(m0=m_T1, μ_seq=μ_seq_2_cont) π_seq_2_cont2, m_seq_2_cont2, p_seq_2_cont2 = solve(cm3, T-1-T1) -m_seq_2_regime2 = np.concatenate([m_seq_2_path1[:T1+1], - m_seq_2_cont2]) -p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], - p_seq_2_cont2]) +m_seq_2_regime2 = np.concatenate((m_seq_2_path1[:T1+1], + m_seq_2_cont2)) +p_seq_2_regime2 = np.concatenate((p_seq_2_path1[:T1+1], + p_seq_2_cont2)) ``` ```{code-cell} ipython3 @@ -529,7 +529,7 @@ p_seq_2_regime2 = np.concatenate([p_seq_2_path1[:T1+1], T_seq = range(T+2) # plot both regimes -fig, ax = plt.subplots(5, 1, figsize=[5, 12]) +fig, ax = plt.subplots(5, 1, figsize=(5, 12)) # Configuration for each subplot plot_configs = [ @@ -587,7 +587,7 @@ unanticipated, as in experiment 2. :tags: [hide-input] # compare foreseen vs unforeseen shock -fig, ax = plt.subplots(5, figsize=[5, 12]) +fig, ax = plt.subplots(5, figsize=(5, 12)) plot_configs = [ {'data': [(T_seq[:-1], μ_seq_2)], 'ylabel': r'$\mu$'}, @@ -644,10 +644,10 @@ cm4 = create_cagan_model(μ_seq=μ_seq_stab) π_seq_4, m_seq_4, p_seq_4 = solve(cm4, T) -sequences = [μ_seq_stab, π_seq_4, - m_seq_4 - p_seq_4, m_seq_4, p_seq_4] -plot_sequences(sequences, [r'$\mu$', r'$\pi$', - r'$m - p$', r'$m$', r'$p$']) +sequences = (μ_seq_stab, π_seq_4, + m_seq_4 - p_seq_4, m_seq_4, p_seq_4) +plot_sequences(sequences, (r'$\mu$', r'$\pi$', + r'$m - p$', r'$m$', r'$p$')) ``` ## Sequel From 44a47ffb9b313f6c94ed61b52168baf647dbcda7 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 3 Apr 2024 13:10:11 +1100 Subject: [PATCH 13/13] revert changes on dpi settings --- lectures/cagan_ree.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lectures/cagan_ree.md b/lectures/cagan_ree.md index a082995d..d694c57d 100644 --- a/lectures/cagan_ree.md +++ b/lectures/cagan_ree.md @@ -236,7 +236,6 @@ As usual, we'll start by importing some Python modules. import numpy as np from collections import namedtuple import matplotlib.pyplot as plt -plt.rcParams['figure.dpi'] = 200 ``` First, we store parameters in a `namedtuple`: @@ -339,7 +338,7 @@ Now we use the following function to plot the result ```{code-cell} ipython3 def plot_sequences(sequences, labels): - fig, axs = plt.subplots(len(sequences), 1, figsize=(5, 12)) + fig, axs = plt.subplots(len(sequences), 1, figsize=(5, 12), dpi=200) for ax, seq, label in zip(axs, sequences, labels): ax.plot(range(len(seq)), seq, label=label) ax.set_ylabel(label) @@ -529,7 +528,7 @@ p_seq_2_regime2 = np.concatenate((p_seq_2_path1[:T1+1], T_seq = range(T+2) # plot both regimes -fig, ax = plt.subplots(5, 1, figsize=(5, 12)) +fig, ax = plt.subplots(5, 1, figsize=(5, 12), dpi=200) # Configuration for each subplot plot_configs = [ @@ -587,7 +586,7 @@ unanticipated, as in experiment 2. :tags: [hide-input] # compare foreseen vs unforeseen shock -fig, ax = plt.subplots(5, figsize=(5, 12)) +fig, ax = plt.subplots(5, figsize=(5, 12), dpi=200) plot_configs = [ {'data': [(T_seq[:-1], μ_seq_2)], 'ylabel': r'$\mu$'},