diff --git a/lectures/_toc.yml b/lectures/_toc.yml
index 694a32ba..0e950b57 100644
--- a/lectures/_toc.yml
+++ b/lectures/_toc.yml
@@ -66,7 +66,7 @@ parts:
- file: mccall_model
- file: mccall_model_with_separation
- file: mccall_fitted_vfi
- - file: mccall_correlated
+ - file: mccall_persist_trans
- file: career
- file: jv
- file: mccall_q
@@ -79,13 +79,10 @@ parts:
- file: cass_fiscal
- file: cass_fiscal_2
- file: ak2
- - file: cake_eating_problem
- - file: cake_eating_numerical
- - file: optgrowth
- - file: optgrowth_fast
- - file: coleman_policy_iter
- - file: egm_policy_iter
- - file: ifp
+ - file: os
+ - file: os_numerical
+ - file: os_stochastic
+ - file: ifp_egm
- file: ifp_advanced
- caption: LQ控制
numbered: true
diff --git a/lectures/coleman_policy_iter.md b/lectures/coleman_policy_iter.md
deleted file mode 100644
index 337c1e9f..00000000
--- a/lectures/coleman_policy_iter.md
+++ /dev/null
@@ -1,426 +0,0 @@
----
-jupytext:
- text_representation:
- extension: .md
- format_name: myst
-kernelspec:
- display_name: Python 3
- language: python
- name: python3
----
-
-```{raw} jupyter
-
-```
-
-# {index}`最优增长 III:时间迭代 `
-
-```{contents} 目录
-:depth: 2
-```
-
-除Anaconda已包含的库外,本讲义还需要安装以下库:
-
-```{code-cell} ipython
----
-tags: [hide-output]
----
-!pip install quantecon
-```
-## 概述
-
-在本讲中,我们将继续此前对{doc}`随机最优增长模型 `的研究。
-
-在那一讲中,我们使用价值函数迭代求解了相关的动态规划问题。
-
-这种技术的优点在于其广泛的适用性。
-
-然而,在数值问题中,我们常常可以通过推导出更贴合具体应用的算法,以获得更高的效率。
-
-随机最优增长模型具备丰富的结构可供利用,尤其当我们对原始要素施加某些凹性与光滑性假设时。
-
-我们将利用这一结构,获得基于欧拉方程的方法。
-
-这将是我们在基础讲义{doc}`吃蛋糕问题 `中所考虑的时间迭代方法的扩展。
-
-在{doc}`下一讲 `中,我们将看到,时间迭代可以进一步调整,以获得更高的效率。
-
-接下来,让我们从导入开始:
-
-```{code-cell} ipython
-import matplotlib.pyplot as plt
-import matplotlib as mpl
-FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
-mpl.font_manager.fontManager.addfont(FONTPATH)
-plt.rcParams['font.family'] = ['Source Han Serif SC']
-
-import numpy as np
-from quantecon.optimize import brentq
-from numba import jit
-```
-## 欧拉方程
-
-我们的第一步是推导欧拉方程,这是此前在{doc}`吃蛋糕问题 `中得到的欧拉方程的推广。
-
-我们采用{doc}`随机增长模型 `中的模型设定,并加入以下假设:
-
-1. $u$ 和 $f$ 是连续可微且严格凹函数;
-1. $f(0) = 0$;
-1. $\lim_{c \to 0} u'(c) = \infty$ 且 $\lim_{c \to \infty} u'(c) = 0$;
-1. $\lim_{k \to 0} f'(k) = \infty$ 且 $\lim_{k \to \infty} f'(k) = 0$。
-
-最后两个条件通常被称为**Inada条件**。
-
-回顾贝尔曼方程:
-
-```{math}
-:label: cpi_fpb30
-
-v^*(y) = \max_{0 \leq c \leq y}
- \left\{
- u(c) + \beta \int v^*(f(y - c) z) \phi(dz)
- \right\}
-\quad \forall y \in \mathbb R_+
-```
-
-令最优消费策略记为 $\sigma^*$。
-
-我们知道 $\sigma^*$ 是一个 $v^*$-逐期最优的,因此 $\sigma^*(y)$ 是{eq}`cpi_fpb30`中的最大化解。
-
-上述条件表明:
-
-* $\sigma^*$ 是随机最优增长模型的唯一最优策略;
-* 该最优策略是连续的、严格递增的,并且是**内部解**,即对于所有严格正的 $y$,都有 $0 < \sigma^*(y) < y$;
-* 价值函数是严格凹的且连续可微的,并满足:
-
-```{math}
-:label: cpi_env
-
-(v^*)'(y) = u' (\sigma^*(y) ) := (u' \circ \sigma^*)(y)
-```
-
-最后一个结果被称为**包络条件**,因为它与[包络定理](https://baike.baidu.com/item/%E5%8C%85%E7%BB%9C%E5%AE%9A%E7%90%86/5746200)有关。
-
-要理解为什么{eq}`cpi_env`成立,可以将贝尔曼方程写成等价形式:
-
-$$
-v^*(y) = \max_{0 \leq k \leq y}
- \left\{
- u(y-k) + \beta \int v^*(f(k) z) \phi(dz)
- \right\},
-$$
-
-对 $y$ 求导,并在最优解处求值,即可得到{eq}`cpi_env`。
-
-([EDTC](https://johnstachurski.net/edtc.html)第12.1节给出了这些结果的完整证明,许多其他教材中也可找到类似讨论。)
-
-价值函数的可微性和最优策略的内部性意味着,最优消费决策满足与{eq}`cpi_fpb30`相关的一阶条件,即
-
-```{math}
-:label: cpi_foc
-
-u'(\sigma^*(y)) = \beta \int (v^*)'(f(y - \sigma^*(y)) z) f'(y - \sigma^*(y)) z \phi(dz)
-```
-
-将{eq}`cpi_env`和该一阶条件{eq}`cpi_foc`结合,得到**欧拉方程**:
-
-```{math}
-:label: cpi_euler
-
-(u'\circ \sigma^*)(y)
-= \beta \int (u'\circ \sigma^*)(f(y - \sigma^*(y)) z) f'(y - \sigma^*(y)) z \phi(dz)
-```
-
-我们可以将欧拉方程视为一个函数方程:
-
-```{math}
-:label: cpi_euler_func
-
-(u'\circ \sigma)(y)
-= \beta \int (u'\circ \sigma)(f(y - \sigma(y)) z) f'(y - \sigma(y)) z \phi(dz)
-```
-其中 $\sigma$ 为内部消费策略,其解之一即为最优策略 $\sigma^*$。
-
-我们的目标是求解函数方程 {eq}`cpi_euler_func` 从而获得 $\sigma^*$。
-
-### Coleman-Reffett 算子
-
-回顾贝尔曼算子:
-
-```{math}
-:label: fcbell20_coleman
-
-Tv(y) := \max_{0 \leq c \leq y}
-\left\{
- u(c) + \beta \int v(f(y - c) z) \phi(dz)
-\right\}
-```
-
-正如我们引入贝尔曼算子来求解贝尔曼方程一样,我们现在将引入一个作用于策略空间的算子,用于帮助我们求解欧拉方程。
-
-该算子 $K$ 将作用于所有连续、严格递增且为内部解的 $\sigma \in \Sigma$。
-
-此后我们将这类策略集合记为 $\mathscr P$。
-
-1. 算子 $K$ 的自变量是一个 $\sigma \in \mathscr P$;
-1. 返回一个新函数 $K\sigma$,其中 $(K\sigma)(y)$ 是求解以下方程的 $c \in (0, y)$:
-
-```{math}
-:label: cpi_coledef
-
-u'(c)
-= \beta \int (u' \circ \sigma) (f(y - c) z ) f'(y - c) z \phi(dz)
-```
-
-我们称这个算子为**Coleman-Reffett算子**,以此致敬{cite}`Coleman1990`和{cite}`Reffett1996`的研究工作。
-
-本质上,$K\sigma$ 表示在给定未来消费策略为 $\sigma$ 时,欧拉方程指导你今天应选择的消费策略。
-
-值得注意的是:依据构造,算子 $K$ 的不动点恰好与函数方程{eq}`cpi_euler_func`的解相一致。
-
-特别地,最优政策 $\sigma^*$ 是一个不动点。
-
-事实上,对于固定的 $y$,$(K\sigma^*)(y)$ 是满足以下方程的 $c$:
-
-$$
-u'(c)
-= \beta \int (u' \circ \sigma^*) (f(y - c) z ) f'(y - c) z \phi(dz)
-$$
-
-根据欧拉方程,该解正是 $\sigma^*(y)$。
-
-### Coleman-Reffett算子是否定义良好?
-
-特别地,是否总存在唯一的 $c \in (0, y)$ 使其满足{eq}`cpi_coledef`?
-
-在我们的假设条件下,答案是肯定的。
-
-对于任何 $\sigma \in \mathscr P$,{eq}`cpi_coledef` 的右侧:
-
-* 在 $(0, y)$ 上关于 $c$ 是连续且严格递增的;
-* 当 $c \uparrow y$ 时趋向于 $+\infty$。
-
-{eq}`cpi_coledef` 的左侧:
-
-* 在 $(0, y)$ 上关于 $c$ 是连续且严格递减的;
-* 当 $c \downarrow 0$ 时趋向于 $+\infty$。
-
-绘制这些曲线并利用上述信息,二者在 $c \in (0, y)$ 上恰好有且仅有一次交点。
-
-进一步分析可得:若 $\sigma \in \mathscr P$,则 $K \sigma \in \mathscr P$。
-
-### 与价值函数迭代的理论比较
-
-可以证明,算子 $K$ 的迭代与贝尔曼算子的迭代之间存在紧密关系。
-
-从数学上讲,这两个算子是*拓扑共轭的*。
-
-简单来说,这意味着:如果一个算子的迭代收敛,那么另一个算子的迭代也会收敛,反之亦然。
-
-此外,在理论上可以认为二者的收敛速率是相同的。
-
-然而,事实证明,算子 $K$ 在数值计算上更加稳定,因此在我们考虑的应用中更加高效。
-
-下面给出若干示例。
-
-## 实现
-
-与{doc}`上一讲 `一样,我们继续假设:
-
-* $u(c) = \ln c$;
-* $f(k) = k^{\alpha}$;
-* $\phi$ 是 $\xi := \exp(\mu + s \zeta)$ 的分布,且 $\zeta$ 服从标准正态分布。
-
-这一设定使我们能够将数值结果与解析解进行比较。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth/cd_analytical.py
-```
-如上所述,我们的目标是通过时间迭代来求解模型,即对算子 $K$ 进行迭代。
-
-为此,我们需要函数 $u', f$ 和 $f'$。
-
-我们将使用{doc}`上一讲 `中构建的`OptimalGrowthModel`类来实现。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth_fast/ogm.py
-```
-接下来我们实现一个名为`euler_diff`的方法,该方法返回:
-
-```{math}
-:label: euler_diff
-
-u'(c) - \beta \int (u' \circ \sigma) (f(y - c) z ) f'(y - c) z \phi(dz)
-```
-
-```{code-cell} ipython
-@jit
-def euler_diff(c, σ, y, og):
- """
- 设置一个函数,使得关于c的根,
- 在给定y和σ的情况下,等于Kσ(y)。
-
- """
-
- β, shocks, grid = og.β, og.shocks, og.grid
- f, f_prime, u_prime = og.f, og.f_prime, og.u_prime
-
- # 首先通过插值将σ转换为函数
- σ_func = lambda x: np.interp(x, grid, σ)
-
- # 现在设置我们需要找到根的函数
- vals = u_prime(σ_func(f(y - c) * shocks)) * f_prime(y - c) * shocks
- return u_prime(c) - β * np.mean(vals)
-```
-函数`euler_diff`通过蒙特卡洛方法计算积分,并使用线性插值对函数进行近似。
-
-我们将使用求根算法来求解式{eq}`euler_diff`,给定状态 $y$ 和 $σ$,寻找当前期消费 $c$。
-
-下面是实现该求根算法的算子 $K$。
-
-```{code-cell} ipython3
-@jit
-def K(σ, og):
- """
- Coleman-Reffett算子
-
- 这里og是OptimalGrowthModel的一个实例。
- """
-
- β = og.β
- f, f_prime, u_prime = og.f, og.f_prime, og.u_prime
- grid, shocks = og.grid, og.shocks
-
- σ_new = np.empty_like(σ)
- for i, y in enumerate(grid):
- # 在y处求解最优c
- c_star = brentq(euler_diff, 1e-10, y-1e-10, args=(σ, y, og))[0]
- σ_new[i] = c_star
-
- return σ_new
-```
-### 测试
-
-接下来,我们生成一个实例并绘制算子 $K$ 的若干次迭代结果,初始条件取 $σ(y) = y$。
-
-```{code-cell} ipython3
-og = OptimalGrowthModel()
-grid = og.grid
-
-n = 15
-σ = grid.copy() # 设置初始条件
-
-fig, ax = plt.subplots()
-lb = '初始条件 $\sigma(y) = y$'
-ax.plot(grid, σ, color=plt.cm.jet(0), alpha=0.6, label=lb)
-
-for i in range(n):
- σ = K(σ, og)
- ax.plot(grid, σ, color=plt.cm.jet(i / n), alpha=0.6)
-
-# 再更新一次并用黑色绘制最后一次迭代
-σ = K(σ, og)
-ax.plot(grid, σ, color='k', alpha=0.8, label='最后一次迭代')
-
-ax.legend()
-
-plt.show()
-```
-我们可以看到,迭代过程快速收敛到一个极限,该极限与我们在{doc}`上一讲`中得到的解非常相似。
-
-这里给出一个名为`solve_model_time_iter`的函数,它接收一个`OptimalGrowthModel`实例作为输入,并通过时间迭代法返回最优策略的近似解。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/coleman_policy_iter/solve_time_iter.py
-```
-让我们运行它:
-
-```{code-cell} ipython3
-σ_init = np.copy(og.grid)
-σ = solve_model_time_iter(og, σ_init)
-```
-这是得到的策略与真实策略的对比图:
-
-```{code-cell} ipython3
-fig, ax = plt.subplots()
-
-ax.plot(og.grid, σ, lw=2,
- alpha=0.8, label='近似策略函数')
-
-ax.plot(og.grid, σ_star(og.grid, og.α, og.β), 'k--',
- lw=2, alpha=0.8, label='真实策略函数')
-
-ax.legend()
-plt.show()
-```
-再次说明,拟合效果非常好。
-
-两种策略之间的最大绝对偏差是:
-
-```{code-cell} ipython3
-np.max(np.abs(σ - σ_star(og.grid, og.α, og.β)))
-```
-收敛所需时间如下:
-
-```{code-cell} ipython3
-%%timeit -n 3 -r 1
-σ = solve_model_time_iter(og, σ_init, verbose=False)
-```
-收敛速度非常快,甚至优于我们{doc}`基于JIT编译的价值函数迭代`。
-
-总的来说,我们发现,至少对于该模型而言,时间迭代法在效率与准确度上均展现出高度优势。
-
-## 练习
-
-```{exercise}
-:label: cpi_ex1
-
-求解具有CRRA效用函数的模型
-
-$$
-u(c) = \frac{c^{1 - \gamma}} {1 - \gamma}
-$$
-
-其中`γ = 1.5`。
-
-计算并绘制最优策略。
-```
-
-```{solution-start} cpi_ex1
-:class: dropdown
-```
-
-我们使用{doc}`VFI讲义`中的`OptimalGrowthModel_CRRA`类。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth_fast/ogm_crra.py
-```
-
-创建一个实例:
-
-```{code-cell} ipython3
-og_crra = OptimalGrowthModel_CRRA()
-```
-
-求解并绘制策略:
-
-```{code-cell} ipython3
-%%time
-σ = solve_model_time_iter(og_crra, σ_init)
-
-
-fig, ax = plt.subplots()
-
-ax.plot(og.grid, σ, lw=2,
- alpha=0.8, label='近似策略函数')
-
-ax.legend()
-plt.show()
-```
-
-```{solution-end}
-```
diff --git a/lectures/egm_policy_iter.md b/lectures/egm_policy_iter.md
deleted file mode 100644
index 4c02fb97..00000000
--- a/lectures/egm_policy_iter.md
+++ /dev/null
@@ -1,251 +0,0 @@
----
-jupytext:
- text_representation:
- extension: .md
- format_name: myst
-kernelspec:
- display_name: Python 3
- language: python
- name: python3
----
-
-```{raw} jupyter
-
-```
-
-# {index}`最优增长 IV:内生网格法 `
-
-```{contents} 目录
-:depth: 2
-```
-
-## 概述
-
-在之前,我们使用以下方法求解了随机最优增长模型:
-
-1. {doc}`价值函数迭代 `
-1. {doc}`基于欧拉方程的时间迭代 `
-
-我们发现时间迭代在准确性和效率方面都明显更好。
-
-在本讲义中,我们将介绍时间迭代的一种巧妙变体,称为**内生网格法**(EGM)。
-
-EGM是由[Chris Carroll](http://www.econ2.jhu.edu/people/ccarroll/)发明的一种用于实现政策迭代的数值方法。
-
-该方法的原始参考文献是{cite}`Carroll2006`。
-
-让我们从一些标准导入开始:
-
-```{code-cell} ipython
-import matplotlib.pyplot as plt
-import matplotlib as mpl
-FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
-mpl.font_manager.fontManager.addfont(FONTPATH)
-plt.rcParams['font.family'] = ['Source Han Serif SC']
-
-import numpy as np
-from numba import jit
-```
-
-## 核心思想
-
-我们首先回顾理论背景,然后说明数值方法如何融入其中。
-
-### 理论
-
-我们沿用{doc}`时间迭代 `中的模型设定,遵循相同的术语和符号。
-
-欧拉方程为:
-
-```{math}
-:label: egm_euler
-
-(u'\circ \sigma^*)(y)
-= \beta \int (u'\circ \sigma^*)(f(y - \sigma^*(y)) z) f'(y - \sigma^*(y)) z \phi(dz)
-```
-
-如前所示,Coleman-Reffett算子是一个非线性算子 $K$,其设计使得 $\sigma^*$ 是 $K$ 的不动点。
-
-该算子以一个连续且严格递增的消费策略 $\sigma \in \Sigma$ 作为自变量。
-
-它返回一个新函数 $K \sigma$,其中 $(K \sigma)(y)$ 是满足以下方程的 $c \in (0, \infty)$:
-
-```{math}
-:label: egm_coledef
-
-u'(c)
-= \beta \int (u' \circ \sigma) (f(y - c) z ) f'(y - c) z \phi(dz)
-```
-
-### 外生网格
-
-如{doc}`时间迭代 `中所述,为了在计算机上实现该方法,我们需要数值近似。
-
-具体来说,我们通过在有限网格上取值的方式表示策略函数。
-
-在需要时,使用插值或其他方法从该有限表示中重建原函数。
-
-在{doc}`时间迭代 `中,为了获得更新后的消费策略的有限表示,我们:
-
-* 固定一组收入点 $\{y_i\}$;
-* 使用{eq}`egm_coledef`与求根算法,计算与每个 $y_i$ 对应的消费值 $c_i$。
-
-每个 $c_i$ 被解释为函数 $K \sigma$ 在 $y_i$ 处的值。
-
-因此,有了点集 $\{y_i, c_i\}$,我们可以通过近似重建 $K \sigma$。
-
-然后继续迭代...
-
-### 内生网格
-
-上述方法需要通过求根算法来确定与给定收入值 $y_i$ 对应的消费水平 $c_i$。
-
-然而,求根运算的代价较高,因为其通常涉及大量函数求值。
-
-正如Carroll {cite}`Carroll2006`所指出的,如果 $y_i$ 是内生选择的,则可避免这一过程。
-
-唯一需要的假设是:$u'$ 在 $(0, \infty)$ 上是可逆的。
-
-令 $(u')^{-1}$ 为 $u'$ 的反函数。
-
-其核心思想如下:
-
-* 首先,固定一个关于资本($k = y - c$)的*外生*网格 $\{k_i\}$;
-* 接着,根据以下公式求得 $c_i$:
-
-```{math}
-:label: egm_getc
-
-c_i =
-(u')^{-1}
-\left\{
- \beta \int (u' \circ \sigma) (f(k_i) z ) \, f'(k_i) \, z \, \phi(dz)
-\right\}
-```
-
-* 最后,对每个 $c_i$,设定 $y_i = c_i + k_i$。
-
-显然,每个通过上述方式构建的 $(y_i, c_i)$ 都满足{eq}`egm_coledef`。
-
-有了点集 $\{y_i, c_i\}$,我们即可通过近似方法重建 $K \sigma$。
-
-新的EGM算法的关键在于:网格 $\{y_i\}$ 是**内生**决定的。
-
-## 实现
-
-与{doc}`时间迭代 `相同,我们从一个简单设定开始:
-
-* $u(c) = \ln c$;
-* 生产函数是柯布-道格拉斯形式;
-* 冲击项服从对数正态分布。
-
-这一设定使我们能够将数值解与解析解进行对比。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth/cd_analytical.py
-```
-
-我们重用 `OptimalGrowthModel` 类
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth_fast/ogm.py
-```
-
-### 算子
-
-以下给出使用EGM方法实现算子 $K$ 的代码:
-
-```{code-cell} ipython3
-@jit
-def K(σ_array, og):
- """
- 使用EGM的Coleman-Reffett算子
-
- """
-
- # 简化命名
- f, β = og.f, og.β
- f_prime, u_prime = og.f_prime, og.u_prime
- u_prime_inv = og.u_prime_inv
- grid, shocks = og.grid, og.shocks
-
- # 确定内生网格
- y = grid + σ_array # y_i = k_i + c_i
-
- # 使用内生网格进行策略的线性插值
- σ = lambda x: np.interp(x, y, σ_array)
-
- # 为新的消费数组分配内存
- c = np.empty_like(grid)
-
- # 求解更新后的消费值
- for i, k in enumerate(grid):
- vals = u_prime(σ(f(k) * shocks)) * f_prime(k) * shocks
- c[i] = u_prime_inv(β * np.mean(vals))
-
- return c
-```
-
-值得注意的是,该算法不需要求根算法。
-
-### 测试
-
-首先,我们创建一个实例。
-
-```{code-cell} ipython3
-og = OptimalGrowthModel()
-grid = og.grid
-```
-
-下面是求解程序:
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/coleman_policy_iter/solve_time_iter.py
-```
-
-让我们运行它:
-
-```{code-cell} ipython3
-σ_init = np.copy(grid)
-σ = solve_model_time_iter(og, σ_init)
-```
-
-以下是得到的策略与真实策略的比较:
-
-```{code-cell} ipython3
-y = grid + σ # y_i = k_i + c_i
-
-fig, ax = plt.subplots()
-
-ax.plot(y, σ, lw=2,
- alpha=0.8, label='近似策略函数')
-
-ax.plot(y, σ_star(y, og.α, og.β), 'k--',
- lw=2, alpha=0.8, label='真实策略函数')
-
-ax.legend()
-plt.show()
-```
-
-两个策略之间的最大绝对偏差是
-
-```{code-cell} ipython3
-np.max(np.abs(σ - σ_star(y, og.α, og.β)))
-```
-
-收敛所需的时间为:
-
-```{code-cell} ipython3
-%%timeit -n 3 -r 1
-σ = solve_model_time_iter(og, σ_init, verbose=False)
-```
-
-相较于已被证明高度高效的时间迭代法,内生网格法(EGM)在保持精度不变的前提下,进一步显著减少了运行时间。
-
-其主要原因在于该方法不需要进行数值求根步骤。
-
-因此,我们能够在给定参数下以极高的速度求解最优增长模型。
\ No newline at end of file
diff --git a/lectures/ifp.md b/lectures/ifp_egm.md
similarity index 100%
rename from lectures/ifp.md
rename to lectures/ifp_egm.md
diff --git a/lectures/mccall_correlated.md b/lectures/mccall_persist_trans.md
similarity index 100%
rename from lectures/mccall_correlated.md
rename to lectures/mccall_persist_trans.md
diff --git a/lectures/optgrowth_fast.md b/lectures/optgrowth_fast.md
deleted file mode 100644
index 2ac1e130..00000000
--- a/lectures/optgrowth_fast.md
+++ /dev/null
@@ -1,382 +0,0 @@
----
-jupytext:
- text_representation:
- extension: .md
- format_name: myst
-kernelspec:
- display_name: Python 3
- language: python
- name: python3
----
-
-(optgrowth)=
-```{raw} jupyter
-
-```
-
-# {index}`最优增长 II:使用Numba加速代码 `
-
-```{contents} 目录
-:depth: 2
-```
-
-除了Anaconda中已有的库外,本讲座还需要以下库:
-
-```{code-cell} ipython
----
-tags: [hide-output]
----
-!pip install quantecon
-```
-
-## 概述
-
-在{doc}`上一讲 `中,我们研究了一个具有代表性个体的随机最优增长模型。
-
-我们使用动态规划方法对该模型进行了求解。
-
-在编写代码时,我们注重清晰性和灵活性。
-
-尽管这些特性十分重要,但在实际应用中,灵活性与运行速度之间往往存在权衡。
-
-其原因在于,当代码的灵活性降低时,我们能够更容易地利用模型的结构特征。
-
-(这一点在算法与数学问题中普遍成立:越具体的问题往往具有更强的结构特征,而经过适当设计,这些结构可被有效利用,从而获得更优的结果。)
-
-因此,在本讲中,我们将牺牲一定的灵活性以换取更高的运行速度,采用即时(JIT)编译来加速代码的执行。
-
-下面让我们从导入相关库开始:
-
-```{code-cell} ipython
-import matplotlib.pyplot as plt
-import matplotlib as mpl
-FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
-mpl.font_manager.fontManager.addfont(FONTPATH)
-plt.rcParams['font.family'] = ['Source Han Serif SC']
-
-import numpy as np
-from numba import jit, jit
-from quantecon.optimize.scalar_maximization import brent_max
-```
-
-函数`brent_max`同样被设计用于嵌入JIT编译代码中。
-
-这些函数可作为SciPy中类似函数的替代方案(遗憾的是,SciPy中的相关函数目前尚不支持JIT)。
-
-## 模型
-
-```{index} single: Optimal Growth; Model
-```
-
-本节所使用的模型与我们在{doc}`前一讲 `关于最优增长的讲授中所讨论的模型相同。
-
-我们从对数型效用函数开始:
-
-$$
-u(c) = \ln(c)
-$$
-
-并继续作如下假设:
-
-* 生产函数为 $f(k) = k^{\alpha}$;
-* 随机冲击项 $\xi$ 的分布为 $\phi$,其中 $\xi := \exp(\mu + s \zeta)$ 且 $\zeta$ 为标准正态分布。
-
-我们将再次使用价值函数迭代(VFI)来求解这个模型。
-
-具体来说,算法保持不变,唯一的区别在于具体的实现方式。
-
-和之前一样,我们会对比本次计算所得结果与真实解。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth/cd_analytical.py
-```
-
-## 计算
-
-```{index} single: Dynamic Programming; Computation
-```
-
-我们将再次把最优增长模型的基本要素封装在一个类中。
-
-然而,与此前不同的是,我们将使用[Numba](https://python-programming.quantecon.org/numba.html)的 `@jitclass`装饰器来对该类进行JIT编译。
-
-由于我们计划使用Numba来编译该类,因此需要明确指定数据类型。
-
-在代码中,你将看到一个名为`opt_growth_data`的列表,该列表定义在类的上方,用于说明这些类型。
-
-与{doc}`上一讲`不同的是,这里我们将生产和效用函数的具体形式直接写入类中,而非保持一般性形式。
-
-也就是说,我们在此牺牲了一定的灵活性,以换取更高的运行速度。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth_fast/ogm.py
-```
-
-该类还包含若干方法,例如`u_prime`,虽然在当前讲义中尚未使用,但将在后续课程中发挥作用。
-
-### 贝尔曼算子
-
-我们将使用JIT编译来加速贝尔曼算子的计算。
-
-首先,定义一个函数,用于计算在给定状态`y`下,某一特定消费选择`c`所对应的价值。该函数基于贝尔曼方程{eq}`fpb30`。
-
-```{code-cell} ipython3
-@jit
-def state_action_value(c, y, v_array, og):
- """
- 贝尔曼方程右侧。
-
- * c是消费
- * y是收入
- * og是OptimalGrowthModel的一个实例
- * v_array表示网格上的值函数猜测
-
- """
-
- u, f, β, shocks = og.u, og.f, og.β, og.shocks
-
- v = lambda x: np.interp(x, og.grid, v_array)
-
- return u(c) + β * np.mean(v(f(y - c) * shocks))
-```
-
-现在我们可以实现贝尔曼算子,它用于最大化贝尔曼方程的右侧:
-
-```{code-cell} ipython3
-@jit
-def T(v, og):
- """
- 贝尔曼算子。
-
- * og 是 OptimalGrowthModel 的一个实例
- * v 是一个数组,表示价值函数的猜测值
-
- """
-
- v_new = np.empty_like(v)
- v_greedy = np.empty_like(v)
-
- for i in range(len(og.grid)):
- y = og.grid[i]
-
- # 在状态 y 下最大化贝尔曼方程的右侧
- result = brent_max(state_action_value, 1e-10, y, args=(y, v, og))
- v_greedy[i], v_new[i] = result[0], result[1]
-
- return v_greedy, v_new
-```
-
-我们使用`solve_model`函数进行迭代直到收敛。
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth/solve_model.py
-```
-
-让我们用默认参数计算近似解。
-
-首先创建一个实例:
-
-```{code-cell} ipython3
-og = OptimalGrowthModel()
-```
-
-现在我们调用`solve_model`,使用`%%time`魔法指令来记录运行时间。
-
-```{code-cell} ipython3
-%%time
-v_greedy, v_solution = solve_model(og)
-```
-
-你会发现,这比我们的{doc}`原始实现 `要*快得多*。
-
-下面,生成近似策略与真实策略的对比图:
-
-```{code-cell} ipython3
-fig, ax = plt.subplots()
-
-ax.plot(og.grid, v_greedy, lw=2,
- alpha=0.8, label='近似策略函数')
-
-ax.plot(og.grid, σ_star(og.grid, og.α, og.β), 'k--',
- lw=2, alpha=0.8, label='真实策略函数')
-
-ax.legend()
-plt.show()
-```
-
-与之前一样,拟合效果非常好 --- 这是意料之中的,因为我们没有改变算法。
-
-两种策略之间的最大绝对偏差是
-
-```{code-cell} ipython3
-np.max(np.abs(v_greedy - σ_star(og.grid, og.α, og.β)))
-```
-
-## 练习
-
-```{exercise}
-:label: ogfast_ex1
-
-在默认参数设定下,从给定的初始条件 $v(y) = u(y)$ 开始,对贝尔曼算子进行 20 次迭代,并记录整个迭代过程所耗费的时间。
-```
-
-```{solution-start} ogfast_ex1
-:class: dropdown
-```
-
-设置初始条件:
-
-```{code-cell} ipython3
-v = og.u(og.grid)
-```
-
-计时:
-
-```{code-cell} ipython3
-%%time
-
-for i in range(20):
- v_greedy, v_new = T(v, og)
- v = v_new
-```
-
-与非编译版本的价值函数迭代的{ref}`用时 `相比,JIT编译的代码通常快一个数量级。
-
-```{solution-end}
-```
-
-```{exercise}
-:label: ogfast_ex2
-
-将最优增长模型修改为采用CRRA效用函数的设定:
-
-$$
-u(c) = \frac{c^{1 - \gamma} } {1 - \gamma}
-$$
-
-设定`γ = 1.5`为默认值,并保持其他模型设定不变。
-
-(注意,`jitclass`目前不支持类继承,因此你需要复制原有的类,并相应修改相关的参数与方法。)
-
-计算最优策略的估计值,并绘制其图像。将所得图像与第一讲最优增长模型中{ref}`对应练习 `的图表进行比较。
-
-同时,对比两种实现的运行时间。
-```
-
-```{solution-start} ogfast_ex2
-:class: dropdown
-```
-
-这是CRRA版本的`OptimalGrowthModel`:
-
-```{code-cell} ipython3
-:load: _static/lecture_specific/optgrowth_fast/ogm_crra.py
-```
-
-创建一个实例:
-
-```{code-cell} ipython3
-og_crra = OptimalGrowthModel_CRRA()
-```
-
-调用`solve_model`,使用`%%time`魔术命令来记录运行时间。
-
-```{code-cell} ipython3
-%%time
-v_greedy, v_solution = solve_model(og_crra)
-```
-
-以下是得到的策略图:
-
-```{code-cell} ipython3
-fig, ax = plt.subplots()
-
-ax.plot(og.grid, v_greedy, lw=2,
- alpha=0.6, label='近似价值函数')
-
-ax.legend(loc='lower right')
-plt.show()
-```
-
-这与我们在{ref}`练习 `中使用非jit代码得到的答案相符,但执行时间快了一个数量级。
-
-```{solution-end}
-```
-
-
-```{exercise-start}
-:label: ogfast_ex3
-```
-
-在本练习中,我们回到最初的对数型效用函数设定。
-
-当给定最优消费政策 $\sigma$ 后,收入的动态演化如下:
-
-$$
-y_{t+1} = f(y_t - \sigma(y_t)) \xi_{t+1}
-$$
-
-下图展示了该序列在三种不同贴现因子(因而对应三种不同政策)下的模拟结果,每个序列包含 100 个样本点。
-
-```{figure} /_static/lecture_specific/optgrowth/solution_og_ex2.png
-```
-
-在每个序列中,初始条件都是 $y_0 = 0.1$。
-
-贴现因子分别为`discount_factors = (0.8, 0.9, 0.98)`。
-
-我们还通过设置`s = 0.05`稍微降低了冲击的幅度。
-
-除此之外,参数和原始设定与前面讨论的对数线性模型相同。
-
-注意,更有耐心的个体通常拥有更高的财富。
-
-请在保持随机性结构的前提下,复现该图像。
-
-```{exercise-end}
-```
-
-```{solution-start} ogfast_ex3
-:class: dropdown
-```
-
-参考答案:
-
-```{code-cell} ipython3
-def simulate_og(σ_func, og, y0=0.1, ts_length=100):
- '''
- 根据消费策略σ计算时间序列。
- '''
- y = np.empty(ts_length)
- ξ = np.random.randn(ts_length-1)
- y[0] = y0
- for t in range(ts_length-1):
- y[t+1] = (y[t] - σ_func(y[t]))**og.α * np.exp(og.μ + og.s * ξ[t])
- return y
-```
-
-```{code-cell} ipython3
-fig, ax = plt.subplots()
-
-for β in (0.8, 0.9, 0.98):
-
- og = OptimalGrowthModel(β=β, s=0.05)
-
- v_greedy, v_solution = solve_model(og, verbose=False)
-
- # 定义最优策略函数
- σ_func = lambda x: np.interp(x, og.grid, v_greedy)
- y = simulate_og(σ_func, og)
- ax.plot(y, lw=2, alpha=0.6, label=rf'$\beta = {β}$')
-
-ax.legend(loc='lower right')
-plt.show()
-```
-
-```{solution-end}
-```
-
diff --git a/lectures/cake_eating_problem.md b/lectures/os.md
similarity index 100%
rename from lectures/cake_eating_problem.md
rename to lectures/os.md
diff --git a/lectures/cake_eating_numerical.md b/lectures/os_numerical.md
similarity index 100%
rename from lectures/cake_eating_numerical.md
rename to lectures/os_numerical.md
diff --git a/lectures/optgrowth.md b/lectures/os_stochastic.md
similarity index 100%
rename from lectures/optgrowth.md
rename to lectures/os_stochastic.md