From cb7b423a61f176eff0d8089dca479ed67c6fa4eb Mon Sep 17 00:00:00 2001 From: Longye Tian Date: Fri, 13 Sep 2024 21:59:42 +1000 Subject: [PATCH 1/7] Create linear_equations_cn.md --- lectures/linear_equations_cn.md | 1197 +++++++++++++++++++++++++++++++ 1 file changed, 1197 insertions(+) create mode 100644 lectures/linear_equations_cn.md diff --git a/lectures/linear_equations_cn.md b/lectures/linear_equations_cn.md new file mode 100644 index 00000000..d6b7bcd3 --- /dev/null +++ b/lectures/linear_equations_cn.md @@ -0,0 +1,1197 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# 线性方程和矩阵代数 + +```{index} single: Linear Equations and Matrix Algebra +``` + +## 概述 +经济学和金融学中的许多问题都需要解线性方程。 + +在本讲座中,我们将讨论线性方程及其应用。 + +为了说明线性方程的重要性,我们从一个两种商品的供需模型开始。 + +两种商品的情况非常简单,可以手动计算解。 + +但我们经常需要考虑包含多种商品的市场。 + +在多种商品的情况下,我们面对的是大型线性方程组,有许多方程和未知数。 + +为了处理这样的系统,我们需要两样东西: + +* 矩阵代数(以及如何使用它的知识)以及 +* 将矩阵代数应用于感兴趣问题的计算机代码。 + +本讲座涵盖了这些步骤。 + +我们将使用以下的库: + +```{code-cell} ipython3 +import numpy as np +import matplotlib.pyplot as plt +``` +## 两种商品的例子 +在本节中,我们将讨论一个简单的两种商品例子,并通过以下两种方法解决: +1. 纸笔计算 +2. 矩阵代数 +正如我们将看到的,第二种方法更具普遍性。 + +### 纸笔计算方法 +假设我们有两种相关的商品,比如: +* 丙烷和乙醇,或 +* 大米和小麦等。 +为了简化问题,我们将它们标记为商品0和商品1。 +每种商品的需求取决于两种商品的价格: +```{math} +:label: two_eq_demand +\begin{aligned} + q_0^d = 100 - 10 p_0 - 5 p_1 \\ + q_1^d = 50 - p_0 - 10 p_1 +\end{aligned} +``` +(我们假设当任一商品的价格上涨时需求会下降,但其他情况也是可能的。) +让我们假设供给由以下方程给出: + +```{math} +:label: two_eq_supply +\begin{aligned} + q_0^s = 10 p_0 + 5 p_1 \\ + q_1^s = 5 p_0 + 10 p_1 +\end{aligned} +``` +当供给等于需求时($q_0^s = q_0^d$ 和 $q_1^s = q_1^d$),市场达到均衡。 +这产生了以下线性系统: + +```{math} +:label: two_equilibrium +\begin{aligned} + 100 - 10 p_0 - 5 p_1 = 10 p_0 + 5 p_1 \\ + 50 - p_0 - 10 p_1 = 5 p_0 + 10 p_1 +\end{aligned} +``` + +我们可以用纸笔计算得到: +$$ + p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. +$$ +将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: +$$ + q_0 = 50 \quad \text{和} \quad q_1 = 33.82. +$$ + +### 展望未来 +在两种商品的情况下,纸笔计算方法很容易。 +但如果有很多种商品呢? +对于这样的问题,我们需要矩阵代数。 +在用矩阵代数解决问题之前,让我们先回顾一下向量和矩阵的基础知识,包括理论和计算。 + + +## {index}`向量 ` + + ```{index} single: Linear Algebra; Vectors + ``` + +一个长度为$n$的**向量**就是一个由$n$个数字组成的序列(或数组,或元组),我们将其写作$x = (x_1, \ldots, x_n)$或$x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$。 +我们可以将这些序列横向或纵向写出。 +但当我们使用矩阵运算时,我们默认假设向量是列向量。 +所有$n$维向量的集合用$\mathbb R^n$表示。 +例如, +* $\mathbb R^2$是平面 --- 即所有$(x_1, x_2)$对的集合。 +* $\mathbb R^3$是三维空间 --- 即所有$(x_1, x_2, x_3)$向量的集合。 +向量通常在视觉上表示为从原点到某点的箭头。 +这里是一个可视化示例。 + +```{code-cell} ipython3 +:tags: [hide-input] + +fig, ax = plt.subplots() +# 通过原点建立坐标轴 +for spine in ['left', 'bottom']: + ax.spines[spine].set_position('zero') +for spine in ['right', 'top']: + ax.spines[spine].set_color('none') + +ax.set(xlim=(-5, 5), ylim=(-5, 5)) + +vecs = ((2, 4), (-3, 3), (-4, -3.5)) +for v in vecs: + ax.annotate('', xy=v, xytext=(0, 0), + arrowprops=dict(facecolor='blue', + shrink=0, + alpha=0.7, + width=0.5)) + ax.text(1.1 * v[0], 1.1 * v[1], str(v)) +plt.show() +``` + +### 向量运算 + +```{index} single: Vectors; Operations +``` + +有时我们需要修改向量。 +对向量最常见的两种运算是加法和标量乘法,我们现在来描述这两种运算。 +当我们对两个向量进行加法运算时,我们是逐元素相加。 +例如, +$$ +\begin{bmatrix} + 4 \\ + -2 +\end{bmatrix} ++ +\begin{bmatrix} + 3 \\ + 3 +\end{bmatrix} += +\begin{bmatrix} + 4 & + & 3 \\ + -2 & + & 3 +\end{bmatrix} += +\begin{bmatrix} + 7 \\ + 1 +\end{bmatrix}. +$$ +一般来说, +$$ +x + y = +\begin{bmatrix} + x_1 \\ + x_2 \\ + \vdots \\ + x_n +\end{bmatrix} + +\begin{bmatrix} + y_1 \\ + y_2 \\ + \vdots \\ + y_n +\end{bmatrix} := +\begin{bmatrix} + x_1 + y_1 \\ + x_2 + y_2 \\ + \vdots \\ + x_n + y_n +\end{bmatrix}. +$$ +我们可以在$\mathbb{R}^2$中将向量加法可视化如下。 + +```{code-cell} ipython3 +:tags: [hide-input] + +fig, ax = plt.subplots() +# 通过原点建立坐标轴 +for spine in ['left', 'bottom']: + ax.spines[spine].set_position('zero') +for spine in ['right', 'top']: + ax.spines[spine].set_color('none') + +ax.set(xlim=(-2, 10), ylim=(-4, 4)) +# ax.grid() +vecs = ((4, -2), (3, 3), (7, 1)) +tags = ('(x1, x2)', '(y1, y2)', '(x1+x2, y1+y2)') +colors = ('blue', 'green', 'red') +for i, v in enumerate(vecs): + ax.annotate('', xy=v, xytext=(0, 0), + arrowprops=dict(color=colors[i], + shrink=0, + alpha=0.7, + width=0.5, + headwidth=8, + headlength=15)) + ax.text(v[0] + 0.2, v[1] + 0.1, tags[i]) + +for i, v in enumerate(vecs): + ax.annotate('', xy=(7, 1), xytext=v, + arrowprops=dict(color='gray', + shrink=0, + alpha=0.3, + width=0.5, + headwidth=5, + headlength=20)) +plt.show() +``` + +标量乘法是一种将向量 $x$ 与一个标量进行元素级别相乘的运算。 +例如, +$$ +-2 +\begin{bmatrix} + 3 \\ + -7 +\end{bmatrix} += +\begin{bmatrix} + -2 & \times & 3 \\ + -2 & \times & -7 +\end{bmatrix} += +\begin{bmatrix} + -6 \\ + 14 +\end{bmatrix}. +$$ +更一般地,它取一个数 $\gamma$ 和一个向量 $x$,得到 +$$ +\gamma x := +\begin{bmatrix} + \gamma x_1 \\ + \gamma x_2 \\ + \vdots \\ + \gamma x_n +\end{bmatrix}. +$$ +标量乘法在下图中进行了说明。 + +```{code-cell} ipython3 +:tags: [hide-input] + +fig, ax = plt.subplots() +# 通过原点建立坐标轴 +for spine in ['left', 'bottom']: + ax.spines[spine].set_position('zero') +for spine in ['right', 'top']: + ax.spines[spine].set_color('none') + +ax.set(xlim=(-5, 5), ylim=(-5, 5)) +x = (2, 2) +ax.annotate('', xy=x, xytext=(0, 0), + arrowprops=dict(facecolor='blue', + shrink=0, + alpha=1, + width=0.5)) +ax.text(x[0] + 0.4, x[1] - 0.2, '$x$', fontsize='16') + +scalars = (-2, 2) +x = np.array(x) + +for s in scalars: + v = s * x + ax.annotate('', xy=v, xytext=(0, 0), + arrowprops=dict(facecolor='red', + shrink=0, + alpha=0.5, + width=0.5)) + ax.text(v[0] + 0.4, v[1] - 0.2, f'${s} x$', fontsize='16') +plt.show() +``` + +在Python中,向量可以用列表或元组表示, +例如 `x = [2, 4, 6]` 或 `x = (2, 4, 6]`。 +然而,更常见的是用 +[NumPy数组](https://python-programming.quantecon.org/numpy.html#numpy-arrays)来表示向量。 + +NumPy数组的一个优点是标量乘法和加法具有非常自然的语法。 + +```{code-cell} ipython3 +x = np.ones(3) # 三个元素为一的向量 +y = np.array((2, 4, 6)) # 将 (2, 4, 6) 转换为 NumPy 数组 +x + y # 每个元素相加 +``` + +```{code-cell} +4 * x # 标量乘法 +``` + +### 内积和范数 + +```{index} single: Vectors; Inner Product +``` + +```{index} single: Vectors; Norm +``` + +向量 $x,y \in \mathbb R^n$ 的**内积**定义为 +$$ +x^\top y = +\begin{bmatrix} + \color{red}{x_1} & \color{blue}{x_2} & \cdots & x_n +\end{bmatrix} +\begin{bmatrix} + \color{red}{y_1} \\ + \color{blue}{y_2} \\ + \vdots \\ + y_n +\end{bmatrix} += {\color{red}{x_1 y_1}} + {\color{blue}{x_2 y_2}} + \cdots + x_n y_n +:= \sum_{i=1}^n x_i y_i. +$$ +向量 $x$ 的**范数**表示其"长度"(即,其与零向量的距离),定义为 +$$ + \| x \| := \sqrt{x^\top x} := \left( \sum_{i=1}^n x_i^2 \right)^{1/2}. +$$ +表达式 $\| x - y\|$ 可以被理解为 $x$ 和 $y$ 之间的"距离"。 +内积和范数可以按以下方式计算 + +```{code-cell} ipython3 +np.sum(x*y) # x和y的内积 +``` + +```{code-cell} ipython3 +x @ y # 另外一种计算内积的办法 +``` + +```{code-cell} ipython3 +np.sqrt(np.sum(x**2)) # x的范数,方法一 +``` + +```{code-cell} ipython3 +np.linalg.norm(x) # x的范数,方法二 +``` + +## 矩阵运算 + +```{index} single: Matrix; Operations +``` + +当我们讨论线性价格系统时,我们提到了使用矩阵代数。 +矩阵代数类似于数字代数。 +让我们回顾一些细节。 +### 加法和标量乘法 +就像向量一样,我们可以对矩阵进行加法、减法和标量乘法。 +标量乘法和加法是向量情况的推广: +以下是标量乘法的一个例子 +$$ +3 +\begin{bmatrix} + 2 & -13 \\ + 0 & 5 +\end{bmatrix} += +\begin{bmatrix} + 6 & -39 \\ + 0 & 15 +\end{bmatrix}. +$$ +一般来说,对于任意数 $\gamma$ 和任意矩阵 $A$, +$$ +\gamma A = +\gamma +\begin{bmatrix} + a_{11} & \cdots & a_{1k} \\ + \vdots & \vdots & \vdots \\ + a_{n1} & \cdots & a_{nk} +\end{bmatrix} := +\begin{bmatrix} + \gamma a_{11} & \cdots & \gamma a_{1k} \\ + \vdots & \vdots & \vdots \\ + \gamma a_{n1} & \cdots & \gamma a_{nk} +\end{bmatrix}. +$$ +考虑这个矩阵加法的例子, +$$ +\begin{bmatrix} + 1 & 5 \\ + 7 & 3 \\ +\end{bmatrix} ++ +\begin{bmatrix} + 12 & -1 \\ + 0 & 9 +\end{bmatrix} += +\begin{bmatrix} + 13 & 4 \\ + 7 & 12 +\end{bmatrix}. +$$ +一般来说, +$$ +A + B = +\begin{bmatrix} + a_{11} & \cdots & a_{1k} \\ + \vdots & \vdots & \vdots \\ + a_{n1} & \cdots & a_{nk} +\end{bmatrix} + +\begin{bmatrix} + b_{11} & \cdots & b_{1k} \\ + \vdots & \vdots & \vdots \\ + b_{n1} & \cdots & b_{nk} +\end{bmatrix} := +\begin{bmatrix} + a_{11} + b_{11} & \cdots & a_{1k} + b_{1k} \\ + \vdots & \vdots & \vdots \\ + a_{n1} + b_{n1} & \cdots & a_{nk} + b_{nk} +\end{bmatrix}. +$$ +在后一种情况下,矩阵必须具有相同的形状才能使定义有意义。 +### 矩阵乘法 +我们还有一个*相乘*两个矩阵的约定。 +矩阵乘法的规则推广了上面讨论的内积的概念。 +如果 $A$ 和 $B$ 是两个矩阵,那么它们的乘积 $A B$ 的形成是通过取 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列的内积作为其第 $i,j$ 个元素。 +如果 $A$ 是 $n \times k$ 的,$B$ 是 $j \times m$ 的,那么要相乘 $A$ 和 $B$,我们需要 $k = j$,而得到的矩阵 $A B$ 是 $n \times m$ 的。 +这里是一个 $2 \times 2$ 矩阵乘以 $2 \times 1$ 向量的例子。 +$$ +Ax = +\begin{bmatrix} + \color{red}{a_{11}} & \color{red}{a_{12}} \\ + a_{21} & a_{22} +\end{bmatrix} +\begin{bmatrix} + \color{red}{x_1} \\ + \color{red}{x_2} +\end{bmatrix} += +\begin{bmatrix} + \color{red}{a_{11}x_1 + a_{12}x_2} \\ + a_{21}x_1 + a_{22}x_2 +\end{bmatrix} +$$ +作为一个重要的特殊情况,考虑将 $n \times k$ 矩阵 $A$ 和 $k \times 1$ 列向量 $x$ 相乘。 +根据前面的规则,这给我们一个 $n \times 1$ 列向量。 + +```{math} +:label: la_atx + +A x = +{\begin{bmatrix} + a_{11} & a_{12} & \cdots & a_{1k} \\ + \vdots & \vdots & & \vdots \\ + \color{red}{a_{i1}} & \color{red}{a_{i2}} & \color{red}{\cdots} & \color{red}{a_{i}k} \\ + \vdots & \vdots & & \vdots \\ + a_{n1} & a_{n2} & \cdots & a_{nk} +\end{bmatrix}}_{n \times k} +{\begin{bmatrix} + \color{red}{x_{1}} \\ + \color{red}{x_{2}} \\ + \color{red}{\vdots} \\ + \color{red}{\vdots} \\ + \color{red}{x_{k}} +\end{bmatrix}}_{k \times 1} := +{\begin{bmatrix} + a_{11} x_1 + a_{22} x_2 + \cdots + a_{1k} x_k \\ + \vdots \\ + \color{red}{a_{i1} x_1 + a_{i2} x_2 + \cdots + a_{ik} x_k} \\ + \vdots \\ + a_{n1} x_1 + a_{n2} x_2 + \cdots + a_{nk} x_k +\end{bmatrix}}_{n \times 1} +``` + +下面展示了两个矩阵的乘法。 + +$$ +AB = +\begin{bmatrix} + a_{11} & a_{12} \\ + \color{red}{a_{21}} & \color{red}{a_{22}} \\ +\end{bmatrix} +\begin{bmatrix} + b_{11} & \color{red}{b_{12}} \\ + b_{21} & \color{red}{b_{22}} \\ +\end{bmatrix} := +\begin{bmatrix} + a_{11}b_{11} + a_{12}b_{21} & a_{11}b_{12} + a_{12}b_{22} \\ + a_{21}b_{11} + a_{22}b_{21} & \color{red}{a_{21}b_{12} + a_{22}b_{22}} +\end{bmatrix} +$$ + +有许多教程可以帮助你进一步可视化这个操作,例如 +* [这个教程](http://www.mathsisfun.com/algebra/matrix-multiplying.html),或者 +* [维基百科页面](https://en.wikipedia.org/wiki/Matrix_multiplication)上的讨论。 + +```{note} +与数字乘积不同,$A B$ 和 $B A$ 通常不是同一件事。 +``` + +一个重要的特殊情况是[单位矩阵](https://en.wikipedia.org/wiki/Identity_matrix),它在主对角线上有 1,其他地方都是 0: +$$ + I = + \begin{bmatrix} + 1 & \cdots & 0 \\ + \vdots & \ddots & \vdots \\ + 0 & \cdots & 1 + \end{bmatrix} +$$ +验证以下内容是一个有用的练习: +* 如果 $A$ 是 $n \times k$ 矩阵,$I$ 是 $k \times k$ 单位矩阵,那么 $AI = A$,并且 +* 如果 $I$ 是 $n \times n$ 单位矩阵,那么 $IA = A$。 + + +### NumPy中的矩阵 + +```{index} single: Matrix; Numpy +``` +NumPy 数组也被用作矩阵,并且对所有标准矩阵运算都有快速、高效的函数和方法。 +你可以通过以下方式从元组的元组(或列表的列表)手动创建它们 + +```{code-cell} ipython3 +A = ((1, 2), + (3, 4)) + +type(A) +``` + +```{code-cell} ipython3 +A = np.array(A) + +type(A) +``` + +```{code-cell} ipython3 +A.shape +``` + +`shape` 属性是一个给出行数和列数的元组 --- +更多讨论请参见[这里](https://python-programming.quantecon.org/numpy.html#shape-and-dimension)。 +要获得 `A` 的转置,使用 `A.transpose()` 或更简单地使用 `A.T`。 +有许多方便的函数用于创建常见矩阵(零矩阵、单位矩阵等) --- 请参见[这里](https://python-programming.quantecon.org/numpy.html#creating-arrays)。 +由于默认情况下操作是按元素执行的,标量乘法和加法具有非常自然的语法。 + +```{code-cell} ipython3 +A = np.identity(3) # 3 x 3 单位矩阵 +B = np.ones((3, 3)) # 3 x 3 元素为一的矩阵 +2 * A +``` + +```{code-cell} ipython3 +A + B +``` + +我们用 `@` 来进行矩阵乘法。 + + +```{note} +其中 `A @ B` 是矩阵乘法, 但是 `A * B`是每个元素之间的运算。 +``` + +### 矩阵形式的两种商品模型 +我们现在可以重新审视两种商品模型,并通过矩阵代数数值求解 {eq}`two_equilibrium` 方程。 +这涉及一些额外的步骤,但这种方法广泛适用 --- 正如我们在包含更多商品时将看到的那样。 +首先,我们将 {eq}`two_eq_demand` 重写为 + +```{math} +:label: two_eq_demand_mat + q^d = D p + h + \quad \text{where} \quad + q^d = + \begin{bmatrix} + q_0^d \\ + q_1^d + \end{bmatrix} + \quad + D = + \begin{bmatrix} + -10 & - 5 \\ + - 1 & - 10 + \end{bmatrix} + \quad \text{and} \quad + h = + \begin{bmatrix} + 100 \\ + 50 + \end{bmatrix}. +``` +回想一下,$p \in \mathbb{R}^{2}$ 是两种商品的价格。 +(请检查 $q^d = D p + h$ 是否表示与 {eq}`two_eq_demand` 相同的方程。) +我们将 {eq}`two_eq_supply` 重写为 + +```{math} +:label: two_eq_supply_mat + q^s = C p + \quad \text{where} \quad + q^s = + \begin{bmatrix} + q_0^s \\ + q_1^s + \end{bmatrix} + \quad \text{and} \quad + C = + \begin{bmatrix} + 10 & 5 \\ + 5 & 10 + \end{bmatrix}. +``` + +现在供给和需求的相等可以表示为 $q^s = q^d$,或 +$$ + C p = D p + h. +$$ +我们可以重新排列这些项得到 +$$ + (C - D) p = h. +$$ +如果所有项都是数字,我们可以求解价格为 $p = h / (C-D)$。 +矩阵代数允许我们做类似的事情:我们可以使用 $C - D$ 的逆矩阵来求解均衡价格: + +```{math} +:label: two_matrix + p = (C - D)^{-1} h. +``` + +在我们实施解决方案之前,让我们考虑一个更一般的设置。 + +### 更多商品 +考虑有更多商品的需求系统是很自然的。 +例如,即使在能源商品中也有许多不同的商品, +包括原油、汽油、煤炭、天然气、乙醇和铀。 +这些商品的价格是相关的,所以一起研究它们是有意义的。 +对于大型系统,纸笔方法会变得非常耗时。 +但幸运的是,上面描述的矩阵方法基本上保持不变。 + +一般来说,我们可以将需求方程写为 $q^d = Dp + h$,其中 +* $q^d$ 是一个 $n \times 1$ 的向量,表示 $n$ 种不同商品的需求量。 +* $D$ 是一个 $n \times n$ 的"系数"矩阵。 +* $h$ 是一个 $n \times 1$ 的常数值向量。 + +类似地,我们可以将供给方程写为 $q^s = Cp + e$,其中 +* $q^s$ 是一个 $n \times 1$ 的向量,表示相同商品的供给量。 +* $C$ 是一个 $n \times n$ 的"系数"矩阵。 +* $e$ 是一个 $n \times 1$ 的常数值向量。 + +为了找到均衡,我们求解 $Dp + h = Cp + e$,或 + +```{math} +:label: n_eq_sys_la + (D- C)p = e - h. +``` + +那么,n 种不同商品的价格向量是 +$$ + p = (D- C)^{-1}(e - h). +$$ + +### 一般线性系统 +上述问题的一个更一般版本看起来如下。 + +```{math} +:label: la_se + +\begin{matrix} + a_{11} x_1 & + & a_{12} x_2 & + & \cdots & + & a_{1n} x_n & = & b_1 \\ + \vdots & & \vdots & & & & \vdots & & \vdots \\ + a_{n1} x_1 & + & a_{n2} x_2 & + & \cdots & + & a_{nn} x_n & = & b_n +\end{matrix} +``` + +这里的目标是解出"未知数" $x_1, \ldots, x_n$。 +我们给定系数 $a_{11}, \ldots, a_{nn}$ 和常数 $b_1, \ldots, b_n$。 +注意,我们处理的是未知数数量等于方程数量的情况。 +这是我们最有可能找到明确定义解的情况。 +(其他情况被称为[超定](https://en.wikipedia.org/wiki/Overdetermined_system)和[欠定](https://en.wikipedia.org/wiki/Underdetermined_system)方程组 --- 我们将在后续讲座中讨论这些情况。) +用矩阵形式表示,方程组 {eq}`la_se` 变为 + +```{math} +:label: la_gf + A x = b + \quad \text{where} \quad + A = + \begin{bmatrix} + a_{11} & \cdots & a_{1n} \\ + \vdots & \vdots & \vdots \\ + a_{n1} & \cdots & a_{nn} + \end{bmatrix} + \quad \text{and} \quad + b = + \begin{bmatrix} + b_1 \\ + \vdots \\ + b_n + \end{bmatrix}. +``` +例如,{eq}`n_eq_sys_la` 具有这种形式,其中 +$$ + A = D - C, + \quad + b = e - h + \quad \text{和} \quad + x = p. +$$ +当考虑诸如 {eq}`la_gf` 这样的问题时,我们至少需要问以下一些问题: +* 解是否真的存在? +* 如果解存在,我们应该如何计算它? + +## 解方程组 + +```{index} single: Matrix; Solving Systems of Equations +``` + +再次回顾方程组 {eq}`la_se`,我们在此重新写为 + +```{math} +:label: la_se2 + A x = b. +``` +我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 +{eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 +我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 +我们在下面举例说明两种这样的情况。 +### 无解 +考虑由以下给出的方程组: +$$ +\begin{aligned} + x + 3y &= 3 \\ + 2x + 6y &= -8. +\end{aligned} +$$ +可以手动验证这个系统没有可能的解。 +为了说明为什么会出现这种情况,让我们绘制这两条直线。 + +```{code-cell} ipython3 +fig, ax = plt.subplots() +x = np.linspace(-10, 10) +plt.plot(x, (3-x)/3, label=f'$x + 3y = 3$') +plt.plot(x, (-8-2*x)/6, label=f'$2x + 6y = -8$') +plt.legend() +plt.show() +``` + ++++ {"tags": []} + + +显然,这些是平行线,因此我们永远无法找到一个点 $x \in \mathbb{R}^2$ 使得这些线相交。 +因此,这个系统没有可能的解。 +我们可以将这个系统用矩阵形式重写为 + +```{math} +:label: no_soln + A x = b + \quad \text{where} \quad + A = + \begin{bmatrix} + 1 & 3 \\ + 2 & 6 + \end{bmatrix} + \quad \text{and} \quad + b = + \begin{bmatrix} + 3 \\ + -8 + \end{bmatrix}. +``` + +可以注意到,矩阵 $A$ 的第 $2$ 行 $(2, 6)$ 只是第 $1$ 行 $(1, 3)$ 的标量倍数。 +在这种情况下,矩阵 $A$ 的行被称为**线性相关的。** + +```{note} +高级读者可以在[这里](https://python.quantecon.org/linear_algebra.html#linear-independence)找到关于线性相关和线性无关的详细解释。 +但在接下来的内容中不需要这些细节。 + +``` + + +### 多解 +现在考虑, +$$ +\begin{aligned} + x - 2y &= -4 \\ + -2x + 4y &= 8. +\end{aligned} +$$ +任何满足 $x = 2y - 4$ 的向量 $v = (x,y)$ 都将解决上述系统。 +由于我们可以找到无限多个这样的向量,这个系统有无穷多个解。 +这是因为对应矩阵的行 + +```{math} +:label: many_solns + A = + \begin{bmatrix} + 1 & -2 \\ + -2 & 4 + \end{bmatrix}. +``` + +是线性相关的 --- 你能看出为什么吗? +我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 +### 非奇异矩阵 +对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 +对于 $2 \times 2$ 矩阵,行列式由以下公式给出: +$$ +\begin{bmatrix} + \color{red}{a} & \color{blue}{b} \\ + \color{blue}{c} & \color{red}{d} +\end{bmatrix} += +{\color{red}{ad}} - {\color{blue}{bc}}. +$$ +如果 $A$ 的行列式不为零,我们就说 $A$ 是*非奇异的*。 +当且仅当 $A$ 的行和列是线性无关的,方阵 $A$ 才是非奇异的。 +关于矩阵逆的更详细解释可以在[这里](https://www.mathsisfun.com/algebra/matrix-inverse.html)找到。 +你可以自己检查 {eq}`no_soln` 和 {eq}`many_solns` 中具有线性相关行的矩阵是奇异矩阵。 +这为我们提供了一个有用的单数值概括,用来判断一个方阵是否可逆。 +特别地,方阵 $A$ 具有非零行列式,当且仅当它具有*逆矩阵* $A^{-1}$,满足 $A A^{-1} = A^{-1} A = I$。 +因此,如果我们用 $A^{-1}$ 左乘 $Ax = b$ 的两边,我们得到 + +```{math} +:label: la_se_inv + x = A^{-1} b. +``` + +这是对 $Ax = b$ 的解答 --- 这就是我们要寻找的解。 + +### 使用NumPy求解线性方程 +```{index} single: Linear Algebra; SciPy +``` + +在两个好的例子中,我们得到了矩阵方程: +$$ +p = (C-D)^{-1} h. +$$ +其中 $C$、$D$ 和 $h$ 由 {eq}`two_eq_demand_mat` 和 {eq}`two_eq_supply_mat` 给出。 +这个方程类似于 {eq}`la_se_inv`,其中 $A = (C-D)^{-1}$,$b = h$,且 $x = p$。 +我们现在可以使用NumPy的`linalg`子模块求解均衡价格。 +所有这些程序都是经过时间检验和高度优化的FORTRAN代码的Python前端。 + +```{code-cell} ipython3 +C = ((10, 5), # 矩阵 C + (5, 10)) +``` + +Now we change this to a NumPy array. + +```{code-cell} ipython3 +C = np.array(C) +``` + +```{code-cell} ipython3 +D = ((-10, -5), # 矩阵 D + (-1, -10)) +D = np.array(D) +``` + +```{code-cell} ipython3 +h = np.array((100, 50)) # 向量 h +h.shape = 2,1 # 将h转换为列向量 +``` + +```{code-cell} ipython3 +from numpy.linalg import det, inv +A = C - D +#检查A是否为奇异矩阵(行列式是否为零),是否可逆 +det(A) +``` + +```{code-cell} ipython3 +A_inv = inv(A) #计算逆矩阵 +A_inv +``` + +```{code-cell} ipython3 +p = A_inv @ h #均衡价格 +p +``` + +```{code-cell} ipython3 +q = C @ p # 均衡数量 +q +``` + +注意,我们得到的解与纸笔计算的情况相同。 +我们还可以使用 `solve(A, h)` 来求解 $p$,如下所示。 + +```{code-cell} ipython3 +from numpy.linalg import solve +p = solve(A, h) # 均衡价格 +p +``` + +```{code-cell} ipython3 +q = C @ p # 均衡数量 +q +``` +观察我们如何通过 `inv(A) @ y` 或使用 `solve(A, y)` 来求解 $x = A^{-1} y$。 +后一种方法使用了一种不同的算法,在数值上更加稳定,因此应该是默认选项。 + + +## 练习 +```{exercise-start} +:label: lin_eqs_ex1 +``` +让我们考虑一个有3种商品的市场 - 商品0、商品1和商品2。 +每种商品的需求取决于其他两种商品的价格,由以下公式给出: +$$ +\begin{aligned} + q_0^d & = 90 - 15p_0 + 5p_1 + 5p_2 \\ + q_1^d & = 60 + 5p_0 - 10p_1 + 10p_2 \\ + q_2^d & = 50 + 5p_0 + 5p_1 - 5p_2 +\end{aligned} +$$ +(这里,当自身价格上涨时需求下降,但当其他商品价格上涨时需求增加。) +每种商品的供给由以下公式给出: +$$ +\begin{aligned} + q_0^s & = -10 + 20p_0 \\ + q_1^s & = -15 + 15p_1 \\ + q_2^s & = -5 + 10p_2 +\end{aligned} +$$ +当供给等于需求时,市场达到均衡,即 $q_0^d = q_0^s$,$q_1^d = q_1^s$ 和 $q_2^d = q_2^s$。 +1. 将市场设置为线性方程组。 +2. 使用矩阵代数求解均衡价格。分别使用 `numpy.linalg.solve` 和 `inv(A)` 方法来做这个。比较这两种解法。 + +```{exercise-end} +``` +```{solution-start} lin_eqs_ex1 +:class: dropdown +``` +生成的系统将是: +$$ +\begin{aligned} + 35p_0 - 5p_1 - 5p_2 = 100 \\ + -5p_0 + 25p_1 - 10p_2 = 75 \\ + -5p_0 - 5p_1 + 15p_2 = 55 +\end{aligned} +$$ +用矩阵形式,我们将其表示为: +$$ +Ap = b +\quad \text{其中} \quad +A = +\begin{bmatrix} + 35 & -5 & -5 \\ + -5 & 25 & -10 \\ + -5 & -5 & 15 +\end{bmatrix} +, \quad p = +\begin{bmatrix} + p_0 \\ + p_1 \\ + p_2 +\end{bmatrix} +\quad \text{且} \quad +b = +\begin{bmatrix} + 100 \\ + 75 \\ + 55 +\end{bmatrix} +$$ + +```{code-cell} +import numpy as np +from numpy.linalg import det + +A = np.array([[35, -5, -5], # 矩阵 A + [-5, 25, -10], + [-5, -5, 15]]) + +b = np.array((100, 75, 55)) # 列向量 b +b.shape = (3, 1) + +det(A) # 检查A是否为奇异矩阵 +``` + +```{code-cell} +# 使用inverse +from numpy.linalg import det + +A_inv = inv(A) + +p = A_inv @ b +p +``` + +```{code-cell} +# 使用 numpy.linalg.solve +from numpy.linalg import solve +p = solve(A, b) +p +``` + +答案为: +$$ +p_0 = 4.6925, \; p_1 = 7.0625 \;\; \text{and} \;\; p_2 = 7.675 +$$ + +```{solution-end} +``` + +```{exercise-start} +:label: lin_eqs_ex2 +``` +在讲座的早些时候,我们讨论了$Ax = b$这个方程组没有解的情况。 +在这种情况下,$Ax = b$被称为*不相容*方程组。 +面对不相容系统时,我们尝试找到最佳的"近似"解。 +有多种方法可以做到这一点,其中一种是**最小二乘法**。 +假设我们有一个不相容系统 + +```{math} +:label: inconsistent + Ax = b +``` + +其中$A$是一个$m \times n$矩阵,$b$是一个$m \times 1$列向量。 +对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 +小于$Ax$到$b$的距离。 +即, +$$ + \|A\hat{x} - b\| \leq \|Ax - b\| +$$ +可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 + +```{math} +:label: least_squares + \hat{x} = (A^T A)^{-1} A^T b +``` + +现在考虑一种商品的线性需求曲线的一般方程: +$$ + p = m - nq +$$ +其中$p$是商品的价格,$q$是需求量。 +假设我们正试图*估计*$m$和$n$的值。 +我们通过重复观察价格和数量(例如,每个月)来做到这一点,然后选择$m$和$n$来拟合$p$和$q$之间的关系。 +我们有以下观察结果: +| 价格 | 需求量 | +|:-----:|:-----------------:| +| 1 | 9 | +| 3 | 7 | +| 8 | 3 | +要求需求曲线$p = m - nq$通过所有这些点,得到以下三个方程: +$$ +\begin{aligned} + 1 = m - 9n \\ + 3 = m - 7n \\ + 8 = m - 3n +\end{aligned} +$$ +因此,我们得到一个方程组$Ax = b$,其中$A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, +$x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$。 +可以验证这个系统没有解。 +(问题在于我们有三个方程但只有两个未知数。) +因此,我们将尝试找到$x$的最佳近似解。 +1. 使用{eq}`least_squares`和矩阵代数找到最小二乘解$\hat{x}$。 +2. 使用`numpy.linalg.lstsq`找到最小二乘解,并比较结果。 + + +```{exercise-end} +``` + +```{solution-start} lin_eqs_ex2 +:class: dropdown +``` + +```{code-cell} ipython3 +import numpy as np +from numpy.linalg import inv +``` + +```{code-cell} ipython3 +# 运用线性代数 +A = np.array([[1, -9], # 矩阵 A + [1, -7], + [1, -3]]) + +A_T = np.transpose(A) # 矩阵A的转置 + +b = np.array((1, 3, 8)) # 列向量 b +b.shape = (3, 1) + +x = inv(A_T @ A) @ A_T @ b +x +``` + +```{code-cell} ipython3 +# 使用 numpy.linalg.lstsq +x, res, _, _ = np.linalg.lstsq(A, b, rcond=None) +``` + +```{code-cell} ipython3 +:tags: [hide-input] + +print(f"x\u0302 = {x}") +print(f"\u2016Ax\u0302 - b\u2016\u00B2 = {res[0]}") +``` +这是一个可视化图,展示了最小二乘法如何近似一组点之间连线的方程。 +我们也可以将此描述为在一组点之间"拟合"一条直线。 + + +```{code-cell} ipython3 +fig, ax = plt.subplots() +p = np.array((1, 3, 8)) +q = np.array((9, 7, 3)) + +a, b = x + +ax.plot(q, p, 'o', label='观测点', markersize=5) +ax.plot(q, a - b*q, 'r', label='拟合线') +plt.xlabel('需求数量') +plt.ylabel('价格') +plt.legend() +plt.show() +``` + +```{solution-end} +``` + +### 延伸阅读 +`numpy.linalg` 子模块的文档可以在[这里](https://numpy.org/devdocs/reference/routines.linalg.html)找到。 +线性代数的更高级主题可以在[这里](https://python.quantecon.org/linear_algebra.html#id5)找到。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d0f6db0d5ede9c4a32239a95e6c592deb2aa2c11 Mon Sep 17 00:00:00 2001 From: Longye Tian Date: Mon, 23 Sep 2024 18:11:30 +1000 Subject: [PATCH 2/7] update --- lectures/linear_equations.md | 868 +++++++++------------- lectures/linear_equations_cn.md | 1197 ------------------------------- 2 files changed, 338 insertions(+), 1727 deletions(-) delete mode 100644 lectures/linear_equations_cn.md diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index 4b9ccb0f..d6b7bcd3 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -11,62 +11,49 @@ kernelspec: name: python3 --- -# Linear Equations and Matrix Algebra +# 线性方程和矩阵代数 ```{index} single: Linear Equations and Matrix Algebra ``` -## Overview +## 概述 +经济学和金融学中的许多问题都需要解线性方程。 -Many problems in economics and finance require solving linear equations. +在本讲座中,我们将讨论线性方程及其应用。 -In this lecture we discuss linear equations and their applications. +为了说明线性方程的重要性,我们从一个两种商品的供需模型开始。 -To illustrate the importance of linear equations, we begin with a two good -model of supply and demand. +两种商品的情况非常简单,可以手动计算解。 -The two good case is so simple that solutions can be calculated by hand. +但我们经常需要考虑包含多种商品的市场。 -But often we need to consider markets containing many goods. +在多种商品的情况下,我们面对的是大型线性方程组,有许多方程和未知数。 -In the multiple goods case we face large systems of linear equations, with many equations -and unknowns. +为了处理这样的系统,我们需要两样东西: -To handle such systems we need two things: +* 矩阵代数(以及如何使用它的知识)以及 +* 将矩阵代数应用于感兴趣问题的计算机代码。 -* matrix algebra (and the knowledge of how to use it) plus -* computer code to apply matrix algebra to the problems of interest. +本讲座涵盖了这些步骤。 -This lecture covers these steps. - -We will use the following packages: +我们将使用以下的库: ```{code-cell} ipython3 import numpy as np import matplotlib.pyplot as plt ``` - -## A two good example - -In this section we discuss a simple two good example and solve it by - -1. pencil and paper -2. matrix algebra - -The second method is more general, as we will see. - - -### Pencil and paper methods - -Suppose that we have two related goods, such as - -* propane and ethanol, and -* rice and wheat, etc. - -To keep things simple, we label them as good 0 and good 1. - -The demand for each good depends on the price of both goods: - +## 两种商品的例子 +在本节中,我们将讨论一个简单的两种商品例子,并通过以下两种方法解决: +1. 纸笔计算 +2. 矩阵代数 +正如我们将看到的,第二种方法更具普遍性。 + +### 纸笔计算方法 +假设我们有两种相关的商品,比如: +* 丙烷和乙醇,或 +* 大米和小麦等。 +为了简化问题,我们将它们标记为商品0和商品1。 +每种商品的需求取决于两种商品的价格: ```{math} :label: two_eq_demand \begin{aligned} @@ -74,11 +61,8 @@ The demand for each good depends on the price of both goods: q_1^d = 50 - p_0 - 10 p_1 \end{aligned} ``` - -(We are assuming demand decreases when the price of either good goes up, but -other cases are also possible.) - -Let's suppose that supply is given by +(我们假设当任一商品的价格上涨时需求会下降,但其他情况也是可能的。) +让我们假设供给由以下方程给出: ```{math} :label: two_eq_supply @@ -87,10 +71,8 @@ Let's suppose that supply is given by q_1^s = 5 p_0 + 10 p_1 \end{aligned} ``` - -Equilibrium holds when supply equals demand ($q_0^s = q_0^d$ and $q_1^s = q_1^d$). - -This yields the linear system +当供给等于需求时($q_0^s = q_0^d$ 和 $q_1^s = q_1^d$),市场达到均衡。 +这产生了以下线性系统: ```{math} :label: two_equilibrium @@ -100,63 +82,42 @@ This yields the linear system \end{aligned} ``` -We can solve this with pencil and paper to get - +我们可以用纸笔计算得到: $$ - p_0 = 4.41 \quad \text{and} \quad p_1 = 1.18. + p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. $$ - -Inserting these results into either {eq}`two_eq_demand` or {eq}`two_eq_supply` yields the -equilibrium quantities - +将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: $$ - q_0 = 50 \quad \text{and} \quad q_1 = 33.82. + q_0 = 50 \quad \text{和} \quad q_1 = 33.82. $$ +### 展望未来 +在两种商品的情况下,纸笔计算方法很容易。 +但如果有很多种商品呢? +对于这样的问题,我们需要矩阵代数。 +在用矩阵代数解决问题之前,让我们先回顾一下向量和矩阵的基础知识,包括理论和计算。 -### Looking forward - -Pencil and paper methods are easy in the two good case. - -But what if there are many goods? - -For such problems we need matrix algebra. -Before solving problems with matrix algebra, let's first recall the -basics of vectors and matrices, in both theory and computation. - - - -## {index}`Vectors ` +## {index}`向量 ` ```{index} single: Linear Algebra; Vectors ``` -A **vector** of length $n$ is just a sequence (or array, or tuple) of $n$ numbers, which we write as $x = (x_1, \ldots, x_n)$ or $x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$. - -We can write these sequences either horizontally or vertically. - -But when we use matrix operations, our default assumption is that vectors are -column vectors. - -The set of all $n$-vectors is denoted by $\mathbb R^n$. - -```{prf:example} -:label: le_ex_dim - -* $\mathbb R^2$ is the plane --- the set of pairs $(x_1, x_2)$. -* $\mathbb R^3$ is 3 dimensional space --- the set of vectors $(x_1, x_2, x_3)$. -``` - -Often vectors are represented visually as arrows from the origin to the point. - -Here's a visualization. +一个长度为$n$的**向量**就是一个由$n$个数字组成的序列(或数组,或元组),我们将其写作$x = (x_1, \ldots, x_n)$或$x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$。 +我们可以将这些序列横向或纵向写出。 +但当我们使用矩阵运算时,我们默认假设向量是列向量。 +所有$n$维向量的集合用$\mathbb R^n$表示。 +例如, +* $\mathbb R^2$是平面 --- 即所有$(x_1, x_2)$对的集合。 +* $\mathbb R^3$是三维空间 --- 即所有$(x_1, x_2, x_3)$向量的集合。 +向量通常在视觉上表示为从原点到某点的箭头。 +这里是一个可视化示例。 ```{code-cell} ipython3 :tags: [hide-input] fig, ax = plt.subplots() -# Set the axes through the origin +# 通过原点建立坐标轴 for spine in ['left', 'bottom']: ax.spines[spine].set_position('zero') for spine in ['right', 'top']: @@ -175,21 +136,15 @@ for v in vecs: plt.show() ``` -### Vector operations +### 向量运算 ```{index} single: Vectors; Operations ``` -Sometimes we want to modify vectors. - -The two most common operators on vectors are addition and scalar -multiplication, which we now describe. - -When we add two vectors, we add them element-by-element. - -```{prf:example} -:label: le_ex_add - +有时我们需要修改向量。 +对向量最常见的两种运算是加法和标量乘法,我们现在来描述这两种运算。 +当我们对两个向量进行加法运算时,我们是逐元素相加。 +例如, $$ \begin{bmatrix} 4 \\ @@ -211,10 +166,7 @@ $$ 1 \end{bmatrix}. $$ -``` - -In general, - +一般来说, $$ x + y = \begin{bmatrix} @@ -236,14 +188,13 @@ x + y = x_n + y_n \end{bmatrix}. $$ - -We can visualise vector addition in $\mathbb{R}^2$ as follows. +我们可以在$\mathbb{R}^2$中将向量加法可视化如下。 ```{code-cell} ipython3 :tags: [hide-input] fig, ax = plt.subplots() -# Set the axes through the origin +# 通过原点建立坐标轴 for spine in ['left', 'bottom']: ax.spines[spine].set_position('zero') for spine in ['right', 'top']: @@ -275,11 +226,8 @@ for i, v in enumerate(vecs): plt.show() ``` -Scalar multiplication is an operation that multiplies a vector $x$ with a scalar elementwise. - -```{prf:example} -:label: le_ex_mul - +标量乘法是一种将向量 $x$ 与一个标量进行元素级别相乘的运算。 +例如, $$ -2 \begin{bmatrix} @@ -297,10 +245,7 @@ $$ 14 \end{bmatrix}. $$ -``` - -More generally, it takes a number $\gamma$ and a vector $x$ and produces - +更一般地,它取一个数 $\gamma$ 和一个向量 $x$,得到 $$ \gamma x := \begin{bmatrix} @@ -310,14 +255,13 @@ $$ \gamma x_n \end{bmatrix}. $$ - -Scalar multiplication is illustrated in the next figure. +标量乘法在下图中进行了说明。 ```{code-cell} ipython3 :tags: [hide-input] fig, ax = plt.subplots() -# Set the axes through the origin +# 通过原点建立坐标轴 for spine in ['left', 'bottom']: ax.spines[spine].set_position('zero') for spine in ['right', 'top']: @@ -346,26 +290,24 @@ for s in scalars: plt.show() ``` -In Python, a vector can be represented as a list or tuple, -such as `x = [2, 4, 6]` or `x = (2, 4, 6)`. +在Python中,向量可以用列表或元组表示, +例如 `x = [2, 4, 6]` 或 `x = (2, 4, 6]`。 +然而,更常见的是用 +[NumPy数组](https://python-programming.quantecon.org/numpy.html#numpy-arrays)来表示向量。 -However, it is more common to represent vectors with -[NumPy arrays](https://python-programming.quantecon.org/numpy.html#numpy-arrays). - -One advantage of NumPy arrays is that scalar multiplication and addition have -very natural syntax. +NumPy数组的一个优点是标量乘法和加法具有非常自然的语法。 ```{code-cell} ipython3 -x = np.ones(3) # Vector of three ones -y = np.array((2, 4, 6)) # Converts tuple (2, 4, 6) into a NumPy array -x + y # Add (element-by-element) +x = np.ones(3) # 三个元素为一的向量 +y = np.array((2, 4, 6)) # 将 (2, 4, 6) 转换为 NumPy 数组 +x + y # 每个元素相加 ``` ```{code-cell} -4 * x # Scalar multiply +4 * x # 标量乘法 ``` -### Inner product and norm +### 内积和范数 ```{index} single: Vectors; Inner Product ``` @@ -373,8 +315,7 @@ x + y # Add (element-by-element) ```{index} single: Vectors; Norm ``` -The **inner product** of vectors $x,y \in \mathbb R^n$ is defined as - +向量 $x,y \in \mathbb R^n$ 的**内积**定义为 $$ x^\top y = \begin{bmatrix} @@ -389,55 +330,41 @@ x^\top y = = {\color{red}{x_1 y_1}} + {\color{blue}{x_2 y_2}} + \cdots + x_n y_n := \sum_{i=1}^n x_i y_i. $$ - -The **norm** of a vector $x$ represents its "length" (i.e., its distance from -the zero vector) and is defined as - +向量 $x$ 的**范数**表示其"长度"(即,其与零向量的距离),定义为 $$ \| x \| := \sqrt{x^\top x} := \left( \sum_{i=1}^n x_i^2 \right)^{1/2}. $$ - -The expression $\| x - y\|$ can be thought of as the "distance" between $x$ and $y$. - -The inner product and norm can be computed as follows +表达式 $\| x - y\|$ 可以被理解为 $x$ 和 $y$ 之间的"距离"。 +内积和范数可以按以下方式计算 ```{code-cell} ipython3 -np.sum(x*y) # Inner product of x and y +np.sum(x*y) # x和y的内积 ``` ```{code-cell} ipython3 -x @ y # Another way to compute the inner product +x @ y # 另外一种计算内积的办法 ``` ```{code-cell} ipython3 -np.sqrt(np.sum(x**2)) # Norm of x, method one +np.sqrt(np.sum(x**2)) # x的范数,方法一 ``` ```{code-cell} ipython3 -np.linalg.norm(x) # Norm of x, method two +np.linalg.norm(x) # x的范数,方法二 ``` -## Matrix operations +## 矩阵运算 ```{index} single: Matrix; Operations ``` -When we discussed linear price systems, we mentioned using matrix algebra. - -Matrix algebra is similar to algebra for numbers. - -Let's review some details. - -### Addition and scalar multiplication - -Just as was the case for vectors, we can add, subtract and scalar multiply -matrices. - -Scalar multiplication and addition are generalizations of the vector case: - -```{prf:example} -:label: le_ex_asm - +当我们讨论线性价格系统时,我们提到了使用矩阵代数。 +矩阵代数类似于数字代数。 +让我们回顾一些细节。 +### 加法和标量乘法 +就像向量一样,我们可以对矩阵进行加法、减法和标量乘法。 +标量乘法和加法是向量情况的推广: +以下是标量乘法的一个例子 $$ 3 \begin{bmatrix} @@ -450,10 +377,7 @@ $$ 0 & 15 \end{bmatrix}. $$ -``` - -In general for a number $\gamma$ and any matrix $A$, - +一般来说,对于任意数 $\gamma$ 和任意矩阵 $A$, $$ \gamma A = \gamma @@ -468,12 +392,7 @@ $$ \gamma a_{n1} & \cdots & \gamma a_{nk} \end{bmatrix}. $$ - -```{prf:example} -:label: le_ex_ma - -Consider this example of matrix addition, - +考虑这个矩阵加法的例子, $$ \begin{bmatrix} 1 & 5 \\ @@ -490,10 +409,7 @@ $$ 7 & 12 \end{bmatrix}. $$ -``` - -In general, - +一般来说, $$ A + B = \begin{bmatrix} @@ -512,29 +428,13 @@ A + B = a_{n1} + b_{n1} & \cdots & a_{nk} + b_{nk} \end{bmatrix}. $$ - -In the latter case, the matrices must have the same shape in order for the -definition to make sense. - -### Matrix multiplication - -We also have a convention for *multiplying* two matrices. - -The rule for matrix multiplication generalizes the idea of inner products -discussed above. - -If $A$ and $B$ are two matrices, then their product $A B$ is formed by taking -as its $i,j$-th element the inner product of the $i$-th row of $A$ and the -$j$-th column of $B$. - -If $A$ is $n \times k$ and $B$ is $j \times m$, then to multiply $A$ and $B$ -we require $k = j$, and the resulting matrix $A B$ is $n \times m$. - -```{prf:example} -:label: le_ex_2dmul - -Here's an example of a $2 \times 2$ matrix multiplied by a $2 \times 1$ vector. - +在后一种情况下,矩阵必须具有相同的形状才能使定义有意义。 +### 矩阵乘法 +我们还有一个*相乘*两个矩阵的约定。 +矩阵乘法的规则推广了上面讨论的内积的概念。 +如果 $A$ 和 $B$ 是两个矩阵,那么它们的乘积 $A B$ 的形成是通过取 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列的内积作为其第 $i,j$ 个元素。 +如果 $A$ 是 $n \times k$ 的,$B$ 是 $j \times m$ 的,那么要相乘 $A$ 和 $B$,我们需要 $k = j$,而得到的矩阵 $A B$ 是 $n \times m$ 的。 +这里是一个 $2 \times 2$ 矩阵乘以 $2 \times 1$ 向量的例子。 $$ Ax = \begin{bmatrix} @@ -551,12 +451,8 @@ Ax = a_{21}x_1 + a_{22}x_2 \end{bmatrix} $$ -``` - -As an important special case, consider multiplying $n \times k$ -matrix $A$ and $k \times 1$ column vector $x$. - -According to the preceding rule, this gives us an $n \times 1$ column vector. +作为一个重要的特殊情况,考虑将 $n \times k$ 矩阵 $A$ 和 $k \times 1$ 列向量 $x$ 相乘。 +根据前面的规则,这给我们一个 $n \times 1$ 列向量。 ```{math} :label: la_atx @@ -585,7 +481,7 @@ A x = \end{bmatrix}}_{n \times 1} ``` -Here is a simple illustration of multiplication of two matrices. +下面展示了两个矩阵的乘法。 $$ AB = @@ -603,18 +499,15 @@ AB = \end{bmatrix} $$ -There are many tutorials to help you further visualize this operation, such as - -* [this one](http://www.mathsisfun.com/algebra/matrix-multiplying.html), or -* the discussion on the [Wikipedia page](https://en.wikipedia.org/wiki/Matrix_multiplication). - +有许多教程可以帮助你进一步可视化这个操作,例如 +* [这个教程](http://www.mathsisfun.com/algebra/matrix-multiplying.html),或者 +* [维基百科页面](https://en.wikipedia.org/wiki/Matrix_multiplication)上的讨论。 ```{note} -Unlike number products, $A B$ and $B A$ are not generally the same thing. +与数字乘积不同,$A B$ 和 $B A$ 通常不是同一件事。 ``` -One important special case is the [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix), which has ones on the principal diagonal and zero elsewhere: - +一个重要的特殊情况是[单位矩阵](https://en.wikipedia.org/wiki/Identity_matrix),它在主对角线上有 1,其他地方都是 0: $$ I = \begin{bmatrix} @@ -623,22 +516,17 @@ $$ 0 & \cdots & 1 \end{bmatrix} $$ +验证以下内容是一个有用的练习: +* 如果 $A$ 是 $n \times k$ 矩阵,$I$ 是 $k \times k$ 单位矩阵,那么 $AI = A$,并且 +* 如果 $I$ 是 $n \times n$ 单位矩阵,那么 $IA = A$。 -It is a useful exercise to check the following: - -* if $A$ is $n \times k$ and $I$ is the $k \times k$ identity matrix, then $AI = A$, and -* if $I$ is the $n \times n$ identity matrix, then $IA = A$. - - -### Matrices in NumPy +### NumPy中的矩阵 ```{index} single: Matrix; Numpy ``` - -NumPy arrays are also used as matrices, and have fast, efficient functions and methods for all the standard matrix operations. - -You can create them manually from tuples of tuples (or lists of lists) as follows +NumPy 数组也被用作矩阵,并且对所有标准矩阵运算都有快速、高效的函数和方法。 +你可以通过以下方式从元组的元组(或列表的列表)手动创建它们 ```{code-cell} ipython3 A = ((1, 2), @@ -657,20 +545,15 @@ type(A) A.shape ``` -The `shape` attribute is a tuple giving the number of rows and columns --- -see [here](https://python-programming.quantecon.org/numpy.html#shape-and-dimension) -for more discussion. - -To get the transpose of `A`, use `A.transpose()` or, more simply, `A.T`. - -There are many convenient functions for creating common matrices (matrices of zeros, -ones, etc.) --- see [here](https://python-programming.quantecon.org/numpy.html#creating-arrays). - -Since operations are performed elementwise by default, scalar multiplication and addition have very natural syntax. +`shape` 属性是一个给出行数和列数的元组 --- +更多讨论请参见[这里](https://python-programming.quantecon.org/numpy.html#shape-and-dimension)。 +要获得 `A` 的转置,使用 `A.transpose()` 或更简单地使用 `A.T`。 +有许多方便的函数用于创建常见矩阵(零矩阵、单位矩阵等) --- 请参见[这里](https://python-programming.quantecon.org/numpy.html#creating-arrays)。 +由于默认情况下操作是按元素执行的,标量乘法和加法具有非常自然的语法。 ```{code-cell} ipython3 -A = np.identity(3) # 3 x 3 identity matrix -B = np.ones((3, 3)) # 3 x 3 matrix of ones +A = np.identity(3) # 3 x 3 单位矩阵 +B = np.ones((3, 3)) # 3 x 3 元素为一的矩阵 2 * A ``` @@ -678,22 +561,17 @@ B = np.ones((3, 3)) # 3 x 3 matrix of ones A + B ``` -To multiply matrices we use the `@` symbol. +我们用 `@` 来进行矩阵乘法。 ```{note} -In particular, `A @ B` is matrix multiplication, whereas `A * B` is element-by-element multiplication. +其中 `A @ B` 是矩阵乘法, 但是 `A * B`是每个元素之间的运算。 ``` -### Two good model in matrix form - -We can now revisit the two good model and solve {eq}`two_equilibrium` -numerically via matrix algebra. - -This involves some extra steps but the method is widely applicable --- as we -will see when we include more goods. - -First we rewrite {eq}`two_eq_demand` as +### 矩阵形式的两种商品模型 +我们现在可以重新审视两种商品模型,并通过矩阵代数数值求解 {eq}`two_equilibrium` 方程。 +这涉及一些额外的步骤,但这种方法广泛适用 --- 正如我们在包含更多商品时将看到的那样。 +首先,我们将 {eq}`two_eq_demand` 重写为 ```{math} :label: two_eq_demand_mat @@ -717,12 +595,9 @@ First we rewrite {eq}`two_eq_demand` as 50 \end{bmatrix}. ``` - -Recall that $p \in \mathbb{R}^{2}$ is the price of two goods. - -(Please check that $q^d = D p + h$ represents the same equations as {eq}`two_eq_demand`.) - -We rewrite {eq}`two_eq_supply` as +回想一下,$p \in \mathbb{R}^{2}$ 是两种商品的价格。 +(请检查 $q^d = D p + h$ 是否表示与 {eq}`two_eq_demand` 相同的方程。) +我们将 {eq}`two_eq_supply` 重写为 ```{math} :label: two_eq_supply_mat @@ -741,76 +616,56 @@ We rewrite {eq}`two_eq_supply` as \end{bmatrix}. ``` -Now equality of supply and demand can be expressed as $q^s = q^d$, or - +现在供给和需求的相等可以表示为 $q^s = q^d$,或 $$ C p = D p + h. $$ - -We can rearrange the terms to get - +我们可以重新排列这些项得到 $$ (C - D) p = h. $$ - -If all of the terms were numbers, we could solve for prices as $p = h / -(C-D)$. - -Matrix algebra allows us to do something similar: we can solve for equilibrium -prices using the inverse of $C - D$: +如果所有项都是数字,我们可以求解价格为 $p = h / (C-D)$。 +矩阵代数允许我们做类似的事情:我们可以使用 $C - D$ 的逆矩阵来求解均衡价格: ```{math} :label: two_matrix p = (C - D)^{-1} h. ``` -Before we implement the solution let us consider a more general setting. - - - -### More goods - -It is natural to think about demand systems with more goods. - -For example, even within energy commodities there are many different goods, -including crude oil, gasoline, coal, natural gas, ethanol, and uranium. - -The prices of these goods are related, so it makes sense to study them -together. - -Pencil and paper methods become very time consuming with large systems. - -But fortunately the matrix methods described above are essentially unchanged. +在我们实施解决方案之前,让我们考虑一个更一般的设置。 -In general, we can write the demand equation as $q^d = Dp + h$, where +### 更多商品 +考虑有更多商品的需求系统是很自然的。 +例如,即使在能源商品中也有许多不同的商品, +包括原油、汽油、煤炭、天然气、乙醇和铀。 +这些商品的价格是相关的,所以一起研究它们是有意义的。 +对于大型系统,纸笔方法会变得非常耗时。 +但幸运的是,上面描述的矩阵方法基本上保持不变。 -* $q^d$ is an $n \times 1$ vector of demand quantities for $n$ different goods. -* $D$ is an $n \times n$ "coefficient" matrix. -* $h$ is an $n \times 1$ vector of constant values. +一般来说,我们可以将需求方程写为 $q^d = Dp + h$,其中 +* $q^d$ 是一个 $n \times 1$ 的向量,表示 $n$ 种不同商品的需求量。 +* $D$ 是一个 $n \times n$ 的"系数"矩阵。 +* $h$ 是一个 $n \times 1$ 的常数值向量。 -Similarly, we can write the supply equation as $q^s = Cp + e$, where +类似地,我们可以将供给方程写为 $q^s = Cp + e$,其中 +* $q^s$ 是一个 $n \times 1$ 的向量,表示相同商品的供给量。 +* $C$ 是一个 $n \times n$ 的"系数"矩阵。 +* $e$ 是一个 $n \times 1$ 的常数值向量。 -* $q^s$ is an $n \times 1$ vector of supply quantities for the same goods. -* $C$ is an $n \times n$ "coefficient" matrix. -* $e$ is an $n \times 1$ vector of constant values. - -To find an equilibrium, we solve $Dp + h = Cp + e$, or +为了找到均衡,我们求解 $Dp + h = Cp + e$,或 ```{math} :label: n_eq_sys_la (D- C)p = e - h. ``` -Then the price vector of the n different goods is - +那么,n 种不同商品的价格向量是 $$ p = (D- C)^{-1}(e - h). $$ - -### General linear systems - -A more general version of the problem described above looks as follows. +### 一般线性系统 +上述问题的一个更一般版本看起来如下。 ```{math} :label: la_se @@ -822,19 +677,12 @@ A more general version of the problem described above looks as follows. \end{matrix} ``` -The objective here is to solve for the "unknowns" $x_1, \ldots, x_n$. - -We take as given the coefficients $a_{11}, \ldots, a_{nn}$ and constants $b_1, \ldots, b_n$. - -Notice that we are treating a setting where the number of unknowns equals the -number of equations. - -This is the case where we are most likely to find a well-defined solution. - -(The other cases are referred to as [overdetermined](https://en.wikipedia.org/wiki/Overdetermined_system) and [underdetermined](https://en.wikipedia.org/wiki/Underdetermined_system) systems -of equations --- we defer discussion of these cases until later lectures.) - -In matrix form, the system {eq}`la_se` becomes +这里的目标是解出"未知数" $x_1, \ldots, x_n$。 +我们给定系数 $a_{11}, \ldots, a_{nn}$ 和常数 $b_1, \ldots, b_n$。 +注意,我们处理的是未知数数量等于方程数量的情况。 +这是我们最有可能找到明确定义解的情况。 +(其他情况被称为[超定](https://en.wikipedia.org/wiki/Overdetermined_system)和[欠定](https://en.wikipedia.org/wiki/Underdetermined_system)方程组 --- 我们将在后续讲座中讨论这些情况。) +用矩阵形式表示,方程组 {eq}`la_se` 变为 ```{math} :label: la_gf @@ -854,61 +702,43 @@ In matrix form, the system {eq}`la_se` becomes b_n \end{bmatrix}. ``` - -```{prf:example} -:label: le_ex_gls -For example, {eq}`n_eq_sys_la` has this form with - -$$ - A = D - C, +例如,{eq}`n_eq_sys_la` 具有这种形式,其中 +$$ + A = D - C, \quad b = e - h - \quad \text{and} \quad + \quad \text{和} \quad x = p. $$ -``` - -When considering problems such as {eq}`la_gf`, we need to ask at least some of -the following questions +当考虑诸如 {eq}`la_gf` 这样的问题时,我们至少需要问以下一些问题: +* 解是否真的存在? +* 如果解存在,我们应该如何计算它? -* Does a solution actually exist? -* If a solution exists, how should we compute it? - - - -## Solving systems of equations +## 解方程组 ```{index} single: Matrix; Solving Systems of Equations ``` -Recall again the system of equations {eq}`la_se`, which we write here again as +再次回顾方程组 {eq}`la_se`,我们在此重新写为 ```{math} :label: la_se2 A x = b. ``` - -The problem we face is to find a vector $x \in \mathbb R^n$ that solves -{eq}`la_se2`, taking $b$ and $A$ as given. - -We may not always find a unique vector $x$ that solves {eq}`la_se2`. - -We illustrate two such cases below. - -### No solution - -Consider the system of equations given by, - +我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 +{eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 +我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 +我们在下面举例说明两种这样的情况。 +### 无解 +考虑由以下给出的方程组: $$ \begin{aligned} x + 3y &= 3 \\ 2x + 6y &= -8. \end{aligned} $$ - -It can be verified manually that this system has no possible solution. - -To illustrate why this situation arises let's plot the two lines. +可以手动验证这个系统没有可能的解。 +为了说明为什么会出现这种情况,让我们绘制这两条直线。 ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -921,12 +751,10 @@ plt.show() +++ {"tags": []} -Clearly, these are parallel lines and hence we will never find a point $x \in \mathbb{R}^2$ -such that these lines intersect. -Thus, this system has no possible solution. - -We can rewrite this system in matrix form as +显然,这些是平行线,因此我们永远无法找到一个点 $x \in \mathbb{R}^2$ 使得这些线相交。 +因此,这个系统没有可能的解。 +我们可以将这个系统用矩阵形式重写为 ```{math} :label: no_soln @@ -945,38 +773,27 @@ We can rewrite this system in matrix form as \end{bmatrix}. ``` -It can be noted that the $2^{nd}$ row of matrix $A = (2, 6)$ is just a scalar multiple of the $1^{st}$ row of matrix $A = (1, 3)$. - -The rows of matrix $A$ in this case are called **linearly dependent.** - - +可以注意到,矩阵 $A$ 的第 $2$ 行 $(2, 6)$ 只是第 $1$ 行 $(1, 3)$ 的标量倍数。 +在这种情况下,矩阵 $A$ 的行被称为**线性相关的。** ```{note} -Advanced readers can find a detailed explanation of linear dependence and -independence [here](https://python.quantecon.org/linear_algebra.html#linear-independence). - -But these details are not needed in what follows. +高级读者可以在[这里](https://python.quantecon.org/linear_algebra.html#linear-independence)找到关于线性相关和线性无关的详细解释。 +但在接下来的内容中不需要这些细节。 ``` - -### Many solutions - -Now consider, - +### 多解 +现在考虑, $$ \begin{aligned} x - 2y &= -4 \\ -2x + 4y &= 8. \end{aligned} $$ - -Any vector $v = (x,y)$ such that $x = 2y - 4$ will solve the above system. - -Since we can find infinite such vectors this system has infinitely many solutions. - -This is because the rows of the corresponding matrix +任何满足 $x = 2y - 4$ 的向量 $v = (x,y)$ 都将解决上述系统。 +由于我们可以找到无限多个这样的向量,这个系统有无穷多个解。 +这是因为对应矩阵的行 ```{math} :label: many_solns @@ -987,18 +804,11 @@ This is because the rows of the corresponding matrix \end{bmatrix}. ``` -are linearly dependent --- can you see why? - -We now impose conditions on $A$ in {eq}`la_se2` that rule out these problems. - - -### Nonsingular matrices - -To every square matrix we can assign a unique number called the -[determinant](https://en.wikipedia.org/wiki/Determinant). - -For $2 \times 2$ matrices, the determinant is given by, - +是线性相关的 --- 你能看出为什么吗? +我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 +### 非奇异矩阵 +对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 +对于 $2 \times 2$ 矩阵,行列式由以下公式给出: $$ \begin{bmatrix} \color{red}{a} & \color{blue}{b} \\ @@ -1007,57 +817,36 @@ $$ = {\color{red}{ad}} - {\color{blue}{bc}}. $$ - -If the determinant of $A$ is not zero, then we say that $A$ is *nonsingular*. - -A square matrix $A$ is nonsingular if and only if the rows and columns of $A$ -are linearly independent. - -A more detailed explanation of matrix inverse can be found [here](https://www.mathsisfun.com/algebra/matrix-inverse.html). - -You can check yourself that the in {eq}`no_soln` and {eq}`many_solns` with -linearly dependent rows are singular matrices. - -This gives us a useful one-number summary of whether or not a square matrix -can be inverted. - -In particular, a square matrix $A$ has a nonzero determinant, if and only if -it possesses an *inverse matrix* $A^{-1}$, with the property that $A A^{-1} = -A^{-1} A = I$. - -As a consequence, if we pre-multiply both sides of $Ax = b$ by $A^{-1}$, we -get +如果 $A$ 的行列式不为零,我们就说 $A$ 是*非奇异的*。 +当且仅当 $A$ 的行和列是线性无关的,方阵 $A$ 才是非奇异的。 +关于矩阵逆的更详细解释可以在[这里](https://www.mathsisfun.com/algebra/matrix-inverse.html)找到。 +你可以自己检查 {eq}`no_soln` 和 {eq}`many_solns` 中具有线性相关行的矩阵是奇异矩阵。 +这为我们提供了一个有用的单数值概括,用来判断一个方阵是否可逆。 +特别地,方阵 $A$ 具有非零行列式,当且仅当它具有*逆矩阵* $A^{-1}$,满足 $A A^{-1} = A^{-1} A = I$。 +因此,如果我们用 $A^{-1}$ 左乘 $Ax = b$ 的两边,我们得到 ```{math} :label: la_se_inv x = A^{-1} b. ``` -This is the solution to $Ax = b$ --- the solution we are looking for. - - - -### Linear equations with NumPy +这是对 $Ax = b$ 的解答 --- 这就是我们要寻找的解。 +### 使用NumPy求解线性方程 ```{index} single: Linear Algebra; SciPy ``` -In the two good example we obtained the matrix equation, - +在两个好的例子中,我们得到了矩阵方程: $$ p = (C-D)^{-1} h. $$ - -where $C$, $D$ and $h$ are given by {eq}`two_eq_demand_mat` and {eq}`two_eq_supply_mat`. - -This equation is analogous to {eq}`la_se_inv` with $A = (C-D)^{-1}$, $b = h$, and $x = p$. - -We can now solve for equilibrium prices with NumPy's `linalg` submodule. - -All of these routines are Python front ends to time-tested and highly optimized FORTRAN code. +其中 $C$、$D$ 和 $h$ 由 {eq}`two_eq_demand_mat` 和 {eq}`two_eq_supply_mat` 给出。 +这个方程类似于 {eq}`la_se_inv`,其中 $A = (C-D)^{-1}$,$b = h$,且 $x = p$。 +我们现在可以使用NumPy的`linalg`子模块求解均衡价格。 +所有这些程序都是经过时间检验和高度优化的FORTRAN代码的Python前端。 ```{code-cell} ipython3 -C = ((10, 5), # Matrix C +C = ((10, 5), # 矩阵 C (5, 10)) ``` @@ -1068,69 +857,61 @@ C = np.array(C) ``` ```{code-cell} ipython3 -D = ((-10, -5), # Matrix D +D = ((-10, -5), # 矩阵 D (-1, -10)) D = np.array(D) ``` ```{code-cell} ipython3 -h = np.array((100, 50)) # Vector h -h.shape = 2,1 # Transforming h to a column vector +h = np.array((100, 50)) # 向量 h +h.shape = 2,1 # 将h转换为列向量 ``` ```{code-cell} ipython3 from numpy.linalg import det, inv A = C - D -# Check that A is nonsingular (non-zero determinant), and hence invertible +#检查A是否为奇异矩阵(行列式是否为零),是否可逆 det(A) ``` ```{code-cell} ipython3 -A_inv = inv(A) # compute the inverse +A_inv = inv(A) #计算逆矩阵 A_inv ``` ```{code-cell} ipython3 -p = A_inv @ h # equilibrium prices +p = A_inv @ h #均衡价格 p ``` ```{code-cell} ipython3 -q = C @ p # equilibrium quantities +q = C @ p # 均衡数量 q ``` -Notice that we get the same solutions as the pencil and paper case. - -We can also solve for $p$ using `solve(A, h)` as follows. +注意,我们得到的解与纸笔计算的情况相同。 +我们还可以使用 `solve(A, h)` 来求解 $p$,如下所示。 ```{code-cell} ipython3 from numpy.linalg import solve -p = solve(A, h) # equilibrium prices +p = solve(A, h) # 均衡价格 p ``` ```{code-cell} ipython3 -q = C @ p # equilibrium quantities +q = C @ p # 均衡数量 q ``` - -Observe how we can solve for $x = A^{-1} y$ by either via `inv(A) @ y`, or using `solve(A, y)`. - -The latter method uses a different algorithm that is numerically more stable and hence should be the default option. - +观察我们如何通过 `inv(A) @ y` 或使用 `solve(A, y)` 来求解 $x = A^{-1} y$。 +后一种方法使用了一种不同的算法,在数值上更加稳定,因此应该是默认选项。 -## Exercises - +## 练习 ```{exercise-start} :label: lin_eqs_ex1 ``` - -Let's consider a market with 3 commodities - good 0, good 1 and good 2. - -The demand for each good depends on the price of the other two goods and is given by: - +让我们考虑一个有3种商品的市场 - 商品0、商品1和商品2。 +每种商品的需求取决于其他两种商品的价格,由以下公式给出: $$ \begin{aligned} q_0^d & = 90 - 15p_0 + 5p_1 + 5p_2 \\ @@ -1138,11 +919,8 @@ $$ q_2^d & = 50 + 5p_0 + 5p_1 - 5p_2 \end{aligned} $$ - -(Here demand decreases when own price increases but increases when prices of other goods increase.) - -The supply of each good is given by: - +(这里,当自身价格上涨时需求下降,但当其他商品价格上涨时需求增加。) +每种商品的供给由以下公式给出: $$ \begin{aligned} q_0^s & = -10 + 20p_0 \\ @@ -1150,21 +928,16 @@ $$ q_2^s & = -5 + 10p_2 \end{aligned} $$ - -Equilibrium holds when supply equals demand, i.e, $q_0^d = q_0^s$, $q_1^d = q_1^s$ and $q_2^d = q_2^s$. - -1. Set up the market as a system of linear equations. -2. Use matrix algebra to solve for equilibrium prices. Do this using both the `numpy.linalg.solve` - and `inv(A)` methods. Compare the solutions. +当供给等于需求时,市场达到均衡,即 $q_0^d = q_0^s$,$q_1^d = q_1^s$ 和 $q_2^d = q_2^s$。 +1. 将市场设置为线性方程组。 +2. 使用矩阵代数求解均衡价格。分别使用 `numpy.linalg.solve` 和 `inv(A)` 方法来做这个。比较这两种解法。 ```{exercise-end} ``` ```{solution-start} lin_eqs_ex1 :class: dropdown ``` - -The generated system would be: - +生成的系统将是: $$ \begin{aligned} 35p_0 - 5p_1 - 5p_2 = 100 \\ @@ -1172,12 +945,10 @@ $$ -5p_0 - 5p_1 + 15p_2 = 55 \end{aligned} $$ - -In matrix form we will write this as: - +用矩阵形式,我们将其表示为: $$ Ap = b -\quad \text{where} \quad +\quad \text{其中} \quad A = \begin{bmatrix} 35 & -5 & -5 \\ @@ -1190,7 +961,7 @@ A = p_1 \\ p_2 \end{bmatrix} -\quad \text{and} \quad +\quad \text{且} \quad b = \begin{bmatrix} 100 \\ @@ -1203,18 +974,18 @@ $$ import numpy as np from numpy.linalg import det -A = np.array([[35, -5, -5], # matrix A +A = np.array([[35, -5, -5], # 矩阵 A [-5, 25, -10], [-5, -5, 15]]) -b = np.array((100, 75, 55)) # column vector b +b = np.array((100, 75, 55)) # 列向量 b b.shape = (3, 1) -det(A) # check if A is nonsingular +det(A) # 检查A是否为奇异矩阵 ``` ```{code-cell} -# Using inverse +# 使用inverse from numpy.linalg import det A_inv = inv(A) @@ -1224,13 +995,13 @@ p ``` ```{code-cell} -# Using numpy.linalg.solve +# 使用 numpy.linalg.solve from numpy.linalg import solve p = solve(A, b) p ``` -The solution is given by: +答案为: $$ p_0 = 4.6925, \; p_1 = 7.0625 \;\; \text{and} \;\; p_2 = 7.675 $$ @@ -1241,65 +1012,45 @@ $$ ```{exercise-start} :label: lin_eqs_ex2 ``` -Earlier in the lecture we discussed cases where the system of equations given by $Ax = b$ has no solution. - -In this case $Ax = b$ is called an _inconsistent_ system of equations. - -When faced with an inconsistent system we try to find the best "approximate" solution. - -There are various methods to do this, one such method is the **method of least squares.** - -Suppose we have an inconsistent system +在讲座的早些时候,我们讨论了$Ax = b$这个方程组没有解的情况。 +在这种情况下,$Ax = b$被称为*不相容*方程组。 +面对不相容系统时,我们尝试找到最佳的"近似"解。 +有多种方法可以做到这一点,其中一种是**最小二乘法**。 +假设我们有一个不相容系统 ```{math} :label: inconsistent Ax = b ``` -where $A$ is an $m \times n$ matrix and $b$ is an $m \times 1$ column vector. - -A **least squares solution** to {eq}`inconsistent` is an $n \times 1$ column vector $\hat{x}$ such that, for all other vectors $x \in \mathbb{R}^n$, the distance from $A\hat{x}$ to $b$ -is less than the distance from $Ax$ to $b$. - -That is, +其中$A$是一个$m \times n$矩阵,$b$是一个$m \times 1$列向量。 +对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 +小于$Ax$到$b$的距离。 +即, $$ \|A\hat{x} - b\| \leq \|Ax - b\| $$ - -It can be shown that, for the system of equations $Ax = b$, the least squares -solution $\hat{x}$ is +可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 ```{math} :label: least_squares \hat{x} = (A^T A)^{-1} A^T b ``` -Now consider the general equation of a linear demand curve of a good given by: - +现在考虑一种商品的线性需求曲线的一般方程: $$ p = m - nq $$ - -where $p$ is the price of the good and $q$ is the quantity demanded. - -Suppose we are trying to *estimate* the values of $m$ and $n$. - -We do this by repeatedly observing the price and quantity (for example, each -month) and then choosing $m$ and $n$ to fit the relationship between $p$ and -$q$. - -We have the following observations: - -| Price | Quantity Demanded | +其中$p$是商品的价格,$q$是需求量。 +假设我们正试图*估计*$m$和$n$的值。 +我们通过重复观察价格和数量(例如,每个月)来做到这一点,然后选择$m$和$n$来拟合$p$和$q$之间的关系。 +我们有以下观察结果: +| 价格 | 需求量 | |:-----:|:-----------------:| | 1 | 9 | | 3 | 7 | | 8 | 3 | - - -Requiring the demand curve $p = m - nq$ to pass through all these points leads to the -following three equations: - +要求需求曲线$p = m - nq$通过所有这些点,得到以下三个方程: $$ \begin{aligned} 1 = m - 9n \\ @@ -1307,18 +1058,14 @@ $$ 8 = m - 3n \end{aligned} $$ +因此,我们得到一个方程组$Ax = b$,其中$A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, +$x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$。 +可以验证这个系统没有解。 +(问题在于我们有三个方程但只有两个未知数。) +因此,我们将尝试找到$x$的最佳近似解。 +1. 使用{eq}`least_squares`和矩阵代数找到最小二乘解$\hat{x}$。 +2. 使用`numpy.linalg.lstsq`找到最小二乘解,并比较结果。 -Thus we obtain a system of equations $Ax = b$ where $A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, -$x = \begin{bmatrix} m \\ n \end{bmatrix}$ and $b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$. - -It can be verified that this system has no solutions. - -(The problem is that we have three equations and only two unknowns.) - -We will thus try to find the best approximate solution for $x$. - -1. Use {eq}`least_squares` and matrix algebra to find the least squares solution $\hat{x}$. -2. Find the least squares solution using `numpy.linalg.lstsq` and compare the results. ```{exercise-end} ``` @@ -1333,14 +1080,14 @@ from numpy.linalg import inv ``` ```{code-cell} ipython3 -# Using matrix algebra -A = np.array([[1, -9], # matrix A +# 运用线性代数 +A = np.array([[1, -9], # 矩阵 A [1, -7], [1, -3]]) -A_T = np.transpose(A) # transpose of matrix A +A_T = np.transpose(A) # 矩阵A的转置 -b = np.array((1, 3, 8)) # column vector b +b = np.array((1, 3, 8)) # 列向量 b b.shape = (3, 1) x = inv(A_T @ A) @ A_T @ b @@ -1348,7 +1095,7 @@ x ``` ```{code-cell} ipython3 -# Using numpy.linalg.lstsq +# 使用 numpy.linalg.lstsq x, res, _, _ = np.linalg.lstsq(A, b, rcond=None) ``` @@ -1358,10 +1105,9 @@ x, res, _, _ = np.linalg.lstsq(A, b, rcond=None) print(f"x\u0302 = {x}") print(f"\u2016Ax\u0302 - b\u2016\u00B2 = {res[0]}") ``` +这是一个可视化图,展示了最小二乘法如何近似一组点之间连线的方程。 +我们也可以将此描述为在一组点之间"拟合"一条直线。 -Here is a visualization of how the least squares method approximates the equation of a line connecting a set of points. - -We can also describe this as "fitting" a line between a set of points. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -1370,20 +1116,82 @@ q = np.array((9, 7, 3)) a, b = x -ax.plot(q, p, 'o', label='observations', markersize=5) -ax.plot(q, a - b*q, 'r', label='Fitted line') -plt.xlabel('quantity demanded') -plt.ylabel('price') +ax.plot(q, p, 'o', label='观测点', markersize=5) +ax.plot(q, a - b*q, 'r', label='拟合线') +plt.xlabel('需求数量') +plt.ylabel('价格') plt.legend() plt.show() ``` ```{solution-end} ``` + +### 延伸阅读 +`numpy.linalg` 子模块的文档可以在[这里](https://numpy.org/devdocs/reference/routines.linalg.html)找到。 +线性代数的更高级主题可以在[这里](https://python.quantecon.org/linear_algebra.html#id5)找到。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -### Further reading -The documentation of the `numpy.linalg` submodule can be found [here](https://numpy.org/devdocs/reference/routines.linalg.html). -More advanced topics in linear algebra can be found [here](https://python.quantecon.org/linear_algebra.html#id5). diff --git a/lectures/linear_equations_cn.md b/lectures/linear_equations_cn.md deleted file mode 100644 index d6b7bcd3..00000000 --- a/lectures/linear_equations_cn.md +++ /dev/null @@ -1,1197 +0,0 @@ ---- -jupytext: - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.4 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# 线性方程和矩阵代数 - -```{index} single: Linear Equations and Matrix Algebra -``` - -## 概述 -经济学和金融学中的许多问题都需要解线性方程。 - -在本讲座中,我们将讨论线性方程及其应用。 - -为了说明线性方程的重要性,我们从一个两种商品的供需模型开始。 - -两种商品的情况非常简单,可以手动计算解。 - -但我们经常需要考虑包含多种商品的市场。 - -在多种商品的情况下,我们面对的是大型线性方程组,有许多方程和未知数。 - -为了处理这样的系统,我们需要两样东西: - -* 矩阵代数(以及如何使用它的知识)以及 -* 将矩阵代数应用于感兴趣问题的计算机代码。 - -本讲座涵盖了这些步骤。 - -我们将使用以下的库: - -```{code-cell} ipython3 -import numpy as np -import matplotlib.pyplot as plt -``` -## 两种商品的例子 -在本节中,我们将讨论一个简单的两种商品例子,并通过以下两种方法解决: -1. 纸笔计算 -2. 矩阵代数 -正如我们将看到的,第二种方法更具普遍性。 - -### 纸笔计算方法 -假设我们有两种相关的商品,比如: -* 丙烷和乙醇,或 -* 大米和小麦等。 -为了简化问题,我们将它们标记为商品0和商品1。 -每种商品的需求取决于两种商品的价格: -```{math} -:label: two_eq_demand -\begin{aligned} - q_0^d = 100 - 10 p_0 - 5 p_1 \\ - q_1^d = 50 - p_0 - 10 p_1 -\end{aligned} -``` -(我们假设当任一商品的价格上涨时需求会下降,但其他情况也是可能的。) -让我们假设供给由以下方程给出: - -```{math} -:label: two_eq_supply -\begin{aligned} - q_0^s = 10 p_0 + 5 p_1 \\ - q_1^s = 5 p_0 + 10 p_1 -\end{aligned} -``` -当供给等于需求时($q_0^s = q_0^d$ 和 $q_1^s = q_1^d$),市场达到均衡。 -这产生了以下线性系统: - -```{math} -:label: two_equilibrium -\begin{aligned} - 100 - 10 p_0 - 5 p_1 = 10 p_0 + 5 p_1 \\ - 50 - p_0 - 10 p_1 = 5 p_0 + 10 p_1 -\end{aligned} -``` - -我们可以用纸笔计算得到: -$$ - p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. -$$ -将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: -$$ - q_0 = 50 \quad \text{和} \quad q_1 = 33.82. -$$ - -### 展望未来 -在两种商品的情况下,纸笔计算方法很容易。 -但如果有很多种商品呢? -对于这样的问题,我们需要矩阵代数。 -在用矩阵代数解决问题之前,让我们先回顾一下向量和矩阵的基础知识,包括理论和计算。 - - -## {index}`向量 ` - - ```{index} single: Linear Algebra; Vectors - ``` - -一个长度为$n$的**向量**就是一个由$n$个数字组成的序列(或数组,或元组),我们将其写作$x = (x_1, \ldots, x_n)$或$x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$。 -我们可以将这些序列横向或纵向写出。 -但当我们使用矩阵运算时,我们默认假设向量是列向量。 -所有$n$维向量的集合用$\mathbb R^n$表示。 -例如, -* $\mathbb R^2$是平面 --- 即所有$(x_1, x_2)$对的集合。 -* $\mathbb R^3$是三维空间 --- 即所有$(x_1, x_2, x_3)$向量的集合。 -向量通常在视觉上表示为从原点到某点的箭头。 -这里是一个可视化示例。 - -```{code-cell} ipython3 -:tags: [hide-input] - -fig, ax = plt.subplots() -# 通过原点建立坐标轴 -for spine in ['left', 'bottom']: - ax.spines[spine].set_position('zero') -for spine in ['right', 'top']: - ax.spines[spine].set_color('none') - -ax.set(xlim=(-5, 5), ylim=(-5, 5)) - -vecs = ((2, 4), (-3, 3), (-4, -3.5)) -for v in vecs: - ax.annotate('', xy=v, xytext=(0, 0), - arrowprops=dict(facecolor='blue', - shrink=0, - alpha=0.7, - width=0.5)) - ax.text(1.1 * v[0], 1.1 * v[1], str(v)) -plt.show() -``` - -### 向量运算 - -```{index} single: Vectors; Operations -``` - -有时我们需要修改向量。 -对向量最常见的两种运算是加法和标量乘法,我们现在来描述这两种运算。 -当我们对两个向量进行加法运算时,我们是逐元素相加。 -例如, -$$ -\begin{bmatrix} - 4 \\ - -2 -\end{bmatrix} -+ -\begin{bmatrix} - 3 \\ - 3 -\end{bmatrix} -= -\begin{bmatrix} - 4 & + & 3 \\ - -2 & + & 3 -\end{bmatrix} -= -\begin{bmatrix} - 7 \\ - 1 -\end{bmatrix}. -$$ -一般来说, -$$ -x + y = -\begin{bmatrix} - x_1 \\ - x_2 \\ - \vdots \\ - x_n -\end{bmatrix} + -\begin{bmatrix} - y_1 \\ - y_2 \\ - \vdots \\ - y_n -\end{bmatrix} := -\begin{bmatrix} - x_1 + y_1 \\ - x_2 + y_2 \\ - \vdots \\ - x_n + y_n -\end{bmatrix}. -$$ -我们可以在$\mathbb{R}^2$中将向量加法可视化如下。 - -```{code-cell} ipython3 -:tags: [hide-input] - -fig, ax = plt.subplots() -# 通过原点建立坐标轴 -for spine in ['left', 'bottom']: - ax.spines[spine].set_position('zero') -for spine in ['right', 'top']: - ax.spines[spine].set_color('none') - -ax.set(xlim=(-2, 10), ylim=(-4, 4)) -# ax.grid() -vecs = ((4, -2), (3, 3), (7, 1)) -tags = ('(x1, x2)', '(y1, y2)', '(x1+x2, y1+y2)') -colors = ('blue', 'green', 'red') -for i, v in enumerate(vecs): - ax.annotate('', xy=v, xytext=(0, 0), - arrowprops=dict(color=colors[i], - shrink=0, - alpha=0.7, - width=0.5, - headwidth=8, - headlength=15)) - ax.text(v[0] + 0.2, v[1] + 0.1, tags[i]) - -for i, v in enumerate(vecs): - ax.annotate('', xy=(7, 1), xytext=v, - arrowprops=dict(color='gray', - shrink=0, - alpha=0.3, - width=0.5, - headwidth=5, - headlength=20)) -plt.show() -``` - -标量乘法是一种将向量 $x$ 与一个标量进行元素级别相乘的运算。 -例如, -$$ --2 -\begin{bmatrix} - 3 \\ - -7 -\end{bmatrix} -= -\begin{bmatrix} - -2 & \times & 3 \\ - -2 & \times & -7 -\end{bmatrix} -= -\begin{bmatrix} - -6 \\ - 14 -\end{bmatrix}. -$$ -更一般地,它取一个数 $\gamma$ 和一个向量 $x$,得到 -$$ -\gamma x := -\begin{bmatrix} - \gamma x_1 \\ - \gamma x_2 \\ - \vdots \\ - \gamma x_n -\end{bmatrix}. -$$ -标量乘法在下图中进行了说明。 - -```{code-cell} ipython3 -:tags: [hide-input] - -fig, ax = plt.subplots() -# 通过原点建立坐标轴 -for spine in ['left', 'bottom']: - ax.spines[spine].set_position('zero') -for spine in ['right', 'top']: - ax.spines[spine].set_color('none') - -ax.set(xlim=(-5, 5), ylim=(-5, 5)) -x = (2, 2) -ax.annotate('', xy=x, xytext=(0, 0), - arrowprops=dict(facecolor='blue', - shrink=0, - alpha=1, - width=0.5)) -ax.text(x[0] + 0.4, x[1] - 0.2, '$x$', fontsize='16') - -scalars = (-2, 2) -x = np.array(x) - -for s in scalars: - v = s * x - ax.annotate('', xy=v, xytext=(0, 0), - arrowprops=dict(facecolor='red', - shrink=0, - alpha=0.5, - width=0.5)) - ax.text(v[0] + 0.4, v[1] - 0.2, f'${s} x$', fontsize='16') -plt.show() -``` - -在Python中,向量可以用列表或元组表示, -例如 `x = [2, 4, 6]` 或 `x = (2, 4, 6]`。 -然而,更常见的是用 -[NumPy数组](https://python-programming.quantecon.org/numpy.html#numpy-arrays)来表示向量。 - -NumPy数组的一个优点是标量乘法和加法具有非常自然的语法。 - -```{code-cell} ipython3 -x = np.ones(3) # 三个元素为一的向量 -y = np.array((2, 4, 6)) # 将 (2, 4, 6) 转换为 NumPy 数组 -x + y # 每个元素相加 -``` - -```{code-cell} -4 * x # 标量乘法 -``` - -### 内积和范数 - -```{index} single: Vectors; Inner Product -``` - -```{index} single: Vectors; Norm -``` - -向量 $x,y \in \mathbb R^n$ 的**内积**定义为 -$$ -x^\top y = -\begin{bmatrix} - \color{red}{x_1} & \color{blue}{x_2} & \cdots & x_n -\end{bmatrix} -\begin{bmatrix} - \color{red}{y_1} \\ - \color{blue}{y_2} \\ - \vdots \\ - y_n -\end{bmatrix} -= {\color{red}{x_1 y_1}} + {\color{blue}{x_2 y_2}} + \cdots + x_n y_n -:= \sum_{i=1}^n x_i y_i. -$$ -向量 $x$ 的**范数**表示其"长度"(即,其与零向量的距离),定义为 -$$ - \| x \| := \sqrt{x^\top x} := \left( \sum_{i=1}^n x_i^2 \right)^{1/2}. -$$ -表达式 $\| x - y\|$ 可以被理解为 $x$ 和 $y$ 之间的"距离"。 -内积和范数可以按以下方式计算 - -```{code-cell} ipython3 -np.sum(x*y) # x和y的内积 -``` - -```{code-cell} ipython3 -x @ y # 另外一种计算内积的办法 -``` - -```{code-cell} ipython3 -np.sqrt(np.sum(x**2)) # x的范数,方法一 -``` - -```{code-cell} ipython3 -np.linalg.norm(x) # x的范数,方法二 -``` - -## 矩阵运算 - -```{index} single: Matrix; Operations -``` - -当我们讨论线性价格系统时,我们提到了使用矩阵代数。 -矩阵代数类似于数字代数。 -让我们回顾一些细节。 -### 加法和标量乘法 -就像向量一样,我们可以对矩阵进行加法、减法和标量乘法。 -标量乘法和加法是向量情况的推广: -以下是标量乘法的一个例子 -$$ -3 -\begin{bmatrix} - 2 & -13 \\ - 0 & 5 -\end{bmatrix} -= -\begin{bmatrix} - 6 & -39 \\ - 0 & 15 -\end{bmatrix}. -$$ -一般来说,对于任意数 $\gamma$ 和任意矩阵 $A$, -$$ -\gamma A = -\gamma -\begin{bmatrix} - a_{11} & \cdots & a_{1k} \\ - \vdots & \vdots & \vdots \\ - a_{n1} & \cdots & a_{nk} -\end{bmatrix} := -\begin{bmatrix} - \gamma a_{11} & \cdots & \gamma a_{1k} \\ - \vdots & \vdots & \vdots \\ - \gamma a_{n1} & \cdots & \gamma a_{nk} -\end{bmatrix}. -$$ -考虑这个矩阵加法的例子, -$$ -\begin{bmatrix} - 1 & 5 \\ - 7 & 3 \\ -\end{bmatrix} -+ -\begin{bmatrix} - 12 & -1 \\ - 0 & 9 -\end{bmatrix} -= -\begin{bmatrix} - 13 & 4 \\ - 7 & 12 -\end{bmatrix}. -$$ -一般来说, -$$ -A + B = -\begin{bmatrix} - a_{11} & \cdots & a_{1k} \\ - \vdots & \vdots & \vdots \\ - a_{n1} & \cdots & a_{nk} -\end{bmatrix} + -\begin{bmatrix} - b_{11} & \cdots & b_{1k} \\ - \vdots & \vdots & \vdots \\ - b_{n1} & \cdots & b_{nk} -\end{bmatrix} := -\begin{bmatrix} - a_{11} + b_{11} & \cdots & a_{1k} + b_{1k} \\ - \vdots & \vdots & \vdots \\ - a_{n1} + b_{n1} & \cdots & a_{nk} + b_{nk} -\end{bmatrix}. -$$ -在后一种情况下,矩阵必须具有相同的形状才能使定义有意义。 -### 矩阵乘法 -我们还有一个*相乘*两个矩阵的约定。 -矩阵乘法的规则推广了上面讨论的内积的概念。 -如果 $A$ 和 $B$ 是两个矩阵,那么它们的乘积 $A B$ 的形成是通过取 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列的内积作为其第 $i,j$ 个元素。 -如果 $A$ 是 $n \times k$ 的,$B$ 是 $j \times m$ 的,那么要相乘 $A$ 和 $B$,我们需要 $k = j$,而得到的矩阵 $A B$ 是 $n \times m$ 的。 -这里是一个 $2 \times 2$ 矩阵乘以 $2 \times 1$ 向量的例子。 -$$ -Ax = -\begin{bmatrix} - \color{red}{a_{11}} & \color{red}{a_{12}} \\ - a_{21} & a_{22} -\end{bmatrix} -\begin{bmatrix} - \color{red}{x_1} \\ - \color{red}{x_2} -\end{bmatrix} -= -\begin{bmatrix} - \color{red}{a_{11}x_1 + a_{12}x_2} \\ - a_{21}x_1 + a_{22}x_2 -\end{bmatrix} -$$ -作为一个重要的特殊情况,考虑将 $n \times k$ 矩阵 $A$ 和 $k \times 1$ 列向量 $x$ 相乘。 -根据前面的规则,这给我们一个 $n \times 1$ 列向量。 - -```{math} -:label: la_atx - -A x = -{\begin{bmatrix} - a_{11} & a_{12} & \cdots & a_{1k} \\ - \vdots & \vdots & & \vdots \\ - \color{red}{a_{i1}} & \color{red}{a_{i2}} & \color{red}{\cdots} & \color{red}{a_{i}k} \\ - \vdots & \vdots & & \vdots \\ - a_{n1} & a_{n2} & \cdots & a_{nk} -\end{bmatrix}}_{n \times k} -{\begin{bmatrix} - \color{red}{x_{1}} \\ - \color{red}{x_{2}} \\ - \color{red}{\vdots} \\ - \color{red}{\vdots} \\ - \color{red}{x_{k}} -\end{bmatrix}}_{k \times 1} := -{\begin{bmatrix} - a_{11} x_1 + a_{22} x_2 + \cdots + a_{1k} x_k \\ - \vdots \\ - \color{red}{a_{i1} x_1 + a_{i2} x_2 + \cdots + a_{ik} x_k} \\ - \vdots \\ - a_{n1} x_1 + a_{n2} x_2 + \cdots + a_{nk} x_k -\end{bmatrix}}_{n \times 1} -``` - -下面展示了两个矩阵的乘法。 - -$$ -AB = -\begin{bmatrix} - a_{11} & a_{12} \\ - \color{red}{a_{21}} & \color{red}{a_{22}} \\ -\end{bmatrix} -\begin{bmatrix} - b_{11} & \color{red}{b_{12}} \\ - b_{21} & \color{red}{b_{22}} \\ -\end{bmatrix} := -\begin{bmatrix} - a_{11}b_{11} + a_{12}b_{21} & a_{11}b_{12} + a_{12}b_{22} \\ - a_{21}b_{11} + a_{22}b_{21} & \color{red}{a_{21}b_{12} + a_{22}b_{22}} -\end{bmatrix} -$$ - -有许多教程可以帮助你进一步可视化这个操作,例如 -* [这个教程](http://www.mathsisfun.com/algebra/matrix-multiplying.html),或者 -* [维基百科页面](https://en.wikipedia.org/wiki/Matrix_multiplication)上的讨论。 - -```{note} -与数字乘积不同,$A B$ 和 $B A$ 通常不是同一件事。 -``` - -一个重要的特殊情况是[单位矩阵](https://en.wikipedia.org/wiki/Identity_matrix),它在主对角线上有 1,其他地方都是 0: -$$ - I = - \begin{bmatrix} - 1 & \cdots & 0 \\ - \vdots & \ddots & \vdots \\ - 0 & \cdots & 1 - \end{bmatrix} -$$ -验证以下内容是一个有用的练习: -* 如果 $A$ 是 $n \times k$ 矩阵,$I$ 是 $k \times k$ 单位矩阵,那么 $AI = A$,并且 -* 如果 $I$ 是 $n \times n$ 单位矩阵,那么 $IA = A$。 - - -### NumPy中的矩阵 - -```{index} single: Matrix; Numpy -``` -NumPy 数组也被用作矩阵,并且对所有标准矩阵运算都有快速、高效的函数和方法。 -你可以通过以下方式从元组的元组(或列表的列表)手动创建它们 - -```{code-cell} ipython3 -A = ((1, 2), - (3, 4)) - -type(A) -``` - -```{code-cell} ipython3 -A = np.array(A) - -type(A) -``` - -```{code-cell} ipython3 -A.shape -``` - -`shape` 属性是一个给出行数和列数的元组 --- -更多讨论请参见[这里](https://python-programming.quantecon.org/numpy.html#shape-and-dimension)。 -要获得 `A` 的转置,使用 `A.transpose()` 或更简单地使用 `A.T`。 -有许多方便的函数用于创建常见矩阵(零矩阵、单位矩阵等) --- 请参见[这里](https://python-programming.quantecon.org/numpy.html#creating-arrays)。 -由于默认情况下操作是按元素执行的,标量乘法和加法具有非常自然的语法。 - -```{code-cell} ipython3 -A = np.identity(3) # 3 x 3 单位矩阵 -B = np.ones((3, 3)) # 3 x 3 元素为一的矩阵 -2 * A -``` - -```{code-cell} ipython3 -A + B -``` - -我们用 `@` 来进行矩阵乘法。 - - -```{note} -其中 `A @ B` 是矩阵乘法, 但是 `A * B`是每个元素之间的运算。 -``` - -### 矩阵形式的两种商品模型 -我们现在可以重新审视两种商品模型,并通过矩阵代数数值求解 {eq}`two_equilibrium` 方程。 -这涉及一些额外的步骤,但这种方法广泛适用 --- 正如我们在包含更多商品时将看到的那样。 -首先,我们将 {eq}`two_eq_demand` 重写为 - -```{math} -:label: two_eq_demand_mat - q^d = D p + h - \quad \text{where} \quad - q^d = - \begin{bmatrix} - q_0^d \\ - q_1^d - \end{bmatrix} - \quad - D = - \begin{bmatrix} - -10 & - 5 \\ - - 1 & - 10 - \end{bmatrix} - \quad \text{and} \quad - h = - \begin{bmatrix} - 100 \\ - 50 - \end{bmatrix}. -``` -回想一下,$p \in \mathbb{R}^{2}$ 是两种商品的价格。 -(请检查 $q^d = D p + h$ 是否表示与 {eq}`two_eq_demand` 相同的方程。) -我们将 {eq}`two_eq_supply` 重写为 - -```{math} -:label: two_eq_supply_mat - q^s = C p - \quad \text{where} \quad - q^s = - \begin{bmatrix} - q_0^s \\ - q_1^s - \end{bmatrix} - \quad \text{and} \quad - C = - \begin{bmatrix} - 10 & 5 \\ - 5 & 10 - \end{bmatrix}. -``` - -现在供给和需求的相等可以表示为 $q^s = q^d$,或 -$$ - C p = D p + h. -$$ -我们可以重新排列这些项得到 -$$ - (C - D) p = h. -$$ -如果所有项都是数字,我们可以求解价格为 $p = h / (C-D)$。 -矩阵代数允许我们做类似的事情:我们可以使用 $C - D$ 的逆矩阵来求解均衡价格: - -```{math} -:label: two_matrix - p = (C - D)^{-1} h. -``` - -在我们实施解决方案之前,让我们考虑一个更一般的设置。 - -### 更多商品 -考虑有更多商品的需求系统是很自然的。 -例如,即使在能源商品中也有许多不同的商品, -包括原油、汽油、煤炭、天然气、乙醇和铀。 -这些商品的价格是相关的,所以一起研究它们是有意义的。 -对于大型系统,纸笔方法会变得非常耗时。 -但幸运的是,上面描述的矩阵方法基本上保持不变。 - -一般来说,我们可以将需求方程写为 $q^d = Dp + h$,其中 -* $q^d$ 是一个 $n \times 1$ 的向量,表示 $n$ 种不同商品的需求量。 -* $D$ 是一个 $n \times n$ 的"系数"矩阵。 -* $h$ 是一个 $n \times 1$ 的常数值向量。 - -类似地,我们可以将供给方程写为 $q^s = Cp + e$,其中 -* $q^s$ 是一个 $n \times 1$ 的向量,表示相同商品的供给量。 -* $C$ 是一个 $n \times n$ 的"系数"矩阵。 -* $e$ 是一个 $n \times 1$ 的常数值向量。 - -为了找到均衡,我们求解 $Dp + h = Cp + e$,或 - -```{math} -:label: n_eq_sys_la - (D- C)p = e - h. -``` - -那么,n 种不同商品的价格向量是 -$$ - p = (D- C)^{-1}(e - h). -$$ - -### 一般线性系统 -上述问题的一个更一般版本看起来如下。 - -```{math} -:label: la_se - -\begin{matrix} - a_{11} x_1 & + & a_{12} x_2 & + & \cdots & + & a_{1n} x_n & = & b_1 \\ - \vdots & & \vdots & & & & \vdots & & \vdots \\ - a_{n1} x_1 & + & a_{n2} x_2 & + & \cdots & + & a_{nn} x_n & = & b_n -\end{matrix} -``` - -这里的目标是解出"未知数" $x_1, \ldots, x_n$。 -我们给定系数 $a_{11}, \ldots, a_{nn}$ 和常数 $b_1, \ldots, b_n$。 -注意,我们处理的是未知数数量等于方程数量的情况。 -这是我们最有可能找到明确定义解的情况。 -(其他情况被称为[超定](https://en.wikipedia.org/wiki/Overdetermined_system)和[欠定](https://en.wikipedia.org/wiki/Underdetermined_system)方程组 --- 我们将在后续讲座中讨论这些情况。) -用矩阵形式表示,方程组 {eq}`la_se` 变为 - -```{math} -:label: la_gf - A x = b - \quad \text{where} \quad - A = - \begin{bmatrix} - a_{11} & \cdots & a_{1n} \\ - \vdots & \vdots & \vdots \\ - a_{n1} & \cdots & a_{nn} - \end{bmatrix} - \quad \text{and} \quad - b = - \begin{bmatrix} - b_1 \\ - \vdots \\ - b_n - \end{bmatrix}. -``` -例如,{eq}`n_eq_sys_la` 具有这种形式,其中 -$$ - A = D - C, - \quad - b = e - h - \quad \text{和} \quad - x = p. -$$ -当考虑诸如 {eq}`la_gf` 这样的问题时,我们至少需要问以下一些问题: -* 解是否真的存在? -* 如果解存在,我们应该如何计算它? - -## 解方程组 - -```{index} single: Matrix; Solving Systems of Equations -``` - -再次回顾方程组 {eq}`la_se`,我们在此重新写为 - -```{math} -:label: la_se2 - A x = b. -``` -我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 -{eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 -我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 -我们在下面举例说明两种这样的情况。 -### 无解 -考虑由以下给出的方程组: -$$ -\begin{aligned} - x + 3y &= 3 \\ - 2x + 6y &= -8. -\end{aligned} -$$ -可以手动验证这个系统没有可能的解。 -为了说明为什么会出现这种情况,让我们绘制这两条直线。 - -```{code-cell} ipython3 -fig, ax = plt.subplots() -x = np.linspace(-10, 10) -plt.plot(x, (3-x)/3, label=f'$x + 3y = 3$') -plt.plot(x, (-8-2*x)/6, label=f'$2x + 6y = -8$') -plt.legend() -plt.show() -``` - -+++ {"tags": []} - - -显然,这些是平行线,因此我们永远无法找到一个点 $x \in \mathbb{R}^2$ 使得这些线相交。 -因此,这个系统没有可能的解。 -我们可以将这个系统用矩阵形式重写为 - -```{math} -:label: no_soln - A x = b - \quad \text{where} \quad - A = - \begin{bmatrix} - 1 & 3 \\ - 2 & 6 - \end{bmatrix} - \quad \text{and} \quad - b = - \begin{bmatrix} - 3 \\ - -8 - \end{bmatrix}. -``` - -可以注意到,矩阵 $A$ 的第 $2$ 行 $(2, 6)$ 只是第 $1$ 行 $(1, 3)$ 的标量倍数。 -在这种情况下,矩阵 $A$ 的行被称为**线性相关的。** - -```{note} -高级读者可以在[这里](https://python.quantecon.org/linear_algebra.html#linear-independence)找到关于线性相关和线性无关的详细解释。 -但在接下来的内容中不需要这些细节。 - -``` - - -### 多解 -现在考虑, -$$ -\begin{aligned} - x - 2y &= -4 \\ - -2x + 4y &= 8. -\end{aligned} -$$ -任何满足 $x = 2y - 4$ 的向量 $v = (x,y)$ 都将解决上述系统。 -由于我们可以找到无限多个这样的向量,这个系统有无穷多个解。 -这是因为对应矩阵的行 - -```{math} -:label: many_solns - A = - \begin{bmatrix} - 1 & -2 \\ - -2 & 4 - \end{bmatrix}. -``` - -是线性相关的 --- 你能看出为什么吗? -我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 -### 非奇异矩阵 -对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 -对于 $2 \times 2$ 矩阵,行列式由以下公式给出: -$$ -\begin{bmatrix} - \color{red}{a} & \color{blue}{b} \\ - \color{blue}{c} & \color{red}{d} -\end{bmatrix} -= -{\color{red}{ad}} - {\color{blue}{bc}}. -$$ -如果 $A$ 的行列式不为零,我们就说 $A$ 是*非奇异的*。 -当且仅当 $A$ 的行和列是线性无关的,方阵 $A$ 才是非奇异的。 -关于矩阵逆的更详细解释可以在[这里](https://www.mathsisfun.com/algebra/matrix-inverse.html)找到。 -你可以自己检查 {eq}`no_soln` 和 {eq}`many_solns` 中具有线性相关行的矩阵是奇异矩阵。 -这为我们提供了一个有用的单数值概括,用来判断一个方阵是否可逆。 -特别地,方阵 $A$ 具有非零行列式,当且仅当它具有*逆矩阵* $A^{-1}$,满足 $A A^{-1} = A^{-1} A = I$。 -因此,如果我们用 $A^{-1}$ 左乘 $Ax = b$ 的两边,我们得到 - -```{math} -:label: la_se_inv - x = A^{-1} b. -``` - -这是对 $Ax = b$ 的解答 --- 这就是我们要寻找的解。 - -### 使用NumPy求解线性方程 -```{index} single: Linear Algebra; SciPy -``` - -在两个好的例子中,我们得到了矩阵方程: -$$ -p = (C-D)^{-1} h. -$$ -其中 $C$、$D$ 和 $h$ 由 {eq}`two_eq_demand_mat` 和 {eq}`two_eq_supply_mat` 给出。 -这个方程类似于 {eq}`la_se_inv`,其中 $A = (C-D)^{-1}$,$b = h$,且 $x = p$。 -我们现在可以使用NumPy的`linalg`子模块求解均衡价格。 -所有这些程序都是经过时间检验和高度优化的FORTRAN代码的Python前端。 - -```{code-cell} ipython3 -C = ((10, 5), # 矩阵 C - (5, 10)) -``` - -Now we change this to a NumPy array. - -```{code-cell} ipython3 -C = np.array(C) -``` - -```{code-cell} ipython3 -D = ((-10, -5), # 矩阵 D - (-1, -10)) -D = np.array(D) -``` - -```{code-cell} ipython3 -h = np.array((100, 50)) # 向量 h -h.shape = 2,1 # 将h转换为列向量 -``` - -```{code-cell} ipython3 -from numpy.linalg import det, inv -A = C - D -#检查A是否为奇异矩阵(行列式是否为零),是否可逆 -det(A) -``` - -```{code-cell} ipython3 -A_inv = inv(A) #计算逆矩阵 -A_inv -``` - -```{code-cell} ipython3 -p = A_inv @ h #均衡价格 -p -``` - -```{code-cell} ipython3 -q = C @ p # 均衡数量 -q -``` - -注意,我们得到的解与纸笔计算的情况相同。 -我们还可以使用 `solve(A, h)` 来求解 $p$,如下所示。 - -```{code-cell} ipython3 -from numpy.linalg import solve -p = solve(A, h) # 均衡价格 -p -``` - -```{code-cell} ipython3 -q = C @ p # 均衡数量 -q -``` -观察我们如何通过 `inv(A) @ y` 或使用 `solve(A, y)` 来求解 $x = A^{-1} y$。 -后一种方法使用了一种不同的算法,在数值上更加稳定,因此应该是默认选项。 - - -## 练习 -```{exercise-start} -:label: lin_eqs_ex1 -``` -让我们考虑一个有3种商品的市场 - 商品0、商品1和商品2。 -每种商品的需求取决于其他两种商品的价格,由以下公式给出: -$$ -\begin{aligned} - q_0^d & = 90 - 15p_0 + 5p_1 + 5p_2 \\ - q_1^d & = 60 + 5p_0 - 10p_1 + 10p_2 \\ - q_2^d & = 50 + 5p_0 + 5p_1 - 5p_2 -\end{aligned} -$$ -(这里,当自身价格上涨时需求下降,但当其他商品价格上涨时需求增加。) -每种商品的供给由以下公式给出: -$$ -\begin{aligned} - q_0^s & = -10 + 20p_0 \\ - q_1^s & = -15 + 15p_1 \\ - q_2^s & = -5 + 10p_2 -\end{aligned} -$$ -当供给等于需求时,市场达到均衡,即 $q_0^d = q_0^s$,$q_1^d = q_1^s$ 和 $q_2^d = q_2^s$。 -1. 将市场设置为线性方程组。 -2. 使用矩阵代数求解均衡价格。分别使用 `numpy.linalg.solve` 和 `inv(A)` 方法来做这个。比较这两种解法。 - -```{exercise-end} -``` -```{solution-start} lin_eqs_ex1 -:class: dropdown -``` -生成的系统将是: -$$ -\begin{aligned} - 35p_0 - 5p_1 - 5p_2 = 100 \\ - -5p_0 + 25p_1 - 10p_2 = 75 \\ - -5p_0 - 5p_1 + 15p_2 = 55 -\end{aligned} -$$ -用矩阵形式,我们将其表示为: -$$ -Ap = b -\quad \text{其中} \quad -A = -\begin{bmatrix} - 35 & -5 & -5 \\ - -5 & 25 & -10 \\ - -5 & -5 & 15 -\end{bmatrix} -, \quad p = -\begin{bmatrix} - p_0 \\ - p_1 \\ - p_2 -\end{bmatrix} -\quad \text{且} \quad -b = -\begin{bmatrix} - 100 \\ - 75 \\ - 55 -\end{bmatrix} -$$ - -```{code-cell} -import numpy as np -from numpy.linalg import det - -A = np.array([[35, -5, -5], # 矩阵 A - [-5, 25, -10], - [-5, -5, 15]]) - -b = np.array((100, 75, 55)) # 列向量 b -b.shape = (3, 1) - -det(A) # 检查A是否为奇异矩阵 -``` - -```{code-cell} -# 使用inverse -from numpy.linalg import det - -A_inv = inv(A) - -p = A_inv @ b -p -``` - -```{code-cell} -# 使用 numpy.linalg.solve -from numpy.linalg import solve -p = solve(A, b) -p -``` - -答案为: -$$ -p_0 = 4.6925, \; p_1 = 7.0625 \;\; \text{and} \;\; p_2 = 7.675 -$$ - -```{solution-end} -``` - -```{exercise-start} -:label: lin_eqs_ex2 -``` -在讲座的早些时候,我们讨论了$Ax = b$这个方程组没有解的情况。 -在这种情况下,$Ax = b$被称为*不相容*方程组。 -面对不相容系统时,我们尝试找到最佳的"近似"解。 -有多种方法可以做到这一点,其中一种是**最小二乘法**。 -假设我们有一个不相容系统 - -```{math} -:label: inconsistent - Ax = b -``` - -其中$A$是一个$m \times n$矩阵,$b$是一个$m \times 1$列向量。 -对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 -小于$Ax$到$b$的距离。 -即, -$$ - \|A\hat{x} - b\| \leq \|Ax - b\| -$$ -可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 - -```{math} -:label: least_squares - \hat{x} = (A^T A)^{-1} A^T b -``` - -现在考虑一种商品的线性需求曲线的一般方程: -$$ - p = m - nq -$$ -其中$p$是商品的价格,$q$是需求量。 -假设我们正试图*估计*$m$和$n$的值。 -我们通过重复观察价格和数量(例如,每个月)来做到这一点,然后选择$m$和$n$来拟合$p$和$q$之间的关系。 -我们有以下观察结果: -| 价格 | 需求量 | -|:-----:|:-----------------:| -| 1 | 9 | -| 3 | 7 | -| 8 | 3 | -要求需求曲线$p = m - nq$通过所有这些点,得到以下三个方程: -$$ -\begin{aligned} - 1 = m - 9n \\ - 3 = m - 7n \\ - 8 = m - 3n -\end{aligned} -$$ -因此,我们得到一个方程组$Ax = b$,其中$A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, -$x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$。 -可以验证这个系统没有解。 -(问题在于我们有三个方程但只有两个未知数。) -因此,我们将尝试找到$x$的最佳近似解。 -1. 使用{eq}`least_squares`和矩阵代数找到最小二乘解$\hat{x}$。 -2. 使用`numpy.linalg.lstsq`找到最小二乘解,并比较结果。 - - -```{exercise-end} -``` - -```{solution-start} lin_eqs_ex2 -:class: dropdown -``` - -```{code-cell} ipython3 -import numpy as np -from numpy.linalg import inv -``` - -```{code-cell} ipython3 -# 运用线性代数 -A = np.array([[1, -9], # 矩阵 A - [1, -7], - [1, -3]]) - -A_T = np.transpose(A) # 矩阵A的转置 - -b = np.array((1, 3, 8)) # 列向量 b -b.shape = (3, 1) - -x = inv(A_T @ A) @ A_T @ b -x -``` - -```{code-cell} ipython3 -# 使用 numpy.linalg.lstsq -x, res, _, _ = np.linalg.lstsq(A, b, rcond=None) -``` - -```{code-cell} ipython3 -:tags: [hide-input] - -print(f"x\u0302 = {x}") -print(f"\u2016Ax\u0302 - b\u2016\u00B2 = {res[0]}") -``` -这是一个可视化图,展示了最小二乘法如何近似一组点之间连线的方程。 -我们也可以将此描述为在一组点之间"拟合"一条直线。 - - -```{code-cell} ipython3 -fig, ax = plt.subplots() -p = np.array((1, 3, 8)) -q = np.array((9, 7, 3)) - -a, b = x - -ax.plot(q, p, 'o', label='观测点', markersize=5) -ax.plot(q, a - b*q, 'r', label='拟合线') -plt.xlabel('需求数量') -plt.ylabel('价格') -plt.legend() -plt.show() -``` - -```{solution-end} -``` - -### 延伸阅读 -`numpy.linalg` 子模块的文档可以在[这里](https://numpy.org/devdocs/reference/routines.linalg.html)找到。 -线性代数的更高级主题可以在[这里](https://python.quantecon.org/linear_algebra.html#id5)找到。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 82697ae1658ff727cb1406e9be9432c827d65cbb Mon Sep 17 00:00:00 2001 From: Longye Tian Date: Wed, 25 Sep 2024 20:46:17 +1000 Subject: [PATCH 3/7] Update linear_equations.md --- lectures/linear_equations.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index d6b7bcd3..b32ca1d8 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -686,6 +686,7 @@ $$ ```{math} :label: la_gf + A x = b \quad \text{where} \quad A = @@ -723,8 +724,10 @@ $$ ```{math} :label: la_se2 - A x = b. + + A x = b ``` + 我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 {eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 @@ -797,6 +800,7 @@ $$ ```{math} :label: many_solns + A = \begin{bmatrix} 1 & -2 \\ @@ -806,6 +810,7 @@ $$ 是线性相关的 --- 你能看出为什么吗? 我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 + ### 非奇异矩阵 对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 对于 $2 \times 2$ 矩阵,行列式由以下公式给出: @@ -827,6 +832,7 @@ $$ ```{math} :label: la_se_inv + x = A^{-1} b. ``` From 838c450726bbdb093c63ea3a87afb3b4cce88891 Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 26 Sep 2024 14:54:43 +1000 Subject: [PATCH 4/7] @mmcky review and white space suggestions --- lectures/linear_equations.md | 232 ++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 111 deletions(-) diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index b32ca1d8..b75a1a9c 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -17,6 +17,7 @@ kernelspec: ``` ## 概述 + 经济学和金融学中的许多问题都需要解线性方程。 在本讲座中,我们将讨论线性方程及其应用。 @@ -43,24 +44,32 @@ import numpy as np import matplotlib.pyplot as plt ``` ## 两种商品的例子 + 在本节中,我们将讨论一个简单的两种商品例子,并通过以下两种方法解决: + 1. 纸笔计算 2. 矩阵代数 + 正如我们将看到的,第二种方法更具普遍性。 ### 纸笔计算方法 + 假设我们有两种相关的商品,比如: * 丙烷和乙醇,或 * 大米和小麦等。 + 为了简化问题,我们将它们标记为商品0和商品1。 每种商品的需求取决于两种商品的价格: + ```{math} :label: two_eq_demand + \begin{aligned} q_0^d = 100 - 10 p_0 - 5 p_1 \\ q_1^d = 50 - p_0 - 10 p_1 \end{aligned} ``` + (我们假设当任一商品的价格上涨时需求会下降,但其他情况也是可能的。) 让我们假设供给由以下方程给出: @@ -71,6 +80,7 @@ import matplotlib.pyplot as plt q_1^s = 5 p_0 + 10 p_1 \end{aligned} ``` + 当供给等于需求时($q_0^s = q_0^d$ 和 $q_1^s = q_1^d$),市场达到均衡。 这产生了以下线性系统: @@ -83,15 +93,19 @@ import matplotlib.pyplot as plt ``` 我们可以用纸笔计算得到: + $$ - p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. +p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. $$ + 将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: + $$ - q_0 = 50 \quad \text{和} \quad q_1 = 33.82. +q_0 = 50 \quad \text{和} \quad q_1 = 33.82. $$ ### 展望未来 + 在两种商品的情况下,纸笔计算方法很容易。 但如果有很多种商品呢? 对于这样的问题,我们需要矩阵代数。 @@ -100,16 +114,18 @@ $$ ## {index}`向量 ` - ```{index} single: Linear Algebra; Vectors - ``` +```{index} single: Linear Algebra; Vectors +``` 一个长度为$n$的**向量**就是一个由$n$个数字组成的序列(或数组,或元组),我们将其写作$x = (x_1, \ldots, x_n)$或$x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$。 我们可以将这些序列横向或纵向写出。 但当我们使用矩阵运算时,我们默认假设向量是列向量。 所有$n$维向量的集合用$\mathbb R^n$表示。 例如, + * $\mathbb R^2$是平面 --- 即所有$(x_1, x_2)$对的集合。 * $\mathbb R^3$是三维空间 --- 即所有$(x_1, x_2, x_3)$向量的集合。 + 向量通常在视觉上表示为从原点到某点的箭头。 这里是一个可视化示例。 @@ -145,6 +161,7 @@ plt.show() 对向量最常见的两种运算是加法和标量乘法,我们现在来描述这两种运算。 当我们对两个向量进行加法运算时,我们是逐元素相加。 例如, + $$ \begin{bmatrix} 4 \\ @@ -166,7 +183,9 @@ $$ 1 \end{bmatrix}. $$ + 一般来说, + $$ x + y = \begin{bmatrix} @@ -188,6 +207,7 @@ x + y = x_n + y_n \end{bmatrix}. $$ + 我们可以在$\mathbb{R}^2$中将向量加法可视化如下。 ```{code-cell} ipython3 @@ -228,6 +248,7 @@ plt.show() 标量乘法是一种将向量 $x$ 与一个标量进行元素级别相乘的运算。 例如, + $$ -2 \begin{bmatrix} @@ -245,7 +266,9 @@ $$ 14 \end{bmatrix}. $$ + 更一般地,它取一个数 $\gamma$ 和一个向量 $x$,得到 + $$ \gamma x := \begin{bmatrix} @@ -255,6 +278,7 @@ $$ \gamma x_n \end{bmatrix}. $$ + 标量乘法在下图中进行了说明。 ```{code-cell} ipython3 @@ -428,13 +452,17 @@ A + B = a_{n1} + b_{n1} & \cdots & a_{nk} + b_{nk} \end{bmatrix}. $$ + 在后一种情况下,矩阵必须具有相同的形状才能使定义有意义。 + ### 矩阵乘法 + 我们还有一个*相乘*两个矩阵的约定。 矩阵乘法的规则推广了上面讨论的内积的概念。 如果 $A$ 和 $B$ 是两个矩阵,那么它们的乘积 $A B$ 的形成是通过取 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列的内积作为其第 $i,j$ 个元素。 如果 $A$ 是 $n \times k$ 的,$B$ 是 $j \times m$ 的,那么要相乘 $A$ 和 $B$,我们需要 $k = j$,而得到的矩阵 $A B$ 是 $n \times m$ 的。 这里是一个 $2 \times 2$ 矩阵乘以 $2 \times 1$ 向量的例子。 + $$ Ax = \begin{bmatrix} @@ -451,6 +479,7 @@ Ax = a_{21}x_1 + a_{22}x_2 \end{bmatrix} $$ + 作为一个重要的特殊情况,考虑将 $n \times k$ 矩阵 $A$ 和 $k \times 1$ 列向量 $x$ 相乘。 根据前面的规则,这给我们一个 $n \times 1$ 列向量。 @@ -508,6 +537,7 @@ $$ ``` 一个重要的特殊情况是[单位矩阵](https://en.wikipedia.org/wiki/Identity_matrix),它在主对角线上有 1,其他地方都是 0: + $$ I = \begin{bmatrix} @@ -516,6 +546,7 @@ $$ 0 & \cdots & 1 \end{bmatrix} $$ + 验证以下内容是一个有用的练习: * 如果 $A$ 是 $n \times k$ 矩阵,$I$ 是 $k \times k$ 单位矩阵,那么 $AI = A$,并且 * 如果 $I$ 是 $n \times n$ 单位矩阵,那么 $IA = A$。 @@ -525,6 +556,7 @@ $$ ```{index} single: Matrix; Numpy ``` + NumPy 数组也被用作矩阵,并且对所有标准矩阵运算都有快速、高效的函数和方法。 你可以通过以下方式从元组的元组(或列表的列表)手动创建它们 @@ -569,6 +601,7 @@ A + B ``` ### 矩阵形式的两种商品模型 + 我们现在可以重新审视两种商品模型,并通过矩阵代数数值求解 {eq}`two_equilibrium` 方程。 这涉及一些额外的步骤,但这种方法广泛适用 --- 正如我们在包含更多商品时将看到的那样。 首先,我们将 {eq}`two_eq_demand` 重写为 @@ -595,6 +628,7 @@ A + B 50 \end{bmatrix}. ``` + 回想一下,$p \in \mathbb{R}^{2}$ 是两种商品的价格。 (请检查 $q^d = D p + h$ 是否表示与 {eq}`two_eq_demand` 相同的方程。) 我们将 {eq}`two_eq_supply` 重写为 @@ -617,19 +651,24 @@ A + B ``` 现在供给和需求的相等可以表示为 $q^s = q^d$,或 + $$ C p = D p + h. $$ + 我们可以重新排列这些项得到 + $$ (C - D) p = h. $$ + 如果所有项都是数字,我们可以求解价格为 $p = h / (C-D)$。 矩阵代数允许我们做类似的事情:我们可以使用 $C - D$ 的逆矩阵来求解均衡价格: ```{math} :label: two_matrix - p = (C - D)^{-1} h. + +p = (C - D)^{-1} h. ``` 在我们实施解决方案之前,让我们考虑一个更一般的设置。 @@ -656,15 +695,18 @@ $$ ```{math} :label: n_eq_sys_la - (D- C)p = e - h. + +(D- C)p = e - h. ``` 那么,n 种不同商品的价格向量是 + $$ p = (D- C)^{-1}(e - h). $$ ### 一般线性系统 + 上述问题的一个更一般版本看起来如下。 ```{math} @@ -687,23 +729,25 @@ $$ ```{math} :label: la_gf - A x = b - \quad \text{where} \quad - A = - \begin{bmatrix} - a_{11} & \cdots & a_{1n} \\ - \vdots & \vdots & \vdots \\ - a_{n1} & \cdots & a_{nn} - \end{bmatrix} - \quad \text{and} \quad - b = - \begin{bmatrix} - b_1 \\ - \vdots \\ - b_n - \end{bmatrix}. +A x = b +\quad \text{where} \quad +A = +\begin{bmatrix} + a_{11} & \cdots & a_{1n} \\ + \vdots & \vdots & \vdots \\ + a_{n1} & \cdots & a_{nn} +\end{bmatrix} +\quad \text{and} \quad +b = +\begin{bmatrix} + b_1 \\ + \vdots \\ + b_n +\end{bmatrix}. ``` + 例如,{eq}`n_eq_sys_la` 具有这种形式,其中 + $$ A = D - C, \quad @@ -711,6 +755,7 @@ $$ \quad \text{和} \quad x = p. $$ + 当考虑诸如 {eq}`la_gf` 这样的问题时,我们至少需要问以下一些问题: * 解是否真的存在? * 如果解存在,我们应该如何计算它? @@ -725,21 +770,25 @@ $$ ```{math} :label: la_se2 - A x = b +A x = b ``` 我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 {eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 我们在下面举例说明两种这样的情况。 + ### 无解 + 考虑由以下给出的方程组: + $$ \begin{aligned} x + 3y &= 3 \\ 2x + 6y &= -8. \end{aligned} $$ + 可以手动验证这个系统没有可能的解。 为了说明为什么会出现这种情况,让我们绘制这两条直线。 @@ -752,28 +801,26 @@ plt.legend() plt.show() ``` -+++ {"tags": []} - - 显然,这些是平行线,因此我们永远无法找到一个点 $x \in \mathbb{R}^2$ 使得这些线相交。 因此,这个系统没有可能的解。 我们可以将这个系统用矩阵形式重写为 ```{math} :label: no_soln - A x = b - \quad \text{where} \quad - A = - \begin{bmatrix} - 1 & 3 \\ - 2 & 6 - \end{bmatrix} - \quad \text{and} \quad - b = - \begin{bmatrix} - 3 \\ - -8 - \end{bmatrix}. + +A x = b +\quad \text{where} \quad +A = +\begin{bmatrix} + 1 & 3 \\ + 2 & 6 +\end{bmatrix} +\quad \text{and} \quad +b = +\begin{bmatrix} + 3 \\ + -8 +\end{bmatrix}. ``` 可以注意到,矩阵 $A$ 的第 $2$ 行 $(2, 6)$ 只是第 $1$ 行 $(1, 3)$ 的标量倍数。 @@ -782,18 +829,19 @@ plt.show() ```{note} 高级读者可以在[这里](https://python.quantecon.org/linear_algebra.html#linear-independence)找到关于线性相关和线性无关的详细解释。 但在接下来的内容中不需要这些细节。 - ``` - ### 多解 + 现在考虑, + $$ \begin{aligned} x - 2y &= -4 \\ -2x + 4y &= 8. \end{aligned} $$ + 任何满足 $x = 2y - 4$ 的向量 $v = (x,y)$ 都将解决上述系统。 由于我们可以找到无限多个这样的向量,这个系统有无穷多个解。 这是因为对应矩阵的行 @@ -801,19 +849,21 @@ $$ ```{math} :label: many_solns - A = - \begin{bmatrix} - 1 & -2 \\ - -2 & 4 - \end{bmatrix}. +A = +\begin{bmatrix} + 1 & -2 \\ + -2 & 4 +\end{bmatrix}. ``` 是线性相关的 --- 你能看出为什么吗? 我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 ### 非奇异矩阵 + 对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 对于 $2 \times 2$ 矩阵,行列式由以下公式给出: + $$ \begin{bmatrix} \color{red}{a} & \color{blue}{b} \\ @@ -822,6 +872,7 @@ $$ = {\color{red}{ad}} - {\color{blue}{bc}}. $$ + 如果 $A$ 的行列式不为零,我们就说 $A$ 是*非奇异的*。 当且仅当 $A$ 的行和列是线性无关的,方阵 $A$ 才是非奇异的。 关于矩阵逆的更详细解释可以在[这里](https://www.mathsisfun.com/algebra/matrix-inverse.html)找到。 @@ -833,19 +884,22 @@ $$ ```{math} :label: la_se_inv - x = A^{-1} b. +x = A^{-1} b. ``` 这是对 $Ax = b$ 的解答 --- 这就是我们要寻找的解。 ### 使用NumPy求解线性方程 + ```{index} single: Linear Algebra; SciPy ``` 在两个好的例子中,我们得到了矩阵方程: + $$ p = (C-D)^{-1} h. $$ + 其中 $C$、$D$ 和 $h$ 由 {eq}`two_eq_demand_mat` 和 {eq}`two_eq_supply_mat` 给出。 这个方程类似于 {eq}`la_se_inv`,其中 $A = (C-D)^{-1}$,$b = h$,且 $x = p$。 我们现在可以使用NumPy的`linalg`子模块求解均衡价格。 @@ -908,16 +962,20 @@ p q = C @ p # 均衡数量 q ``` + 观察我们如何通过 `inv(A) @ y` 或使用 `solve(A, y)` 来求解 $x = A^{-1} y$。 后一种方法使用了一种不同的算法,在数值上更加稳定,因此应该是默认选项。 ## 练习 + ```{exercise-start} :label: lin_eqs_ex1 ``` + 让我们考虑一个有3种商品的市场 - 商品0、商品1和商品2。 每种商品的需求取决于其他两种商品的价格,由以下公式给出: + $$ \begin{aligned} q_0^d & = 90 - 15p_0 + 5p_1 + 5p_2 \\ @@ -925,8 +983,10 @@ $$ q_2^d & = 50 + 5p_0 + 5p_1 - 5p_2 \end{aligned} $$ + (这里,当自身价格上涨时需求下降,但当其他商品价格上涨时需求增加。) 每种商品的供给由以下公式给出: + $$ \begin{aligned} q_0^s & = -10 + 20p_0 \\ @@ -934,16 +994,19 @@ $$ q_2^s & = -5 + 10p_2 \end{aligned} $$ + 当供给等于需求时,市场达到均衡,即 $q_0^d = q_0^s$,$q_1^d = q_1^s$ 和 $q_2^d = q_2^s$。 1. 将市场设置为线性方程组。 2. 使用矩阵代数求解均衡价格。分别使用 `numpy.linalg.solve` 和 `inv(A)` 方法来做这个。比较这两种解法。 ```{exercise-end} ``` + ```{solution-start} lin_eqs_ex1 :class: dropdown ``` 生成的系统将是: + $$ \begin{aligned} 35p_0 - 5p_1 - 5p_2 = 100 \\ @@ -951,7 +1014,9 @@ $$ -5p_0 - 5p_1 + 15p_2 = 55 \end{aligned} $$ + 用矩阵形式,我们将其表示为: + $$ Ap = b \quad \text{其中} \quad @@ -1008,6 +1073,7 @@ p ``` 答案为: + $$ p_0 = 4.6925, \; p_1 = 7.0625 \;\; \text{and} \;\; p_2 = 7.675 $$ @@ -1033,9 +1099,11 @@ $$ 对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 小于$Ax$到$b$的距离。 即, + $$ \|A\hat{x} - b\| \leq \|Ax - b\| $$ + 可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 ```{math} @@ -1044,19 +1112,24 @@ $$ ``` 现在考虑一种商品的线性需求曲线的一般方程: + $$ p = m - nq $$ + 其中$p$是商品的价格,$q$是需求量。 假设我们正试图*估计*$m$和$n$的值。 我们通过重复观察价格和数量(例如,每个月)来做到这一点,然后选择$m$和$n$来拟合$p$和$q$之间的关系。 我们有以下观察结果: + | 价格 | 需求量 | |:-----:|:-----------------:| | 1 | 9 | | 3 | 7 | | 8 | 3 | + 要求需求曲线$p = m - nq$通过所有这些点,得到以下三个方程: + $$ \begin{aligned} 1 = m - 9n \\ @@ -1064,8 +1137,10 @@ $$ 8 = m - 3n \end{aligned} $$ + 因此,我们得到一个方程组$Ax = b$,其中$A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, $x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$。 + 可以验证这个系统没有解。 (问题在于我们有三个方程但只有两个未知数。) 因此,我们将尝试找到$x$的最佳近似解。 @@ -1136,68 +1211,3 @@ plt.show() ### 延伸阅读 `numpy.linalg` 子模块的文档可以在[这里](https://numpy.org/devdocs/reference/routines.linalg.html)找到。 线性代数的更高级主题可以在[这里](https://python.quantecon.org/linear_algebra.html#id5)找到。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 9bf06e7d2e0f72452eddcdc0c1e4486addaef3ea Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 26 Sep 2024 17:01:52 +1000 Subject: [PATCH 5/7] white space before {eq} --- lectures/linear_equations.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index b75a1a9c..898496b6 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -98,7 +98,7 @@ $$ p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. $$ -将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: +将这些结果代入 {eq}`two_eq_demand` 或 {eq}`two_eq_supply` 中,可得均衡数量: $$ q_0 = 50 \quad \text{和} \quad q_1 = 33.82. @@ -773,8 +773,7 @@ $$ A x = b ``` -我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 -{eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 +我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 {eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 我们在下面举例说明两种这样的情况。 @@ -1096,12 +1095,12 @@ $$ ``` 其中$A$是一个$m \times n$矩阵,$b$是一个$m \times 1$列向量。 -对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 +对于 {eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 小于$Ax$到$b$的距离。 即, $$ - \|A\hat{x} - b\| \leq \|Ax - b\| +\|A\hat{x} - b\| \leq \|Ax - b\| $$ 可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 @@ -1114,7 +1113,7 @@ $$ 现在考虑一种商品的线性需求曲线的一般方程: $$ - p = m - nq +p = m - nq $$ 其中$p$是商品的价格,$q$是需求量。 @@ -1144,8 +1143,8 @@ $x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \e 可以验证这个系统没有解。 (问题在于我们有三个方程但只有两个未知数。) 因此,我们将尝试找到$x$的最佳近似解。 -1. 使用{eq}`least_squares`和矩阵代数找到最小二乘解$\hat{x}$。 -2. 使用`numpy.linalg.lstsq`找到最小二乘解,并比较结果。 +1. 使用 {eq}`least_squares` 和矩阵代数找到最小二乘解 $\hat{x}$。 +2. 使用 `numpy.linalg.lstsq` 找到最小二乘解,并比较结果。 ```{exercise-end} From 21134ce7fa16f375b3508f916d1d39796be1048f Mon Sep 17 00:00:00 2001 From: Longye Tian Date: Thu, 26 Sep 2024 19:59:48 +1000 Subject: [PATCH 6/7] Update linear_equations.md --- lectures/linear_equations.md | 244 ++++++++++++++++++++++++++--------- 1 file changed, 182 insertions(+), 62 deletions(-) diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index 898496b6..b8001027 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -55,10 +55,12 @@ import matplotlib.pyplot as plt ### 纸笔计算方法 假设我们有两种相关的商品,比如: + * 丙烷和乙醇,或 * 大米和小麦等。 为了简化问题,我们将它们标记为商品0和商品1。 + 每种商品的需求取决于两种商品的价格: ```{math} @@ -73,8 +75,10 @@ import matplotlib.pyplot as plt (我们假设当任一商品的价格上涨时需求会下降,但其他情况也是可能的。) 让我们假设供给由以下方程给出: + ```{math} :label: two_eq_supply + \begin{aligned} q_0^s = 10 p_0 + 5 p_1 \\ q_1^s = 5 p_0 + 10 p_1 @@ -82,10 +86,12 @@ import matplotlib.pyplot as plt ``` 当供给等于需求时($q_0^s = q_0^d$ 和 $q_1^s = q_1^d$),市场达到均衡。 + 这产生了以下线性系统: ```{math} :label: two_equilibrium + \begin{aligned} 100 - 10 p_0 - 5 p_1 = 10 p_0 + 5 p_1 \\ 50 - p_0 - 10 p_1 = 5 p_0 + 10 p_1 @@ -95,38 +101,47 @@ import matplotlib.pyplot as plt 我们可以用纸笔计算得到: $$ -p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. + p_0 = 4.41 \quad \text{和} \quad p_1 = 1.18. $$ -将这些结果代入 {eq}`two_eq_demand` 或 {eq}`two_eq_supply` 中,可得均衡数量: +将这些结果代入{eq}`two_eq_demand`或{eq}`two_eq_supply`中,可得均衡数量: $$ -q_0 = 50 \quad \text{和} \quad q_1 = 33.82. + q_0 = 50 \quad \text{和} \quad q_1 = 33.82. $$ ### 展望未来 在两种商品的情况下,纸笔计算方法很容易。 + 但如果有很多种商品呢? + 对于这样的问题,我们需要矩阵代数。 + 在用矩阵代数解决问题之前,让我们先回顾一下向量和矩阵的基础知识,包括理论和计算。 ## {index}`向量 ` -```{index} single: Linear Algebra; Vectors -``` + ```{index} single: Linear Algebra; Vectors + ``` 一个长度为$n$的**向量**就是一个由$n$个数字组成的序列(或数组,或元组),我们将其写作$x = (x_1, \ldots, x_n)$或$x = \begin{bmatrix}x_1, \ldots, x_n\end{bmatrix}$。 + 我们可以将这些序列横向或纵向写出。 + 但当我们使用矩阵运算时,我们默认假设向量是列向量。 + 所有$n$维向量的集合用$\mathbb R^n$表示。 -例如, + +```{prf:example} +:label: le_ex_dim * $\mathbb R^2$是平面 --- 即所有$(x_1, x_2)$对的集合。 * $\mathbb R^3$是三维空间 --- 即所有$(x_1, x_2, x_3)$向量的集合。 - 向量通常在视觉上表示为从原点到某点的箭头。 +``` + 这里是一个可视化示例。 ```{code-cell} ipython3 @@ -158,9 +173,13 @@ plt.show() ``` 有时我们需要修改向量。 + 对向量最常见的两种运算是加法和标量乘法,我们现在来描述这两种运算。 + 当我们对两个向量进行加法运算时,我们是逐元素相加。 -例如, + +```{prf:example} +:label: le_ex_add $$ \begin{bmatrix} @@ -183,6 +202,7 @@ $$ 1 \end{bmatrix}. $$ +``` 一般来说, @@ -247,7 +267,9 @@ plt.show() ``` 标量乘法是一种将向量 $x$ 与一个标量进行元素级别相乘的运算。 -例如, + +```{prf:example} +:label: le_ex_mul $$ -2 @@ -266,6 +288,7 @@ $$ 14 \end{bmatrix}. $$ +``` 更一般地,它取一个数 $\gamma$ 和一个向量 $x$,得到 @@ -316,6 +339,7 @@ plt.show() 在Python中,向量可以用列表或元组表示, 例如 `x = [2, 4, 6]` 或 `x = (2, 4, 6]`。 + 然而,更常见的是用 [NumPy数组](https://python-programming.quantecon.org/numpy.html#numpy-arrays)来表示向量。 @@ -340,6 +364,7 @@ x + y # 每个元素相加 ``` 向量 $x,y \in \mathbb R^n$ 的**内积**定义为 + $$ x^\top y = \begin{bmatrix} @@ -354,11 +379,15 @@ x^\top y = = {\color{red}{x_1 y_1}} + {\color{blue}{x_2 y_2}} + \cdots + x_n y_n := \sum_{i=1}^n x_i y_i. $$ + 向量 $x$ 的**范数**表示其"长度"(即,其与零向量的距离),定义为 + $$ \| x \| := \sqrt{x^\top x} := \left( \sum_{i=1}^n x_i^2 \right)^{1/2}. $$ + 表达式 $\| x - y\|$ 可以被理解为 $x$ 和 $y$ 之间的"距离"。 + 内积和范数可以按以下方式计算 ```{code-cell} ipython3 @@ -383,12 +412,20 @@ np.linalg.norm(x) # x的范数,方法二 ``` 当我们讨论线性价格系统时,我们提到了使用矩阵代数。 + 矩阵代数类似于数字代数。 + 让我们回顾一些细节。 + ### 加法和标量乘法 + 就像向量一样,我们可以对矩阵进行加法、减法和标量乘法。 + 标量乘法和加法是向量情况的推广: -以下是标量乘法的一个例子 + +```{prf:example} +:label: le_ex_asm + $$ 3 \begin{bmatrix} @@ -401,7 +438,10 @@ $$ 0 & 15 \end{bmatrix}. $$ +``` + 一般来说,对于任意数 $\gamma$ 和任意矩阵 $A$, + $$ \gamma A = \gamma @@ -416,6 +456,10 @@ $$ \gamma a_{n1} & \cdots & \gamma a_{nk} \end{bmatrix}. $$ + +```{prf:example} +:label: le_ex_ma + 考虑这个矩阵加法的例子, $$ \begin{bmatrix} @@ -433,7 +477,10 @@ $$ 7 & 12 \end{bmatrix}. $$ +``` + 一般来说, + $$ A + B = \begin{bmatrix} @@ -458,9 +505,16 @@ $$ ### 矩阵乘法 我们还有一个*相乘*两个矩阵的约定。 + 矩阵乘法的规则推广了上面讨论的内积的概念。 + 如果 $A$ 和 $B$ 是两个矩阵,那么它们的乘积 $A B$ 的形成是通过取 $A$ 的第 $i$ 行和 $B$ 的第 $j$ 列的内积作为其第 $i,j$ 个元素。 + 如果 $A$ 是 $n \times k$ 的,$B$ 是 $j \times m$ 的,那么要相乘 $A$ 和 $B$,我们需要 $k = j$,而得到的矩阵 $A B$ 是 $n \times m$ 的。 + +```{prf:example} +:label: le_ex_2dmul + 这里是一个 $2 \times 2$ 矩阵乘以 $2 \times 1$ 向量的例子。 $$ @@ -479,8 +533,10 @@ Ax = a_{21}x_1 + a_{22}x_2 \end{bmatrix} $$ +``` 作为一个重要的特殊情况,考虑将 $n \times k$ 矩阵 $A$ 和 $k \times 1$ 列向量 $x$ 相乘。 + 根据前面的规则,这给我们一个 $n \times 1$ 列向量。 ```{math} @@ -529,6 +585,7 @@ AB = $$ 有许多教程可以帮助你进一步可视化这个操作,例如 + * [这个教程](http://www.mathsisfun.com/algebra/matrix-multiplying.html),或者 * [维基百科页面](https://en.wikipedia.org/wiki/Matrix_multiplication)上的讨论。 @@ -548,6 +605,7 @@ $$ $$ 验证以下内容是一个有用的练习: + * 如果 $A$ 是 $n \times k$ 矩阵,$I$ 是 $k \times k$ 单位矩阵,那么 $AI = A$,并且 * 如果 $I$ 是 $n \times n$ 单位矩阵,那么 $IA = A$。 @@ -556,8 +614,8 @@ $$ ```{index} single: Matrix; Numpy ``` - NumPy 数组也被用作矩阵,并且对所有标准矩阵运算都有快速、高效的函数和方法。 + 你可以通过以下方式从元组的元组(或列表的列表)手动创建它们 ```{code-cell} ipython3 @@ -579,8 +637,11 @@ A.shape `shape` 属性是一个给出行数和列数的元组 --- 更多讨论请参见[这里](https://python-programming.quantecon.org/numpy.html#shape-and-dimension)。 + 要获得 `A` 的转置,使用 `A.transpose()` 或更简单地使用 `A.T`。 + 有许多方便的函数用于创建常见矩阵(零矩阵、单位矩阵等) --- 请参见[这里](https://python-programming.quantecon.org/numpy.html#creating-arrays)。 + 由于默认情况下操作是按元素执行的,标量乘法和加法具有非常自然的语法。 ```{code-cell} ipython3 @@ -603,11 +664,13 @@ A + B ### 矩阵形式的两种商品模型 我们现在可以重新审视两种商品模型,并通过矩阵代数数值求解 {eq}`two_equilibrium` 方程。 + 这涉及一些额外的步骤,但这种方法广泛适用 --- 正如我们在包含更多商品时将看到的那样。 首先,我们将 {eq}`two_eq_demand` 重写为 ```{math} :label: two_eq_demand_mat + q^d = D p + h \quad \text{where} \quad q^d = @@ -630,11 +693,14 @@ A + B ``` 回想一下,$p \in \mathbb{R}^{2}$ 是两种商品的价格。 + (请检查 $q^d = D p + h$ 是否表示与 {eq}`two_eq_demand` 相同的方程。) + 我们将 {eq}`two_eq_supply` 重写为 ```{math} :label: two_eq_supply_mat + q^s = C p \quad \text{where} \quad q^s = @@ -668,25 +734,32 @@ $$ ```{math} :label: two_matrix -p = (C - D)^{-1} h. + p = (C - D)^{-1} h. ``` 在我们实施解决方案之前,让我们考虑一个更一般的设置。 ### 更多商品 + 考虑有更多商品的需求系统是很自然的。 + 例如,即使在能源商品中也有许多不同的商品, 包括原油、汽油、煤炭、天然气、乙醇和铀。 + 这些商品的价格是相关的,所以一起研究它们是有意义的。 + 对于大型系统,纸笔方法会变得非常耗时。 + 但幸运的是,上面描述的矩阵方法基本上保持不变。 一般来说,我们可以将需求方程写为 $q^d = Dp + h$,其中 + * $q^d$ 是一个 $n \times 1$ 的向量,表示 $n$ 种不同商品的需求量。 * $D$ 是一个 $n \times n$ 的"系数"矩阵。 * $h$ 是一个 $n \times 1$ 的常数值向量。 类似地,我们可以将供给方程写为 $q^s = Cp + e$,其中 + * $q^s$ 是一个 $n \times 1$ 的向量,表示相同商品的供给量。 * $C$ 是一个 $n \times n$ 的"系数"矩阵。 * $e$ 是一个 $n \times 1$ 的常数值向量。 @@ -696,7 +769,7 @@ p = (C - D)^{-1} h. ```{math} :label: n_eq_sys_la -(D- C)p = e - h. + (D- C)p = e - h. ``` 那么,n 种不同商品的价格向量是 @@ -720,32 +793,36 @@ $$ ``` 这里的目标是解出"未知数" $x_1, \ldots, x_n$。 + 我们给定系数 $a_{11}, \ldots, a_{nn}$ 和常数 $b_1, \ldots, b_n$。 + 注意,我们处理的是未知数数量等于方程数量的情况。 + 这是我们最有可能找到明确定义解的情况。 + (其他情况被称为[超定](https://en.wikipedia.org/wiki/Overdetermined_system)和[欠定](https://en.wikipedia.org/wiki/Underdetermined_system)方程组 --- 我们将在后续讲座中讨论这些情况。) + 用矩阵形式表示,方程组 {eq}`la_se` 变为 ```{math} :label: la_gf -A x = b -\quad \text{where} \quad -A = -\begin{bmatrix} - a_{11} & \cdots & a_{1n} \\ - \vdots & \vdots & \vdots \\ - a_{n1} & \cdots & a_{nn} -\end{bmatrix} -\quad \text{and} \quad -b = -\begin{bmatrix} - b_1 \\ - \vdots \\ - b_n -\end{bmatrix}. + A x = b + \quad \text{where} \quad + A = + \begin{bmatrix} + a_{11} & \cdots & a_{1n} \\ + \vdots & \vdots & \vdots \\ + a_{n1} & \cdots & a_{nn} + \end{bmatrix} + \quad \text{and} \quad + b = + \begin{bmatrix} + b_1 \\ + \vdots \\ + b_n + \end{bmatrix}. ``` - 例如,{eq}`n_eq_sys_la` 具有这种形式,其中 $$ @@ -757,6 +834,7 @@ $$ $$ 当考虑诸如 {eq}`la_gf` 这样的问题时,我们至少需要问以下一些问题: + * 解是否真的存在? * 如果解存在,我们应该如何计算它? @@ -770,11 +848,13 @@ $$ ```{math} :label: la_se2 -A x = b + A x = b ``` -我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 {eq}`la_se2`,其中 $b$ 和 $A$ 是给定的。 -我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2`。 +我们面临的问题是找到一个向量 $x \in \mathbb R^n$,使其解决 {eq}`la_se2` ,其中 $b$ 和 $A$ 是给定的。 + +我们可能并不总能找到一个唯一的向量 $x$ 来解决 {eq}`la_se2` 。 + 我们在下面举例说明两种这样的情况。 ### 无解 @@ -789,6 +869,7 @@ $$ $$ 可以手动验证这个系统没有可能的解。 + 为了说明为什么会出现这种情况,让我们绘制这两条直线。 ```{code-cell} ipython3 @@ -800,36 +881,45 @@ plt.legend() plt.show() ``` ++++ {"tags": []} + + 显然,这些是平行线,因此我们永远无法找到一个点 $x \in \mathbb{R}^2$ 使得这些线相交。 + 因此,这个系统没有可能的解。 + 我们可以将这个系统用矩阵形式重写为 ```{math} :label: no_soln -A x = b -\quad \text{where} \quad -A = -\begin{bmatrix} - 1 & 3 \\ - 2 & 6 -\end{bmatrix} -\quad \text{and} \quad -b = -\begin{bmatrix} - 3 \\ - -8 -\end{bmatrix}. + A x = b + \quad \text{where} \quad + A = + \begin{bmatrix} + 1 & 3 \\ + 2 & 6 + \end{bmatrix} + \quad \text{and} \quad + b = + \begin{bmatrix} + 3 \\ + -8 + \end{bmatrix}. ``` 可以注意到,矩阵 $A$ 的第 $2$ 行 $(2, 6)$ 只是第 $1$ 行 $(1, 3)$ 的标量倍数。 + 在这种情况下,矩阵 $A$ 的行被称为**线性相关的。** ```{note} 高级读者可以在[这里](https://python.quantecon.org/linear_algebra.html#linear-independence)找到关于线性相关和线性无关的详细解释。 + 但在接下来的内容中不需要这些细节。 + ``` + ### 多解 现在考虑, @@ -842,25 +932,29 @@ $$ $$ 任何满足 $x = 2y - 4$ 的向量 $v = (x,y)$ 都将解决上述系统。 + 由于我们可以找到无限多个这样的向量,这个系统有无穷多个解。 + 这是因为对应矩阵的行 ```{math} :label: many_solns -A = -\begin{bmatrix} - 1 & -2 \\ - -2 & 4 -\end{bmatrix}. + A = + \begin{bmatrix} + 1 & -2 \\ + -2 & 4 + \end{bmatrix}. ``` 是线性相关的 --- 你能看出为什么吗? + 我们现在对 {eq}`la_se2` 中的 $A$ 施加条件,以排除这些问题。 ### 非奇异矩阵 对于每个方阵,我们都可以指定一个唯一的数,称为[行列式](https://en.wikipedia.org/wiki/Determinant)。 + 对于 $2 \times 2$ 矩阵,行列式由以下公式给出: $$ @@ -873,17 +967,23 @@ $$ $$ 如果 $A$ 的行列式不为零,我们就说 $A$ 是*非奇异的*。 + 当且仅当 $A$ 的行和列是线性无关的,方阵 $A$ 才是非奇异的。 + 关于矩阵逆的更详细解释可以在[这里](https://www.mathsisfun.com/algebra/matrix-inverse.html)找到。 + 你可以自己检查 {eq}`no_soln` 和 {eq}`many_solns` 中具有线性相关行的矩阵是奇异矩阵。 + 这为我们提供了一个有用的单数值概括,用来判断一个方阵是否可逆。 + 特别地,方阵 $A$ 具有非零行列式,当且仅当它具有*逆矩阵* $A^{-1}$,满足 $A A^{-1} = A^{-1} A = I$。 + 因此,如果我们用 $A^{-1}$ 左乘 $Ax = b$ 的两边,我们得到 ```{math} :label: la_se_inv -x = A^{-1} b. + x = A^{-1} b. ``` 这是对 $Ax = b$ 的解答 --- 这就是我们要寻找的解。 @@ -900,8 +1000,11 @@ p = (C-D)^{-1} h. $$ 其中 $C$、$D$ 和 $h$ 由 {eq}`two_eq_demand_mat` 和 {eq}`two_eq_supply_mat` 给出。 + 这个方程类似于 {eq}`la_se_inv`,其中 $A = (C-D)^{-1}$,$b = h$,且 $x = p$。 + 我们现在可以使用NumPy的`linalg`子模块求解均衡价格。 + 所有这些程序都是经过时间检验和高度优化的FORTRAN代码的Python前端。 ```{code-cell} ipython3 @@ -949,6 +1052,7 @@ q ``` 注意,我们得到的解与纸笔计算的情况相同。 + 我们还可以使用 `solve(A, h)` 来求解 $p$,如下所示。 ```{code-cell} ipython3 @@ -961,18 +1065,17 @@ p q = C @ p # 均衡数量 q ``` - 观察我们如何通过 `inv(A) @ y` 或使用 `solve(A, y)` 来求解 $x = A^{-1} y$。 + 后一种方法使用了一种不同的算法,在数值上更加稳定,因此应该是默认选项。 ## 练习 - ```{exercise-start} :label: lin_eqs_ex1 ``` - 让我们考虑一个有3种商品的市场 - 商品0、商品1和商品2。 + 每种商品的需求取决于其他两种商品的价格,由以下公式给出: $$ @@ -984,6 +1087,7 @@ $$ $$ (这里,当自身价格上涨时需求下降,但当其他商品价格上涨时需求增加。) + 每种商品的供给由以下公式给出: $$ @@ -995,12 +1099,12 @@ $$ $$ 当供给等于需求时,市场达到均衡,即 $q_0^d = q_0^s$,$q_1^d = q_1^s$ 和 $q_2^d = q_2^s$。 + 1. 将市场设置为线性方程组。 2. 使用矩阵代数求解均衡价格。分别使用 `numpy.linalg.solve` 和 `inv(A)` 方法来做这个。比较这两种解法。 ```{exercise-end} ``` - ```{solution-start} lin_eqs_ex1 :class: dropdown ``` @@ -1084,41 +1188,51 @@ $$ :label: lin_eqs_ex2 ``` 在讲座的早些时候,我们讨论了$Ax = b$这个方程组没有解的情况。 + 在这种情况下,$Ax = b$被称为*不相容*方程组。 + 面对不相容系统时,我们尝试找到最佳的"近似"解。 + 有多种方法可以做到这一点,其中一种是**最小二乘法**。 + 假设我们有一个不相容系统 ```{math} :label: inconsistent + Ax = b ``` 其中$A$是一个$m \times n$矩阵,$b$是一个$m \times 1$列向量。 -对于 {eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离 -小于$Ax$到$b$的距离。 + +对于{eq}`inconsistent`,**最小二乘解**是一个$n \times 1$列向量$\hat{x}$,使得对于所有其他向量$x \in \mathbb{R}^n$,$A\hat{x}$到$b$的距离小于$Ax$到$b$的距离。 + 即, $$ -\|A\hat{x} - b\| \leq \|Ax - b\| + \|A\hat{x} - b\| \leq \|Ax - b\| $$ 可以证明,对于方程组$Ax = b$,最小二乘解$\hat{x}$是 ```{math} :label: least_squares + \hat{x} = (A^T A)^{-1} A^T b ``` 现在考虑一种商品的线性需求曲线的一般方程: $$ -p = m - nq + p = m - nq $$ 其中$p$是商品的价格,$q$是需求量。 + 假设我们正试图*估计*$m$和$n$的值。 + 我们通过重复观察价格和数量(例如,每个月)来做到这一点,然后选择$m$和$n$来拟合$p$和$q$之间的关系。 + 我们有以下观察结果: | 价格 | 需求量 | @@ -1139,12 +1253,15 @@ $$ 因此,我们得到一个方程组$Ax = b$,其中$A = \begin{bmatrix} 1 & -9 \\ 1 & -7 \\ 1 & -3 \end{bmatrix}$, $x = \begin{bmatrix} m \\ n \end{bmatrix}$,$b = \begin{bmatrix} 1 \\ 3 \\ 8 \end{bmatrix}$。 - 可以验证这个系统没有解。 + (问题在于我们有三个方程但只有两个未知数。) + 因此,我们将尝试找到$x$的最佳近似解。 -1. 使用 {eq}`least_squares` 和矩阵代数找到最小二乘解 $\hat{x}$。 -2. 使用 `numpy.linalg.lstsq` 找到最小二乘解,并比较结果。 + +1. 使用{eq}`least_squares`和矩阵代数找到最小二乘解$\hat{x}$。 + +2. 使用`numpy.linalg.lstsq`找到最小二乘解,并比较结果。 ```{exercise-end} @@ -1186,6 +1303,7 @@ print(f"x\u0302 = {x}") print(f"\u2016Ax\u0302 - b\u2016\u00B2 = {res[0]}") ``` 这是一个可视化图,展示了最小二乘法如何近似一组点之间连线的方程。 + 我们也可以将此描述为在一组点之间"拟合"一条直线。 @@ -1208,5 +1326,7 @@ plt.show() ``` ### 延伸阅读 + `numpy.linalg` 子模块的文档可以在[这里](https://numpy.org/devdocs/reference/routines.linalg.html)找到。 + 线性代数的更高级主题可以在[这里](https://python.quantecon.org/linear_algebra.html#id5)找到。 From 9e534a340bc89dbb64ebd300ce7e9fa94c166e7f Mon Sep 17 00:00:00 2001 From: Longye Tian Date: Thu, 26 Sep 2024 20:38:21 +1000 Subject: [PATCH 7/7] Update linear_equations.md --- lectures/linear_equations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/linear_equations.md b/lectures/linear_equations.md index b8001027..fec1bf7e 100644 --- a/lectures/linear_equations.md +++ b/lectures/linear_equations.md @@ -734,7 +734,7 @@ $$ ```{math} :label: two_matrix - p = (C - D)^{-1} h. +p = (C - D)^{-1} h. ``` 在我们实施解决方案之前,让我们考虑一个更一般的设置。