Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 90 additions & 86 deletions lectures/coleman_policy_iter.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ kernelspec:
:depth: 2
```

除了Anaconda中已有的库外,本讲座还需要以下库
除Anaconda已包含的库外,本讲义还需要安装以下库

```{code-cell} ipython
---
Expand All @@ -33,22 +33,23 @@ tags: [hide-output]
```
## 概述

在本讲中,我们将继续我们{doc}`之前 <optgrowth>`对随机最优增长模型的研究
在本讲中,我们将继续此前对{doc}`随机最优增长模型 <optgrowth>`的研究

在那节课中,我们使用值函数迭代求解了相关的动态规划问题
在那一讲中,我们使用价值函数迭代求解了相关的动态规划问题

这种技术的优点在于其广泛的适用性。

然而,对于数值问题,我们通常可以通过推导专门针对具体应用的方法来获得更高的效率
然而,在数值问题中,我们常常可以通过推导出更贴合具体应用的算法,以获得更高的效率

随机最优增长模型有大量可供利用的结构,特别是当我们对原始函数采用一些凹性和光滑性假设时
随机最优增长模型具备丰富的结构可供利用,尤其当我们对原始要素施加某些凹性与光滑性假设时

我们将利用这种结构来获得一个基于欧拉方程的方法
我们将利用这一结构,获得基于欧拉方程的方法

这将是对我们在{doc}`蛋糕食用问题 <cake_eating_numerical>`的基础讲座中考虑的时间迭代法的扩展
这将是我们在基础讲义{doc}`吃蛋糕问题 <cake_eating_numerical>`中所考虑的时间迭代方法的扩展

在{doc}`后续讲座 <egm_policy_iter>`中,我们将看到时间迭代可以进一步调整以获得更高的效率。
让我们从一些导入开始:
在{doc}`下一讲 <egm_policy_iter>`中,我们将看到,时间迭代可以进一步调整,以获得更高的效率。

接下来,让我们从导入开始:

```{code-cell} ipython
import matplotlib.pyplot as plt
Expand All @@ -63,18 +64,18 @@ from numba import jit
```
## 欧拉方程

我们的第一步是推导欧拉方程,这是对我们在{doc}`蛋糕食用问题讲座 <cake_eating_problem>`中得到的欧拉方程的推广。
我们的第一步是推导欧拉方程,这是此前在{doc}`吃蛋糕问题 <cake_eating_problem>`中得到的欧拉方程的推广。

我们采用{doc}`随机增长模型讲座 <optgrowth>`中设定的模型,并添加以下假设
我们采用{doc}`随机增长模型 <optgrowth>`中的模型设定,并加入以下假设

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$
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
Expand All @@ -83,28 +84,28 @@ v^*(y) = \max_{0 \leq c \leq y}
\left\{
u(c) + \beta \int v^*(f(y - c) z) \phi(dz)
\right\}
\quad \text{for all} \quad
y \in \mathbb R_+
\quad \forall y \in \mathbb R_+
```

让最优消费策略用$\sigma^*$表示。
令最优消费策略记为 $\sigma^*$。

我们知道 $\sigma^*$ 是一个 $v^*$-逐期最优的,因此 $\sigma^*(y)$ 是{eq}`cpi_fpb30`中的最大化解。

我们知道$\sigma^*$是一个$v^*$-贪婪策略,因此$\sigma^*(y)$是{eq}`cpi_fpb30`中的最大化值。
上述条件表明
上述条件表明:

* $\sigma^*$ 是随机最优增长模型的唯一最优策略
* 最优策略是连续的、严格递增的,并且是**内部的**,即对于所有严格正的 $y$,都有 $0 < \sigma^*(y) < y$,并且
* 值函数是严格凹的且连续可微的,满足
* $\sigma^*$ 是随机最优增长模型的唯一最优策略
* 该最优策略是连续的、严格递增的,并且是**内部解**,即对于所有严格正的 $y$,都有 $0 < \sigma^*(y) < y$
* 价值函数是严格凹的且连续可微的,并满足:

```{math}
:label: cpi_env

(v^*)'(y) = u' (\sigma^*(y) ) := (u' \circ \sigma^*)(y)
```

