@@ -58,7 +58,7 @@ import numpy as np
5858import 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
6464def spectral_density_var1(A, V, ω_grid):
@@ -209,15 +209,17 @@ A_list = [samuelson_transition(c, v) for _, c, v in cases]
209209for (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
215216With weak acceleration ($v=0.1$), the discriminant is positive and the roots are real.
216217
217218With 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
221223T = 40
222224s0 = np.array([1.0, 0.0])
223225irfs = []
@@ -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)
279281axes[0].plot(np.cos(θ_circle), np.sin(θ_circle),
280282 'k--', lw=0.8, label='unit circle')
@@ -651,7 +653,7 @@ cos_ω = factor * np.cos(θ)
651653print(f"Chow's example: r = {r_example}, θ = {θ_deg}°")
652654print(f" cos(ω) = {cos_ω:.3f}")
653655print(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
657659As $r \to 1$, the peak frequency converges to $\theta$.
@@ -710,8 +712,10 @@ c_real, v_real = 0.8, 0.1
710712A_real = samuelson_transition(c_real, v_real)
711713eig_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
716720F_complex = spectral_density_var1(A_complex, V_hs, ω_grid)
717721F_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+
13021308ax.set_xlabel(r'frequency $\omega/2\pi$')
13031309ax.set_ylabel('$g_i(\\omega)$')
13041310ax.set_xlim([1/18, 0.5])
@@ -1536,7 +1542,8 @@ plt.show()
15361542
15371543threshold_idx = np.where(~np.isnan(peak_periods))[0]
15381544if 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
15421549The interior peak appears only when the shock correlation exceeds a threshold.
@@ -1587,7 +1594,8 @@ print("\nRecursion method:")
15871594print(np.real(Γ_recursion[5][:3, :3]).round(10))
15881595print("\nEigendecomposition method:")
15891596print(Γ_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
15931601Both methods produce essentially identical results, up to numerical precision.
0 commit comments