Skip to content

Commit 9de7a5d

Browse files
committed
updates
1 parent 65b8e4c commit 9de7a5d

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

lectures/chow_business_cycles.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import numpy as np
5858
import matplotlib.pyplot as plt
5959
```
6060

61-
We will use the following helper functions throughout the lecture:
61+
We will use the following helper functions throughout the lecture
6262

6363
```{code-cell} ipython3
6464
def spectral_density_var1(A, V, ω_grid):
@@ -209,15 +209,17 @@ A_list = [samuelson_transition(c, v) for _, c, v in cases]
209209
for (label, c, v), A in zip(cases, A_list):
210210
eig = np.linalg.eigvals(A)
211211
disc = (c + v)**2 - 4*v
212-
print(f"{label}: c={c}, v={v}, discriminant={disc:.2f}, eigenvalues={eig}")
212+
print(
213+
f"{label}: c={c}, v={v}, discriminant={disc:.2f}, eigenvalues={eig}")
213214
```
214215

215216
With weak acceleration ($v=0.1$), the discriminant is positive and the roots are real.
216217

217218
With strong acceleration ($v=0.8$), the discriminant is negative and the roots are complex conjugates that enable oscillatory dynamics.
218219

220+
Now let's see how these different eigenvalue structures affect the impulse responses to a one-time shock in $Y$
221+
219222
```{code-cell} ipython3
220-
# impulse responses from a one-time unit shock in Y
221223
T = 40
222224
s0 = np.array([1.0, 0.0])
223225
irfs = []
@@ -274,7 +276,7 @@ for v in v_grid:
274276
s = A @ s
275277
axes[1].plot(range(T_irf + 1), irf, lw=2, label=f'$v={v}$')
276278
277-
# Eigenvalue panel with unit circle
279+
# Visualize the eigenvalue locations and the unit circle
278280
θ_circle = np.linspace(0, 2*np.pi, 100)
279281
axes[0].plot(np.cos(θ_circle), np.sin(θ_circle),
280282
'k--', lw=0.8, label='unit circle')
@@ -651,7 +653,7 @@ cos_ω = factor * np.cos(θ)
651653
print(f"Chow's example: r = {r_example}, θ = {θ_deg}°")
652654
print(f" cos(ω) = {cos_ω:.3f}")
653655
print(f" ω = {np.rad2deg(ω_example):.1f}°")
654-
print(f" Peak period = {360/np.rad2deg(ω_example):.1f} (vs deterministic period = {360/θ_deg:.1f})")
656+
print(f" Peak period = {360/np.rad2deg(ω_example):.1f}")
655657
```
656658

657659
As $r \to 1$, the peak frequency converges to $\theta$.
@@ -710,8 +712,10 @@ c_real, v_real = 0.8, 0.1
710712
A_real = samuelson_transition(c_real, v_real)
711713
eig_real = np.linalg.eigvals(A_real)
712714
713-
print(f"Complex case (c={c_complex}, v={v_complex}): eigenvalues = {eig_complex}")
714-
print(f"Real case (c={c_real}, v={v_real}): eigenvalues = {eig_real}")
715+
print(
716+
f"Complex case (c={c_complex}, v={v_complex}): eigenvalues = {eig_complex}")
717+
print(
718+
f"Real case (c={c_real}, v={v_real}): eigenvalues = {eig_real}")
715719
716720
F_complex = spectral_density_var1(A_complex, V_hs, ω_grid)
717721
F_real = spectral_density_var1(A_real, V_hs, ω_grid)
@@ -1045,7 +1049,8 @@ def spectral_density_chow(λ, B, W, ω_grid):
10451049
F_star = np.zeros((p, p), dtype=complex)
10461050
for i in range(p):
10471051
for j in range(p):
1048-
denom = (1 - λ[i] * np.exp(-1j * ω)) * (1 - λ[j] * np.exp(1j * ω))
1052+
denom = (1 - λ[i] * np.exp(-1j * ω)) \
1053+
* (1 - λ[j] * np.exp(1j * ω))
10491054
F_star[i, j] = W[i, j] / denom
10501055
F[k] = B @ F_star @ B.T
10511056
return F / (2 * np.pi)
@@ -1265,7 +1270,7 @@ These implied leads and lags are broadly consistent with turning-point timing su
12651270

12661271
### Building blocks of spectral shape
12671272

1268-
Each eigenvalue contributes a characteristic spectral shape through the **scalar kernel**
1273+
Each eigenvalue contributes a characteristic spectral shape through the *scalar kernel*
12691274

12701275
```{math}
12711276
:label: chow_scalar_kernel
@@ -1299,6 +1304,7 @@ for i, λ_i in enumerate(λ):
12991304
label = f'$\\lambda_{i+1}$ = {λ_i:.4f}' \
13001305
if np.isreal(λ_i) else f'$\\lambda_{i+1}$ = {λ_i:.3f}'
13011306
ax.semilogy(freq, g_i, label=label, lw=2)
1307+
13021308
ax.set_xlabel(r'frequency $\omega/2\pi$')
13031309
ax.set_ylabel('$g_i(\\omega)$')
13041310
ax.set_xlim([1/18, 0.5])
@@ -1536,7 +1542,8 @@ plt.show()
15361542
15371543
threshold_idx = np.where(~np.isnan(peak_periods))[0]
15381544
if len(threshold_idx) > 0:
1539-
print(f"interior peak appears when correlation >= {corr_grid[threshold_idx[0]]:.2f}")
1545+
print(
1546+
f"interior peak when correlation >= {corr_grid[threshold_idx[0]]:.2f}")
15401547
```
15411548

15421549
The interior peak appears only when the shock correlation exceeds a threshold.
@@ -1587,7 +1594,8 @@ print("\nRecursion method:")
15871594
print(np.real(Γ_recursion[5][:3, :3]).round(10))
15881595
print("\nEigendecomposition method:")
15891596
print(Γ_eigen[5][:3, :3].round(10))
1590-
print("\nMax absolute difference:", np.max(np.abs(np.real(Γ_recursion[5]) - Γ_eigen[5])))
1597+
print("\nMax absolute difference:",
1598+
np.max(np.abs(np.real(Γ_recursion[5]) - Γ_eigen[5])))
15911599
```
15921600

