Files
Iris Series: Visualize Math -- From Arithmetic Basics to Machine Learning 79be5dda7d Add files via upload
2025-02-01 17:06:45 +08:00

693 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"id": "73bd968b-d970-4a05-94ef-4e7abf990827",
"metadata": {},
"source": [
"Chapter 05\n",
"\n",
"# 爱因斯坦求和约定\n",
"Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)"
]
},
{
"cell_type": "markdown",
"id": "05612796-d376-409c-bb07-3da0f851fa29",
"metadata": {},
"source": [
"这段代码使用 `numpy` 库的 `einsum` 函数进行各种矩阵和向量的运算。`einsum` 函数的主要优势在于其高效的索引处理方式,使得许多复杂的矩阵和向量操作可以用简单的字符串表达式来实现。这段代码包括以下几个主要部分:\n",
"\n",
"1. **定义向量与矩阵** \n",
" 定义了两个列向量\n",
"\n",
" $$ a = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix} $$\n",
" $$ b = \\begin{bmatrix} -4 \\\\ -5 \\\\ -6 \\end{bmatrix} $$\n",
"\n",
" 以及它们对应的一维向量形式 \\( a_{1D} = [1, 2, 3] \\) 和 \\( b_{1D} = [-4, -5, -6] \\)。\n",
"\n",
"3. **向量和矩阵的求和** \n",
" 使用 `einsum('ij->', a)` 计算 \\( a \\) 中所有元素的和,即 \\( \\sum_{i,j} a_{ij} \\)。 \n",
" 同样地,`einsum('i->', a_{1D})` 计算 \\( a_{1D} \\) 的元素和,即 \\( \\sum_i a_{i} \\)。\n",
"\n",
"4. **逐元素乘积** \n",
" 使用 `einsum('ij,ij->ij', a, b)` 计算 \\( a \\) 和 \\( b \\) 的逐元素乘积,其结果为一个矩阵,其中每个元素 \\( (i,j) \\) 对应 \\( a_{ij} \\times b_{ij} \\)。 \n",
" 对一维向量 `a_1D` 和 `b_1D` 的逐元素乘积,则通过 `einsum('i,i->i', a_{1D}, b_{1D})` 实现,得到 \\( [a_1 \\times b_1, a_2 \\times b_2, a_3 \\times b_3] \\)。\n",
"\n",
"5. **向量的内积** \n",
" 使用 `einsum('ij,ij->', a, b)` 计算 \\( a \\) 和 \\( b \\) 的内积,即 \\( \\sum_{i,j} a_{ij} \\cdot b_{ij} \\)。 \n",
" 类似地,对于一维向量的内积,通过 `einsum('i,i->', a_{1D}, b_{1D})` 计算,公式为 \\( \\sum_i a_i \\cdot b_i \\)。\n",
"\n",
"6. **向量的外积** \n",
" `einsum('ij,ji->ij', a, a)` 计算向量 \\( a \\) 自身的外积,生成一个矩阵,每个元素为 \\( a_{ij} \\cdot a_{ji} \\)。 \n",
" 而 `einsum('i,j->ij', a_{1D}, a_{1D})` 计算 \\( a_{1D} \\) 的外积,得到一个 \\( 3 \\times 3 \\) 矩阵,其元素为 \\( a_i \\cdot a_j \\)。\n",
"\n",
"7. **矩阵的定义及运算** \n",
" 定义了两个 \\( 3 \\times 3 \\) 的矩阵 \\( A \\) 和 \\( B \\)。矩阵 \\( A \\) 和 \\( B \\) 之间的运算包括以下内容: \n",
" \n",
" - **转置** `einsum('ji', A)` 计算 \\( A \\) 的转置。\n",
" \n",
" - **矩阵求和** `einsum('ij->', A)` 计算矩阵 \\( A \\) 所有元素的和。 \n",
" \n",
" - **按行和按列求和** \n",
" 使用 `einsum('ij->j', A)` 计算每列的和,结果为一个一维数组,形式为 \\( \\sum_i A_{ij} \\)。 \n",
" `einsum('ij->i', A)` 计算每行的和,结果形式为 \\( \\sum_j A_{ij} \\)。\n",
"\n",
" - **提取主对角线和计算迹** \n",
" `einsum('ii->i', A)` 提取 \\( A \\) 的主对角线元素,结果为 \\( [A_{11}, A_{22}, A_{33}] \\)。 \n",
" `einsum('ii->', A)` 计算矩阵 \\( A \\) 的迹 \\( \\text{tr}(A) = \\sum_i A_{ii} \\)。\n",
"\n",
" - **矩阵乘法和结果求和** \n",
" `einsum('ij,jk->ik', A, B)` 计算 \\( A \\) 和 \\( B \\) 的矩阵乘积 \\( C = A \\times B \\),即 \\( C_{ik} = \\sum_j A_{ij} \\cdot B_{jk} \\)。 \n",
" `einsum('ij,jk->', A, B)` 计算 \\( A \\times B \\) 的所有元素和。 \n",
" `einsum('ij,jk->ki', A, B)` 先进行矩阵乘法,再对结果转置。\n",
"\n",
" - **逐元素乘积** \n",
" `einsum('ij,ij->ij', A, B)` 计算 \\( A \\) 和 \\( B \\) 的逐元素乘积,结果为矩阵 \\( D \\),其中 \\( D_{ij} = A_{ij} \\cdot B_{ij} \\)。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "97fcb029-de43-4a4b-ba5f-ad331b7a78eb",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "markdown",
"id": "4a4e312b-9e45-4be6-afcc-83060d1798ee",
"metadata": {},
"source": [
"## 定义矩阵和向量"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b8e03123-64d1-4387-8fc7-6e7464e5a529",
"metadata": {},
"outputs": [],
"source": [
"a = np.array([[1],\n",
" [2],\n",
" [3]]) # 定义列向量 a"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c691db9b-31d1-4661-ac0b-17f39e31bddb",
"metadata": {},
"outputs": [],
"source": [
"a_1D = np.array([1,2,3]) # 定义一维向量 a_1D"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6f95f355-f84a-4476-a424-89279c00eab2",
"metadata": {},
"outputs": [],
"source": [
"b = np.array([[-4],\n",
" [-5],\n",
" [-6]]) # 定义列向量 b"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "9868ad35-72ff-4e73-b364-02186f82ddde",
"metadata": {},
"outputs": [],
"source": [
"b_1D = np.array([-4,-5,-6]) # 定义一维向量 b_1D"
]
},
{
"cell_type": "markdown",
"id": "da290670-c5b3-45fb-90b9-d2260356cb7f",
"metadata": {},
"source": [
"## 计算向量 a 的元素和"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "ce155c35-ebdc-4fb7-9036-b64a5e7c51c5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6\n"
]
}
],
"source": [
"print(np.einsum('ij->',a)) # 计算矩阵 a 所有元素的和"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "fc84a3f0-61a5-4a06-af67-dc92507acf20",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6\n"
]
}
],
"source": [
"print(np.einsum('i->',a_1D)) # 计算向量 a_1D 所有元素的和"
]
},
{
"cell_type": "markdown",
"id": "3fe87ea0-03ac-4f71-8571-8ae0ed8a5269",
"metadata": {},
"source": [
"## 向量 a 和 b 的逐元素乘积"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "bc000421-7392-4603-8fe8-aa6608e1c1cb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -4]\n",
" [-10]\n",
" [-18]]\n"
]
}
],
"source": [
"print(np.einsum('ij,ij->ij',a,b)) # 计算矩阵 a 和 b 的逐元素乘积"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "bb28fdab-b2b0-4d28-8f62-1453d77bfbb4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ -4 -10 -18]\n"
]
}
],
"source": [
"print(np.einsum('i,i->i',a_1D,b_1D)) # 计算向量 a_1D 和 b_1D 的逐元素乘积"
]
},
{
"cell_type": "markdown",
"id": "aee84a7c-d65b-440a-967b-ac45f0c28acd",
"metadata": {},
"source": [
"## 向量 a 和 b 的内积"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "34d92cbc-b818-409d-ab86-d075c27236cd",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-32\n"
]
}
],
"source": [
"print(np.einsum('ij,ij->',a,b)) # 计算矩阵 a 和 b 的内积"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "3142feb7-5501-49de-9576-a3c010cbb4be",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-32\n"
]
}
],
"source": [
"print(np.einsum('i,i->',a_1D,b_1D)) # 计算向量 a_1D 和 b_1D 的内积"
]
},
{
"cell_type": "markdown",
"id": "f19a1dbf-204b-4d08-bb7f-89fe08a5a40f",
"metadata": {},
"source": [
"## 向量 a 自身的外积"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "e46e5895-d71d-4eed-a6ae-4c6875da71bb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1 2 3]\n",
" [2 4 6]\n",
" [3 6 9]]\n"
]
}
],
"source": [
"print(np.einsum('ij,ji->ij',a,a)) # 计算矩阵 a 和自身的外积"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "1568a79b-9345-474a-aa5a-a977ef5ead8f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1 2 3]\n",
" [2 4 6]\n",
" [3 6 9]]\n"
]
}
],
"source": [
"print(np.einsum('i,j->ij',a_1D,a_1D)) # 计算向量 a_1D 和自身的外积"
]
},
{
"cell_type": "markdown",
"id": "b8cf3e0c-da91-4cb8-885e-145cc69b2bb3",
"metadata": {},
"source": [
"## 向量 a 和 b 的外积"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "442d8342-ac8e-4b31-8dd7-ab0c8704c3ff",
"metadata": {},
"outputs": [],
"source": [
"print(np.einsum('ij,ji->ij',a,b)) # 计算矩阵 a 和 b 的外积"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81954884-d255-4524-b09b-2848891ef7e7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -4 -5 -6]\n",
" [ -8 -10 -12]\n",
" [-12 -15 -18]]\n",
"[[ -4 -5 -6]\n",
" [ -8 -10 -12]\n",
" [-12 -15 -18]]\n"
]
}
],
"source": [
"print(np.einsum('i,j->ij',a_1D,b_1D)) # 计算向量 a_1D 和 b_1D 的外积"
]
},
{
"cell_type": "markdown",
"id": "9f897baa-6fca-4bf5-9613-9379363878b8",
"metadata": {},
"source": [
"## 定义方阵 A 和 B"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "31dd6b69-fc1a-4613-a3bc-f5cb51988014",
"metadata": {},
"outputs": [],
"source": [
"A = np.array([[1,2,3],\n",
" [4,5,6],\n",
" [7,8,9]]) # 定义方阵 A"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "08d16cb0-a5cb-4b32-8f2e-fc8cf5f2a206",
"metadata": {},
"outputs": [],
"source": [
"B = np.array([[-1,-4,-7],\n",
" [-2,-5,-8],\n",
" [-3,-6,-9]]) # 定义方阵 B"
]
},
{
"cell_type": "markdown",
"id": "ccad52d1-dc84-4b3c-a097-3380f3ec90a6",
"metadata": {},
"source": [
"## A 的转置"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "12e193cf-71e4-48b0-8cbb-cbcf3ccdbc6c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1 4 7]\n",
" [2 5 8]\n",
" [3 6 9]]\n"
]
}
],
"source": [
"print(np.einsum('ji',A)) # 计算矩阵 A 的转置"
]
},
{
"cell_type": "markdown",
"id": "1528a603-b271-4274-9f83-045fe64a99db",
"metadata": {},
"source": [
"## A 的元素和"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "2d6b2be7-e73a-46b1-9415-944930809770",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"45\n"
]
}
],
"source": [
"print(np.einsum('ij->',A)) # 计算矩阵 A 所有元素的和"
]
},
{
"cell_type": "markdown",
"id": "257c86ae-4793-4f91-9bfc-6128b1c9aa01",
"metadata": {},
"source": [
"## 按行求和"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "7cef1bf8-aed8-4f0a-b97b-8758d33075da",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[12 15 18]\n"
]
}
],
"source": [
"print(np.einsum('ij->j',A)) # 计算矩阵 A 的每列的和"
]
},
{
"cell_type": "markdown",
"id": "58267372-554b-4284-92c1-cee2453df11e",
"metadata": {},
"source": [
"## 按列求和"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "595287a8-6e24-408e-8552-aa7ecc6fc55f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 6 15 24]\n"
]
}
],
"source": [
"print(np.einsum('ij->i',A)) # 计算矩阵 A 的每行的和"
]
},
{
"cell_type": "markdown",
"id": "d64a84cf-72a0-408d-b896-c3b88087dbf7",
"metadata": {},
"source": [
"## 提取主对角线"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "200ca6b1-c240-4d6d-a8c2-f3fd64763bea",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 5 9]\n"
]
}
],
"source": [
"print(np.einsum('ii->i',A)) # 提取矩阵 A 的主对角线元素"
]
},
{
"cell_type": "markdown",
"id": "2b786c9a-5864-451f-906c-0f14253e5aad",
"metadata": {},
"source": [
"## 计算矩阵 A 的迹"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "9e3a19a5-0f54-4dfe-829c-be92fd12aa7b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"15\n"
]
}
],
"source": [
"print(np.einsum('ii->',A)) # 计算矩阵 A 的迹(主对角线元素的和)"
]
},
{
"cell_type": "markdown",
"id": "05751e89-a555-438c-898a-bf925c4f66b4",
"metadata": {},
"source": [
"## 矩阵 A 和 B 的乘积"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "64413023-b87d-4a78-b275-cfd84e257fc4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -14 -32 -50]\n",
" [ -32 -77 -122]\n",
" [ -50 -122 -194]]\n"
]
}
],
"source": [
"print(np.einsum('ij,jk->ik', A, B)) # 计算矩阵 A 和 B 的矩阵乘法"
]
},
{
"cell_type": "markdown",
"id": "3af4c95f-aa69-49cb-a2ce-aab8772b09c4",
"metadata": {},
"source": [
"## A 和 B 的矩阵乘积的所有元素和"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "7c47a0c5-20af-4bb1-96e8-56c601115c6a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-693\n"
]
}
],
"source": [
"print(np.einsum('ij,jk->', A, B)) # 计算矩阵 A 和 B 的乘积矩阵的所有元素的和"
]
},
{
"cell_type": "markdown",
"id": "a85f940b-b6bd-483e-8ddb-9cab6ee24ce0",
"metadata": {},
"source": [
"## 矩阵相乘后转置"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "56598ed4-fd7a-4f82-ab5b-573f72f966a2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -14 -32 -50]\n",
" [ -32 -77 -122]\n",
" [ -50 -122 -194]]\n"
]
}
],
"source": [
"print(np.einsum('ij,jk->ki', A, B)) # 计算矩阵 A 和 B 的乘积后对结果转置"
]
},
{
"cell_type": "markdown",
"id": "3ade29c2-f09c-420a-a4e4-ef3aba2aac18",
"metadata": {},
"source": [
"## A 和 B 的逐元素乘积"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "d5e5fe17-96cd-4c6d-8326-da9f6df6ac1f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -1 -8 -21]\n",
" [ -8 -25 -48]\n",
" [-21 -48 -81]]\n"
]
}
],
"source": [
"print(np.einsum('ij,ij->ij', A, B)) # 计算矩阵 A 和 B 的逐元素乘积"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "ecd322f4-f919-4be2-adc3-69d28ef25e69",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}