最后这个结果被称为**包络条件**,因为它与[包络定理](https://en.wikipedia.org/wiki/Envelope_theorem)有关。
最后一个结果被称为**包络条件**,因为它与[包络定理](https://baike.baidu.com/item/%E5%8C%85%E7%BB%9C%E5%AE%9A%E7%90%86/5746200)有关。

要理解为什么{eq}`cpi_env`成立,可以将贝尔曼方程写成等价形式
要理解为什么{eq}`cpi_env`成立,可以将贝尔曼方程写成等价形式

$$
v^*(y) = \max_{0 \leq k \leq y}
Expand All @@ -113,18 +114,19 @@ v^*(y) = \max_{0 \leq k \leq y}
\right\},
$$

对 $y$ 求导,然后在最优点处求值即可得到{eq}`cpi_env`。
([EDTC](https://johnstachurski.net/edtc.html)第12.1节包含这些结果的完整证明,许多其他教材中也可以找到密切相关的讨论。)
对 $y$ 求导,并在最优解处求值,即可得到{eq}`cpi_env`。

([EDTC](https://johnstachurski.net/edtc.html)第12.1节给出了这些结果的完整证明,许多其他教材中也可找到类似讨论。)

价值函数的可微性和最优策略的内部性意味着最优消费满足与{eq}`cpi_fpb30`相关的一阶条件,即
价值函数的可微性和最优策略的内部性意味着,最优消费决策满足与{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`结合得到**欧拉方程**
将{eq}`cpi_env`和该一阶条件{eq}`cpi_foc`结合,得到**欧拉方程**

```{math}
:label: cpi_euler
Expand All @@ -133,21 +135,21 @@ u'(\sigma^*(y)) = \beta \int (v^*)'(f(y - \sigma^*(y)) z) f'(y - \sigma^*(y)) z
= \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^*$。
其中 $\sigma$ 为内部消费策略,其解之一即为最优策略 $\sigma^*$。

我们的目标是求解函数方程 {eq}`cpi_euler_func` 从而获得 $\sigma^*$。

### Coleman-Reffett 算子

回顾 Bellman 算子
回顾贝尔曼算子:

```{math}
:label: fcbell20_coleman
Expand All @@ -158,14 +160,14 @@ Tv(y) := \max_{0 \leq c \leq y}
\right\}
```

正如我们引入 Bellman 算子来求解 Bellman 方程一样,我们现在将引入一个作用于策略的算子来帮助我们求解欧拉方程
正如我们引入贝尔曼算子来求解贝尔曼方程一样,我们现在将引入一个作用于策略空间的算子,用于帮助我们求解欧拉方程

这个算子 $K$ 将作用于所有连续、严格递增且内部的 $\sigma \in \Sigma$ 的集合上
该算子 $K$ 将作用于所有连续、严格递增且为内部解的 $\sigma \in \Sigma$。

此后我们用 $\mathscr P$ 表示这个策略集合
此后我们将这类策略集合记为 $\mathscr P$

1. 算子 $K$ $\sigma \in \mathscr P$ 为参数
1. 返回一个新函数 $K\sigma$,其中 $K\sigma(y)$ 是求解以下方程的 $c \in (0, y)$
1. 算子 $K$ 的自变量是一个 $\sigma \in \mathscr P$
1. 返回一个新函数 $K\sigma$,其中 $(K\sigma)(y)$ 是求解以下方程的 $c \in (0, y)$:

```{math}
:label: cpi_coledef
Expand All @@ -176,76 +178,78 @@ u'(c)

我们称这个算子为**Coleman-Reffett算子**,以此致敬{cite}`Coleman1990`和{cite}`Reffett1996`的研究工作。

本质上,当你的未来消费政策是$\sigma$时,$K\sigma$是欧拉方程告诉你今天应该选择的消费政策
本质上,$K\sigma$ 表示在给定未来消费策略为 $\sigma$ 时,欧拉方程指导你今天应选择的消费策略

关于$K$需要注意的重要一点是,根据其构造,其不动点恰好与函数方程{eq}`cpi_euler_func`的解coincide
值得注意的是:依据构造,算子 $K$ 的不动点恰好与函数方程{eq}`cpi_euler_func`的解相一致

特别地,最优政策$\sigma^*$就是一个不动点
特别地,最优政策 $\sigma^*$ 是一个不动点

事实上,对于固定的$y$,$K\sigma^*(y)$是解决以下方程的$c$:
事实上,对于固定的 $y$,$(K\sigma^*)(y)$ 是满足以下方程的 $c$:

$$
u'(c)
= \beta \int (u' \circ \sigma^*) (f(y - c) z ) f'(y - c) z \phi(dz)
$$

根据欧拉方程,这恰好就是$\sigma^*(y)$。
根据欧拉方程,该解正是 $\sigma^*(y)$。

### Coleman-Reffett算子是否良定义
### Coleman-Reffett算子是否定义良好

特别地,是否总存在唯一的$c \in (0, y)$来解决{eq}`cpi_coledef`?
特别地,是否总存在唯一的 $c \in (0, y)$ 使其满足{eq}`cpi_coledef`?

在我们的假设条件下,答案是肯定的。
对于任何 $\sigma \in \mathscr P$,{eq}`cpi_coledef` 右侧

* 在 $(0, y)$ 上关于 $c$ 是连续且严格递增的
* 当 $c \uparrow y$ 时趋向于 $+\infty$
对于任何 $\sigma \in \mathscr P$,{eq}`cpi_coledef` 的右侧:

{eq}`cpi_coledef` 左侧
* 在 $(0, y)$ 上关于 $c$ 是连续且严格递增的;
* 当 $c \uparrow y$ 时趋向于 $+\infty$。

* 在 $(0, y)$ 上关于 $c$ 是连续且严格递减的
* 当 $c \downarrow 0$ 时趋向于 $+\infty$
{eq}`cpi_coledef` 的左侧:

绘制这些曲线并利用上述信息,你会确信当 $c$ 在 $(0, y)$ 范围内变化时,这些曲线恰好相交一次。
* 在 $(0, y)$ 上关于 $c$ 是连续且严格递减的;
* 当 $c \downarrow 0$ 时趋向于 $+\infty$。

通过更深入的分析,可以进一步证明当 $\sigma \in \mathscr P$ 时,$K \sigma \in \mathscr P$
绘制这些曲线并利用上述信息,二者在 $c \in (0, y)$ 上恰好有且仅有一次交点

### 与值函数迭代的比较(理论)
进一步分析可得:若 $\sigma \in \mathscr P$,则 $K \sigma \in \mathscr P$。

可以证明 $K$ 的迭代与贝尔曼算子的迭代之间存在紧密关系。
### 与价值函数迭代的理论比较

从数学角度来说,这两个算子是*拓扑共轭的*
可以证明,算子 $K$ 的迭代与贝尔曼算子的迭代之间存在紧密关系

简单来说,这意味着如果一个算子的迭代收敛,那么另一个算子的迭代也会收敛,反之亦然
从数学上讲,这两个算子是*拓扑共轭的*

而且,至少从理论上讲,它们的收敛速度是相同的。
然而,事实证明算子 $K$ 在数值计算上更加稳定,因此在我们考虑的应用中更加高效。
简单来说,这意味着:如果一个算子的迭代收敛,那么另一个算子的迭代也会收敛,反之亦然。

下面给出一些例子。
此外,在理论上可以认为二者的收敛速率是相同的。

然而,事实证明,算子 $K$ 在数值计算上更加稳定,因此在我们考虑的应用中更加高效。

下面给出若干示例。

## 实现

如同我们在{doc}`之前的研究 <optgrowth_fast>`中一样,我们继续假设
{doc}`上一讲 <optgrowth_fast>`一样,我们继续假设

* $u(c) = \ln c$
* $f(k) = k^{\alpha}$
* $\phi$ 是当 $\zeta$ 为标准正态分布时 $\xi := \exp(\mu + s \zeta)$ 的分布
* $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$进行迭代。
如上所述,我们的目标是通过时间迭代来求解模型,即对算子 $K$ 进行迭代。

为此,我们需要访问函数$u'$和$f, f'$。
为此,我们需要函数 $u', f$ 和 $f'$。

这些函数在我们在{doc}`之前的讲座 <optgrowth_fast>`中构建的`OptimalGrowthModel`类中可用
我们将使用{doc}`上一讲 <optgrowth_fast>`中构建的`OptimalGrowthModel`类来实现

```{code-cell} ipython3
:load: _static/lecture_specific/optgrowth_fast/ogm.py
```
现在我们实现一个名为`euler_diff`的方法,它返回
接下来我们实现一个名为`euler_diff`的方法,该方法返回:

```{math}
:label: euler_diff
Expand All @@ -272,11 +276,11 @@ def euler_diff(c, σ, y, og):
vals = u_prime(σ_func(f(y - c) * shocks)) * f_prime(y - c) * shocks
return u_prime(c) - β * np.mean(vals)
```
函数`euler_diff`通过蒙特卡洛方法计算积分,并使用线性插值来近似函数
函数`euler_diff`通过蒙特卡洛方法计算积分,并使用线性插值对函数进行近似

我们将使用根查找算法来求解{eq}`euler_diff`,在给定状态$y$$σ$(当前策略猜测值)的情况下求解$c$。
我们将使用求根算法来求解式{eq}`euler_diff`,给定状态 $y$$σ$,寻找当前期消费 $c$。

以下是实现根查找步骤的算子$K$。
下面是实现该求根算法的算子 $K$。

```{code-cell} ipython3
@jit
Expand All @@ -301,7 +305,7 @@ def K(σ, og):
```
### 测试

让我们生成一个实例并绘制$K$的一些迭代结果,从$σ(y) = y$开始
接下来,我们生成一个实例并绘制算子 $K$ 的若干次迭代结果,初始条件取 $σ(y) = y$。

```{code-cell} ipython3
og = OptimalGrowthModel()
Expand All @@ -326,9 +330,9 @@ ax.legend()

plt.show()
```
我们可以看到迭代过程快速收敛到一个极限值,这与我们在{doc}`上一讲<optgrowth_fast>`中得到的解相似
我们可以看到,迭代过程快速收敛到一个极限,该极限与我们在{doc}`上一讲<optgrowth_fast>`中得到的解非常相似

这里有一个名为`solve_model_time_iter`的函数,它接收一个`OptimalGrowthModel`实例作为输入,并通过时间迭代法返回最优策略的近似解。
这里给出一个名为`solve_model_time_iter`的函数,它接收一个`OptimalGrowthModel`实例作为输入,并通过时间迭代法返回最优策略的近似解。

```{code-cell} ipython3
:load: _static/lecture_specific/coleman_policy_iter/solve_time_iter.py
Expand All @@ -355,33 +359,33 @@ 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编译的值函数迭代<optgrowth_fast>`相比,收敛速度非常快
收敛速度非常快,甚至优于我们{doc}`基于JIT编译的价值函数迭代<optgrowth_fast>`。

总的来说,我们发现时间迭代方法对于这个模型来说提供了很高的效率和准确性
总的来说,我们发现,至少对于该模型而言,时间迭代法在效率与准确度上均展现出高度优势

## 练习

```{exercise}
:label: cpi_ex1

用CRRA效用函数求解模型
求解具有CRRA效用函数的模型

$$
u(c) = \frac{c^{1 - \gamma}} {1 - \gamma}
$$

设定`γ = 1.5`。
其中`γ = 1.5`。

计算并绘制最优策略。
```
Expand All @@ -390,19 +394,19 @@ $$
:class: dropdown
```

我们使用{doc}`VFI讲座<optgrowth_fast>`中的`OptimalGrowthModel_CRRA`类。
我们使用{doc}`VFI讲义<optgrowth_fast>`中的`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
Expand All @@ -412,7 +416,7 @@ og_crra = OptimalGrowthModel_CRRA()
fig, ax = plt.subplots()

ax.plot(og.grid, σ, lw=2,
alpha=0.8, label='approximate policy function')
alpha=0.8, label='近似策略函数')

ax.legend()
plt.show()
Expand Down
Loading