15931601
Both methods produce essentially identical results, up to numerical precision.

lectures/measurement_models.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ quite different sets of restrictions on the data.
7474
In this lecture we follow {cite:t}`Sargent1989` and study how these
7575
alternative measurement schemes affect empirical implications.
7676

77-
We start with imports and helper functions to be used throughout this lecture
77+
We start with imports and helper functions to be used throughout this lecture to generate LaTeX output
7878

7979
```{code-cell} ipython3
8080
import numpy as np
@@ -203,7 +203,7 @@ Assumption 1 is crucial for the strict form of the accelerator.
203203

204204
Relaxing it to allow serially correlated $\theta_t$ preserves an
205205
accelerator in a broad sense but loses the sharp geometric-lag
206-
form of {eq}`accelerator`.
206+
form of {eq}`mm_accelerator`.
207207

208208
Adding a second shock breaks the one-index structure entirely
209209
and can generate nontrivial Granger causality even without
@@ -227,7 +227,7 @@ c_t = \left(\frac{1-\beta}{1-\beta L}\right) y_{nt},
227227
```
228228

229229
```{math}
230-
:label: accelerator
230+
:label: mm_accelerator
231231
k_{t+1} - k_t = f^{-1} \left(\frac{1-L}{1-\beta L}\right) y_{nt},
232232
```
233233

@@ -240,7 +240,7 @@ Equation {eq}`friedman_consumption` is Friedman's consumption
240240
model: consumption is a geometric distributed lag of income,
241241
with the decay coefficient $\beta$ equal to the discount factor.
242242

243-
Equation {eq}`accelerator` is the distributed lag accelerator:
243+
Equation {eq}`mm_accelerator` is the distributed lag accelerator:
244244
investment is a geometric distributed lag of the first difference
245245
of income.
246246

@@ -746,7 +746,8 @@ def fev_contributions(psi, V, n_horizons=20):
746746
747747
748748
psi1 = measured_wold_coeffs(F1, G1, H1, n_terms=40)
749-
resp1 = np.array([psi1[j] @ linalg.cholesky(V1, lower=True) for j in range(14)])
749+
resp1 = np.array(
750+
[psi1[j] @ linalg.cholesky(V1, lower=True) for j in range(14)])
750751
decomp1 = fev_contributions(psi1, V1, n_horizons=20)
751752
```
752753

@@ -829,7 +830,8 @@ shock_titles = [r'\text{A. Innovation in } y_n',
829830
parts = []
830831
for i, title in enumerate(shock_titles):
831832
arr = df_to_latex_array(fev_table(decomp1, i, horizons)).strip('$')
832-
parts.append(r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
833+
parts.append(
834+
r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
833835
834836
display(Latex('$' + r' \quad '.join(parts) + '$'))
835837
```
@@ -896,7 +898,8 @@ wold_titles = [r'\text{A. Response to } y_n \text{ innovation}',
896898
parts = []
897899
for i, title in enumerate(wold_titles):
898900
arr = df_to_latex_array(wold_response_table(resp1, i, lags)).strip('$')
899-
parts.append(r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
901+
parts.append(
902+
r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
900903
901904
display(Latex('$' + r' \quad '.join(parts) + '$'))
902905
```
@@ -1130,7 +1133,8 @@ just like the true economy
11301133
parts = []
11311134
for i, title in enumerate(shock_titles):
11321135
arr = df_to_latex_array(fev_table(decomp2, i, horizons)).strip('$')
1133-
parts.append(r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
1136+
parts.append(
1137+
r'\begin{array}{c} ' + title + r' \\ ' + arr + r' \end{array}')
11341138
11351139
display(Latex('$' + r' \quad '.join(parts) + '$'))
11361140
```

0 commit comments

Comments
 (0)