diff --git a/lectures/_static/quant-econ.bib b/lectures/_static/quant-econ.bib
index 55eb1e7a4..0ba2eddd3 100644
--- a/lectures/_static/quant-econ.bib
+++ b/lectures/_static/quant-econ.bib
@@ -3,6 +3,14 @@
Note: Extended Information (like abstracts, doi, url's etc.) can be found in quant-econ-extendedinfo.bib file in _static/
###
+@inproceedings{hansen2004certainty,
+ title={Certainty equivalence and model uncertainty},
+ author={Hansen, Lars Peter and Sargent, Thomas J},
+ booktitle={Conference on Models and Monetary Policy: Research in the Tradition of Dale Henderson, Richard Porter, and Peter Tinsley (http://www. federalreserve. gov/events/conferences/mmp2004/pdf/hansensargent. pdf)},
+ year={2004}
+}
+
+
@article{evans2005interview,
title={An interview with Thomas J. Sargent},
author={Evans, George W and Honkapohja, Seppo},
@@ -216,6 +224,14 @@ @book{Burns_2023
address = {New York}
}
+@book{lucas1981rational,
+ title={Rational expectations and econometric practice},
+ author={Lucas, Robert E and Sargent, Thomas J},
+ year={1981},
+ publisher={U of Minnesota Press},
+ address = {Minneapolis, Minnesota}
+}
+
@article{Orcutt_Winokur_69,
issn = {00129682, 14680262},
abstract = {Monte Carlo techniques are used to study the first order autoregressive time series model with unknown level, slope, and error variance. The effect of lagged variables on inference, estimation, and prediction is described, using results from the classical normal linear regression model as a standard. In particular, use of the t and x^2 distributions as approximate sampling distributions is verified for inference concerning the level and residual error variance. Bias in the least squares estimate of the slope is measured, and two bias corrections are evaluated. Least squares chained prediction is studied, and attempts to measure the success of prediction and to improve on the least squares technique are discussed.},
@@ -230,6 +246,35 @@ @article{Orcutt_Winokur_69
year = {1969}
}
+
+@incollection{Hurwicz:1962,
+ address = {Stanford, CA},
+ author = {Hurwicz, Leonid},
+ booktitle = {Logic, Methodology and Philosophy of Science},
+ date-added = {2014-12-26 17:45:57 +0000},
+ date-modified = {2022-01-09 19:40:37 -0600},
+ pages = {232-239},
+ publisher = {Stanford University Press},
+ title = {On the Structural Form of Interdependent Systems},
+ year = {1962}
+}
+
+
+@article{Hurwicz:1966,
+ abstract = {Publisher Summary This chapter concentrates on the structural form of interdependent systems. A great deal of effort is devoted in econometrics and elsewhere to find the behavior pattern of an observed configuration. Such effort is justified on the grounds that the knowledge of the behavior pattern is needed for the purpose of giving explanation or prediction. The merits of this justification are also examined in the chapter. At this point, the chapter considers certain difficulties encountered in the process of looking for the behavior patterns. In certain fields, notably economics (but also— for example, electronic network theory), it deals with a set (configuration) of objects (components) that are interdependent in their behavior. For purposes of both theoretical analysis and empirical investigation of such situations, the phenomena are often described in the chapter (in idealized form) by means of a system of simultaneous equations. History alone is not enabled to determine the behavior pattern of the configuration; but this does not mean that the task is hopeless. The priori information is obtained from the axiom systems or theories that are believed to be relevant to the behavior pattern of the configuration.},
+ author = {Leonid Hurwicz},
+ doi = {http://dx.doi.org/10.1016/S0049-237X(09)70590-7},
+ editor = {Patrick S Ernest Nagel and Alfred Tarski},
+ journal = {Logic, Methodology and Philosophy of Science Proceeding of the 1960 International Congress},
+ pages = {232-239},
+ publisher = {Elsevier},
+ title = {On the Structural Form of Interdependent Systems},
+ volume = {44},
+ url = {http://www.sciencedirect.com/science/article/pii/S0049237X09705907},
+ year = {1966},
+}
+
+
@article{hurwicz1950least,
title = {Least squares bias in time series},
author = {Hurwicz, Leonid},
@@ -570,6 +615,24 @@ @article{HST_1999
}
+@article{simon1956dynamic,
+ title={Dynamic programming under uncertainty with a quadratic criterion function},
+ author={Simon, Herbert A},
+ journal={Econometrica, Journal of the Econometric Society},
+ pages={74--81},
+ year={1956},
+ publisher={JSTOR}
+}
+
+@article{theil1957note,
+ title={A note on certainty equivalence in dynamic planning},
+ author={Theil, Henri},
+ journal={Econometrica: Journal of the Econometric Society},
+ pages={346--349},
+ year={1957},
+ publisher={JSTOR}
+}
+
@article{Jacobson_73,
author = {D. H. Jacobson},
year = {1973},
@@ -1943,6 +2006,36 @@ @article{hopenhayn1992entry
publisher = {JSTOR}
}
+
+@book{bacsar2008h,
+ title={H-infinity optimal control and related minimax design problems: a dynamic game approach},
+ author={Ba{\c{s}}ar, Tamer and Bernhard, Pierre},
+ year={2008},
+ publisher={Springer Science \& Business Media}
+}
+
+@article{sargent1981interpreting,
+ title={Interpreting economic time series},
+ author={Sargent, Thomas J},
+ journal={Journal of political Economy},
+ volume={89},
+ number={2},
+ pages={213--248},
+ year={1981},
+ publisher={The University of Chicago Press}
+}
+
+
+@inproceedings{lucas1976econometric,
+ title={Econometric policy evaluation: A critique},
+ author={Lucas, Robert E Jr},
+ booktitle={Carnegie-Rochester conference series on public policy},
+ volume={1},
+ pages={19--46},
+ year={1976},
+ organization={North-Holland}
+}
+
@article{HopenhaynRogerson1993,
author = {Hopenhayn, Hugo A and Rogerson, Richard},
journal = {Journal of Political Economy},
diff --git a/lectures/_toc.yml b/lectures/_toc.yml
index f43d7f3dc..da19f0b03 100644
--- a/lectures/_toc.yml
+++ b/lectures/_toc.yml
@@ -104,6 +104,8 @@ parts:
- file: cross_product_trick
- file: perm_income
- file: perm_income_cons
+ - file: theil_1
+ - file: theil_2
- file: lq_inventories
- caption: Optimal Growth
numbered: true
diff --git a/lectures/risk_aversion_or_mistaken_beliefs.md b/lectures/risk_aversion_or_mistaken_beliefs.md
index 2bf92343b..c8cce6826 100644
--- a/lectures/risk_aversion_or_mistaken_beliefs.md
+++ b/lectures/risk_aversion_or_mistaken_beliefs.md
@@ -1607,8 +1607,8 @@ mystnb:
name: fig-us-yields
---
data = pd.read_csv(
- 'https://raw.githubusercontent.com/QuantEcon/lecture-python.myst/update-asset/lectures/'
- '_static/lecture_specific/risk_aversion_or_mistaken_beliefs/fred_data.csv',
+ 'https://raw.githubusercontent.com/QuantEcon/lecture-python.myst/refs/heads/'
+ 'main/lectures/_static/lecture_specific/risk_aversion_or_mistaken_beliefs/fred_data.csv',
parse_dates=['DATE'], index_col='DATE'
)
diff --git a/lectures/theil_1.md b/lectures/theil_1.md
new file mode 100644
index 000000000..caaa874ec
--- /dev/null
+++ b/lectures/theil_1.md
@@ -0,0 +1,391 @@
+---
+jupytext:
+ text_representation:
+ extension: .md
+ format_name: myst
+kernelspec:
+ display_name: Python 3
+ language: python
+ name: python3
+---
+
+(certainty_equiv_theil1)=
+```{raw} jupyter
+
+```
+
+# Certainty Equivalence
+
+```{index} single: Certainty Equivalence; Robustness
+```
+
+```{index} single: LQ Control; Permanent Income
+```
+
+```{contents} Contents
+:depth: 2
+```
+
+
+In addition to what's in Anaconda, this lecture will need the following libraries:
+
+```{code-cell} ipython3
+---
+tags: [hide-output]
+---
+!pip install quantecon
+```
+
+```{code-cell} ipython3
+import numpy as np
+import matplotlib.pyplot as plt
+from quantecon import LQ
+```
+
+## Overview
+
+{cite:t}`simon1956dynamic` and {cite:t}`theil1957note` established a celebrated *certainty equivalence* (CE) property for linear-quadratic (LQ) dynamic programming problems.
+
+Their result justifies a convenient two-step algorithm:
+
+1. **Optimize** under perfect foresight (treat future exogenous variables as known).
+2. **Forecast** — substitute optimal forecasts for the unknown future values.
+
+The striking insight is that these two steps are completely separable.
+
+The decision rule that emerges from step 1 is *identical* to the decision rule for the original stochastic problem once optimal forecasts are substituted in step 2.
+
+The decision rule does not depend on the variance of the shocks, but the *level* of the optimal value function *does*.
+
+After describing the structure of the certainty equivalence property in detail, this lecture describes its role in rational expectations modeling.
+
+We do so by drawing heavily on the introduction to {cite}`lucas1981rational`.
+
+In addition to learning the certainty equivalence principle, this lecture describes troubles with pre-rational expectations econometric policy evaluation procedures described by {cite}`lucas1976econometric`.
+
+```{note}
+That volume collected early papers on rational expectations modeling and econometrics.
+```
+
+## A central problem of empirical economics
+
+To set the stage, {cite:t}`lucas1981rational` stated the central question for empirical economics that had been posed by Leonid Hurwicz ({cite}`Hurwicz:1962`,{cite}`Hurwicz:1966`):
+
+ * Given observations on an agent's behavior in a particular economic environment, what can we infer about how that behavior *would have differed* had the environment been altered?
+
+```{note}
+Hurwicz formulates a notion of 'causality' as a context-specific concept that he casts in terms of a well posed decision problem.
+```
+
+This is the problem of policy-invariant structural inference in the following setting.
+
+ * Observations emerged under one environment or 'regime'
+ * We want to predict behavior under another 'regime'
+ * Unless we understand *why* agents behaved as they did in the historical regime, i.e., their purposes, we can't predict their behavior under the constraints they face in the new regime.
+
+To confront the problem that Hurwicz had posed, {cite:t}`lucas1981rational` formulated the following decision framework.
+
+## A formal setup
+
+Consider a single decision maker whose situation at date $t$ is fully described by two state variables $(x_t, z_t)$.
+
+**The environment** $z_t \in S_1$ is selected by "nature" and evolves exogenously according to
+
+```{math}
+:label: eq:z_transition_v3
+z_{t+1} = f(z_t,\, \epsilon_{t+1}),
+```
+
+where the innovations $\{\epsilon_t\}$ are i.i.d. draws from a fixed c.d.f. $\Phi(\cdot) : \mathcal{E} \to [0,1]$.
+
+The function $f : S_1 \times \mathcal{E} \to S_1$ is called the **decision maker's environment**.
+
+**The endogenous state** $x_t \in S_2$ is under partial control of the agent.
+
+Each period the agent selects an action $u_t \in U$.
+
+A fixed technology $g : S_1 \times S_2 \times U \to S_2$ governs the transition
+
+```{math}
+:label: eq:x_transition_v3
+x_{t+1} = g(z_t,\, x_t,\, u_t).
+```
+
+**The decision rule** $h : S_1 \times S_2 \to U$ maps the agent's current situation into an action:
+
+```{math}
+:label: eq:decision_rule_v3
+u_t = h(z_t,\, x_t).
+```
+
+The econometrician observes (some or all of) the process $\{z_t, x_t, u_t\}$, the joint motion of which is determined by {eq}`eq:z_transition_v3`, {eq}`eq:x_transition_v3`, and {eq}`eq:decision_rule_v3`.
+
+
+## Estimated rules are not enough
+
+Suppose we have estimated $f$, $g$, and $h$ from a long time series generated under a fixed environment $f_0$.
+
+This gives us $h_0 = T(f_0)$, where $T$ is the (unknown) functional mapping environments into optimal decision rules.
+
+But this single estimate, however precise, *reveals nothing* about how $T(f)$ varies with $f$.
+
+Policy evaluation requires knowledge of the entire map $f \mapsto T(f)$.
+
+Under an environment change $f_0 \to f_1$, agents will in general revise their decision rules $h_0 \to h_1 = T(f_1)$, rendering the estimated rule $h_0$ invalid for forecasting behavior under $f_1$.
+
+{cite:t}`lucas1976econometric` and the introduction to {cite}`lucas1981rational` conclude that the only nonexperimental path forward is to recover the **return function** $V$ from which $h$ is derived as the solution to an optimization problem, and then re-solve that problem under the counterfactual environment $f_1$.
+
+
+## An optimization problem
+
+Assume the agent selects $h$ to maximize the expected discounted sum of current-period returns $V : S_1 \times S_2 \times U \to \mathbb{R}$:
+
+```{math}
+:label: eq:objective_v3
+E_0\!\left\{\sum_{t=0}^{\infty} \beta^t\, V(z_t,\, x_t,\, u_t)\right\}, \qquad 0 < \beta < 1,
+```
+
+given initial conditions $(z_0, x_0)$, the environment $f$, and the technology $g$.
+
+Here $E_0\{\cdot\}$ denotes expectation conditional on $(z_0, x_0)$ with respect to the distribution of $\{z_1, z_2, \ldots\}$ induced by {eq}`eq:z_transition_v3`.
+
+In principle, knowledge of $V$ (together with $g$ and $f$) allows one to compute $h = T(f)$ theoretically and hence to trace out $T(f)$ for any counterfactual $f$.
+
+The essential question is whether $V$ can itself be recovered from observations on $\{f, g, h\}$.
+
+```{note}
+The decision rule is in general a functional $h = T(f, g, V)$.
+The dependence on $g$ and $V$ is suppressed in the main text but made explicit when needed.
+```
+
+
+## A linear-quadratic DP problem and certainty equivalence
+
+Progress beyond the level of generality of the previous section requires restricting the primitives.
+
+A productive restriction, exploited in the papers collected in {cite}`lucas1981rational`, imposes *quadratic* $V$ and *linear* $g$, which forces $h$ to be linear.
+
+As part of its computational tractability, this specialization delivers a striking structural result:
+
+* the **certainty equivalence** theorem of {cite:t}`simon1956dynamic` and {cite:t}`theil1957note`.
+
+### Decomposition of $h$
+
+Under quadratic $V$ and linear $g$, the optimal decision rule $h$ decomposes into two components applied in sequence.
+
+**Step 1 — Forecasting.** Define the infinite sequence of optimal point forecasts of all current and future states of nature:
+
+```{math}
+:label: eq:forecast_sequence_v3
+\tilde{z}_t \;=\; \bigl(z_t,\;\; {}_{t+1}z_t^e,\;\; {}_{t+2}z_t^e,\;\ldots\bigr) \;\in\; S_1^\infty,
+```
+
+where ${}_{t+j}z_t^e$ denotes the least-mean-squared-error forecast of $z_{t+j}$ formed at time $t$.
+
+The optimal forecast sequence is a (generally nonlinear) function of the current state:
+
+```{math}
+:label: eq:forecast_rule_v3
+\tilde{z}_t = h_2(z_t).
+```
+
+The function $h_2 : S_1 \to S_1^\infty$ depends entirely on the environment $(f, \Phi)$ and is obtained as the solution to a **pure forecasting problem**, with no reference to preferences or technology.
+
+**Step 2 — Optimization.** Given the forecast sequence $\tilde{z}_t$, the optimal action is a **linear** function of $\tilde{z}_t$ and $x_t$:
+
+```{math}
+:label: eq:optimization_rule_v3
+u_t = h_1(\tilde{z}_t,\, x_t).
+```
+
+The function $h_1 : S_1^\infty \times S_2 \to U$ depends entirely on preferences $(V)$ and technology $(g)$ but **not** on the stochastic environment $(f, \Phi)$.
+
+The ultimate decision rule is therefore the **composite**:
+
+```{math}
+:label: eq:composite_rule_v3
+\boxed{h(z_t, x_t) \;=\; h_1\!\bigl[h_2(z_t),\; x_t\bigr].}
+```
+
+### The separation principle
+
+{eq}`eq:composite_rule_v3` embodies a clean **separation** of the two sources of dependence in $h$:
+
+| Component | Depends on | Independent of |
+|-----------|-----------|----------------|
+| $h_1$ (optimization) | $V$, $g$ | $f$, $\Phi$ |
+| $h_2$ (forecasting) | $f$, $\Phi$ | $V$, $g$ |
+
+Since policy analysis concerns changes in $f$, and since $h_1$ is invariant to $f$, the policy analyst need only re-solve the forecasting problem $h_2 = S(f)$ under the new environment, keeping $h_1$ fixed.
+
+The relationship of original interest, $h = T(f)$, then follows directly from {eq}`eq:composite_rule_v3`.
+
+### Certainty equivalence and perfect foresight
+
+The name "certainty equivalence" reflects a further implication of the LQ structure: the function $h_1$ can be derived as if the agent **knew the future path $z_{t+1}, z_{t+2}, \ldots$ with certainty** — i.e., by solving the deterministic problem in which $\tilde{z}_t$ is treated as the realized path rather than a forecast.
+
+Randomness of the environment affects actions only through the forecast $\tilde{z}_t$; conditional on $\tilde{z}_t$, the optimization problem is deterministic.
+
+This means the LQ problem decouples into:
+
+ * **Dynamic optimization under perfect foresight** — solve for $h_1$ from $(V, g)$ by treating $\tilde{z}_t$ as known, yielding a standard deterministic LQ regulator problem independent of the environment $(f, \Phi)$.
+
+ * **Optimal linear prediction** — solve for $h_2 = S(f)$ from $(f, \Phi)$ using least-squares forecasting theory, which reduces to a standard Kalman/Wiener prediction formula when $f$ is itself linear.
+
+### Cross-equation restrictions
+
+A hallmark of the rational expectations hypothesis as it appears in this framework is that it ties together what would otherwise be free parameters in different equations.
+
+The requirement that $\tilde{z}_t = h_2(z_t) = S(f)(z_t)$ — i.e., that agents' forecasts be *optimal* with respect to the *actual* law of motion $f$ — imposes **cross-equation restrictions** between the parameters of the forecasting rule $h_2$ and the parameters of the environment $f$.
+
+These restrictions, rather than any conditions on distributed lags within a single equation, are the operative empirical content of rational expectations.
+
+```{note}
+This is the message of {cite}`lucas1976econometric` and {cite}`sargent1981interpreting`.
+```
+
+The following code verifies the CE principle numerically.
+
+We consider a simple scalar LQ problem:
+
+$$y_{t+1} = a\, y_t + b\, u_t + \sigma\, \varepsilon_{t+1}, \qquad r(y_t, u_t) = -(q\, y_t^2 + r\, u_t^2)$$
+
+and vary the noise standard deviation $\sigma$ across a wide range.
+
+The CE theorem predicts that:
+
+* the **policy gain** $F$ (the coefficient in $u_t = -F y_t$) is independent of $\sigma$, and
+* the **value constant** $d$ (the additive term in $V(y) = -y^\top P y - d$) grows with $\sigma$.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: "CE: policy does not depend on noise"
+ name: fig-ce-policy-noise
+---
+a, b_coeff = 0.9, 1.0
+q, r = 1.0, 1.0
+β = 0.95
+
+A = np.array([[a]])
+B = np.array([[b_coeff]])
+R_mat = np.array([[q]]) # state cost
+Q_mat = np.array([[r]]) # control cost
+
+σ_vals = np.linspace(0.0, 3.0, 80)
+F_vals, d_vals = [], []
+
+for σ in σ_vals:
+ C = np.array([[σ]])
+ lq = LQ(Q_mat, R_mat, A, B, C=C, beta=β)
+ P, F, d = lq.stationary_values()
+ F_vals.append(float(F[0, 0]))
+ d_vals.append(float(d))
+
+fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+
+axes[0].plot(σ_vals, F_vals, lw=2)
+axes[0].set_xlabel('noise level $\\sigma$')
+axes[0].set_ylabel('policy gain $F$')
+axes[0].set_ylim(0, 2 * max(F_vals) + 0.1)
+
+axes[1].plot(σ_vals, d_vals, lw=2, color='darkorange')
+axes[1].set_xlabel('noise level $\\sigma$')
+axes[1].set_ylabel('value constant $d$')
+
+plt.tight_layout()
+plt.show()
+```
+
+As the plot confirms, $F$ (the policy gain) is *flat* across all noise levels, while the value constant $d$ increases monotonically with $\sigma$.
+
+This is the CE principle in action: uncertainty changes the value of the problem but not the optimal decision rule.
+
+
+## A trouble with ad hoc expectations
+
+Prior practice, exemplified by the adaptive expectations mechanisms of {cite:t}`Friedman1956` and {cite:t}`Cagan`, directly postulated a particular form of {eq}`eq:forecast_rule_v3`:
+
+```{math}
+:label: eq:adaptive_expectations_v3
+\theta_t^e = \lambda \sum_{i=0}^{\infty} (1-\lambda)^i\, \theta_{t-i}, \qquad 0 < \lambda < 1,
+```
+
+treating the coefficient $\lambda$ as a free parameter to be estimated from data, with no reference to the underlying environment $f$.
+
+The deficiency is not that {eq}`eq:adaptive_expectations_v3` is a distributed lag — linear forecasting rules are perfectly acceptable simplifications.
+
+The deficiency is that the **coefficients** of the distributed lag are left unrestricted by theory.
+
+The mapping $h_2 = S(f)$ shows that optimal forecasting coefficients are *determined* by $f$: when $f$ changes, $h_2$ changes, and so does $h$.
+
+An estimated $\lambda$ calibrated under $f_0$ is therefore non-structural and will give incorrect predictions whenever $f$ is altered.
+
+This is the econometric content of the critique delivered by {cite:t}`Muth1960`.
+
+Rational expectations equates the subjective distribution that agents use in forming $\tilde{z}_t$ to the objective distribution $f$ that actually generates the data, thereby closing the model and eliminating free parameters in $h_2$.
+
+
+## Exercises
+
+```{exercise-start}
+:label: theil1_ex1
+```
+
+Using the scalar LQ setup in the code cell above (with $a = 0.9$, $b = 1$,
+$q = r = 1$, $\beta = 0.95$), verify numerically that the value constant $d$
+satisfies $d \propto \sigma^2$.
+
+*Hint:* From the CE analysis, the value constant satisfies
+$d = \tfrac{\beta}{1-\beta}\,\mathrm{tr}(C^\top P C)$,
+and since $C = \sigma$ in the scalar case, this gives
+$d = \tfrac{\beta}{1-\beta}\, P\, \sigma^2$.
+
+Confirm that a plot of $d$ against $\sigma^2$ is linear and compute the theoretical
+slope $\tfrac{\beta}{1-\beta} P$.
+
+```{exercise-end}
+```
+
+```{solution-start} theil1_ex1
+:class: dropdown
+```
+
+```{code-cell} ipython3
+σ_sq_vals = σ_vals ** 2
+
+fig, ax = plt.subplots(figsize=(8, 5))
+ax.plot(σ_sq_vals, d_vals, lw=2)
+ax.set_xlabel('$\\sigma^2$')
+ax.set_ylabel('value constant $d$')
+ax.set_title('Value constant is linear in noise variance (CE principle)')
+
+coeffs = np.polyfit(σ_sq_vals, d_vals, 1)
+ax.plot(σ_sq_vals, np.polyval(coeffs, σ_sq_vals),
+ 'r--', lw=2, label=f'Linear fit: slope = {coeffs[0]:.3f}')
+ax.legend()
+plt.tight_layout()
+plt.show()
+
+P_scalar = float(LQ(Q_mat, R_mat, A, B, C=np.zeros((1, 1)),
+ beta=β).stationary_values()[0].item())
+theoretical_slope = β / (1 - β) * P_scalar
+print(f"Empirical slope: {coeffs[0]:.4f}")
+print(f"Theoretical slope β/(1-β)*P = {theoretical_slope:.4f}")
+```
+
+The slope is indeed $\tfrac{\beta}{1-\beta} P$, confirming the analytic formula.
+
+The value matrix $P$ is determined entirely by preferences and technology, not by the noise level — a direct consequence of the certainty equivalence principle.
+
+```{solution-end}
+```
+
+## Concluding remarks
+
+This sequel [certainty equivalence and model uncertainty](theil_2) describes how to extend the certainty equivalence principle to a linear-quadratic setting in which a decision maker distrusts the transition dynamics specified in his baseline model.
diff --git a/lectures/theil_2.md b/lectures/theil_2.md
new file mode 100644
index 000000000..cd844df39
--- /dev/null
+++ b/lectures/theil_2.md
@@ -0,0 +1,875 @@
+---
+jupytext:
+ text_representation:
+ extension: .md
+ format_name: myst
+kernelspec:
+ display_name: Python 3
+ language: python
+ name: python3
+---
+
+(certainty_equiv_robustness)=
+```{raw} jupyter
+
+```
+
+# Certainty Equivalence and Model Uncertainty
+
+```{index} single: Certainty Equivalence; Robustness
+```
+
+```{index} single: LQ Control; Permanent Income
+```
+
+```{contents} Contents
+:depth: 2
+```
+
+
+
+## Overview
+
+
+This is a sequel to [this lecture on certainty equivalence](theil_1) that established an important *certainty equivalence* (CE) property for linear-quadratic (LQ) dynamic programming
+problems.
+
+The property justifies a two-step algorithm for computing optimal decision rules:
+
+1. *Optimize* under perfect foresight (treat future exogenous variables as known).
+2. *Forecast* — substitute optimal forecasts for the unknown future values.
+
+This lecture extends the certainty equivalence property in two directions motivated by
+{cite}`hansen2004certainty`:
+
+- *Model uncertainty and robustness.* What happens when the decision maker does not
+ trust his model? A remarkable version of CE survives, but now the "forecasting" step
+ uses a *distorted* probability distribution that the decision maker deliberately tilts
+ against himself in order to achieve robustness.
+
+- *Risk-sensitive preferences.* A mathematically equivalent reformulation interprets
+ the same decision rules through recursive risk-sensitive preferences.
+
+ The robustness
+ parameter $\theta$ and the risk-sensitivity parameter $\sigma$ are linked by
+ $\theta = -\sigma^{-1}$.
+
+We illustrate all three settings — ordinary CE, robust CE, and the permanent income
+application — with Python code using `quantecon`.
+
+### Model features
+
+* Linear transition laws and quadratic objectives (LQ framework).
+* Ordinary CE: optimal policy independent of noise variance.
+* Robust CE: distorted forecasts replace baseline model forecasts; policy function depends on $\theta$.
+* Permanent income application: Hall's martingale, precautionary savings under robustness,
+ and observational equivalence between robustness and patience.
+
+
+This lecture draws on {cite}`hansen2004certainty` and {cite}`HansenSargent2008`.
+
+In addition to what's in Anaconda, this lecture will need the following libraries:
+
+```{code-cell} ipython3
+---
+tags: [hide-output]
+---
+!pip install quantecon
+```
+
+
+We use the following imports:
+
+```{code-cell} ipython3
+import numpy as np
+import matplotlib.pyplot as plt
+from quantecon import LQ, RBLQ
+```
+
+
+## Recap: ordinary certainty equivalence
+
+The {ref}`companion lecture ` established the CE
+property in detail.
+
+Here we collect only the elements needed for the
+robustness extension below.
+
+The state vector $y_t = \begin{bmatrix} x_t \\ z_t \end{bmatrix}$ has an
+exogenous component $z_t$ with transition law
+
+```{math}
+:label: eq:z_transition_o
+z_{t+1} = f(z_t,\, \epsilon_{t+1})
+```
+
+and an endogenous component $x_t$ obeying
+
+```{math}
+:label: eq:x_transition_o
+x_{t+1} = g(x_t,\, z_t,\, u_t).
+```
+
+Under the LQ assumption (quadratic return $r(y,u) = -y^\top Qy - u^\top Ru$,
+linear $f$ and $g$, Gaussian shocks), the optimal decision rule $h$ decomposes
+as $u_t = h_1(x_t,\, h_2 \cdot z_t)$ where $h_1$ solves a nonstochastic
+control problem and $h_2$ solves an optimal forecasting problem.
+
+The optimal value function is $V(y_0) = -y_0^\top P\, y_0 - p$ where,
+writing $z_{t+1} = f_1 z_t + f_2 \epsilon_{t+1}$:
+
+- $P$ is the fixed point of an operator $T(P; r, g, f_1)$ that does *not*
+ involve the volatility matrix $f_2$, so neither $P$ nor the decision rule
+ $h$ depends on the noise loadings.
+
+- The constant $p = \beta/(1-\beta)\,\mathrm{tr}(f_2^\top P f_2)$ grows with
+ volatility.
+
+Uncertainty lowers the value (larger $p$) but does not alter behaviour.
+
+The following code sets up a scalar LQ problem and confirms that the policy
+gain $F$ is invariant to the noise level $\sigma$ while $d$ grows with it.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: CE principle — policy vs. value
+ name: fig-ce-policy-value
+---
+a, b_coeff = 0.9, 1.0
+q, r = 1.0, 1.0
+β = 0.95
+
+A = np.array([[a]])
+B = np.array([[b_coeff]])
+Q_mat = np.array([[q]]) # state cost
+R_mat = np.array([[r]]) # control cost
+
+σ_vals = np.linspace(0.0, 3.0, 80)
+F_vals, d_vals = [], []
+
+for σ in σ_vals:
+ C = np.array([[σ]])
+ lq = LQ(R_mat, Q_mat, A, B, C=C, beta=β)
+ P, F, d = lq.stationary_values()
+ F_vals.append(float(F[0, 0]))
+ d_vals.append(float(d))
+
+fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+
+axes[0].plot(σ_vals, F_vals, lw=2)
+axes[0].set_xlabel('noise level $\\sigma$')
+axes[0].set_ylabel('policy gain $F$')
+axes[0].set_ylim(0, 2 * max(F_vals) + 0.1)
+
+axes[1].plot(σ_vals, d_vals, lw=2, color='darkorange')
+axes[1].set_xlabel('noise level $\\sigma$')
+axes[1].set_ylabel('value constant $d$')
+
+plt.tight_layout()
+plt.show()
+```
+
+
+## Model uncertainty and robustness
+
+### Setup and the multiplier problem
+
+The decision maker in Simon and Theil's setting knows his model exactly — he has
+no doubt about the transition law {eq}`eq:z_transition_o`.
+
+Now suppose he suspects that the true
+data-generating process is
+
+```{math}
+:label: eq:distorted_law
+z_{t+1} = f(z_t,\; \epsilon_{t+1} + w_{t+1})
+```
+
+where $w_{t+1} = \omega_t(x^t, z^t)$ is a misspecification term chosen by an
+adversarial "nature."
+
+The decision maker believes his approximating model is a
+good approximation in the sense that
+
+```{math}
+:label: eq:misspec_budget
+\hat{\mathbb{E}}\!\left[\sum_{t=0}^{\infty} \beta^t\, w_{t+1}^\top w_{t+1}
+ \,\Big|\, y_0\right] \leq \eta_0,
+```
+
+where $\eta_0$ parametrises the tolerated misspecification budget and $\hat{\mathbb{E}}$
+is the expectation under the distorted law {eq}`eq:distorted_law`.
+
+To construct a *robust* decision rule the decision maker solves the
+**multiplier problem** — a two-player zero-sum dynamic game:
+
+```{math}
+:label: eq:multiplier
+\min_{\{w_{t+1}\}}\, \max_{\{u_t\}}\;
+\hat{\mathbb{E}}\!\left[\sum_{t=0}^{\infty} \beta^t
+ \Bigl\{r(y_t, u_t) + \theta\beta\, w_{t+1}^\top w_{t+1}\Bigr\}\,
+ \Big|\, y_0\right]
+```
+
+where $\theta > 0$ penalises large distortions.
+
+A larger $\theta$ shrinks the
+feasible misspecification set; as $\theta \to \infty$ the problem reduces to
+ordinary LQ.
+
+The Markov perfect equilibrium of {eq}`eq:multiplier` delivers a *robust* rule
+$u_t = h(x_t, z_t)$ together with a worst-case distortion process
+$w_{t+1} = W(x_t, z_t)$.
+
+### Stackelberg timing and the modified CE
+
+The Markov perfect equilibrium *conceals* a form of CE.
+
+To reveal it, {cite:t}`HansenSargent2001` impose a **Stackelberg timing protocol**: at
+time 0, the *minimising* player commits once and for all to a plan
+$\{w_{t+1}\}$, after which the *maximising* player chooses $u_t$ sequentially.
+
+This makes the minimiser the Stackelberg leader.
+
+To describe the leader's committed plan, introduce "big-letter" state variables
+$(X_t, Z_t)$ (same dimensions as $(x_t, z_t)$) that encode the leader's
+pre-committed strategy:
+
+```{math}
+:label: eq:stackelberg_plan
+\begin{aligned}
+w_{t+1} &= W(X_t, Z_t), \\
+X_{t+1} &= g(X_t, Z_t,\, h(X_t, Z_t)), \\
+Z_{t+1} &= f(Z_t,\, W(X_t, Z_t) + \epsilon_{t+1}).
+\end{aligned}
+```
+
+Summarised with $Y_t = \begin{bmatrix} X_t \\ Z_t \end{bmatrix}$:
+
+```{math}
+:label: eq:stackelberg_law
+Y_{t+1} = M Y_t + N \epsilon_{t+1}, \qquad w_{t+1} = W(Y_t).
+```
+
+The maximising player then faces an *ordinary* dynamic programming problem subject
+to his own dynamics {eq}`eq:x_transition_o`, the distorted $z$-law {eq}`eq:distorted_law`, and the exogenous
+process {eq}`eq:stackelberg_law`.
+
+His optimal rule takes the form
+
+```{math}
+:label: eq:max_rule
+u_t = \tilde{H}(x_t, z_t, Y_t).
+```
+
+{cite:t}`bacsar2008h` and {cite:t}`hansen2008robustness` establish that at
+equilibrium (with "big $K$ = little $k$" imposed) this collapses to
+
+```{math}
+:label: eq:equilibrium_rule
+\tilde{H}(X_t, Z_t, Y_t) = h(Y_t),
+```
+
+the *same* rule as the Markov perfect equilibrium of {eq}`eq:multiplier`.
+
+### Modified separation principle
+
+The Stackelberg timing permits an Euler-equation approach.
+
+The two-step algorithm becomes:
+
+The first step is unchanged: solve the same nonstochastic control problem as before,
+with $\mathbf{z}_t = (z_t, z_{t+1}, \ldots)$ treated as known, giving
+$u_t = h_1(x_t, \mathbf{z}_t)$.
+
+The second step is modified: form forecasts using the *distorted* law of motion
+{eq}`eq:stackelberg_law`. By the linearity and Gaussianity of the system,
+
+```{math}
+:label: eq:distorted_forecast
+\hat{\mathbb{E}}[\mathbf{z}_t \mid z^t, Y^t]
+ = \hat{h}_2 \begin{bmatrix} z_t \\ Y_t \end{bmatrix}
+```
+
+where $\hat{\mathbb{E}}$ uses the distorted model.
+
+Substituting {eq}`eq:distorted_forecast` into $h_1$ and imposing $Y_t = y_t$ gives the robust rule
+
+```{math}
+:label: eq:robust_ce_rule
+u_t = h_1\!\left(x_t,\; \hat{h}_2 \cdot y_t\right) = h(x_t, z_t).
+```
+
+This is the modified CE: *step 1 is identical to the non-robust case*; only
+step 2 changes, using distorted rather than rational forecasts.
+
+In contrast to ordinary CE, the robust policy *does* change as $\theta$ varies.
+
+As $\theta \to \infty$ (no robustness) the robust policy converges to the standard LQ
+policy.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Robust policy varies with θ
+ name: fig-robust-policy-theta
+---
+σ_fixed = 1.0
+C_fixed = np.array([[σ_fixed]])
+
+lq_std = LQ(R_mat, Q_mat, A, B, C=C_fixed, beta=β)
+P_std, F_std_arr, d_std = lq_std.stationary_values()
+F_standard = float(F_std_arr[0, 0])
+P_standard = float(P_std[0, 0])
+
+θ_vals = np.linspace(2.0, 30.0, 120) # restrict attention to a numerically stable range
+F_rob_vals, P_rob_vals = [], []
+
+for θ in θ_vals:
+ rblq = RBLQ(R_mat, Q_mat, A, B, C_fixed, β, θ)
+ F_rob, K_rob, P_rob = rblq.robust_rule()
+ F_rob_vals.append(float(F_rob[0, 0]))
+ P_rob_vals.append(float(P_rob[0, 0]))
+
+fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+
+axes[0].plot(θ_vals, F_rob_vals, lw=2, label='Robust $F(\\theta)$')
+axes[0].axhline(F_standard, color='r', linestyle='--', lw=2,
+ label=f'Standard LQ ($F = {F_standard:.3f}$)')
+axes[0].set_xlabel('robustness parameter $\\theta$')
+axes[0].set_ylabel('policy gain $F$')
+axes[0].legend()
+
+axes[1].plot(θ_vals, P_rob_vals, lw=2, color='purple',
+ label='Robust $P(\\theta)$')
+axes[1].axhline(P_standard, color='r', linestyle='--', lw=2,
+ label=f'Standard LQ ($P = {P_standard:.3f}$)')
+axes[1].set_xlabel('robustness parameter $\\theta$')
+axes[1].set_ylabel('value matrix $P$')
+axes[1].legend()
+
+plt.tight_layout()
+plt.show()
+```
+
+Observe that for small $\theta$ (strong preference for robustness) both $F$ and
+$P$ deviate substantially from their non-robust counterparts, converging to the
+standard values as $\theta \to \infty$.
+
+This contrasts sharply with ordinary CE: under robustness, *both the policy gain
+and the value matrix depend on the robustness parameter $\theta$ and the
+noise-loading matrix $C$*.
+
+
+## Value function under robustness
+
+Under a preference for robustness, the optimised value of {eq}`eq:multiplier` is again
+quadratic,
+
+```{math}
+:label: eq:robust_value
+V(y_0) = -y_0^\top P\, y_0 - p,
+```
+
+but now *both* $P$ *and* $p$ depend on the volatility parameter $f_2$.
+
+Specifically, $P$ is the fixed point of the composite operator $T \circ \mathcal{D}$
+where $T$ is the same Bellman operator as in the non-robust case and
+$\mathcal{D}$ is the **distortion operator**:
+
+```{math}
+:label: eq:distortion_op
+\mathcal{D}(P) = \mathcal{D}(P;\, f_2,\, \theta).
+```
+
+Given the fixed point $P = T(\mathcal{D}(P))$, the constant is
+
+```{math}
+:label: eq:constant_p
+p = p(P;\, f_2,\, \beta,\, \theta).
+```
+
+Despite $P$ now depending on $f_2$, a form of CE still prevails: the same
+decision rule {eq}`eq:robust_ce_rule` also emerges from the *nonstochastic* game that
+maximises {eq}`eq:multiplier` subject to {eq}`eq:x_transition_o` and
+
+```{math}
+:label: eq:nonstoch_z
+z_{t+1} = f(z_t,\, w_{t+1}),
+```
+
+i.e., setting $\epsilon_{t+1} \equiv 0$.
+
+The presence of randomness lowers the value (the constant $p$) but does not change the decision rule.
+
+
+## Risk-sensitive preferences
+
+Building on {cite:t}`Jacobson_73` and {cite:t}`Whittle_1990`, {cite:t}`hansen2004certainty` showed that
+the same decision rules can be reinterpreted through **risk-sensitive preferences**.
+
+Suppose the decision maker *fully trusts* his model
+
+```{math}
+:label: eq:rs_transition
+y_{t+1} = A\, y_t + B\, u_t + C\, \epsilon_{t+1}
+```
+
+but evaluates stochastic processes according to the recursion
+
+```{math}
+:label: eq:rs_utility
+U_t = r(y_t, u_t) + \beta\, \mathcal{R}_t(U_{t+1})
+```
+
+where the *risk-adjusted* continuation operator is
+
+```{math}
+:label: eq:rs_operator
+\mathcal{R}_t(U_{t+1}) = \frac{2}{\sigma}
+ \log \mathbb{E}\!\left[\exp\!\left(\frac{\sigma U_{t+1}}{2}\right)
+ \,\Big|\, y^t\right], \qquad \sigma \leq 0.
+```
+
+When $\sigma = 0$, L'Hôpital's rule recovers the standard expectation operator.
+
+When $\sigma < 0$, $\mathcal{R}_t$ penalises right-tail risk in the continuation
+utility $U_{t+1}$.
+
+For a candidate quadratic continuation value
+$U_{t+1}^e = -y_{t+1}^\top \Omega\, y_{t+1} - \rho$, let
+$\hat{y}_{t+1} \equiv A y_t + B u_t$ denote the conditional mean of $y_{t+1}$.
+
+Evaluating $\mathcal{R}_t$ via the log-moment-generating function of the
+Gaussian distribution yields
+
+```{math}
+:label: eq:rs_eval
+\mathcal{R}_t U_{t+1}^e
+ = -\hat{y}_{t+1}^\top \mathcal{D}(\Omega)\, \hat{y}_{t+1} - \hat{\rho}
+```
+
+where $\mathcal{D}$ is the *same* distortion operator as in {eq}`eq:distortion_op`
+with $\theta = -\sigma^{-1}$, and $\hat{\rho}$ is the corresponding scalar
+adjustment term.
+
+Consequently, the risk-sensitive Bellman equation
+has the *same* fixed point $P$ as the robust control problem, and therefore the
+*same decision rule* $u_t = -F y_t$.
+
+> **Key equivalence:** robust control with parameter $\theta$ and risk-sensitive
+> control with parameter $\sigma = -\theta^{-1}$ produce identical decision rules.
+
+
+## Application: permanent income model
+
+We now illustrate all of the above in a concrete linear-quadratic permanent income
+model.
+
+### Model setup
+
+A consumer receives an exogenous endowment process $\{z_t\}$ and allocates it
+between consumption $c_t$ and savings $x_t$ to maximise
+
+```{math}
+:label: eq:pi_objective
+-\mathbb{E}_0 \sum_{t=0}^{\infty} \beta^t (c_t - b)^2, \qquad \beta \in (0,1)
+```
+
+where $b$ is a bliss level of consumption.
+
+Defining the **marginal utility
+of consumption** $\mu_{ct} \equiv b - c_t$ (the control), the budget constraint
+and endowment process are
+
+```{math}
+:label: eq:pi_budget
+x_{t+1} = R\, x_t + z_t - b + \mu_{ct}
+```
+
+```{math}
+:label: eq:endowment
+z_{t+1} = \mu_d(1-\rho) + \rho\, z_t + c_d(\epsilon_{t+1} + w_{t+1})
+```
+
+where $R > 1$ is the gross return on savings, $|\rho| < 1$, and $w_{t+1}$
+is an optional shock-mean distortion representing model misspecification.
+
+After absorbing the constants $-b$ and $\mu_d(1-\rho)$ by augmenting the state
+vector, or equivalently by working with deviations from steady state, setting
+$w_{t+1} \equiv 0$ and taking $Q = 0$ (return depends only on the
+control $\mu_{ct}$) and $R_{\text{ctrl}} = 1$ puts this in the standard LQ form
+
+```{math}
+:label: eq:pi_lq_matrices
+y_t = \begin{bmatrix} x_t \\ z_t \end{bmatrix},
+\quad
+A = \begin{bmatrix} R & 1 \\ 0 & \rho \end{bmatrix},
+\quad
+B = \begin{bmatrix} 1 \\ 0 \end{bmatrix},
+\quad
+C = \begin{bmatrix} 0 \\ c_d \end{bmatrix}.
+```
+
+In the numerical code below we add a negligible `1e-8 I` regularisation to the
+state-cost matrix to keep the Riccati computation well conditioned in Hall's
+unit-root case $\beta R = 1$.
+
+We calibrate to parameters estimated by {cite:t}`HST_1999`
+from post-WWII U.S. data:
+
+```{code-cell} ipython3
+β_hat = 0.9971
+R_rate = 1.0 / β_hat # β*R = 1 (Hall's case)
+ρ = 0.9992
+c_d = 5.5819
+σ_rs = -2e-7 # σ_hat < 0
+θ_pi = -1.0 / σ_rs # θ = -1/σ_hat
+
+A_pi = np.array([[R_rate, 1.0],
+ [0.0, ρ]])
+B_pi = np.array([[1.0],
+ [0.0]])
+C_pi = np.array([[0.0],
+ [c_d]])
+Q_pi = 1e-8 * np.eye(2) # regularise for β*R = 1
+R_pi = np.array([[1.0]])
+```
+
+### Without robustness: Hall's martingale
+
+Setting $\sigma = 0$ (no preference for robustness), the consumer's Euler
+equation is
+
+```{math}
+:label: eq:euler
+\mathbb{E}_t[\mu_{c,t+1}] = (\beta R)^{-1} \mu_{ct}.
+```
+
+With $\beta R = 1$ (Hall's case), this is
+$\mathbb{E}_t[\mu_{c,t+1}] = \mu_{ct}$, i.e., the **marginal utility of
+consumption is a martingale** — equivalently, consumption follows a random walk.
+
+The optimal policy is $\mu_{ct} = -F y_t$ where, from the solved-forward
+Euler equation, $F = [(R-1),\ (R-1)/(R - \rho)]$.
+
+The resulting closed-loop
+projection onto the one-dimensional direction of $\mu_{ct}$ gives the scalar
+AR(1) representation
+
+```{math}
+:label: eq:std_ar1
+\mu_{c,t+1} = \varphi\, \mu_{ct} + \nu\, \epsilon_{t+1}.
+```
+
+```{code-cell} ipython3
+F_pi = np.array([[(R_rate - 1.0), (R_rate - 1.0) / (R_rate - ρ)]])
+A_cl_std = A_pi - B_pi @ F_pi
+
+φ_std = 1.0 / (β_hat * R_rate)
+ν_std = (R_rate - 1.0) * c_d / (R_rate - ρ)
+
+print(f"φ = {φ_std:.6f}, ν = {ν_std:.4f}")
+```
+
+### With robustness: precautionary savings
+
+Under a preference for robustness ($\sigma < 0$, $\theta < \infty$), the consumer
+uses distorted forecasts $\hat{\mathbb{E}}_t[\cdot]$ evaluated under the
+worst-case model.
+
+The consumption rule takes the certainty-equivalent form
+
+```{math}
+:label: eq:robust_consumption
+\mu_{ct} = -(1 - R^{-2}\beta^{-1})
+ \!\left(R\, x_t + \hat{\mathbb{E}}_t\!\left[
+ \sum_{j=0}^{\infty} R^{-j}(z_{t+j} - b)\right]\right)
+```
+
+where $h_1$ — the first step of the CE algorithm — is *identical* to the
+non-robust case.
+
+Only the expectations operator changes.
+
+The resulting AR(1) dynamics for $\mu_{ct}$ become:
+
+```{math}
+:label: eq:robust_ar1
+\mu_{c,t+1} = \tilde{\varphi}\, \mu_{ct} + \tilde{\nu}\, \epsilon_{t+1}
+```
+
+with $\tilde{\varphi} < 1$, implying $\mathbb{E}_t[c_{t+1}] > c_t$ under the
+approximating model — a form of **precautionary saving**.
+
+The observational equivalence formula {eq}`eq:oe_locus` (derived below) immediately
+gives the robust AR(1) coefficient: $\tilde{\varphi} = 1/(\tilde{\beta} R)$
+where $\tilde{\beta} = \tilde{\beta}(\sigma)$.
+
+The innovation scale $\tilde{\nu}$
+follows from the robust permanent income formula with the distorted persistence;
+{cite:t}`HST_1999` report $\tilde{\nu} \approx 8.0473$ for their
+calibration.
+
+```{code-cell} ipython3
+def beta_tilde(σ, β_hat_val, α_sq_val):
+ """Observational-equivalence locus: β_tilde(σ)."""
+ denom = 2.0 * (1.0 + σ * α_sq_val)
+ numer = β_hat_val * (1.0 + β_hat_val)
+ disc = 1.0 - 4.0 * β_hat_val * (1.0 + σ * α_sq_val) / \
+ (1.0 + β_hat_val) ** 2
+ return (numer / denom) * (1.0 + np.sqrt(np.maximum(disc, 0.0)))
+
+ν_rob = 8.0473
+α_sq = ν_rob ** 2
+bt = beta_tilde(σ_rs, β_hat, α_sq)
+φ_rob = 1.0 / (bt * R_rate)
+
+print(f"β_tilde = {bt:.5f}, φ_tilde = {φ_rob:.4f}, ν_tilde = {ν_rob:.4f}")
+```
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Standard vs robust consumption paths
+ name: fig-std-vs-robust-paths
+---
+np.random.seed(42)
+T_sim = 100
+
+def simulate_ar1(φ, ν, shocks, mu0=0.0):
+ path = np.empty(len(shocks) + 1)
+ path[0] = mu0
+ for t, ε in enumerate(shocks, start=1):
+ path[t] = φ * path[t-1] + ν * ε
+ return path
+
+shock_path = np.random.randn(T_sim - 1)
+mu0_init = 10.0
+mu_std_path = simulate_ar1(φ_std, ν_std, shock_path, mu0=mu0_init)
+mu_rob_path = simulate_ar1(φ_rob, ν_rob, shock_path, mu0=mu0_init)
+
+fig, axes = plt.subplots(2, 1, figsize=(11, 6), sharex=True)
+t_grid = np.arange(T_sim)
+
+axes[0].plot(t_grid, mu_std_path, lw=2, label=f'$\\mu_{{ct}}$ (standard, $\\varphi={φ_std:.4f}$)')
+axes[0].axhline(0, color='k', lw=0.8, linestyle='--')
+axes[0].set_ylabel('$\\mu_{ct}$')
+axes[0].legend(loc='upper right')
+
+axes[1].plot(t_grid, mu_rob_path, lw=2, color='darkorange',
+ label=f'$\\mu_{{ct}}$ (robust, $\\tilde{{\\varphi}}={φ_rob:.4f}$)')
+axes[1].axhline(0, color='k', lw=0.8, linestyle='--')
+axes[1].set_xlabel('period $t$')
+axes[1].set_ylabel('$\\mu_{ct}$')
+axes[1].legend(loc='upper right')
+
+plt.tight_layout()
+plt.show()
+```
+
+### Observational equivalence: robustness acts like patience
+
+A key insight of {cite:t}`HansenSargent2001` is that, in the permanent income model,
+a preference for robustness ($\sigma < 0$) is *observationally equivalent* to an
+increase in the discount factor from $\hat{\beta}$ to a larger value
+$\tilde{\beta}(\sigma)$, with $\sigma$ set back to zero.
+
+The equivalence locus is given by
+
+```{math}
+:label: eq:oe_locus
+\tilde{\beta}(\sigma) =
+ \frac{\hat{\beta}(1 + \hat{\beta})}{2(1 + \sigma\alpha^2)}
+ \left[1 + \sqrt{1 - \frac{4\hat{\beta}(1+\sigma\alpha^2)}{(1+\hat{\beta})^2}}\right]
+```
+
+where $\alpha^2 = \tilde{\nu}^2$ is the squared innovation loading in the
+robust AR(1) representation {eq}`eq:robust_ar1`.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Observational equivalence locus
+ name: fig-oe-locus
+---
+σ_range = np.linspace(-3e-7, 0.0, 200)
+bt_vals = [beta_tilde(s, β_hat, α_sq) for s in σ_range]
+bt_check = beta_tilde(σ_rs, β_hat, α_sq)
+
+fig, ax = plt.subplots(figsize=(9, 5))
+ax.plot(-σ_range * 1e7, bt_vals, lw=2, color='steelblue',
+ label='$\\tilde{\\beta}(\\sigma)$')
+ax.axhline(β_hat, color='r', linestyle='--', lw=2,
+ label=f'$\\hat{{\\beta}} = {β_hat}$')
+ax.scatter([-σ_rs * 1e7], [bt_check], zorder=5, color='darkorange', s=80,
+ label=f'$(\\hat{{\\sigma}},\\, \\tilde{{\\beta}}) '
+ f'= ({σ_rs:.0e},\\, {bt_check:.4f})$')
+ax.set_xlabel('risk sensitivity $-\\sigma$ ($\\times 10^{-7}$)')
+ax.set_ylabel('observationally equivalent discount factor $\\tilde{\\beta}$')
+ax.legend()
+plt.tight_layout()
+plt.show()
+```
+
+The plot confirms the paper's key finding: *activating a preference for
+robustness is observationally equivalent — for consumption and saving behaviour
+— to increasing the discount factor*.
+
+However, {cite:t}`HST_1999` show that the two
+parametrisations do *not* imply the same asset prices.
+
+This happens because a preference for robustness generates different state-prices through the
+$\mathcal{D}(P)$ matrix that enters the stochastic discount factor.
+
+
+## Summary
+
+The table below condenses the main results:
+
+| Setting | Policy depends on noise? | Forecasts used | CE survives? |
+|---------|:------------------------:|:--------------:|:------------:|
+| Simon–Theil (ordinary LQ) | No | Rational | Yes |
+| Robust control (multiplier) | Yes ($P$ changes with $f_2$ and $\theta$) | Distorted (worst-case) | Yes (modified) |
+| Risk-sensitive preferences | Yes (same as robust) | Distorted (same) | Yes (same) |
+
+In all three cases, the decision maker can be described as following a
+two-step procedure: first solve a nonstochastic control problem, then form
+beliefs.
+
+The difference is in which beliefs are formed in the second step.
+
+
+## Exercises
+
+```{exercise-start}
+:label: ce_ex2
+```
+
+Show numerically that as $\theta \to \infty$ the robust policy $F(\theta)$ converges
+to the standard LQ policy $F_{\text{std}}$ and that the rate of convergence is of
+order $1/\theta$. Plot $|F(\theta) - F_{\text{std}}|$ against $1/\theta$ on a
+log–log scale.
+
+```{exercise-end}
+```
+
+```{solution-start} ce_ex2
+:class: dropdown
+```
+
+```{code-cell} ipython3
+θ_large = np.logspace(0.5, 3.0, 100)
+gap_vals = []
+
+for θ in θ_large:
+ rblq = RBLQ(R_mat, Q_mat, A, B, C_fixed, β, θ)
+ F_r, _, _ = rblq.robust_rule()
+ gap_vals.append(abs(float(F_r[0, 0]) - F_standard))
+
+fig, ax = plt.subplots(figsize=(8, 5))
+ax.loglog(1.0 / θ_large, gap_vals, lw=2)
+ax.set_xlabel('$1/\\theta$')
+ax.set_ylabel('$|F(\\theta) - F_{\\mathrm{std}}|$')
+ax.set_title('Robust policy converges to standard LQ at rate $1/\\theta$')
+
+x_ref = 1.0 / θ_large
+ax.loglog(x_ref, x_ref * gap_vals[0] / x_ref[0],
+ 'r--', lw=2, label='Slope 1 reference')
+ax.legend()
+plt.tight_layout()
+plt.show()
+```
+
+The log–log plot reveals an approximately linear relationship, confirming $O(1/\theta)$
+convergence.
+
+```{solution-end}
+```
+
+```{exercise-start}
+:label: ce_ex3
+```
+
+Pick three values $\sigma_i < 0$ and verify numerically that the robust
+permanent income model with $(\sigma_i, \hat{\beta})$ produces the same
+policy matrix $F$ as a suitably chosen non-robust model with
+$(0, \tilde{\beta}_i)$.
+
+To find $\tilde{\beta}_i$, extract the AR(1) coefficient $\varphi_i$ for
+$\mu_{ct}$ from the robust closed-loop dynamics and set
+$\tilde{\beta}_i = 1/(\varphi_i R)$.
+
+Show that $\tilde{\beta}_i > \hat{\beta}$ in every case, confirming that
+robustness acts like increased patience.
+
+```{exercise-end}
+```
+
+```{solution-start} ce_ex3
+:class: dropdown
+```
+
+For each $\sigma_i$ we solve the robust problem with `RBLQ` and extract the
+AR(1) coefficient $\varphi$ for $\mu_{ct}$ from the closed-loop dynamics
+$A_{\text{cl}} = A - B F_{\text{rob}}$.
+
+If $F$ is a left eigenvector of $A_{\text{cl}}$ with eigenvalue $\varphi$,
+then $\mu_{ct} = -F y_t$ satisfies
+$\mu_{c,t+1} = \varphi\, \mu_{ct} + \nu\, \epsilon_{t+1}$.
+
+Setting $\tilde{\beta} = 1/(\varphi R)$ and solving a standard (non-robust)
+LQ problem with discount factor $\tilde{\beta}$ should reproduce $F$.
+
+```{code-cell} ipython3
+σ_trio = np.array([-5e-8, -1e-7, -2e-7])
+
+for s in σ_trio:
+ # Robust model: (σ, β_hat)
+ θ_val = -1.0 / s
+ rblq = RBLQ(R_pi, Q_pi, A_pi, B_pi, C_pi, β_hat, θ_val)
+ F_rob, K_rob, P_rob = rblq.robust_rule()
+
+ # Extract φ from closed-loop under the approximating model
+ A_cl = A_pi - B_pi @ F_rob
+ φ_rob = float((F_rob @ A_cl)[0, 1] / F_rob[0, 1])
+
+ # Implied discount factor
+ bt = 1.0 / (φ_rob * R_rate)
+
+ # Non-robust model with β_tilde
+ lq_nr = LQ(R_pi, Q_pi, A_pi, B_pi, C=C_pi, beta=bt)
+ P_nr, F_nr, d_nr = lq_nr.stationary_values()
+
+ print(f"σ = {s:.1e}, θ = {θ_val:.1e}, β̃ = {bt:.6f} (> β̂ = {β_hat})")
+ print(f" φ_rob = {φ_rob:.8f}")
+ print(f" F_robust = [{F_rob[0,0]:.6f}, {F_rob[0,1]:.6f}]")
+ print(f" F_non-rob = [{F_nr[0,0]:.6f}, {F_nr[0,1]:.6f}]")
+ print(f" |F_rob - F_nr| = {np.max(np.abs(F_rob - F_nr)):.2e}")
+ print(f" K (worst-case distortion): [{K_rob[0,0]:.2e}, {K_rob[0,1]:.2e}]")
+ print()
+```
+
+The policy matrices $F$ match to high precision, confirming observational
+equivalence for consumption and saving decisions.
+
+In every case $\tilde{\beta} > \hat{\beta}$: a preference for robustness
+makes the agent behave as if he were more patient.
+
+The non-zero worst-case distortion $K$ in the robust model has no analogue in
+the non-robust model.
+
+As {cite:t}`HST_1999` show, this is why the two parametrisations imply
+different asset prices even though saving plans coincide.
+
+```{solution-end}
+```